11package com.flipcash.app.deposit
22
3+ import androidx.compose.foundation.layout.Column
4+ import androidx.compose.foundation.layout.fillMaxSize
35import androidx.compose.runtime.Composable
46import androidx.compose.runtime.CompositionLocalProvider
7+ import androidx.compose.runtime.LaunchedEffect
58import androidx.compose.runtime.getValue
6- import androidx.compose.runtime.key
7- import androidx.compose.runtime.remember
9+ import androidx.compose.ui.Alignment
10+ import androidx.compose.ui.Modifier
11+ import androidx.compose.ui.res.stringResource
812import androidx.compose.ui.tooling.preview.Preview
913import androidx.compose.ui.tooling.preview.PreviewWrapper
14+ import androidx.hilt.navigation.compose.hiltViewModel
1015import androidx.lifecycle.compose.collectAsStateWithLifecycle
1116import androidx.navigation3.runtime.NavEntry
1217import androidx.navigation3.runtime.NavKey
1318import androidx.navigation3.runtime.entryProvider
1419import com.flipcash.app.core.AppRoute
1520import com.flipcash.app.core.deposit.DepositResult
1621import com.flipcash.app.core.deposit.DepositStep
17- import com.flipcash.app.featureflags.FeatureFlag
18- import com.flipcash.app.featureflags.LocalFeatureFlags
22+ import com.flipcash.app.core.tokens.TokenPurpose
1923import com.flipcash.app.deposit.internal.DepositViewModel
2024import com.flipcash.app.deposit.internal.UsdcDepositInformationScreen
2125import com.flipcash.app.theme.FlipcashThemeWrapper
26+ import com.flipcash.app.tokens.ui.SelectTokenViewModel
27+ import com.flipcash.app.tokens.ui.TokenList
28+ import com.flipcash.core.R
2229import com.getcode.navigation.annotatedEntry
2330import com.getcode.navigation.core.LocalCodeNavigator
2431import com.getcode.navigation.flow.FlowExitReason
2532import com.getcode.navigation.flow.FlowHost
2633import com.getcode.navigation.flow.LocalFlowNavigator
2734import com.getcode.navigation.flow.PreviewFlowNavigator
2835import com.getcode.navigation.flow.deliverFlowResult
36+ import com.getcode.navigation.flow.rememberFlowNavigator
37+ import com.getcode.navigation.flow.rememberInitialStack
38+ import com.getcode.navigation.flowAnnotatedEntry
2939import com.getcode.navigation.results.NavResultOrCanceled
3040import com.getcode.navigation.results.NavResultStateRegistry
31- import com.getcode.solana.keys.Mint
41+ import com.getcode.ui.components.AppBarWithTitle
42+ import kotlinx.coroutines.flow.filter
43+ import kotlinx.coroutines.flow.filterIsInstance
44+ import kotlinx.coroutines.flow.launchIn
45+ import kotlinx.coroutines.flow.map
46+ import kotlinx.coroutines.flow.onEach
3247
3348@Composable
3449fun DepositFlowScreen (
3550 route : AppRoute .Transfers .Deposit ,
3651 resultStateRegistry : NavResultStateRegistry ,
3752) {
3853 val outerNavigator = LocalCodeNavigator .current
39- val featureFlags = LocalFeatureFlags .current
54+ val initialStack = route.rememberInitialStack< DepositStep >()
4055
41- val directDeposit by featureFlags
42- .observe(FeatureFlag .DepositUsdc )
43- .collectAsStateWithLifecycle()
44-
45- val initialStack = remember(route, directDeposit) {
46- @Suppress(" UNCHECKED_CAST" )
47- val steps = route.initialStack as List <DepositStep >
48- println (" direct deposit = $directDeposit , isUsdf=${route.mint == Mint .usdf} " )
49- if (! directDeposit && route.mint == Mint .usdf) {
50- listOf (DepositStep .Destination (route.mint))
51- } else {
52- steps
53- }
54- }
55-
56- key(directDeposit) {
57- FlowHost (
58- initialStack = initialStack,
59- resultStateRegistry = resultStateRegistry,
60- onExit = { reason, isSheetRoot ->
61- val result: DepositResult = when (reason) {
62- is FlowExitReason .Completed -> reason.result
63- FlowExitReason .Canceled ,
64- FlowExitReason .BackedOutOfRoot -> DepositResult .Canceled
65- }
66- if (isSheetRoot) {
67- outerNavigator.pop()
68- } else {
69- outerNavigator.deliverFlowResult(
70- route = route,
71- value = NavResultOrCanceled .ReturnValue (result),
72- )
73- when (result) {
74- DepositResult .Success -> {
75- outerNavigator.popUntil { it == AppRoute .Sheets .Menu }
76- }
77- DepositResult .Canceled -> {
78- outerNavigator.pop()
79- }
56+ FlowHost (
57+ initialStack = initialStack,
58+ resultStateRegistry = resultStateRegistry,
59+ onExit = { reason, isSheetRoot ->
60+ val result: DepositResult = when (reason) {
61+ is FlowExitReason .Completed -> reason.result
62+ FlowExitReason .Canceled ,
63+ FlowExitReason .BackedOutOfRoot -> DepositResult .Canceled
64+ }
65+ if (isSheetRoot) {
66+ outerNavigator.pop()
67+ } else {
68+ outerNavigator.deliverFlowResult(
69+ route = route,
70+ value = NavResultOrCanceled .ReturnValue (result),
71+ )
72+ when (result) {
73+ DepositResult .Success -> {
74+ outerNavigator.popUntil { it == AppRoute .Sheets .Menu }
75+ }
76+ DepositResult .Canceled -> {
77+ outerNavigator.pop()
8078 }
8179 }
82- },
83- entryProvider = depositEntryProvider(route.mint) ,
84- )
85- }
80+ }
81+ } ,
82+ entryProvider = depositEntryProvider(route.showOtherOptions),
83+ )
8684}
8785
8886private fun depositEntryProvider (
89- mint : Mint ,
87+ showOtherOptions : Boolean ,
9088): (NavKey ) -> NavEntry <NavKey > = entryProvider {
91- annotatedEntry<DepositStep .UsdcInformational > {
92- UsdcDepositInformationScreen ()
89+ flowAnnotatedEntry<DepositStep .UsdcInformational > {
90+ UsdcDepositInformationScreen (showOtherOptions)
91+ }
92+ annotatedEntry<DepositStep .SelectToken > {
93+ DepositSelectTokenScreen ()
94+ }
95+ annotatedEntry<DepositStep .Destination > { key ->
96+ DepositDestinationScreen (key.mint)
97+ }
98+ }
99+
100+ @Composable
101+ private fun DepositSelectTokenScreen () {
102+ val flowNavigator = rememberFlowNavigator<DepositStep , DepositResult >()
103+ val viewModel = hiltViewModel<SelectTokenViewModel >()
104+ val state by viewModel.stateFlow.collectAsStateWithLifecycle()
105+
106+ Column (
107+ modifier = Modifier .fillMaxSize(),
108+ horizontalAlignment = Alignment .CenterHorizontally ,
109+ ) {
110+ AppBarWithTitle (
111+ isInModal = true ,
112+ title = stringResource(R .string.title_selectCurrency),
113+ backButton = true ,
114+ onBackIconClicked = { flowNavigator.back() },
115+ titleAlignment = Alignment .CenterHorizontally ,
116+ )
117+ TokenList (
118+ modifier = Modifier .fillMaxSize(),
119+ tokens = state.tokens,
120+ selectedToken = state.selectedToken,
121+ showFlags = true ,
122+ includeReserves = true ,
123+ onTokenSelected = { viewModel.dispatchEvent(SelectTokenViewModel .Event .OnTokenSelected (it.address)) },
124+ )
93125 }
94- annotatedEntry<DepositStep .Destination > {
95- DepositDestinationScreen (mint)
126+
127+ LaunchedEffect (viewModel) {
128+ viewModel.dispatchEvent(SelectTokenViewModel .Event .OnPurposeChanged (TokenPurpose .Deposit ))
129+ }
130+
131+ LaunchedEffect (viewModel) {
132+ viewModel.eventFlow
133+ .filterIsInstance<SelectTokenViewModel .Event .OnTokenSelected >()
134+ .filter { it.fromUser }
135+ .map { it.mint }
136+ .onEach { mint ->
137+ flowNavigator.navigateTo(DepositStep .Destination (mint))
138+ }.launchIn(this )
96139 }
97140}
98141
@@ -112,5 +155,5 @@ private fun DepositFlowPreview(
112155@PreviewWrapper(FlipcashThemeWrapper ::class )
113156@Composable
114157private fun Preview_UsdcInformational () {
115- DepositFlowPreview { UsdcDepositInformationScreen () }
158+ DepositFlowPreview { UsdcDepositInformationScreen (true ) }
116159}
0 commit comments