From aa683fd5f6f2382a572af924906059c950f3bc82 Mon Sep 17 00:00:00 2001 From: Ethan Lee <125412902+ethan-tbd@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:43:10 -0700 Subject: [PATCH] chore: refactor `onSubmit()` callback in `JsonSchemaForm` (#266) --- .../payment/payment_details_page.dart | 150 ++++++++---------- lib/shared/json_schema_form.dart | 2 +- test/shared/json_schema_form_test.dart | 6 +- 3 files changed, 68 insertions(+), 90 deletions(-) diff --git a/lib/features/payment/payment_details_page.dart b/lib/features/payment/payment_details_page.dart index 6091df6e..7c63aa07 100644 --- a/lib/features/payment/payment_details_page.dart +++ b/lib/features/payment/payment_details_page.dart @@ -23,6 +23,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:tbdex/tbdex.dart'; +import 'package:web5/web5.dart'; class PaymentDetailsPage extends HookConsumerWidget { final PaymentState paymentState; @@ -35,11 +36,11 @@ class PaymentDetailsPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final quote = useState>(ref.watch(quoteProvider)); - final rfq = useState?>(null); final state = useState( paymentState.paymentDetailsState ?? PaymentDetailsState(), ); + final availableMethods = state.value.filterPaymentMethods(state.value.selectedPaymentType); @@ -97,52 +98,43 @@ class PaymentDetailsPage extends HookConsumerWidget { ), ), ) - : _buildPage(context, ref, availableMethods, state, rfq), + : Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Header( + title: + paymentState.transactionType == TransactionType.send + ? state.value.moneyAddresses != null + ? Loc.of(context).checkTheirPaymentDetails + : Loc.of(context).enterTheirPaymentDetails + : Loc.of(context).enterYourPaymentDetails, + subtitle: Loc.of(context).makeSureInfoIsCorrect, + ), + if (state.value.hasMultiplePaymentTypes) + _buildPaymentTypeSelector( + context, + state, + ), + if (state.value.hasNoPaymentTypes || + state.value.selectedPaymentType != null) + _buildPaymentMethodSelector( + context, + availableMethods, + state, + ), + _buildPaymentForm( + context, + ref, + state, + rfq, + ), + ], + ), ), ), ); } - Widget _buildPage( - BuildContext context, - WidgetRef ref, - List? availableMethods, - ValueNotifier state, - ValueNotifier?> rfq, - ) { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Header( - title: paymentState.transactionType == TransactionType.send - ? state.value.moneyAddresses != null - ? Loc.of(context).checkTheirPaymentDetails - : Loc.of(context).enterTheirPaymentDetails - : Loc.of(context).enterYourPaymentDetails, - subtitle: Loc.of(context).makeSureInfoIsCorrect, - ), - if (state.value.hasMultiplePaymentTypes) - _buildPaymentTypeSelector( - context, - state, - ), - if (state.value.hasNoPaymentTypes || - state.value.selectedPaymentType != null) - _buildPaymentMethodSelector( - context, - availableMethods, - state, - ), - _buildPaymentForm( - context, - ref, - state, - rfq, - ), - ], - ); - } - Widget _buildPaymentForm( BuildContext context, WidgetRef ref, @@ -152,14 +144,31 @@ class PaymentDetailsPage extends HookConsumerWidget { Expanded( child: JsonSchemaForm( state: state.value, - onSubmit: (formData) { + onSubmit: (formData) async { state.value = state.value.copyWith(formData: formData); - _checkCredsAndSendRfq( - context, - ref, - rfq, - state, - ); + + final presentationDefinition = paymentState + .paymentAmountState?.selectedOffering?.data.requiredClaims; + + if (presentationDefinition != null) { + final credentials = await _getRequiredCredentials( + context, ref, presentationDefinition,); + + if (credentials == null) { + return; + } + + state.value = state.value.copyWith(credentialsJwt: credentials); + } + + if (context.mounted) { + await _sendRfq( + context, + ref, + state.value, + rfq, + ); + } }, ), ); @@ -247,24 +256,6 @@ class PaymentDetailsPage extends HookConsumerWidget { ); } - Future _checkCredsAndSendRfq( - BuildContext context, - WidgetRef ref, - ValueNotifier?> rfq, - ValueNotifier state, - ) async { - final hasRequiredVc = await _hasRequiredVc(context, ref, state); - - if (hasRequiredVc && context.mounted) { - await _sendRfq( - context, - ref, - state.value, - rfq, - ); - } - } - Future _sendRfq( BuildContext context, WidgetRef ref, @@ -297,27 +288,18 @@ class PaymentDetailsPage extends HookConsumerWidget { } } - Future _hasRequiredVc( + Future?> _getRequiredCredentials( BuildContext context, WidgetRef ref, - ValueNotifier state, + PresentationDefinition presentationDefinition, ) async { - final presentationDefinition = - paymentState.paymentAmountState?.selectedOffering?.data.requiredClaims; final credentials = - presentationDefinition?.selectCredentials(ref.read(vcsProvider)); - - if (credentials == null && presentationDefinition == null) { - return true; - } + presentationDefinition.selectCredentials(ref.read(vcsProvider)); - if (credentials != null && credentials.isNotEmpty) { - state.value = state.value.copyWith(credentialsJwt: credentials); - return true; + if (credentials.isNotEmpty) { + return credentials; } - if (paymentState.paymentAmountState?.pfiDid == null) return false; - final issuedCredential = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => ModalFlow( @@ -329,10 +311,6 @@ class PaymentDetailsPage extends HookConsumerWidget { ), ); - if (issuedCredential == null) return false; - - state.value = - state.value.copyWith(credentialsJwt: [issuedCredential as String]); - return true; + return issuedCredential == null ? null : [issuedCredential as String]; } } diff --git a/lib/shared/json_schema_form.dart b/lib/shared/json_schema_form.dart index def365c3..48957d1e 100644 --- a/lib/shared/json_schema_form.dart +++ b/lib/shared/json_schema_form.dart @@ -10,7 +10,7 @@ import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; class JsonSchemaForm extends HookWidget { final PaymentDetailsState state; - final void Function(Map) onSubmit; + final Future Function(Map) onSubmit; final _formKey = GlobalKey(); diff --git a/test/shared/json_schema_form_test.dart b/test/shared/json_schema_form_test.dart index 403cb26c..a8f7ae66 100644 --- a/test/shared/json_schema_form_test.dart +++ b/test/shared/json_schema_form_test.dart @@ -29,7 +29,7 @@ void main() { group('JsonSchemaForm', () { Widget jsonSchemaFormTestWidget({ - void Function(Map)? onSubmit, + Future Function(Map)? onSubmit, }) => WidgetHelpers.testableWidget( child: JsonSchemaForm( @@ -37,7 +37,7 @@ void main() { selectedPaymentMethod: PaymentMethod(kind: '', schema: jsonSchemaString), ), - onSubmit: onSubmit ?? (_) {}, + onSubmit: onSubmit ?? (_) async {}, ), ); testWidgets('should render form fields based on JSON schema', @@ -70,7 +70,7 @@ void main() { await tester.pumpWidget( jsonSchemaFormTestWidget( - onSubmit: (formData) => submittedData = formData, + onSubmit: (formData) async => submittedData = formData, ), );