Skip to content

Commit ca39edb

Browse files
committed
feat(messenger): add typing notification support
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent f1855b2 commit ca39edb

16 files changed

Lines changed: 244 additions & 107 deletions

File tree

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.flipcash.app.core
22

33
import android.os.Parcelable
44
import androidx.navigation3.runtime.NavKey
5+
import com.flipcash.app.core.chat.ChatIdentifier
56
import com.flipcash.app.core.deposit.DepositResult
67
import com.flipcash.app.core.deposit.DepositStep
78
import com.flipcash.app.core.tokens.CurrencyCreatorResult
@@ -19,7 +20,6 @@ import com.flipcash.app.core.onboarding.OnboardingStep
1920
import com.getcode.navigation.flow.FlowRoute
2021
import com.getcode.navigation.flow.FlowRouteWithResult
2122
import com.getcode.opencode.model.financial.Fiat
22-
import com.flipcash.services.models.chat.ChatId
2323
import com.getcode.solana.keys.Mint
2424
import com.getcode.ui.core.RestrictionType
2525
import kotlinx.parcelize.Parcelize
@@ -238,24 +238,6 @@ sealed interface AppRoute : NavKey, Parcelable {
238238
data object NavBarSettings : Menu, com.getcode.navigation.Sheet, com.getcode.navigation.WrapContentSheet
239239
}
240240

241-
@Serializable
242-
@Parcelize
243-
sealed interface ChatIdentifier : Parcelable {
244-
val key: String
245-
246-
@Serializable
247-
@Parcelize
248-
data class ByChatId(val chatId: ChatId) : ChatIdentifier {
249-
override val key: String get() = chatId.toString()
250-
}
251-
252-
@Serializable
253-
@Parcelize
254-
data class ByContact(val e164: String, val displayName: String, val chatId: ChatId? = null) : ChatIdentifier {
255-
override val key: String get() = e164
256-
}
257-
}
258-
259241
@Serializable
260242
@Parcelize
261243
sealed interface Messaging : AppRoute {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.flipcash.app.core.chat
2+
3+
import android.os.Parcelable
4+
import com.flipcash.services.models.chat.ChatId
5+
import kotlinx.parcelize.Parcelize
6+
import kotlinx.serialization.Serializable
7+
8+
@Serializable
9+
@Parcelize
10+
sealed interface ChatIdentifier : Parcelable {
11+
val key: String
12+
13+
@Serializable
14+
@Parcelize
15+
data class ByChatId(val chatId: ChatId) : ChatIdentifier {
16+
override val key: String get() = chatId.toString()
17+
}
18+
19+
@Serializable
20+
@Parcelize
21+
data class ByContact(val e164: String, val displayName: String, val chatId: ChatId? = null) : ChatIdentifier {
22+
override val key: String get() = e164
23+
}
24+
}

apps/flipcash/features/direct-send/src/main/kotlin/com/flipcash/app/directsend/internal/SendFlowViewModel.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.flipcash.app.contacts.ContactCoordinator.ContactState
99
import com.flipcash.app.contacts.device.DeviceContact
1010
import com.flipcash.app.contacts.device.PickedContactData
1111
import com.flipcash.app.core.AppRoute
12+
import com.flipcash.app.core.chat.ChatIdentifier
1213
import com.flipcash.app.core.send.SendStep
1314
import com.flipcash.app.featureflags.FeatureFlag
1415
import com.flipcash.app.featureflags.FeatureFlagController
@@ -43,7 +44,6 @@ import kotlinx.coroutines.flow.launchIn
4344
import kotlinx.coroutines.flow.map
4445
import kotlinx.coroutines.flow.onEach
4546
import kotlinx.coroutines.flow.take
46-
import kotlinx.coroutines.launch
4747
import javax.inject.Inject
4848
import kotlin.time.Duration.Companion.seconds
4949

@@ -89,7 +89,7 @@ internal class SendFlowViewModel @Inject constructor(
8989
data class ContactRemoved(val e164: String) : Event
9090
data class SendInvite(val contact: DeviceContact) : Event
9191

92-
data class NavigateToChat(val identifier: AppRoute.ChatIdentifier) : Event
92+
data class NavigateToChat(val identifier: ChatIdentifier) : Event
9393
data class NavigateToDirectSend(val contact: DeviceContact) : Event
9494
data object PresentDepositOptions : Event
9595
data class NavigateToUsdfDepositOption(val route: AppRoute): Event
@@ -182,9 +182,9 @@ internal class SendFlowViewModel @Inject constructor(
182182
if (isOnFlipcash) {
183183
if (featureFlags.get(FeatureFlag.Messenger)) {
184184
val identifier = if (contact.e164.isNotEmpty()) {
185-
AppRoute.ChatIdentifier.ByContact(contact.e164, contact.displayName, row.chatId)
185+
ChatIdentifier.ByContact(contact.e164, contact.displayName, row.chatId)
186186
} else {
187-
AppRoute.ChatIdentifier.ByChatId(row.chatId!!)
187+
ChatIdentifier.ByChatId(row.chatId!!)
188188
}
189189
dispatchEvent(Event.NavigateToChat(identifier))
190190
} else {

apps/flipcash/features/direct-send/src/main/kotlin/com/flipcash/app/directsend/internal/screens/ContactListScreen.kt

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import androidx.compose.animation.togetherWith
77
import androidx.compose.foundation.background
88
import androidx.compose.foundation.layout.Arrangement
99
import androidx.compose.foundation.layout.Box
10-
import androidx.compose.foundation.layout.BoxScope
1110
import androidx.compose.foundation.layout.Column
1211
import androidx.compose.foundation.layout.PaddingValues
1312
import androidx.compose.foundation.layout.Row
@@ -24,34 +23,23 @@ import androidx.compose.foundation.shape.CircleShape
2423
import androidx.compose.material.icons.Icons
2524
import androidx.compose.material.icons.filled.GroupAdd
2625
import androidx.compose.material.icons.filled.Person
27-
import androidx.compose.material.icons.rounded.PersonRemove
2826
import androidx.compose.material3.HorizontalDivider
2927
import androidx.compose.material3.Icon
3028
import androidx.compose.material3.Text
3129
import androidx.compose.runtime.Composable
3230
import androidx.compose.runtime.LaunchedEffect
3331
import androidx.compose.runtime.getValue
34-
import androidx.compose.runtime.mutableStateOf
35-
import androidx.compose.runtime.remember
36-
import androidx.compose.runtime.saveable.rememberSaveable
37-
import androidx.compose.runtime.setValue
3832
import androidx.compose.ui.Alignment
3933
import androidx.compose.ui.Modifier
4034
import androidx.compose.ui.draw.clip
4135
import androidx.compose.ui.graphics.Brush
4236
import androidx.compose.ui.graphics.Color
43-
import androidx.compose.ui.platform.LocalContext
4437
import androidx.compose.ui.res.painterResource
4538
import androidx.compose.ui.res.stringResource
46-
import androidx.compose.ui.text.style.TextAlign
4739
import androidx.compose.ui.tooling.preview.Preview
4840
import androidx.compose.ui.tooling.preview.PreviewWrapper
4941
import androidx.compose.ui.unit.dp
50-
import androidx.core.net.toUri
5142
import androidx.lifecycle.compose.collectAsStateWithLifecycle
52-
import coil3.compose.AsyncImage
53-
import coil3.request.ImageRequest
54-
import coil3.request.crossfade
5543
import com.flipcash.app.contacts.device.DeviceContact
5644
import com.flipcash.app.core.AppRoute
5745
import com.flipcash.app.core.send.SendResult
@@ -71,15 +59,11 @@ import com.getcode.ui.components.AppBarDefaults
7159
import com.getcode.ui.components.AppBarWithTitle
7260
import com.getcode.ui.components.CircularIconButton
7361
import com.getcode.ui.components.SearchInput
74-
import com.getcode.ui.components.SwipeAction
75-
import com.getcode.ui.components.SwipeActionRow
7662
import androidx.compose.foundation.clickable
7763
import com.flipcash.app.contacts.ui.ContactAvatar
64+
import com.flipcash.app.core.chat.ChatIdentifier
7865
import com.getcode.ui.core.verticalScrollStateGradient
79-
import com.getcode.ui.theme.CodeCircularProgressIndicator
8066
import com.getcode.ui.theme.CodeScaffold
81-
import com.getcode.view.LoadingSuccessState
82-
import kotlinx.coroutines.delay
8367
import kotlinx.coroutines.flow.filterIsInstance
8468
import kotlinx.coroutines.flow.map
8569

@@ -117,7 +101,7 @@ internal fun ContactListScreen() {
117101
.collect { contact ->
118102
flowNavigator.navigate(
119103
AppRoute.Messaging.AmountEntry(
120-
identifier = AppRoute.ChatIdentifier.ByContact(
104+
identifier = ChatIdentifier.ByContact(
121105
e164 = contact.e164,
122106
displayName = contact.displayName,
123107
)

apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/ChatAmountEntryScreen.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.runtime.getValue
66
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
77
import androidx.lifecycle.compose.collectAsStateWithLifecycle
88
import com.flipcash.app.core.AppRoute
9+
import com.flipcash.app.core.chat.ChatIdentifier
910
import com.flipcash.app.core.tokens.TokenPurpose
1011
import com.flipcash.app.core.ui.TokenSelectionPill
1112
import com.flipcash.app.messenger.internal.ChatViewModel
@@ -29,7 +30,7 @@ import kotlinx.coroutines.flow.onEach
2930
* (messenger disabled). Creates its own [ChatViewModel] scoped to this nav entry.
3031
*/
3132
@Composable
32-
fun ChatAmountEntryScreen(identifier: AppRoute.ChatIdentifier) {
33+
fun ChatAmountEntryScreen(identifier: ChatIdentifier) {
3334
val viewModel = hiltViewModel<ChatViewModel>()
3435
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
3536

apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/ChatFlowScreen.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.navigation3.runtime.NavEntry
99
import androidx.navigation3.runtime.NavKey
1010
import androidx.navigation3.runtime.entryProvider
1111
import com.flipcash.app.core.AppRoute
12+
import com.flipcash.app.core.chat.ChatIdentifier
1213
import com.flipcash.app.core.chat.ChatStep
1314
import com.flipcash.app.messenger.internal.ChatViewModel
1415
import com.flipcash.app.messenger.internal.screens.MessengerScreen
@@ -40,7 +41,7 @@ fun ChatFlowScreen(
4041

4142
@Composable
4243
private fun chatEntryProvider(
43-
identifier: AppRoute.ChatIdentifier,
44+
identifier: ChatIdentifier,
4445
): (NavKey) -> NavEntry<NavKey> = entryProvider {
4546
annotatedEntry<ChatStep.Conversation> {
4647
FlowConversationScreen(identifier)
@@ -51,7 +52,7 @@ private fun chatEntryProvider(
5152
}
5253

5354
@Composable
54-
private fun FlowConversationScreen(identifier: AppRoute.ChatIdentifier) {
55+
private fun FlowConversationScreen(identifier: ChatIdentifier) {
5556
val viewModel = flowSharedViewModel<ChatViewModel>()
5657
val flowNavigator = rememberFlowNavigator<ChatStep, Parcelable>()
5758

0 commit comments

Comments
 (0)