Skip to content

Commit 6dcf6ef

Browse files
committed
feat(flipcash): build out onramp into provider list entry point
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 130186e commit 6dcf6ef

29 files changed

Lines changed: 1038 additions & 230 deletions

File tree

apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ import com.flipcash.app.login.router.LoginRouter
1818
import com.flipcash.app.login.seed.SeedInputScreen
1919
import com.flipcash.app.menu.MenuScreen
2020
import com.flipcash.app.myaccount.MyAccountScreen
21-
import com.flipcash.app.onramp.OnRampTestScreen
22-
import com.flipcash.app.onramp.OnRampWebViewScreen
21+
import com.flipcash.app.onramp.OnRampAmountScreen
22+
import com.flipcash.app.onramp.OnRampProviderListScreen
23+
import com.flipcash.app.onramp.OnRampFlowTracker
2324
import com.flipcash.app.permissions.CameraPermissionScreen
2425
import com.flipcash.app.permissions.NotificationPermissionScreen
2526
import com.flipcash.app.pools.PoolBettingScreen
@@ -32,7 +33,6 @@ import com.flipcash.app.purchase.PurchaseAccountScreen
3233
import com.flipcash.app.scanner.ScannerScreen
3334
import com.flipcash.app.shareapp.ShareAppScreen
3435
import com.flipcash.app.transfers.TransferInformationalScreen
35-
import com.flipcash.app.web.WebViewScreen
3636
import com.flipcash.app.withdrawal.WithdrawalConfirmationScreen
3737
import com.flipcash.app.withdrawal.WithdrawalDestinationScreen
3838
import com.flipcash.app.withdrawal.WithdrawalEntryScreen
@@ -121,16 +121,13 @@ internal fun AppScreenContent(content: @Composable () -> Unit) {
121121
ShareAppScreen()
122122
}
123123

124-
register<NavScreenProvider.HomeScreen.OnRamp.Test> {
125-
OnRampTestScreen()
124+
register<NavScreenProvider.HomeScreen.OnRamp.ProviderList> {
125+
OnRampFlowTracker.start()
126+
OnRampProviderListScreen()
126127
}
127128

128-
register<NavScreenProvider.HomeScreen.OnRamp.PaymentWebview> {
129-
OnRampWebViewScreen(it.url)
130-
}
131-
132-
register<NavScreenProvider.HomeScreen.OnRamp.PhoneVerification> {
133-
WebViewScreen(it.url)
129+
register<NavScreenProvider.HomeScreen.OnRamp.Amount> {
130+
OnRampAmountScreen()
134131
}
135132

136133
register<NavScreenProvider.HomeScreen.Menu.Root> {

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ sealed class NavScreenProvider : ScreenProvider {
5555

5656
data object ShareApp : NavScreenProvider()
5757

58-
sealed class OnRamp {
59-
data object Test : NavScreenProvider()
60-
data class PaymentWebview(val url: String) : NavScreenProvider()
61-
data class PhoneVerification(val url: String): NavScreenProvider()
62-
}
58+
sealed class OnRamp {
59+
data object ProviderList: NavScreenProvider()
60+
data object Amount : NavScreenProvider()
61+
}
6362

6463
sealed class Menu {
6564
data object Root : NavScreenProvider()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.flipcash.app.core.extensions
2+
3+
import kotlinx.coroutines.flow.Flow
4+
import kotlinx.coroutines.flow.filter
5+
6+
inline fun <reified R> Flow<*>.filterIsNotInstance(): Flow<R> = filter { it !is R } as Flow<R>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.flipcash.app.core.extensions
2+
3+
inline fun <reified R, T> List<T>.filterIsNotInstance(): List<T> = filter { it !is R }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="25dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="25">
6+
<path
7+
android:pathData="M20,4.5H4C2.895,4.5 2,5.395 2,6.5V9.5H22V6.499C22,5.393 21.103,4.5 20,4.5Z"
8+
android:fillColor="#ffffff"/>
9+
<path
10+
android:pathData="M2,18.5V11.5H22V18.5C22,19.605 21.105,20.5 20,20.5H4C2.895,20.5 2,19.605 2,18.5ZM7,13.5C6.448,13.5 6,13.948 6,14.5C6,15.052 6.448,15.5 7,15.5H10C10.552,15.5 11,15.052 11,14.5C11,13.948 10.552,13.5 10,13.5H7Z"
11+
android:fillColor="#ffffff"
12+
android:fillType="evenOdd"/>
13+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="25dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="25">
6+
<path
7+
android:pathData="M6.5,3.5C4.567,3.5 3,5.067 3,7V17.5C3,19.709 4.791,21.5 7,21.5H21V8.5H17V3.5H6.5ZM15,8.5V5.5H6.5C5.672,5.5 5,6.172 5,7C5,7.828 5.672,8.5 6.5,8.5H15ZM15.5,16.25C16.19,16.25 16.75,15.69 16.75,15C16.75,14.31 16.19,13.75 15.5,13.75C14.81,13.75 14.25,14.31 14.25,15C14.25,15.69 14.81,16.25 15.5,16.25Z"
8+
android:fillColor="#ffffff"
9+
android:fillType="evenOdd"/>
10+
</vector>

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@
5959
<string name="subtitle_balanceEmptyState">Ask a friend to give you some cash with Flipcash, or deposit USDC from your crypto exchange or another crypto wallet</string>
6060
<string name="action_depositFunds">Deposit Funds</string>
6161

62+
<string name="title_addFundsToWallet">Add Funds to Your Wallet</string>
6263
<string name="title_depositUsdc">Deposit</string>
63-
<string name="title_withdrawUsdc">Withdraw</string>
64+
<string name="title_withdrawUsdc">Withdraw Funds</string>
6465

6566
<string name="title_withdraw">Withdraw</string>
6667

@@ -271,5 +272,9 @@
271272
<item>Will Jill text her ex before dawn?</item>
272273
</string-array>
273274

274-
<string name="title_onramp">Purchase USDC</string>
275+
<string name="title_addCash">Add Cash</string>
276+
<string name="title_amountToAdd">Amount to Add</string>
277+
278+
<string name="subtitle_onrampPurchaseHint">Enter up to %1$s</string>
279+
<string name="subtitle_onrampPurchaseExceeded">You can only add up to %1$s</string>
275280
</resources>

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal data object Deposit : FullMenuItem<MenuScreenViewModel.Event>() {
2121
override val icon: Painter
2222
@Composable get() = painterResource(R.drawable.ic_menu_deposit)
2323
override val name: String
24-
@Composable get() = stringResource(R.string.title_depositUsdc)
24+
@Composable get() = stringResource(R.string.title_addFundsToWallet)
2525
override val action: MenuScreenViewModel.Event = MenuScreenViewModel.Event.OpenScreen(
2626
NavScreenProvider.HomeScreen.Menu.Transfers.Learn(TransferDirection.Incoming)
2727
)
@@ -58,15 +58,14 @@ internal data object AppSettings : FullMenuItem<MenuScreenViewModel.Event>() {
5858
)
5959
}
6060

61-
internal data object OnRamp : StaffMenuItem<MenuScreenViewModel.Event>() {
61+
internal data object OnRamp : FullMenuItem<MenuScreenViewModel.Event>() {
6262
override val icon: Painter
63-
@Composable get() = painterResource(R.drawable.ic_currency_dollar_active)
63+
@Composable get() = painterResource(R.drawable.ic_menu_deposit)
6464
override val name: String
65-
@Composable get() = stringResource(R.string.title_onramp)
65+
@Composable get() = stringResource(R.string.title_addFundsToWallet)
6666
override val action: MenuScreenViewModel.Event = MenuScreenViewModel.Event.OpenScreen(
67-
NavScreenProvider.HomeScreen.OnRamp.Test
67+
NavScreenProvider.HomeScreen.OnRamp.ProviderList
6868
)
69-
override val featureFlag: FeatureFlag = FeatureFlag.OnRamp
7069
}
7170

7271
internal data object SwitchAccount : StaffMenuItem<MenuScreenViewModel.Event>() {

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.flipcash.app.core.NavScreenProvider
66
import com.flipcash.app.core.android.VersionInfo
77
import com.flipcash.app.core.extensions.onResult
88
import com.flipcash.app.featureflags.BetaFeature
9+
import com.flipcash.app.featureflags.FeatureFlag
910
import com.flipcash.app.featureflags.FeatureFlagController
1011
import com.flipcash.app.menu.MenuItem
1112
import com.flipcash.features.menu.R
@@ -28,11 +29,11 @@ import kotlinx.coroutines.launch
2829
import javax.inject.Inject
2930

3031
private val FullMenuList = buildList {
31-
add(Withdraw)
3232
add(Deposit)
33+
add(OnRamp)
34+
add(Withdraw)
3335
add(MyAccount)
3436
add(AppSettings)
35-
add(OnRamp)
3637
add(SwitchAccount)
3738
add(Labs)
3839
add(LogOut)
@@ -158,6 +159,8 @@ internal class MenuScreenViewModel @Inject constructor(
158159
overrode: Boolean,
159160
flags: List<BetaFeature> = emptyList(),
160161
): List<MenuItem<Event>> {
162+
// swap onramp for deposit if enabled
163+
val isOnRampEnabled = flags.find { it.flag is FeatureFlag.OnRamp }?.enabled ?: false
161164
return if (isStaff || overrode) {
162165
FullMenuList
163166
.filter { item ->
@@ -180,6 +183,12 @@ internal class MenuScreenViewModel @Inject constructor(
180183
true
181184
}
182185
}
186+
}.filter { item ->
187+
when (item) {
188+
Deposit -> !isOnRampEnabled
189+
OnRamp -> isOnRampEnabled
190+
else -> true
191+
}
183192
}
184193
}
185194

@@ -228,7 +237,7 @@ internal class MenuScreenViewModel @Inject constructor(
228237
overrode = state.unlockedBetaFeaturesManually,
229238
flags = event.flags
230239
),
231-
flags = event.flags
240+
flags = event.flags,
232241
)
233242
}
234243
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.flipcash.app.onramp
2+
3+
import android.os.Parcelable
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.fillMaxSize
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.runtime.LaunchedEffect
9+
import androidx.compose.runtime.getValue
10+
import androidx.compose.runtime.mutableStateOf
11+
import androidx.compose.runtime.saveable.rememberSaveable
12+
import androidx.compose.runtime.setValue
13+
import androidx.compose.ui.Alignment
14+
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.res.stringResource
16+
import cafe.adriel.voyager.core.registry.ScreenRegistry
17+
import cafe.adriel.voyager.core.screen.ScreenKey
18+
import cafe.adriel.voyager.core.screen.uniqueScreenKey
19+
import com.flipcash.app.core.NavScreenProvider
20+
import com.flipcash.app.onramp.internal.OnRampViewModel
21+
import com.flipcash.app.onramp.internal.screens.OnRampAmountScreen
22+
import com.flipcash.features.onramp.R
23+
import com.getcode.navigation.core.LocalCodeNavigator
24+
import com.getcode.navigation.extensions.getStackScopedViewModel
25+
import com.getcode.navigation.modal.ModalScreen
26+
import com.getcode.navigation.screens.NamedScreen
27+
import com.getcode.ui.components.AppBarWithTitle
28+
import kotlinx.coroutines.flow.filterIsInstance
29+
import kotlinx.coroutines.flow.launchIn
30+
import kotlinx.coroutines.flow.map
31+
import kotlinx.coroutines.flow.onEach
32+
import kotlinx.parcelize.IgnoredOnParcel
33+
import kotlinx.parcelize.Parcelize
34+
35+
@Parcelize
36+
class OnRampAmountScreen : ModalScreen, NamedScreen, Parcelable {
37+
38+
@IgnoredOnParcel
39+
override val key: ScreenKey = uniqueScreenKey
40+
41+
override val name: String
42+
@Composable get() = stringResource(R.string.title_amountToAdd)
43+
44+
@Composable
45+
override fun ModalContent() {
46+
val navigator = LocalCodeNavigator.current
47+
val viewModel = getStackScopedViewModel<OnRampViewModel>(key = OnRampFlowTracker.key)
48+
var paymentLink by rememberSaveable { mutableStateOf<String?>(null) }
49+
Box {
50+
paymentLink?.let {
51+
CoinbaseOnRampWebview(
52+
paymentLinkUrl = it,
53+
onPaymentSuccess = {
54+
paymentLink = null
55+
viewModel.dispatchEvent(OnRampViewModel.Event.OnPaymentSuccess)
56+
},
57+
onPaymentFailure = {
58+
paymentLink = null
59+
viewModel.dispatchEvent(OnRampViewModel.Event.OnPaymentError(it))
60+
}
61+
)
62+
}
63+
64+
Column(
65+
modifier = Modifier.fillMaxSize(),
66+
) {
67+
AppBarWithTitle(
68+
title = name,
69+
isInModal = true,
70+
backButton = true,
71+
onBackIconClicked = { navigator.pop() },
72+
titleAlignment = Alignment.CenterHorizontally,
73+
)
74+
OnRampAmountScreen(viewModel)
75+
}
76+
}
77+
78+
LaunchedEffect(viewModel) {
79+
viewModel.eventFlow
80+
.filterIsInstance<OnRampViewModel.Event.OnPaymentLinkGenerated>()
81+
.map { it.url }
82+
.onEach {
83+
84+
}.launchIn(this)
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)