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

Commit

Permalink
feat: support multiple pfis (#173)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanwlee authored May 28, 2024
1 parent b869279 commit 7ddc179
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 93 deletions.
1 change: 0 additions & 1 deletion lib/features/app/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'package:didpay/features/app/app_tabs.dart';
import 'package:didpay/features/pfis/add_pfi_page.dart';
import 'package:didpay/features/pfis/pfis_notifier.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/modal_flow.dart';
import 'package:didpay/shared/theme/theme.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
Expand Down
10 changes: 7 additions & 3 deletions lib/features/currency/currency_dropdown.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:didpay/features/currency/currency_modal.dart';
import 'package:didpay/features/pfis/pfi.dart';
import 'package:didpay/features/transaction/transaction.dart';
import 'package:didpay/shared/theme/grid.dart';
import 'package:flutter/material.dart';
Expand All @@ -7,13 +8,15 @@ import 'package:tbdex/tbdex.dart';

class CurrencyDropdown extends HookConsumerWidget {
final TransactionType transactionType;
final ValueNotifier<Pfi?> selectedPfi;
final ValueNotifier<Offering?> selectedOffering;
final List<Offering> offerings;
final Map<Pfi, List<Offering>> offeringsMap;

const CurrencyDropdown({
required this.transactionType,
required this.selectedPfi,
required this.selectedOffering,
required this.offerings,
required this.offeringsMap,
super.key,
});

Expand All @@ -33,8 +36,9 @@ class CurrencyDropdown extends HookConsumerWidget {
CurrencyModal.show(
context,
transactionType,
selectedPfi,
selectedOffering,
offerings,
offeringsMap,
);
},
),
Expand Down
103 changes: 63 additions & 40 deletions lib/features/currency/currency_modal.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:didpay/features/pfis/pfi.dart';
import 'package:didpay/features/transaction/transaction.dart';
import 'package:didpay/shared/theme/grid.dart';
import 'package:flutter/material.dart';
Expand All @@ -7,53 +8,77 @@ class CurrencyModal {
static Future<dynamic> show(
BuildContext context,
TransactionType transactionType,
ValueNotifier<Pfi?> selectedPfi,
ValueNotifier<Offering?> selectedOffering,
List<Offering> offerings,
Map<Pfi, List<Offering>> offeringsMap,
) =>
showModalBottomSheet(
useSafeArea: true,
isScrollControlled: true,
context: context,
builder: (context) => SafeArea(
child: SizedBox(
height: 100 + (offerings.length * 30),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: Grid.xs),
child: Text(
'Select currency',
style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center,
),
child: LayoutBuilder(
builder: (context, constraints) {
final totalOfferings = offeringsMap.values
.fold(0, (total, list) => total + list.length);
final height = totalOfferings * Grid.tileHeight;
final maxHeight = MediaQuery.of(context).size.height * 0.4;

return ConstrainedBox(
constraints: BoxConstraints(
maxHeight: maxHeight,
minHeight: height < maxHeight ? height : maxHeight,
),
Expanded(
child: ListView(
children: offerings.map((offering) {
return ListTile(
onTap: () {
selectedOffering.value = offering;
Navigator.pop(context);
},
title: _buildCurrencyTitle(
context,
offering,
transactionType,
),
subtitle: _buildCurrencySubtitle(
context,
offering,
transactionType,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: Grid.xs),
child: Text(
'Select currency',
style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center,
),
),
Flexible(
child: Scrollbar(
thumbVisibility: true,
child: ListView(
shrinkWrap: true,
children: offeringsMap.entries
.expand(
(entry) => entry.value.map(
(offering) => ListTile(
onTap: () {
selectedPfi.value = entry.key;
selectedOffering.value = offering;
Navigator.pop(context);
},
title: _buildCurrencyTitle(
context,
offering,
transactionType,
),
subtitle: _buildCurrencySubtitle(
context,
offering,
transactionType,
),
trailing:
(selectedOffering.value == offering)
? const Icon(Icons.check)
: null,
),
),
)
.toList(),
),
trailing: (selectedOffering.value == offering)
? const Icon(Icons.check)
: null,
);
}).toList(),
),
),
),
],
),
],
),
);
},
),
),
);
Expand All @@ -64,9 +89,7 @@ class CurrencyModal {
TransactionType transactionType,
) =>
Text(
transactionType == TransactionType.deposit
? offering.data.payin.currencyCode
: offering.data.payout.currencyCode,
'${offering.data.payin.currencyCode} → ${offering.data.payout.currencyCode}',
style: Theme.of(context).textTheme.titleMedium,
);

Expand Down
1 change: 0 additions & 1 deletion lib/features/kcc/kcc_retrieval_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class KccRetrievalPage extends HookConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
print("HI I AM A RETRIEVER");
final bearerDid = ref.watch(didProvider);
final kccIssuanceService = ref.watch(kccIssuanceProvider);
final credentialResponse =
Expand Down
1 change: 0 additions & 1 deletion lib/features/kcc/kcc_webview_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';

import 'package:didpay/features/account/account_providers.dart';
import 'package:didpay/features/kcc/kcc_issuance_service.dart';
Expand Down
10 changes: 7 additions & 3 deletions lib/features/payin/payin.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:didpay/features/currency/currency_dropdown.dart';
import 'package:didpay/features/pfis/pfi.dart';
import 'package:didpay/features/transaction/transaction.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/shake_animated_text.dart';
Expand All @@ -14,15 +15,17 @@ class Payin extends HookWidget {
final TransactionType transactionType;
final ValueNotifier<String> amount;
final ValueNotifier<PayinKeyPress> keyPress;
final ValueNotifier<Pfi?> selectedPfi;
final ValueNotifier<Offering?> selectedOffering;
final List<Offering> offerings;
final Map<Pfi, List<Offering>> offeringsMap;

const Payin({
required this.transactionType,
required this.amount,
required this.keyPress,
required this.selectedPfi,
required this.selectedOffering,
required this.offerings,
required this.offeringsMap,
super.key,
});

Expand Down Expand Up @@ -143,8 +146,9 @@ class Payin extends HookWidget {
case TransactionType.deposit:
return CurrencyDropdown(
transactionType: transactionType,
selectedPfi: selectedPfi,
selectedOffering: selectedOffering,
offerings: offerings,
offeringsMap: offeringsMap,
);
case TransactionType.withdraw:
case TransactionType.send:
Expand Down
25 changes: 14 additions & 11 deletions lib/features/payment/payment_amount_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class PaymentAmountPage extends HookConsumerWidget {
final payinAmount = useState('0');
final payoutAmount = useState<double>(0);
final keyPress = useState(PayinKeyPress(0, ''));
final selectedPfi = useState<Pfi?>(null);
final selectedOffering = useState<Offering?>(null);
final getOfferingsState =
useState<AsyncValue<List<Offering>>>(const AsyncLoading());
useState<AsyncValue<Map<Pfi, List<Offering>>>>(const AsyncLoading());

useEffect(
() {
Expand All @@ -51,8 +52,9 @@ class PaymentAmountPage extends HookConsumerWidget {
appBar: AppBar(),
body: SafeArea(
child: getOfferingsState.value.when(
data: (offerings) {
selectedOffering.value ??= offerings.first;
data: (offeringsMap) {
selectedPfi.value ??= offeringsMap.keys.first;
selectedOffering.value ??= offeringsMap[selectedPfi.value]!.first;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
Expand All @@ -72,17 +74,19 @@ class PaymentAmountPage extends HookConsumerWidget {
transactionType: transactionType,
amount: payinAmount,
keyPress: keyPress,
selectedPfi: selectedPfi,
selectedOffering: selectedOffering,
offerings: offerings,
offeringsMap: offeringsMap,
),
const SizedBox(height: Grid.sm),
Payout(
payinAmount:
double.tryParse(payinAmount.value) ?? 0.0,
transactionType: transactionType,
payoutAmount: payoutAmount,
selectedPfi: selectedPfi,
selectedOffering: selectedOffering,
offerings: offerings,
offeringsMap: offeringsMap,
),
const SizedBox(height: Grid.xl),
FeeDetails(
Expand All @@ -109,9 +113,8 @@ class PaymentAmountPage extends HookConsumerWidget {
currency:
selectedOffering.value?.data.payout.currencyCode ?? '',
),
selectedPfi.value,
selectedOffering.value,
// TODO(ethan-tbd): get pfi from selectedOffering
ref.read(pfisProvider)[0],
),
],
);
Expand All @@ -131,8 +134,8 @@ class PaymentAmountPage extends HookConsumerWidget {
BuildContext context,
String payinAmount,
String payoutAmount,
Pfi? selectedPfi,
Offering? selectedOffering,
Pfi pfi,
) =>
Padding(
padding: const EdgeInsets.symmetric(horizontal: Grid.side),
Expand All @@ -151,7 +154,7 @@ class PaymentAmountPage extends HookConsumerWidget {
selectedOffering?.data.payout.methods.firstOrNull,
),
paymentState: PaymentState(
pfi: pfi,
pfi: selectedPfi ?? const Pfi(did: ''),
payoutAmount: payoutAmount,
payinCurrency:
selectedOffering?.data.payin.currencyCode ?? '',
Expand All @@ -175,13 +178,13 @@ class PaymentAmountPage extends HookConsumerWidget {

void _getOfferings(
WidgetRef ref,
ValueNotifier<AsyncValue<List<Offering>>> state,
ValueNotifier<AsyncValue<Map<Pfi, List<Offering>>>> state,
) {
state.value = const AsyncLoading();
ref
.read(tbdexServiceProvider)
.getOfferings(ref.read(pfisProvider))
.then((offerings) => state.value = AsyncData(offerings))
.then((offeringsMap) => state.value = AsyncData(offeringsMap))
.catchError((error, stackTrace) {
state.value = AsyncError(error, stackTrace);
throw error;
Expand Down
10 changes: 7 additions & 3 deletions lib/features/payout/payout.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:didpay/features/currency/currency_dropdown.dart';
import 'package:didpay/features/pfis/pfi.dart';
import 'package:didpay/features/transaction/transaction.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/theme/grid.dart';
Expand All @@ -12,15 +13,17 @@ class Payout extends HookWidget {
final double payinAmount;
final TransactionType transactionType;
final ValueNotifier<double> payoutAmount;
final ValueNotifier<Pfi?> selectedPfi;
final ValueNotifier<Offering?> selectedOffering;
final List<Offering> offerings;
final Map<Pfi, List<Offering>> offeringsMap;

const Payout({
required this.payinAmount,
required this.transactionType,
required this.payoutAmount,
required this.selectedPfi,
required this.selectedOffering,
required this.offerings,
required this.offeringsMap,
super.key,
});

Expand Down Expand Up @@ -80,8 +83,9 @@ class Payout extends HookWidget {
case TransactionType.withdraw:
return CurrencyDropdown(
transactionType: transactionType,
selectedPfi: selectedPfi,
selectedOffering: selectedOffering,
offerings: offerings,
offeringsMap: offeringsMap,
);
case TransactionType.deposit:
case TransactionType.send:
Expand Down
Loading

0 comments on commit 7ddc179

Please sign in to comment.