Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
feat: update AsyncValue use (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanwlee authored Jun 3, 2024
1 parent caafd34 commit 7de505a
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 266 deletions.
42 changes: 23 additions & 19 deletions lib/features/kcc/kcc_retrieval_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,14 @@ class KccRetrievalPage extends HookConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
final bearerDid = ref.watch(didProvider);
final kccIssuanceService = ref.watch(kccIssuanceProvider);
final credentialResponse =
useState<AsyncValue<String>>(const AsyncLoading());

useEffect(
() {
Future.microtask(() async {
try {
final response = await kccIssuanceService.pollForCredential(
pfi,
idvRequest,
bearerDid,
);

await ref.read(vcsProvider.notifier).add(response).then(
(credential) =>
credentialResponse.value = AsyncData(credential),
);
} on Exception catch (e, stackTrace) {
credentialResponse.value = AsyncError(e, stackTrace);
}
});
Future.microtask(
() async => _pollForCredential(ref, credentialResponse),
);

return null;
},
Expand All @@ -59,7 +44,7 @@ class KccRetrievalPage extends HookConsumerWidget {
AsyncLoadingWidget(text: Loc.of(context).verifyingYourIdentity),
error: (error, stackTrace) => AsyncErrorWidget(
text: error.toString(),
onRetry: () => Navigator.of(context).pop(),
onRetry: () => _pollForCredential(ref, credentialResponse),
),
data: (data) => Column(
mainAxisAlignment: MainAxisAlignment.center,
Expand Down Expand Up @@ -97,4 +82,23 @@ class KccRetrievalPage extends HookConsumerWidget {
),
);
}

Future<void> _pollForCredential(
WidgetRef ref,
ValueNotifier<AsyncValue<String>> state,
) async {
try {
final credential = await ref.read(kccIssuanceProvider).pollForCredential(
pfi,
idvRequest,
ref.read(didProvider),
);

await ref.read(vcsProvider.notifier).add(credential).then(
(credential) => state.value = AsyncData(credential),
);
} on Exception catch (e, stackTrace) {
state.value = AsyncError(e, stackTrace);
}
}
}
8 changes: 4 additions & 4 deletions lib/features/payment/payment_amount_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ class PaymentAmountPage extends HookConsumerWidget {
final keyPress = useState(PayinKeyPress(0, ''));
final selectedPfi = useState<Pfi?>(null);
final selectedOffering = useState<Offering?>(null);
final getOfferingsState =
final offeringsResponse =
useState<AsyncValue<Map<Pfi, List<Offering>>>>(const AsyncLoading());

useEffect(
() {
_getOfferings(ref, getOfferingsState);
_getOfferings(ref, offeringsResponse);
return null;
},
[],
Expand All @@ -51,7 +51,7 @@ class PaymentAmountPage extends HookConsumerWidget {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: getOfferingsState.value.when(
child: offeringsResponse.value.when(
data: (offeringsMap) {
selectedPfi.value ??= offeringsMap.keys.first;
selectedOffering.value ??= offeringsMap[selectedPfi.value]!.first;
Expand Down Expand Up @@ -121,7 +121,7 @@ class PaymentAmountPage extends HookConsumerWidget {
AsyncLoadingWidget(text: Loc.of(context).fetchingOfferings),
error: (error, stackTrace) => AsyncErrorWidget(
text: error.toString(),
onRetry: () => _getOfferings(ref, getOfferingsState),
onRetry: () => _getOfferings(ref, offeringsResponse),
),
),
),
Expand Down
25 changes: 11 additions & 14 deletions lib/features/payment/payment_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PaymentDetailsPage extends HookConsumerWidget {
final selectedPaymentMethod = useState<Object?>(null);
final selectedPaymentType = useState<String?>(null);
final offeringCredentials = useState<List<String>?>(null);
final sendRfqState = useState<AsyncValue<Rfq>?>(null);
final rfqResponse = useState<AsyncValue<Rfq>?>(null);

final paymentMethods = _getPaymentMethods(paymentState);
final paymentTypes = _getPaymentTypes(paymentMethods);
Expand All @@ -57,8 +57,8 @@ class PaymentDetailsPage extends HookConsumerWidget {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: sendRfqState.value != null
? sendRfqState.value!.when(
child: rfqResponse.value != null
? rfqResponse.value!.when(
data: (rfq) => AsyncLoadingWidget(
text: Loc.of(context).gettingYourQuote,
),
Expand All @@ -71,7 +71,7 @@ class PaymentDetailsPage extends HookConsumerWidget {
context,
ref,
paymentState,
sendRfqState,
rfqResponse,
claims: offeringCredentials.value,
),
),
Expand Down Expand Up @@ -111,16 +111,13 @@ class PaymentDetailsPage extends HookConsumerWidget {
paymentState,
offeringCredentials,
).then((_) {
if (offeringCredentials.value != null &&
offeringCredentials.value!.isNotEmpty) {
_sendRfq(
context,
ref,
paymentState,
sendRfqState,
claims: offeringCredentials.value,
);
}
_sendRfq(
context,
ref,
paymentState,
rfqResponse,
claims: offeringCredentials.value,
);
});
},
),
Expand Down
6 changes: 3 additions & 3 deletions lib/features/payment/payment_fee_details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ class PaymentFeeDetails extends HookWidget {
}

static String calculateExchangeRate(QuoteData? quote) =>
(Decimal.parse(quote?.payout.amount ?? '0') /
Decimal.parse(quote?.payin.amount ?? '0'))
.toString();
(double.parse(quote?.payout.amount ?? '0') /
double.parse(quote?.payin.amount ?? '0'))
.toStringAsFixed(2);

static String calculateTotalAmount(QuoteData? quote) =>
Decimal.parse(quote?.payin.amount ?? '0')
Expand Down
141 changes: 75 additions & 66 deletions lib/features/payment/payment_review_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:decimal/decimal.dart';
import 'package:didpay/features/account/account_providers.dart';
import 'package:didpay/features/payment/payment_fee_details.dart';
import 'package:didpay/features/payment/payment_state.dart';
import 'package:didpay/features/tbdex/quote_notifier.dart';
import 'package:didpay/features/tbdex/tbdex_service.dart';
import 'package:didpay/features/transaction/transaction.dart';
import 'package:didpay/l10n/app_localizations.dart';
Expand All @@ -24,91 +23,80 @@ class PaymentReviewPage extends HookConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
final sendOrderState = useState<AsyncValue<Order>?>(null);

final getQuoteState = ref.watch(quoteProvider);
QuoteAsyncNotifier getQuoteNotifier() => ref.read(quoteProvider.notifier);
final quoteResponse = useState<AsyncValue<Quote>>(const AsyncLoading());
final orderResponse = useState<AsyncValue<Order>?>(null);

useEffect(
() {
Future.delayed(
Duration.zero,
() => getQuoteNotifier()
.startPolling(paymentState.exchangeId, paymentState.selectedPfi),
Future.microtask(
() async => _pollForQuote(ref, quoteResponse),
);
return getQuoteNotifier().stopPolling;
return null;
},
[],
);

return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: sendOrderState.value != null
? sendOrderState.value!.when(
child: orderResponse.value == null
? quoteResponse.value.when(
data: (quote) => Padding(
padding: const EdgeInsets.symmetric(horizontal: Grid.side),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_buildHeader(
context,
Loc.of(context).reviewYourPayment,
Loc.of(context).makeSureInfoIsCorrect,
),
Expanded(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: Grid.sm),
_buildAmounts(context, quote.data),
_buildFeeDetails(context, quote.data),
_buildPaymentDetails(context),
],
),
),
),
_buildSubmitButton(
context,
ref,
quote,
orderResponse,
),
],
),
),
loading: () => AsyncLoadingWidget(
text: Loc.of(context).gettingYourQuote,
),
error: (error, _) => AsyncErrorWidget(
text: error.toString(),
onRetry: () => _pollForQuote(ref, quoteResponse),
),
)
: orderResponse.value!.when(
data: (_) =>
AsyncDataWidget(text: Loc.of(context).orderConfirmed),
loading: () => AsyncLoadingWidget(
text: Loc.of(context).confirmingYourOrder,
),
error: (error, _) => AsyncErrorWidget(
text: error.toString(),
onRetry: () => submitOrder(
onRetry: () => _submitOrder(
context,
ref,
paymentState,
sendOrderState,
orderResponse,
),
),
)
: getQuoteState.when(
data: (quote) => quote != null
? Padding(
padding:
const EdgeInsets.symmetric(horizontal: Grid.side),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_buildHeader(
context,
Loc.of(context).reviewYourPayment,
Loc.of(context).makeSureInfoIsCorrect,
),
Expanded(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: Grid.sm),
_buildAmounts(context, quote.data),
_buildFeeDetails(context, quote.data),
_buildPaymentDetails(context),
],
),
),
),
_buildSubmitButton(
context,
ref,
quote,
sendOrderState,
),
],
),
)
: AsyncLoadingWidget(
text: Loc.of(context).gettingYourQuote,
),
loading: () =>
AsyncLoadingWidget(text: Loc.of(context).gettingYourQuote),
error: (error, _) => AsyncErrorWidget(
text: error.toString(),
onRetry: () => ref.read(quoteProvider.notifier).startPolling(
paymentState.exchangeId,
paymentState.selectedPfi,
),
),
),
),
);
Expand Down Expand Up @@ -177,7 +165,8 @@ class PaymentReviewPage extends HookConsumerWidget {
children: [
Flexible(
child: AutoSizeText(
quote.payout.amount,
Decimal.parse(quote.payout.amount)
.formatCurrency(quote.payout.currencyCode),
style: Theme.of(context).textTheme.headlineMedium,
maxLines: 1,
),
Expand Down Expand Up @@ -248,7 +237,7 @@ class PaymentReviewPage extends HookConsumerWidget {
sendOrderState,
) =>
FilledButton(
onPressed: () => submitOrder(
onPressed: () => _submitOrder(
context,
ref,
paymentState,
Expand All @@ -259,7 +248,27 @@ class PaymentReviewPage extends HookConsumerWidget {
),
);

void submitOrder(
void _pollForQuote(
WidgetRef ref,
ValueNotifier<AsyncValue<Quote>> state,
) {
try {
if (paymentState.exchangeId != null && paymentState.selectedPfi != null) {
ref
.read(tbdexServiceProvider)
.pollForQuote(
ref.read(didProvider),
paymentState.selectedPfi!,
paymentState.exchangeId!,
)
.then((quote) => state.value = AsyncData(quote));
}
} on Exception catch (error, stackTrace) {
state.value = AsyncError(error, stackTrace);
}
}

void _submitOrder(
BuildContext context,
WidgetRef ref,
PaymentState paymentState,
Expand Down
Loading

0 comments on commit 7de505a

Please sign in to comment.