Skip to content

Commit 98e8dac

Browse files
committed
feat(deposit): show deposit toast on camera after successful deposit
Extract public ToastController interface into core so features can trigger toasts independently of the bill-grab queue. Pass deposited amount through SwapResult.Success and fire the toast before popAll.
1 parent f46168f commit 98e8dac

15 files changed

Lines changed: 80 additions & 41 deletions

File tree

apps/flipcash/app/src/main/kotlin/com/flipcash/app/MainActivity.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import com.flipcash.app.billing.BillingClient
1919
import com.flipcash.app.contacts.ContactCoordinator
2020
import com.flipcash.app.contacts.LocalContactCoordinator
2121
import com.flipcash.app.core.LocalUserManager
22+
import com.flipcash.app.core.toast.LocalToastController
23+
import com.flipcash.app.core.toast.ToastController
2224
import com.flipcash.app.core.verification.email.EmailCodeChannel
2325
import com.flipcash.app.core.verification.email.LocalEmailCodeChannel
2426
import com.flipcash.app.onramp.LocalCoinbaseOnRampController
@@ -125,6 +127,9 @@ class MainActivity : FragmentActivity() {
125127
@Inject
126128
lateinit var contactCoordinator: ContactCoordinator
127129

130+
@Inject
131+
lateinit var toastController: ToastController
132+
128133
@Inject
129134
lateinit var coinbaseOnRampController: CoinbaseOnRampController
130135

@@ -153,6 +158,7 @@ class MainActivity : FragmentActivity() {
153158
LocalAppUpdater provides appUpdater,
154159
LocalEmailCodeChannel provides emailCodeChannel,
155160
LocalContactCoordinator provides contactCoordinator,
161+
LocalToastController provides toastController,
156162
LocalCoinbaseOnRampController provides coinbaseOnRampController,
157163
LocalUiTesting provides intent.getBooleanExtra(UI_TEST, false),
158164
) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ sealed interface AppRoute : NavKey, Parcelable {
173173
data class Swap(
174174
val purpose: SwapPurpose,
175175
val shortfall: Fiat? = null,
176+
val popToRoot: Boolean = false,
176177
) : Token, FlowRouteWithResult<SwapResult> {
177178
override val initialStack: List<NavKey>
178179
get() = listOf(SwapStep.Entry(purpose, initialAmount = shortfall))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.flipcash.app.core.toast
2+
3+
import androidx.compose.runtime.staticCompositionLocalOf
4+
import com.getcode.opencode.model.financial.Fiat
5+
6+
interface ToastController {
7+
fun showToast(amount: Fiat, isDeposit: Boolean)
8+
}
9+
10+
val LocalToastController = staticCompositionLocalOf<ToastController> {
11+
error("No ToastController provided")
12+
}

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/tokens/SwapResult.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package com.flipcash.app.core.tokens
22

33
import android.os.Parcelable
4+
import com.getcode.opencode.model.financial.Fiat
45
import kotlinx.parcelize.Parcelize
56
import kotlinx.serialization.Serializable
67

78
@Serializable
89
sealed interface SwapResult : Parcelable {
910
@Parcelize
1011
@Serializable
11-
data object Success : SwapResult
12+
data class Success(val amount: Fiat = Fiat.Zero) : SwapResult
1213

1314
@Parcelize
1415
@Serializable

apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ internal class BalanceViewModel @Inject constructor(
5454

5555
eventFlow
5656
.filterIsInstance<Event.PresentDepositOptions>()
57-
.mapNotNull { purchaseMethodController.presentDepositOptions() }
57+
.mapNotNull { purchaseMethodController.presentDepositOptions(popToRoot = true) }
5858
.onEach { route -> dispatchEvent(Event.OpenScreen(route)) }
5959
.launchIn(viewModelScope)
6060
}

apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ internal class MenuScreenViewModel @Inject constructor(
152152

153153
eventFlow
154154
.filterIsInstance<Event.PresentDepositOptions>()
155-
.mapNotNull { purchaseMethodController.presentDepositOptions() }
155+
.mapNotNull { purchaseMethodController.presentDepositOptions(popToRoot = true) }
156156
.onEach { route -> dispatchEvent(Event.OpenScreen(route)) }
157157
.launchIn(viewModelScope)
158158
}

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/SwapFlowScreen.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import androidx.navigation3.runtime.NavEntry
55
import androidx.navigation3.runtime.NavKey
66
import androidx.navigation3.runtime.entryProvider
77
import com.flipcash.app.core.AppRoute
8+
import com.flipcash.app.core.toast.LocalToastController
89
import com.flipcash.app.core.tokens.SwapResult
910
import com.flipcash.app.core.tokens.SwapStep
11+
import com.getcode.opencode.model.financial.Fiat
1012
import com.getcode.navigation.annotatedEntry
1113
import com.getcode.navigation.core.LocalCodeNavigator
1214
import com.getcode.navigation.flowAnnotatedEntry
@@ -23,6 +25,7 @@ fun SwapFlowScreen(
2325
resultStateRegistry: NavResultStateRegistry,
2426
) {
2527
val outerNavigator = LocalCodeNavigator.current
28+
val toastController = LocalToastController.current
2629
val initialStack = route.rememberInitialStack<SwapStep>()
2730

2831
FlowHost<SwapStep, SwapResult>(
@@ -39,9 +42,15 @@ fun SwapFlowScreen(
3942
value = NavResultOrCanceled.ReturnValue(result),
4043
)
4144
when (result) {
42-
SwapResult.Success -> {
43-
if (route.shortfall != null) outerNavigator.popAll()
44-
else outerNavigator.pop()
45+
is SwapResult.Success -> {
46+
if (route.shortfall != null || route.popToRoot) {
47+
if (result.amount > Fiat.Zero) {
48+
toastController.showToast(result.amount, isDeposit = true)
49+
}
50+
outerNavigator.popAll()
51+
} else {
52+
outerNavigator.pop()
53+
}
4554
}
4655
SwapResult.OpenDeposit,
4756
SwapResult.Canceled -> outerNavigator.pop()

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenTxProcessingScreen.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ internal fun SwapProcessingScreen() {
2828
viewModel.eventFlow
2929
.filterIsInstance<Event.OnTransactionSuccessful>()
3030
.onEach {
31-
flowNavigator.exitWithResult(SwapResult.Success)
31+
val amount = viewModel.stateFlow.value.enteredAmount
32+
flowNavigator.exitWithResult(SwapResult.Success(amount))
3233
}.launchIn(this)
3334
}
3435

apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/PurchaseMethodController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ interface PurchaseMethodController {
99
val selections: Flow<PurchaseMethodSelection>
1010
fun present(metadata: PurchaseMethodMetadata = PurchaseMethodMetadata())
1111
fun select(method: PurchaseMethod, metadata: PurchaseMethodMetadata)
12-
suspend fun presentDepositOptions(): AppRoute?
12+
suspend fun presentDepositOptions(popToRoot: Boolean = false): AppRoute?
1313
}

apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPurchaseMethodController.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class InternalPurchaseMethodController @Inject constructor(
122122
)
123123
}
124124

125-
override suspend fun presentDepositOptions(): AppRoute? {
125+
override suspend fun presentDepositOptions(popToRoot: Boolean): AppRoute? {
126126
delay(150)
127127
present(PurchaseMethodMetadata(mint = Mint.usdf, showReserves = false, canUseOtherWallets = true))
128128

@@ -133,10 +133,12 @@ class InternalPurchaseMethodController @Inject constructor(
133133

134134
return when (result) {
135135
PurchaseMethod.CoinbaseOnRamp -> AppRoute.Token.Swap(
136-
purpose = SwapPurpose.Buy(Mint.usdf, FundingSource.Coinbase)
136+
purpose = SwapPurpose.Buy(Mint.usdf, FundingSource.Coinbase),
137+
popToRoot = popToRoot,
137138
)
138139
PurchaseMethod.PhantomWallet -> AppRoute.Token.Swap(
139-
purpose = SwapPurpose.Buy(Mint.usdf, FundingSource.Phantom)
140+
purpose = SwapPurpose.Buy(Mint.usdf, FundingSource.Phantom),
141+
popToRoot = popToRoot,
140142
)
141143
PurchaseMethod.OtherWallet -> AppRoute.Transfers.Deposit(showOtherOptions = true)
142144
is PurchaseMethod.CashReserves -> null

0 commit comments

Comments
 (0)