@@ -9,11 +9,12 @@ import com.flipcash.app.core.ui.CurrencyHolder
99import com.flipcash.app.onramp.CoinbaseOnRampState
1010import com.flipcash.app.onramp.OnRampAuthError
1111import com.flipcash.app.onramp.CoinbaseOnRampController
12- import com.flipcash.app.onramp.OnRampPaymentError
12+ import com.flipcash.app.onramp.PurchaseGate
1313import com.flipcash.features.onramp.R
1414import com.flipcash.libs.coroutines.DispatcherProvider
1515import com.flipcash.services.internal.model.thirdparty.OnRampProvider
1616import com.flipcash.services.internal.model.thirdparty.OnRampType
17+ import com.getcode.manager.BottomBarAction
1718import com.getcode.manager.BottomBarManager
1819import com.getcode.opencode.controllers.TokenController
1920import com.getcode.opencode.controllers.TransactionOperations
@@ -39,6 +40,7 @@ import com.getcode.view.LoadingSuccessState
3940import dagger.hilt.android.lifecycle.HiltViewModel
4041import kotlinx.coroutines.flow.filter
4142import kotlinx.coroutines.flow.filterIsInstance
43+ import kotlinx.coroutines.launch
4244import kotlinx.coroutines.flow.launchIn
4345import kotlinx.coroutines.flow.map
4446import kotlinx.coroutines.flow.mapNotNull
@@ -83,7 +85,7 @@ internal class OnRampViewModel @Inject constructor(
8385 tokenController : TokenController ,
8486 transactionController : TransactionOperations ,
8587 dispatchers : DispatcherProvider ,
86- analytics : FlipcashAnalyticsService ,
88+ private val analytics : FlipcashAnalyticsService ,
8789) : BaseViewModel2<OnRampViewModel.State, OnRampViewModel.Event>(
8890 initialState = State (),
8991 updateStateForEvent = updateStateForEvent,
@@ -139,7 +141,7 @@ internal class OnRampViewModel @Inject constructor(
139141 data class UpdateOrderLookupState (
140142 val loading : Boolean = false ,
141143 val success : Boolean = false
142- ): Event
144+ ) : Event
143145
144146 data class OnAmountAccepted (val amount : VerifiedFiat ) : Event
145147
@@ -169,16 +171,21 @@ internal class OnRampViewModel @Inject constructor(
169171 onRampController.state
170172 .onEach { s ->
171173 when (s) {
172- is CoinbaseOnRampState .Completed -> dispatchEvent(Event .UpdateOrderLookupState (success = true ))
174+ is CoinbaseOnRampState .Completed ->
175+ dispatchEvent(Event .UpdateOrderLookupState (success = true ))
176+
173177 is CoinbaseOnRampState .Failed -> {
174178 dispatchEvent(Event .UpdateConfirmingAmountState ())
175179 dispatchEvent(Event .UpdateOrderLookupState ())
176180 }
181+
177182 CoinbaseOnRampState .Idle -> {
178183 dispatchEvent(Event .UpdateConfirmingAmountState ())
179184 dispatchEvent(Event .UpdateOrderLookupState ())
180185 }
181- is CoinbaseOnRampState .Paying -> dispatchEvent(Event .UpdateOrderLookupState (loading = true ))
186+
187+ is CoinbaseOnRampState .Paying ->
188+ dispatchEvent(Event .UpdateOrderLookupState (loading = true ))
182189 }
183190 }
184191 .launchIn(viewModelScope)
@@ -343,62 +350,7 @@ internal class OnRampViewModel @Inject constructor(
343350 return @onEach
344351 }
345352
346- onRampController.placeOrderAndStartPayment(
347- amount = selectedAmount.localFiat.underlyingTokenAmount,
348- token = token,
349- verifiedFiat = selectedAmount,
350- ).onSuccess {
351- analytics.buy(
352- method = Analytics .PurchaseMethod .Coinbase ,
353- amount = selectedAmount.localFiat.nativeAmount,
354- mint = token.address,
355- )
356- }.onFailure { error ->
357- dispatchEvent(Event .UpdateConfirmingAmountState ())
358-
359- when (error) {
360- is OnRampAuthError .CoinbasePhoneVerificationRequired -> {
361- dispatchEvent(Event .OnVerificationNeeded (phone = true ))
362- }
363-
364- is OnRampAuthError .VerificationRequired -> {
365- dispatchEvent(
366- Event .OnVerificationNeeded (
367- phone = error.phone,
368- email = error.email
369- )
370- )
371- }
372-
373- is OnRampPaymentError .GooglePayNotSupported -> {
374- BottomBarManager .showAlert(
375- title = resources.getString(R .string.error_title_onrampGooglePayNotSupported),
376- message = resources.getString(R .string.error_description_onrampGooglePayNotSupported),
377- )
378- }
379-
380- is OnRampPaymentError .GooglePayNoPaymentMethod -> {
381- BottomBarManager .showAlert(
382- title = resources.getString(R .string.error_title_onrampGooglePayNotReady),
383- message = resources.getString(R .string.error_description_onrampGooglePayNotReady),
384- )
385- }
386-
387- else -> {
388- analytics.buy(
389- method = Analytics .PurchaseMethod .Coinbase ,
390- amount = selectedAmount.localFiat.nativeAmount,
391- mint = token.address,
392- error = error
393- )
394-
395- BottomBarManager .showError(
396- title = " Something Went Wrong" ,
397- message = error.message ? : " Please try again" ,
398- )
399- }
400- }
401- }
353+ executeCoinbasePurchase(selectedAmount, token)
402354 }
403355
404356 else -> Unit
@@ -412,6 +364,109 @@ internal class OnRampViewModel @Inject constructor(
412364 }.launchIn(viewModelScope)
413365 }
414366
367+ private suspend fun executeCoinbasePurchase (
368+ selectedAmount : VerifiedFiat ,
369+ token : Token ,
370+ ) {
371+ onRampController.checkPurchaseGates()
372+ .fold(
373+ onSuccess = { proceedWithCoinbasePurchase(selectedAmount, token) },
374+ onFailure = { gate ->
375+ when (gate) {
376+ is PurchaseGate .GooglePayNotSupported -> {
377+ dispatchEvent(Event .UpdateConfirmingAmountState ())
378+ BottomBarManager .showAlert(
379+ title = resources.getString(R .string.error_title_onrampGooglePayNotSupported),
380+ message = resources.getString(R .string.error_description_onrampGooglePayNotSupported),
381+ )
382+ }
383+
384+ is PurchaseGate .GooglePayNoPaymentMethod -> {
385+ dispatchEvent(Event .UpdateConfirmingAmountState ())
386+ BottomBarManager .showAlert(
387+ title = resources.getString(R .string.error_title_onrampGooglePayNotReady),
388+ message = resources.getString(R .string.error_description_onrampGooglePayNotReady),
389+ )
390+ }
391+
392+ is PurchaseGate .WebViewWarning -> {
393+ BottomBarManager .showAlert(
394+ title = resources.getString(R .string.error_title_onrampNonStableWebView),
395+ message = resources.getString(
396+ R .string.error_description_onrampNonStableWebView,
397+ gate.channel.name,
398+ ),
399+ actions = listOf (
400+ BottomBarAction (
401+ text = resources.getString(R .string.action_cancel),
402+ style = BottomBarManager .BottomBarButtonStyle .Filled ,
403+ ) {
404+ dispatchEvent(Event .UpdateConfirmingAmountState ())
405+ },
406+ BottomBarAction (
407+ text = resources.getString(R .string.action_continueAnyway),
408+ style = BottomBarManager .BottomBarButtonStyle .Text ,
409+ ) {
410+ viewModelScope.launch {
411+ proceedWithCoinbasePurchase(selectedAmount, token)
412+ }
413+ },
414+ ),
415+ )
416+ }
417+ }
418+ },
419+ )
420+ }
421+
422+ private suspend fun proceedWithCoinbasePurchase (
423+ selectedAmount : VerifiedFiat ,
424+ token : Token ,
425+ ) {
426+ onRampController.placeOrderAndStartPayment(
427+ amount = selectedAmount.localFiat.underlyingTokenAmount,
428+ token = token,
429+ verifiedFiat = selectedAmount,
430+ ).onSuccess {
431+ analytics.buy(
432+ method = Analytics .PurchaseMethod .Coinbase ,
433+ amount = selectedAmount.localFiat.nativeAmount,
434+ mint = token.address,
435+ )
436+ }.onFailure { error ->
437+ dispatchEvent(Event .UpdateConfirmingAmountState ())
438+
439+ when (error) {
440+ is OnRampAuthError .CoinbasePhoneVerificationRequired -> {
441+ dispatchEvent(Event .OnVerificationNeeded (phone = true ))
442+ }
443+
444+ is OnRampAuthError .VerificationRequired -> {
445+ dispatchEvent(
446+ Event .OnVerificationNeeded (
447+ phone = error.phone,
448+ email = error.email
449+ )
450+ )
451+ }
452+
453+ else -> {
454+ analytics.buy(
455+ method = Analytics .PurchaseMethod .Coinbase ,
456+ amount = selectedAmount.localFiat.nativeAmount,
457+ mint = token.address,
458+ error = error
459+ )
460+
461+ BottomBarManager .showError(
462+ title = " Something Went Wrong" ,
463+ message = error.message ? : " Please try again" ,
464+ )
465+ }
466+ }
467+ }
468+ }
469+
415470 override fun onCleared () {
416471 exchange.resetEntryToBalance()
417472 }
0 commit comments