@@ -2,24 +2,38 @@ package com.flipcash.app.balance.internal
22
33import androidx.lifecycle.viewModelScope
44import com.flipcash.app.core.extensions.onResult
5+ import com.flipcash.app.core.money.formatted
6+ import com.flipcash.features.balance.R
57import com.flipcash.services.controllers.ActivityFeedController
68import com.flipcash.services.models.ActivityFeedMessage
79import com.flipcash.services.models.ActivityFeedType
10+ import com.flipcash.services.models.FeedMessageMetadata
11+ import com.flipcash.services.user.UserManager
12+ import com.getcode.manager.BottomBarManager
13+ import com.getcode.manager.TopBarManager
814import com.getcode.opencode.controllers.BalanceController
15+ import com.getcode.opencode.controllers.TransactionController
916import com.getcode.opencode.model.financial.LocalFiat
17+ import com.getcode.solana.keys.PublicKey
18+ import com.getcode.util.resources.ResourceHelper
1019import com.getcode.view.BaseViewModel2
1120import dagger.hilt.android.lifecycle.HiltViewModel
1221import kotlinx.coroutines.flow.filterIsInstance
1322import kotlinx.coroutines.flow.launchIn
1423import kotlinx.coroutines.flow.map
24+ import kotlinx.coroutines.flow.mapNotNull
1525import kotlinx.coroutines.flow.onEach
26+ import kotlinx.coroutines.launch
1627import javax.inject.Inject
1728
1829@HiltViewModel
1930internal class BalanceViewModel @Inject constructor(
2031 balanceController : BalanceController ,
2132 activityFeedController : ActivityFeedController ,
22- ): BaseViewModel2<BalanceViewModel.State, BalanceViewModel.Event>(
33+ transactionController : TransactionController ,
34+ userManager : UserManager ,
35+ resources : ResourceHelper ,
36+ ) : BaseViewModel2<BalanceViewModel.State, BalanceViewModel.Event>(
2337 initialState = State (),
2438 updateStateForEvent = updateStateForEvent
2539) {
@@ -29,9 +43,11 @@ internal class BalanceViewModel @Inject constructor(
2943 )
3044
3145 sealed interface Event {
32- data class OnBalanceUpdated (val balance : LocalFiat ): Event
33- data object UpdateFeed : Event
34- data class OnMessagesUpdated (val latest : List <ActivityFeedMessage >): Event
46+ data class OnBalanceUpdated (val balance : LocalFiat ) : Event
47+ data object UpdateFeed : Event
48+ data class OnMessagesUpdated (val latest : List <ActivityFeedMessage >) : Event
49+ data class OnCancelRequested (val message : ActivityFeedMessage ) : Event
50+ data class CancelTransfer (val vault : PublicKey ) : Event
3551 }
3652
3753 init {
@@ -50,12 +66,59 @@ internal class BalanceViewModel @Inject constructor(
5066 dispatchEvent(Event .OnMessagesUpdated (it))
5167 }
5268 ).launchIn(viewModelScope)
69+
70+ eventFlow
71+ .filterIsInstance<Event .OnCancelRequested >()
72+ .map { it.message }
73+ .onEach { message ->
74+ val metadata = message.metadata as ? FeedMessageMetadata .SentUsdc ? : return @onEach
75+ val formattedAmount = message.amount?.formatted
76+ val title = formattedAmount?.let {
77+ resources.getString(R .string.prompt_title_cancelTransferWithAmount, it)
78+ } ? : resources.getString(R .string.prompt_title_cancelTransferNoAmount)
79+ BottomBarManager .showMessage(
80+ BottomBarManager .BottomBarMessage (
81+ title = title,
82+ subtitle = resources.getString(R .string.prompt_description_cancelTransfer),
83+ positiveText = resources.getString(R .string.action_cancelTransfer),
84+ onPositive = { dispatchEvent(Event .CancelTransfer (vault = metadata.creator)) },
85+ negativeText = resources.getString(R .string.action_nevermind)
86+ )
87+ )
88+ }.launchIn(viewModelScope)
89+
90+ eventFlow
91+ .filterIsInstance<Event .CancelTransfer >()
92+ .map { it.vault }
93+ .mapNotNull { vault ->
94+ val owner = userManager.accountCluster ? : return @mapNotNull null
95+ transactionController.cancelRemoteSend(
96+ vault = vault,
97+ owner = owner,
98+ )
99+ }.onResult(
100+ onError = {
101+ TopBarManager .showMessage(
102+ title = resources.getString(R .string.error_title_failedToCancelTransfer),
103+ message = resources.getString(R .string.error_description_failedToCancelTransfer),
104+ )
105+ },
106+ onSuccess = {
107+ viewModelScope.launch {
108+ activityFeedController.refreshAfterEvent(
109+ type = ActivityFeedType .TransactionHistory
110+ )
111+ }
112+ }
113+ ).launchIn(viewModelScope)
53114 }
54115
55116 internal companion object {
56117 val updateStateForEvent: (Event ) -> ((State ) -> State ) = { event ->
57118 when (event) {
58119 Event .UpdateFeed -> { state -> state }
120+ is Event .OnCancelRequested -> { state -> state }
121+ is Event .CancelTransfer -> { state -> state }
59122 is Event .OnBalanceUpdated -> { state -> state.copy(balance = event.balance) }
60123 is Event .OnMessagesUpdated -> { state -> state.copy(feed = event.latest) }
61124 }
0 commit comments