@@ -22,6 +22,7 @@ import com.flipcash.core.R
2222import com.flipcash.services.billing.BillingClient
2323import com.flipcash.services.controllers.AccountController
2424import com.flipcash.services.user.UserManager
25+ import com.getcode.manager.BottomBarAction
2526import com.getcode.manager.BottomBarManager
2627import com.getcode.manager.TopBarManager
2728import com.getcode.opencode.controllers.TransactionController
@@ -46,6 +47,7 @@ import com.kik.kikx.models.ScannableKikCode
4647import kotlinx.coroutines.CoroutineScope
4748import kotlinx.coroutines.Dispatchers
4849import kotlinx.coroutines.SupervisorJob
50+ import kotlinx.coroutines.coroutineScope
4951import kotlinx.coroutines.delay
5052import kotlinx.coroutines.flow.MutableStateFlow
5153import kotlinx.coroutines.flow.StateFlow
@@ -301,51 +303,88 @@ class RealSessionController @Inject constructor(
301303 amount : LocalFiat , owner : AccountCluster , restartBillGrabber : () -> Unit
302304 ) {
303305 val giftCard = GiftCardAccount .create()
304-
305- val initiateFunding = { amt: LocalFiat , resetShareController: Boolean ->
306- billController.fundGiftCard(
307- giftCard = giftCard,
308- amount = amt,
309- owner = owner,
310- onFunded = {
311- toastController.show(it)
312- bringActivityFeedCurrent()
313- if (resetShareController) {
314- shareSheetController.reset()
315- }
316- },
317- onError = {
318- cancelSend()
319- TopBarManager .showMessage(
320- title = resources.getString(R .string.error_title_failedToCreateGiftCard),
321- message = resources.getString(R .string.error_description_failedToCreateGiftCard)
322- )
323- }
324- )
325- }
306+ val shareable = Shareable .CashLink (giftCardAccount = giftCard, amount = amount)
326307
327308 scope.launch {
328309 shareSheetController.onShared = { result ->
329310 when (result) {
330311 ShareResult .CopiedToClipboard -> {
331- // pop the bill out as if grabbed/sent, but don't toast until funded
332- cancelSend(PresentationStyle .Pop , overrideToast = true )
312+ presentShareConfirmationModal(
313+ giftCard, owner, amount, result,
314+ onDidNotShare = restartBillGrabber,
315+ reshare = {
316+ scope.launch { shareSheetController.present(shareable) }
317+ }
318+ )
319+ }
320+
321+ is ShareResult .SharedToApp -> {
322+ presentShareConfirmationModal(
323+ giftCard, owner, amount, result,
324+ onDidNotShare = restartBillGrabber,
325+ reshare = {
326+ scope.launch { shareSheetController.present(shareable) }
327+ }
328+ )
329+ }
330+
331+ ShareResult .NotShared -> {
332+ restartBillGrabber()
333+ }
334+ }
335+ }
336+ delay(500 )
337+ shareSheetController.present(shareable)
338+ }
339+ }
340+
341+ private fun presentShareConfirmationModal (
342+ giftCard : GiftCardAccount ,
343+ owner : AccountCluster ,
344+ amount : LocalFiat ,
345+ shareResult : ShareResult ,
346+ onDidNotShare : () -> Unit ,
347+ reshare : () -> Unit ,
348+ ) {
349+ billController.cancelAwaitForGrab()
350+
351+ val handleConfirmationOrTimeout = { didConfirm: Boolean ->
352+ when (shareResult) {
353+ ShareResult .CopiedToClipboard -> {
354+ // pop the bill out as if grabbed/sent, but don't toast until funded
355+ cancelSend(PresentationStyle .Pop , overrideToast = true )
356+ trace(
357+ tag = " Session" ,
358+ message = " Cash link copied to clipboard" ,
359+ metadata = {
360+ " amount" to amount
361+ },
362+ type = TraceType .User ,
363+ )
364+ initiateGiftCardFunding(giftCard, owner, amount, true )
365+ vibrator.vibrate()
366+ }
367+ ShareResult .NotShared -> Unit
368+ is ShareResult .SharedToApp -> {
369+ if (! didConfirm) {
370+ // user never confirmed the send, treat as so
333371 trace(
334372 tag = " Session" ,
335- message = " Cash link copied to clipboard " ,
373+ message = " Cash link shared with ${shareResult.to} " ,
336374 metadata = {
337375 " amount" to amount
338376 },
339377 type = TraceType .User ,
340378 )
341- initiateFunding(amount, true )
342- }
343-
344- is ShareResult .SharedToApp -> {
379+ // pop the bill out as if grabbed/sent, but don't toast until funded
380+ cancelSend(PresentationStyle .Pop , overrideToast = true )
381+ giftCard.fund()
382+ initiateGiftCardFunding(giftCard, owner, amount, false )
383+ } else {
345384 if (! giftCard.funded) {
346385 trace(
347386 tag = " Session" ,
348- message = " Cash link shared with ${result .to} " ,
387+ message = " Cash link shared with ${shareResult .to} " ,
349388 metadata = {
350389 " amount" to amount
351390 },
@@ -354,7 +393,7 @@ class RealSessionController @Inject constructor(
354393 // pop the bill out as if grabbed/sent, but don't toast until funded
355394 cancelSend(PresentationStyle .Pop , overrideToast = true )
356395 giftCard.fund()
357- initiateFunding( amount, false )
396+ initiateGiftCardFunding(giftCard, owner, amount, false )
358397 } else {
359398 // due to android lifecycles, we need to await
360399 // the return to the app before showing the toast
@@ -363,16 +402,82 @@ class RealSessionController @Inject constructor(
363402 shareSheetController.reset()
364403 }
365404 }
366-
367- ShareResult .NotShared -> {
368- restartBillGrabber()
369- }
370405 }
371406 }
372- val shareable = Shareable .CashLink (giftCardAccount = giftCard, amount = amount)
373- delay(500 )
374- shareSheetController.present(shareable)
375407 }
408+ scope.launch {
409+ delay(2.5 .seconds)
410+
411+ BottomBarManager .showMessage(
412+ BottomBarManager .BottomBarMessage (
413+ title = resources.getString(R .string.prompt_title_didYouSendLink),
414+ subtitle = resources.getString(R .string.prompt_description_didYouSendLink),
415+ positiveText = resources.getString(R .string.action_yes),
416+ negativeText = resources.getString(R .string.action_noTryAgain),
417+ tertiaryText = resources.getString(R .string.action_cancelSend),
418+ actions = buildList {
419+ add(
420+ BottomBarAction (
421+ text = resources.getString(R .string.action_yes),
422+ onClick = {
423+ handleConfirmationOrTimeout(true )
424+ },
425+ )
426+ )
427+ add(
428+ BottomBarAction (
429+ text = resources.getString(R .string.action_noTryAgain),
430+ style = BottomBarManager .BottomBarButtonStyle .Filled50 ,
431+ onClick = reshare
432+ )
433+ )
434+ },
435+ onPositive = {
436+
437+ },
438+ onNegative = reshare,
439+ onTertiary = onDidNotShare,
440+ onClose = { fromAction ->
441+ if (! fromAction) {
442+ handleConfirmationOrTimeout(false )
443+ } else {
444+ onDidNotShare()
445+ }
446+ },
447+ type = BottomBarManager .BottomBarMessageType .REMOTE_SEND ,
448+ isDismissible = false ,
449+ showCancel = true ,
450+ timeoutSeconds = 60
451+ )
452+ )
453+ }
454+ }
455+
456+ private fun initiateGiftCardFunding (
457+ giftCard : GiftCardAccount ,
458+ owner : AccountCluster ,
459+ amount : LocalFiat ,
460+ resetShareController : Boolean
461+ ) {
462+ billController.fundGiftCard(
463+ giftCard = giftCard,
464+ amount = amount,
465+ owner = owner,
466+ onFunded = {
467+ toastController.show(it)
468+ bringActivityFeedCurrent()
469+ if (resetShareController) {
470+ shareSheetController.reset()
471+ }
472+ },
473+ onError = {
474+ cancelSend()
475+ TopBarManager .showMessage(
476+ title = resources.getString(R .string.error_title_failedToCreateGiftCard),
477+ message = resources.getString(R .string.error_description_failedToCreateGiftCard)
478+ )
479+ }
480+ )
376481 }
377482
378483 override fun onCodeScan (code : ScannableKikCode ) {
0 commit comments