From e8acbd2c500c79f1ecb60405ce885437b4ed6ee6 Mon Sep 17 00:00:00 2001 From: vjrj <vjrj@comunes.org> Date: Mon, 3 Apr 2023 00:03:37 +0200 Subject: [PATCH] Pay fail with retry message if faulty balance --- assets/translations/en.json | 3 +- assets/translations/es.json | 3 +- lib/ui/screens/pay_form.dart | 98 ++++++++++++++++++++++-------------- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/assets/translations/en.json b/assets/translations/en.json index f6e342b8..a18421a5 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -119,5 +119,6 @@ "long_press_to_edit": "Tap and hold to edit", "form_contact_pub_key": "Public key", "payment_error": "Payment error", - "payment_error_desc": "Oops! the payment failed. More details: {error}" + "payment_error_desc": "Oops! the payment failed. More details: {error}", + "payment_error_retry": "Oops! the payment failed. Please retry in some minutes." } diff --git a/assets/translations/es.json b/assets/translations/es.json index 69de3807..36e8edf6 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -119,5 +119,6 @@ "form_contact_pub_key": "Clave pública", "reloading_nodes": "Refrescando nodos del tipo {type}", "payment_error": "Error en el pago", - "payment_error_desc": "¡Vaya! el pago falló. Más detalles: {error}" + "payment_error_desc": "¡Vaya! el pago falló. Más detalles: {error}", + "payment_error_retry": "¡Vaya! el pago falló. Inténtalo de nuevo en unos minutos" } diff --git a/lib/ui/screens/pay_form.dart b/lib/ui/screens/pay_form.dart index 8c8f956e..af8e41ca 100644 --- a/lib/ui/screens/pay_form.dart +++ b/lib/ui/screens/pay_form.dart @@ -77,45 +77,11 @@ class _PayFormState extends State<PayForm> { !_weHaveBalance(context, state.amount!)) ? null : () async { - // We disable the number, anyway - context.read<PaymentCubit>().sending(); - final String contactPubKey = state.contact!.pubKey; - final bool? confirmed = await _confirmSend( - context, - state.amount.toString(), - humanizePubKey(contactPubKey)); - if (!mounted) { - return; - } - if (confirmed == null || !confirmed) { - context.read<PaymentCubit>().sentFailed(); - } else { - final String response = await pay( - to: contactPubKey, - comment: state.comment, - amount: state.amount!); - if (!mounted) { - // Cannot show a tooltip if the widget is not now visible - return; - } - if (response == 'success') { - context.read<PaymentCubit>().sent(); - showTooltip(context, tr('payment_successful'), - tr('payment_successful_desc')); - } else { - showTooltip( - context, - tr('payment_error'), - tr('payment_error_desc', - namedArgs: <String, String>{ - // We try to translate the error, like "insufficient balance" - 'error': tr(response) - })); - context.read<PaymentCubit>().sentFailed(); - // Shuffle the nodes so we can retry with other - context.read<NodeListCubit>().shuffle(NodeType.gva); - // FIXME - retry manually with other node - } + try { + await payWithRetry(context, state, false); + } on RetryException { + // Here the transactions can be lost, so we must implement some manual retry use + await payWithRetry(context, state, true); } }, style: ElevatedButton.styleFrom( @@ -181,6 +147,60 @@ class _PayFormState extends State<PayForm> { }, ); } + + Future<void> payWithRetry( + BuildContext context, PaymentState state, bool useMempool) async { + logger('Trying to pay state with useMempool: $useMempool'); + // We disable the number, anyway + context.read<PaymentCubit>().sending(); + final String contactPubKey = state.contact!.pubKey; + final bool? confirmed = await _confirmSend( + context, state.amount.toString(), humanizePubKey(contactPubKey)); + if (!mounted) { + return; + } + if (confirmed == null || !confirmed) { + context.read<PaymentCubit>().sentFailed(); + } else { + final String response = await pay( + to: contactPubKey, comment: state.comment, amount: state.amount!); + if (!mounted) { + // Cannot show a tooltip if the widget is not now visible + return; + } + if (response == 'success') { + context.read<PaymentCubit>().sent(); + showTooltip( + context, tr('payment_successful'), tr('payment_successful_desc')); + } else { + /* this retry didn't work + if (!useMempool) { + throw RetryException(); + } */ + final bool failedWithBalance = response == 'insufficient balance' && + _weHaveBalance(context, state.amount!); + showPayError( + context, + failedWithBalance + ? tr('payment_error_retry') + : tr('payment_error_desc', namedArgs: <String, String>{ + // We try to translate the error, like "insufficient balance" + 'error': tr(response) + })); + } + } + } + + void showPayError(BuildContext context, String desc) { + showTooltip(context, tr('payment_error'), desc); + context.read<PaymentCubit>().sentFailed(); + // Shuffle the nodes so we can retry with other + context.read<NodeListCubit>().shuffle(NodeType.gva, true); + } +} + +class RetryException implements Exception { + RetryException(); } class NoNewLineTextInputFormatter extends TextInputFormatter { -- GitLab