Skip to content

Commit 0c73d15

Browse files
committed
chore(fc): implement payment success ack'ing to allow chaining after payment events
Signed-off-by: Brandon McAnsh <[email protected]>
1 parent 814cbf2 commit 0c73d15

File tree

5 files changed

+92
-113
lines changed

5 files changed

+92
-113
lines changed

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/balance/BalanceScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fun BalanceContent(
106106
modifier = Modifier
107107
.fillParentMaxWidth()
108108
.padding(horizontal = CodeTheme.dimens.inset,)
109-
.padding(top = CodeTheme.dimens.grid.x7)
109+
.padding(top = CodeTheme.dimens.inset)
110110
) {
111111
BalanceTop(
112112
state,

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/chat/list/ChatListViewModel.kt

Lines changed: 33 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,6 @@ class ChatListViewModel @Inject constructor(
8282

8383
eventFlow
8484
.filterIsInstance<Event.CreateRoomSelected>()
85-
.onEach {
86-
dispatchEvent(
87-
Event.ShowFullScreenSpinner(
88-
showScrim = true,
89-
showSpinner = false
90-
)
91-
)
92-
}
9385
.map { profileController.getUserFlags() }
9486
.mapNotNull {
9587
it.exceptionOrNull()?.let {
@@ -120,69 +112,46 @@ class ChatListViewModel @Inject constructor(
120112
}
121113
}.flatMapLatest {
122114
paymentController.eventFlow.take(1)
123-
}.mapNotNull {
124-
when (it) {
125-
PaymentEvent.OnPaymentCancelled -> {
126-
dispatchEvent(
127-
Event.ShowFullScreenSpinner(
128-
showScrim = false,
129-
showSpinner = false
130-
)
131-
)
132-
return@mapNotNull null
133-
134-
}
135-
136-
is PaymentEvent.OnPaymentError -> {
137-
dispatchEvent(
138-
Event.ShowFullScreenSpinner(
139-
showScrim = false,
140-
showSpinner = false
141-
)
142-
)
143-
return@mapNotNull null
144-
}
115+
}.onEach { event ->
116+
when (event) {
117+
PaymentEvent.OnPaymentCancelled -> Unit
118+
is PaymentEvent.OnPaymentError -> Unit
145119

146120
is PaymentEvent.OnPaymentSuccess -> {
147-
dispatchEvent(
148-
Event.ShowFullScreenSpinner(
149-
showScrim = true,
150-
showSpinner = true
151-
)
152-
)
153121
chatsController.createGroup(
154122
title = null,
155123
participants = emptyList(),
156-
it.intentId
157-
)
124+
paymentId = event.intentId
125+
).onFailure {
126+
event.acknowledge(false) {
127+
dispatchEvent(
128+
Event.ShowFullScreenSpinner(
129+
showScrim = false,
130+
showSpinner = false
131+
)
132+
)
133+
TopBarManager.showMessage(
134+
TopBarManager.TopBarMessage(
135+
resources.getString(R.string.error_title_failedToCreateRoom),
136+
resources.getString(R.string.error_description_failedToCreateRoom)
137+
)
138+
)
139+
}
140+
}.onSuccess {
141+
event.acknowledge(true) {
142+
dispatchEvent(
143+
Event.ShowFullScreenSpinner(
144+
showScrim = false,
145+
showSpinner = false
146+
)
147+
)
148+
dispatchEvent(Event.OpenRoom(it.id))
149+
paymentController.cancelPayment(fromUser = false)
150+
}
151+
}
158152
}
159153
}
160-
}.onResult(
161-
onError = {
162-
dispatchEvent(
163-
Event.ShowFullScreenSpinner(
164-
showScrim = false,
165-
showSpinner = false
166-
)
167-
)
168-
TopBarManager.showMessage(
169-
TopBarManager.TopBarMessage(
170-
resources.getString(R.string.error_title_failedToCreateRoom),
171-
resources.getString(R.string.error_description_failedToCreateRoom)
172-
)
173-
)
174-
},
175-
onSuccess = {
176-
dispatchEvent(
177-
Event.ShowFullScreenSpinner(
178-
showScrim = false,
179-
showSpinner = false
180-
)
181-
)
182-
dispatchEvent(Event.OpenRoom(it.id))
183-
paymentController.cancelPayment(fromUser = false)
184-
}
185-
).launchIn(viewModelScope)
154+
}.launchIn(viewModelScope)
186155
}
187156

188157
val chats: Flow<PagingData<ConversationWithMembersAndLastMessage>>

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/chat/lookup/confirm/JoinConfirmationViewModel.kt

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import com.getcode.solana.keys.PublicKey
1212
import com.getcode.util.resources.ResourceHelper
1313
import com.getcode.view.BaseViewModel2
1414
import dagger.hilt.android.lifecycle.HiltViewModel
15+
import kotlinx.coroutines.delay
1516
import kotlinx.coroutines.flow.filterIsInstance
1617
import kotlinx.coroutines.flow.flatMapLatest
1718
import kotlinx.coroutines.flow.launchIn
1819
import kotlinx.coroutines.flow.map
1920
import kotlinx.coroutines.flow.mapNotNull
21+
import kotlinx.coroutines.flow.onEach
2022
import kotlinx.coroutines.flow.take
2123
import xyz.flipchat.app.R
2224
import xyz.flipchat.app.data.RoomInfo
@@ -30,6 +32,7 @@ import xyz.flipchat.services.data.erased
3032
import xyz.flipchat.services.data.typeUrl
3133
import xyz.flipchat.services.user.UserManager
3234
import javax.inject.Inject
35+
import kotlin.time.Duration.Companion.seconds
3336

3437
@HiltViewModel
3538
class JoinConfirmationViewModel @Inject constructor(
@@ -115,40 +118,42 @@ class JoinConfirmationViewModel @Inject constructor(
115118
}
116119
}.flatMapLatest {
117120
paymentController.eventFlow.take(1)
118-
}.mapNotNull {
119-
when (it) {
121+
}.onEach { event ->
122+
when (event) {
120123
PaymentEvent.OnPaymentCancelled -> {
121124
dispatchEvent(Event.OnJoiningChanged(false))
122-
return@mapNotNull null
123125
}
126+
124127
is PaymentEvent.OnPaymentError -> {
125128
dispatchEvent(Event.OnJoiningChanged(false))
126-
return@mapNotNull null
127129
}
130+
128131
is PaymentEvent.OnPaymentSuccess -> {
129132
val roomId = stateFlow.value.roomInfo.id.orEmpty()
130-
chatsController.joinRoom(roomId, it.intentId)
133+
chatsController.joinRoom(roomId, event.intentId)
134+
.onFailure {
135+
event.acknowledge(false) {
136+
dispatchEvent(Event.OnJoiningChanged(false))
137+
TopBarManager.showMessage(
138+
TopBarManager.TopBarMessage(
139+
resources.getString(R.string.error_title_failedToJoinRoom),
140+
resources.getString(
141+
R.string.error_description_failedToJoinRoom,
142+
stateFlow.value.roomInfo.title
143+
)
144+
)
145+
)
146+
}
147+
}
148+
.onSuccess {
149+
event.acknowledge(true) {
150+
dispatchEvent(Event.OnJoiningChanged(false))
151+
dispatchEvent(Event.OnJoinedSuccessfully(it.room.id))
152+
}
153+
}
131154
}
132155
}
133-
}.onResult(
134-
onError = {
135-
dispatchEvent(Event.OnJoiningChanged(false))
136-
TopBarManager.showMessage(
137-
TopBarManager.TopBarMessage(
138-
resources.getString(R.string.error_title_failedToJoinRoom),
139-
resources.getString(
140-
R.string.error_description_failedToJoinRoom,
141-
stateFlow.value.roomInfo.title
142-
)
143-
)
144-
)
145-
},
146-
onSuccess = {
147-
dispatchEvent(Event.OnJoiningChanged(false))
148-
dispatchEvent(Event.OnJoinedSuccessfully(it.room.id))
149-
}
150-
)
151-
.launchIn(viewModelScope)
156+
}.launchIn(viewModelScope)
152157
}
153158

154159
companion object {

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/payments/PaymentScaffold.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,7 @@ fun PaymentScaffold(content: @Composable () -> Unit) {
6868
TipConfirmation(
6969
confirmation = state.billState.socialUserPaymentConfirmation,
7070
onSend = {
71-
payments.completePublicPayment(
72-
onSuccess = {
73-
// TODO: fetch chats
74-
},
75-
onError = {}
76-
)
71+
payments.completePublicPayment()
7772
},
7873
onCancel = { payments.cancelPayment() }
7974
)

services/flipchat/payments/src/main/kotlin/xyz/flipchat/services/PaymentController.kt

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import kotlinx.coroutines.launch
2626
import xyz.flipchat.services.payments.R
2727
import javax.inject.Inject
2828
import javax.inject.Singleton
29-
import kotlin.time.Duration.Companion.milliseconds
3029
import kotlin.time.Duration.Companion.seconds
3130

3231
data class PaymentState(
@@ -36,7 +35,8 @@ data class PaymentState(
3635
sealed interface PaymentEvent {
3736
data class OnPaymentSuccess(
3837
val intentId: ID,
39-
val destination: PublicKey
38+
val destination: PublicKey,
39+
val acknowledge: (Boolean, () -> Unit) -> Unit // Caller returns true if they want to proceed as success, false as error
4040
) : PaymentEvent
4141
data object OnPaymentCancelled : PaymentEvent
4242
data class OnPaymentError(val error: Throwable): PaymentEvent
@@ -62,7 +62,7 @@ class PaymentController @Inject constructor(
6262
fun presentPublicPaymentConfirmation(
6363
destination: PublicKey,
6464
amount: KinAmount,
65-
metadata: ExtendedMetadata
65+
metadata: ExtendedMetadata,
6666
) {
6767
billController.update {
6868
it.copy(
@@ -76,7 +76,7 @@ class PaymentController @Inject constructor(
7676
}
7777
}
7878

79-
fun completePublicPayment(onSuccess: () -> Unit = { }, onError: (Throwable) -> Unit = { }) =
79+
fun completePublicPayment() =
8080
scope.launch {
8181
val confirmation = billController.state.value.publicPaymentConfirmation ?: return@launch
8282
val destination = confirmation.destination
@@ -92,21 +92,31 @@ class PaymentController @Inject constructor(
9292
runCatching {
9393
paymentRepository.payPublicly(amount, destination, metadata)
9494
}.onSuccess {
95-
onSuccess()
96-
97-
billController.update { billState ->
98-
val publicPaymentConfirmation =
99-
billState.publicPaymentConfirmation ?: return@update billState
100-
billState.copy(
101-
publicPaymentConfirmation = publicPaymentConfirmation.copy(state = ConfirmationState.Sent),
102-
)
103-
}
104-
delay(1.seconds)
105-
cancelPayment(fromUser = false)
106-
delay(400.milliseconds)
107-
_eventFlow.emit(PaymentEvent.OnPaymentSuccess(it, destination))
95+
_eventFlow.emit(PaymentEvent.OnPaymentSuccess(
96+
intentId = it,
97+
destination = destination,
98+
acknowledge = { isSuccess, after ->
99+
if (isSuccess) {
100+
scope.launch {
101+
billController.update { billState ->
102+
val publicPaymentConfirmation =
103+
billState.publicPaymentConfirmation ?: return@update billState
104+
billState.copy(
105+
publicPaymentConfirmation = publicPaymentConfirmation.copy(state = ConfirmationState.Sent),
106+
)
107+
}
108+
delay(1.33.seconds)
109+
cancelPayment(fromUser = false)
110+
after()
111+
}
112+
} else {
113+
billController.reset()
114+
after()
115+
116+
}
117+
}
118+
))
108119
}.onFailure {
109-
onError(it)
110120
when {
111121
it is PaymentError -> {
112122
when (it) {

0 commit comments

Comments
 (0)