diff --git a/lib/features/feature_flags/lucid/lucid_offerings_page.dart b/lib/features/feature_flags/lucid/lucid_offerings_page.dart index 85c50052..2900c054 100644 --- a/lib/features/feature_flags/lucid/lucid_offerings_page.dart +++ b/lib/features/feature_flags/lucid/lucid_offerings_page.dart @@ -6,8 +6,8 @@ import 'package:didpay/features/pfis/pfis_notifier.dart'; import 'package:didpay/features/tbdex/tbdex_service.dart'; import 'package:didpay/features/transaction/transaction.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/header.dart'; import 'package:didpay/shared/next_button.dart'; import 'package:didpay/shared/theme/grid.dart'; @@ -116,9 +116,9 @@ class LucidOfferingsPage extends HookConsumerWidget { ); }, loading: () => - AsyncLoadingWidget(text: Loc.of(context).fetchingOfferings), - error: (error, stackTrace) => AsyncErrorWidget( - text: error.toString(), + LoadingMessage(message: Loc.of(context).fetchingOfferings), + error: (error, stackTrace) => ErrorMessage( + message: error.toString(), onRetry: () => _getOfferings(ref, offerings), ), ), @@ -135,8 +135,9 @@ class LucidOfferingsPage extends HookConsumerWidget { await ref .read(tbdexServiceProvider) .getOfferings( - const PaymentState(transactionType: TransactionType.send), - ref.read(pfisProvider),) + const PaymentState(transactionType: TransactionType.send), + ref.read(pfisProvider), + ) .then((offerings) => state.value = AsyncData(offerings)); } on Exception catch (e) { state.value = AsyncError(e, StackTrace.current); diff --git a/lib/features/home/home_page.dart b/lib/features/home/home_page.dart index 70655e97..546bad45 100644 --- a/lib/features/home/home_page.dart +++ b/lib/features/home/home_page.dart @@ -9,7 +9,7 @@ import 'package:didpay/features/tbdex/tbdex_service.dart'; import 'package:didpay/features/transaction/transaction.dart'; import 'package:didpay/features/transaction/transaction_tile.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/theme/grid.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -106,8 +106,8 @@ class HomePage extends HookConsumerWidget { ref, state, ), - loading: () => AsyncLoadingWidget( - text: Loc.of(context).fetchingTransactions, + loading: () => LoadingMessage( + message: Loc.of(context).fetchingTransactions, ), ), ), diff --git a/lib/features/kcc/kcc_retrieval_page.dart b/lib/features/kcc/kcc_retrieval_page.dart index 36ad426c..e26e2513 100644 --- a/lib/features/kcc/kcc_retrieval_page.dart +++ b/lib/features/kcc/kcc_retrieval_page.dart @@ -4,8 +4,8 @@ import 'package:didpay/features/kcc/lib/idv_request.dart'; import 'package:didpay/features/pfis/pfi.dart'; import 'package:didpay/features/vcs/vcs_notifier.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/next_button.dart'; import 'package:didpay/shared/theme/grid.dart'; import 'package:flutter/material.dart'; @@ -40,9 +40,9 @@ class KccRetrievalPage extends HookConsumerWidget { body: SafeArea( child: credential.value.when( loading: () => - AsyncLoadingWidget(text: Loc.of(context).verifyingYourIdentity), - error: (error, stackTrace) => AsyncErrorWidget( - text: error.toString(), + LoadingMessage(message: Loc.of(context).verifyingYourIdentity), + error: (error, stackTrace) => ErrorMessage( + message: error.toString(), onRetry: () => _pollForCredential(ref, credential), ), data: (data) => Column( diff --git a/lib/features/kcc/kcc_webview_page.dart b/lib/features/kcc/kcc_webview_page.dart index 27fce3ab..b65c409c 100644 --- a/lib/features/kcc/kcc_webview_page.dart +++ b/lib/features/kcc/kcc_webview_page.dart @@ -6,8 +6,8 @@ import 'package:didpay/features/kcc/kcc_retrieval_page.dart'; import 'package:didpay/features/kcc/lib/idv_request.dart'; import 'package:didpay/features/pfis/pfi.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -51,10 +51,10 @@ class KccWebviewPage extends HookConsumerWidget { ), ), body: idvRequest.value.when( - loading: () => AsyncLoadingWidget(text: Loc.of(context).startingIdv), + loading: () => LoadingMessage(message: Loc.of(context).startingIdv), error: (error, stackTrace) => SafeArea( - child: AsyncErrorWidget( - text: error.toString(), + child: ErrorMessage( + message: error.toString(), onRetry: () => _getIdvRequest(ref, idvRequest), ), ), diff --git a/lib/features/payment/payment_amount_page.dart b/lib/features/payment/payment_amount_page.dart index a8355139..ea1a027a 100644 --- a/lib/features/payment/payment_amount_page.dart +++ b/lib/features/payment/payment_amount_page.dart @@ -8,8 +8,8 @@ import 'package:didpay/features/pfis/pfi.dart'; import 'package:didpay/features/pfis/pfis_notifier.dart'; import 'package:didpay/features/tbdex/tbdex_service.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/next_button.dart'; import 'package:didpay/shared/number/number_key_press.dart'; import 'package:didpay/shared/number/number_pad.dart'; @@ -137,9 +137,9 @@ class PaymentAmountPage extends HookConsumerWidget { ); }, loading: () => - AsyncLoadingWidget(text: Loc.of(context).fetchingOfferings), - error: (error, stackTrace) => AsyncErrorWidget( - text: error.toString(), + LoadingMessage(message: Loc.of(context).fetchingOfferings), + error: (error, stackTrace) => ErrorMessage( + message: error.toString(), onRetry: () => _getOfferings(ref, currentPaymentState.value, offerings), ), diff --git a/lib/features/payment/payment_details_page.dart b/lib/features/payment/payment_details_page.dart index 2e87960b..fcd1abfa 100644 --- a/lib/features/payment/payment_details_page.dart +++ b/lib/features/payment/payment_details_page.dart @@ -10,11 +10,11 @@ import 'package:didpay/features/tbdex/tbdex_service.dart'; import 'package:didpay/features/transaction/transaction.dart'; import 'package:didpay/features/vcs/vcs_notifier.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/header.dart'; import 'package:didpay/shared/json_schema_form.dart'; -import 'package:didpay/shared/modal_flow.dart'; +import 'package:didpay/shared/modal/modal_flow.dart'; import 'package:didpay/shared/theme/grid.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -60,14 +60,14 @@ class PaymentDetailsPage extends HookConsumerWidget { body: SafeArea( child: rfq.value != null ? rfq.value!.when( - data: (_) => AsyncLoadingWidget( - text: Loc.of(context).gettingYourQuote, + data: (_) => LoadingMessage( + message: Loc.of(context).gettingYourQuote, ), - loading: () => AsyncLoadingWidget( - text: Loc.of(context).sendingYourRequest, + loading: () => LoadingMessage( + message: Loc.of(context).sendingYourRequest, ), - error: (error, _) => AsyncErrorWidget( - text: error.toString(), + error: (error, _) => ErrorMessage( + message: error.toString(), onRetry: () => _sendRfq( context, ref, diff --git a/lib/features/payment/payment_review_page.dart b/lib/features/payment/payment_review_page.dart index 0b2f1004..64412d17 100644 --- a/lib/features/payment/payment_review_page.dart +++ b/lib/features/payment/payment_review_page.dart @@ -6,9 +6,9 @@ import 'package:didpay/features/payment/payment_state.dart'; import 'package:didpay/features/tbdex/tbdex_service.dart'; import 'package:didpay/features/transaction/transaction.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_data_widget.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/confirmation_message.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/currency_formatter.dart'; import 'package:didpay/shared/header.dart'; import 'package:didpay/shared/next_button.dart'; @@ -78,22 +78,22 @@ class PaymentReviewPage extends HookConsumerWidget { ), ], ), - loading: () => AsyncLoadingWidget( - text: Loc.of(context).gettingYourQuote, + loading: () => LoadingMessage( + message: Loc.of(context).gettingYourQuote, ), - error: (error, _) => AsyncErrorWidget( - text: error.toString(), + error: (error, _) => ErrorMessage( + message: error.toString(), onRetry: () => _pollForQuote(ref, quote), ), ) : order.value!.when( - data: (_) => - AsyncDataWidget(text: Loc.of(context).orderConfirmed), - loading: () => AsyncLoadingWidget( - text: Loc.of(context).confirmingYourOrder, + data: (_) => ConfirmationMessage( + message: Loc.of(context).orderConfirmed), + loading: () => LoadingMessage( + message: Loc.of(context).confirmingYourOrder, ), - error: (error, _) => AsyncErrorWidget( - text: error.toString(), + error: (error, _) => ErrorMessage( + message: error.toString(), onRetry: () => _submitOrder( context, ref, diff --git a/lib/features/pfis/pfis_add_page.dart b/lib/features/pfis/pfis_add_page.dart index b2702562..b157195e 100644 --- a/lib/features/pfis/pfis_add_page.dart +++ b/lib/features/pfis/pfis_add_page.dart @@ -2,9 +2,9 @@ import 'package:didpay/features/did/did_form.dart'; import 'package:didpay/features/pfis/pfi.dart'; import 'package:didpay/features/pfis/pfis_notifier.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_data_widget.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/confirmation_message.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/header.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -24,11 +24,12 @@ class PfisAddPage extends HookConsumerWidget { body: SafeArea( child: pfi.value != null ? pfi.value!.when( - data: (_) => AsyncDataWidget(text: Loc.of(context).pfiAdded), + data: (_) => + ConfirmationMessage(message: Loc.of(context).pfiAdded), loading: () => - AsyncLoadingWidget(text: Loc.of(context).addingPfi), - error: (error, _) => AsyncErrorWidget( - text: error.toString(), + LoadingMessage(message: Loc.of(context).addingPfi), + error: (error, _) => ErrorMessage( + message: error.toString(), onRetry: () => _addPfi(ref, pfiDidController.text, pfi), ), ) diff --git a/lib/features/send/send_details_page.dart b/lib/features/send/send_details_page.dart index 4dcedae9..fdfd26d3 100644 --- a/lib/features/send/send_details_page.dart +++ b/lib/features/send/send_details_page.dart @@ -1,8 +1,8 @@ import 'package:didpay/features/did/did_form.dart'; import 'package:didpay/l10n/app_localizations.dart'; -import 'package:didpay/shared/async/async_data_widget.dart'; -import 'package:didpay/shared/async/async_error_widget.dart'; -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/confirmation_message.dart'; +import 'package:didpay/shared/error_message.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:didpay/shared/header.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -22,12 +22,12 @@ class SendDetailsPage extends HookConsumerWidget { body: SafeArea( child: send.value != null ? send.value!.when( - data: (_) => - AsyncDataWidget(text: Loc.of(context).yourPaymentWasSent), + data: (_) => ConfirmationMessage( + message: Loc.of(context).yourPaymentWasSent), loading: () => - AsyncLoadingWidget(text: Loc.of(context).sendingPayment), - error: (error, _) => AsyncErrorWidget( - text: error.toString(), + LoadingMessage(message: Loc.of(context).sendingPayment), + error: (error, _) => ErrorMessage( + message: error.toString(), onRetry: () => _sendPayment(send), ), ) diff --git a/lib/features/tbdex/tbdex_service.dart b/lib/features/tbdex/tbdex_service.dart index 9772afbe..b3430b68 100644 --- a/lib/features/tbdex/tbdex_service.dart +++ b/lib/features/tbdex/tbdex_service.dart @@ -42,6 +42,12 @@ class TbdexService { } } + if (offeringsMap.isEmpty) { + throw Exception( + 'No ${paymentState.transactionType.toString().toLowerCase()} offerings found for any linked PFIs', + ); + } + return offeringsMap; } diff --git a/lib/shared/async/async_data_widget.dart b/lib/shared/confirmation_message.dart similarity index 84% rename from lib/shared/async/async_data_widget.dart rename to lib/shared/confirmation_message.dart index ec2ca87a..a4137dd4 100644 --- a/lib/shared/async/async_data_widget.dart +++ b/lib/shared/confirmation_message.dart @@ -5,9 +5,9 @@ import 'package:didpay/shared/theme/grid.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -class AsyncDataWidget extends HookWidget { - final String text; - const AsyncDataWidget({required this.text, super.key}); +class ConfirmationMessage extends HookWidget { + final String message; + const ConfirmationMessage({required this.message, super.key}); @override Widget build(BuildContext context) => Column( @@ -19,7 +19,7 @@ class AsyncDataWidget extends HookWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox(height: Grid.xl), - Text(text, style: Theme.of(context).textTheme.titleMedium), + Text(message, style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: Grid.xs), Icon( Icons.check_circle, diff --git a/lib/shared/async/async_error_widget.dart b/lib/shared/error_message.dart similarity index 85% rename from lib/shared/async/async_error_widget.dart rename to lib/shared/error_message.dart index a00c49c2..cee37d40 100644 --- a/lib/shared/async/async_error_widget.dart +++ b/lib/shared/error_message.dart @@ -5,12 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -class AsyncErrorWidget extends HookConsumerWidget { - final String text; +class ErrorMessage extends HookConsumerWidget { + final String message; final VoidCallback onRetry; - const AsyncErrorWidget({ - required this.text, + const ErrorMessage({ + required this.message, required this.onRetry, super.key, }); @@ -24,7 +24,7 @@ class AsyncErrorWidget extends HookConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Header(title: Loc.of(context).errorFound, subtitle: text), + Header(title: Loc.of(context).errorFound, subtitle: message), Expanded(child: Container()), NextButton(onPressed: onRetry, title: Loc.of(context).tapToRetry), ], diff --git a/lib/shared/async/async_loading_widget.dart b/lib/shared/loading_message.dart similarity index 79% rename from lib/shared/async/async_loading_widget.dart rename to lib/shared/loading_message.dart index c415159e..ffb96a26 100644 --- a/lib/shared/async/async_loading_widget.dart +++ b/lib/shared/loading_message.dart @@ -2,10 +2,10 @@ import 'package:didpay/shared/theme/grid.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -class AsyncLoadingWidget extends HookWidget { - final String text; +class LoadingMessage extends HookWidget { + final String message; - const AsyncLoadingWidget({required this.text, super.key}); + const LoadingMessage({required this.message, super.key}); @override Widget build(BuildContext context) => Column( @@ -13,7 +13,7 @@ class AsyncLoadingWidget extends HookWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - text, + message, style: Theme.of(context).textTheme.titleMedium, textAlign: TextAlign.center, ), diff --git a/lib/shared/modal_flow.dart b/lib/shared/modal/modal_flow.dart similarity index 100% rename from lib/shared/modal_flow.dart rename to lib/shared/modal/modal_flow.dart diff --git a/test/shared/async/async_data_widget_test.dart b/test/shared/confirmation_message_test.dart similarity index 68% rename from test/shared/async/async_data_widget_test.dart rename to test/shared/confirmation_message_test.dart index 701db9f2..56babb95 100644 --- a/test/shared/async/async_data_widget_test.dart +++ b/test/shared/confirmation_message_test.dart @@ -1,15 +1,16 @@ -import 'package:didpay/shared/async/async_data_widget.dart'; +import 'package:didpay/shared/confirmation_message.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../../helpers/widget_helpers.dart'; +import '../helpers/widget_helpers.dart'; void main() { - group('AsyncDataWidget', () { + group('ConfirmationMessage', () { testWidgets('should show request was submitted', (tester) async { await tester.pumpWidget( WidgetHelpers.testableWidget( - child: const AsyncDataWidget(text: 'Your request was submitted!'), + child: + const ConfirmationMessage(message: 'Your request was submitted!'), ), ); @@ -20,8 +21,8 @@ void main() { testWidgets('should show done button', (tester) async { await tester.pumpWidget( WidgetHelpers.testableWidget( - child: const AsyncDataWidget( - text: '', + child: const ConfirmationMessage( + message: '', ), ), ); diff --git a/test/shared/async/async_loading_widget_test.dart b/test/shared/loading_message_test.dart similarity index 65% rename from test/shared/async/async_loading_widget_test.dart rename to test/shared/loading_message_test.dart index 0ef8bd4e..1b88f9a4 100644 --- a/test/shared/async/async_loading_widget_test.dart +++ b/test/shared/loading_message_test.dart @@ -1,15 +1,15 @@ -import 'package:didpay/shared/async/async_loading_widget.dart'; +import 'package:didpay/shared/loading_message.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../../helpers/widget_helpers.dart'; +import '../helpers/widget_helpers.dart'; void main() { - group('AsyncLoadingWidget', () { + group('LoadingMessage', () { testWidgets('should show request is pending', (tester) async { await tester.pumpWidget( WidgetHelpers.testableWidget( - child: const AsyncLoadingWidget(text: 'Your request is pending...'), + child: const LoadingMessage(message: 'Your request is pending...'), ), );