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

Commit 89c3396

Browse files
authored
chore: did qr feature (#155)
1 parent 4463f8d commit 89c3396

8 files changed

Lines changed: 89 additions & 108 deletions

File tree

lib/features/did_qr/did_qr.dart

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import 'package:didpay/features/did_qr/did_qr_scan_page.dart';
2+
import 'package:didpay/l10n/app_localizations.dart';
3+
import 'package:didpay/shared/theme/grid.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:web5/web5.dart';
6+
7+
class DidQr {
8+
static Widget buildScanTile(
9+
BuildContext context,
10+
String title,
11+
TextEditingController didTextController,
12+
ValueNotifier<String?> errorText, {
13+
required bool isPhysicalDevice,
14+
}) =>
15+
Padding(
16+
padding: const EdgeInsets.symmetric(vertical: Grid.xxs),
17+
child: ListTile(
18+
leading: const Icon(Icons.qr_code),
19+
title: Text(
20+
title,
21+
style: Theme.of(context).textTheme.bodyMedium,
22+
),
23+
trailing: const Icon(Icons.chevron_right),
24+
onTap: () => isPhysicalDevice
25+
? _scanQrCode(
26+
context,
27+
didTextController,
28+
errorText,
29+
Loc.of(context).noDidQrCodeFound,
30+
)
31+
: _simulateScanQrCode(
32+
context,
33+
didTextController,
34+
),
35+
),
36+
);
37+
38+
static Future<bool> _isValidDid(String did) async {
39+
final result = await DidResolver.resolve(did);
40+
return !result.hasError();
41+
}
42+
43+
static Future<void> _scanQrCode(
44+
BuildContext context,
45+
TextEditingController didTextController,
46+
ValueNotifier<String?> errorText,
47+
String errorMessage,
48+
) async {
49+
final qrValue = await Navigator.of(context).push<String>(
50+
MaterialPageRoute(builder: (context) => const DidQrScanPage()),
51+
);
52+
53+
final isValid = qrValue != null && await _isValidDid(qrValue);
54+
didTextController.text = isValid ? qrValue : '';
55+
errorText.value = isValid ? null : errorMessage;
56+
}
57+
58+
static Future<void> _simulateScanQrCode(
59+
BuildContext context,
60+
TextEditingController didTextController,
61+
) async {
62+
ScaffoldMessenger.of(context).showSnackBar(
63+
SnackBar(
64+
content: Text(Loc.of(context).simulatedQrCodeScan),
65+
),
66+
);
67+
final did = await DidDht.create(publish: true);
68+
didTextController.text = did.uri;
69+
}
70+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import 'package:flutter/material.dart';
55
import 'package:flutter_hooks/flutter_hooks.dart';
66
import 'package:mobile_scanner/mobile_scanner.dart';
77

8-
class ScanQrPage extends HookWidget {
9-
const ScanQrPage({super.key});
8+
class DidQrScanPage extends HookWidget {
9+
const DidQrScanPage({super.key});
1010

1111
@override
1212
Widget build(BuildContext context) {

lib/features/pfis/pfi_page.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import 'dart:convert';
2+
3+
import 'package:didpay/features/did_qr/did_qr_scan_page.dart';
24
import 'package:didpay/features/onboarding/agreement_page.dart';
35
import 'package:didpay/features/pfis/pfi.dart';
46
import 'package:didpay/features/pfis/pfis_notifier.dart';
5-
import 'package:didpay/features/send/scan_qr_page.dart';
67
import 'package:didpay/l10n/app_localizations.dart';
78
import 'package:didpay/shared/theme/grid.dart';
89
import 'package:flutter/material.dart';
@@ -103,7 +104,8 @@ class PfiPage extends HookConsumerWidget {
103104
onPressed: () async {
104105
final scannedJson = await Navigator.push<String>(
105106
context,
106-
MaterialPageRoute(builder: (context) => const ScanQrPage()),
107+
MaterialPageRoute(
108+
builder: (context) => const DidQrScanPage()),
107109
);
108110
if (scannedJson != null) {
109111
try {

lib/features/send/send_did_page.dart

Lines changed: 9 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import 'package:didpay/features/account/account_providers.dart';
21
import 'package:didpay/features/device/device_info_service.dart';
3-
import 'package:didpay/features/send/scan_qr_page.dart';
2+
import 'package:didpay/features/did_qr/did_qr.dart';
43
import 'package:didpay/features/send/send_confirmation_page.dart';
54
import 'package:didpay/l10n/app_localizations.dart';
65
import 'package:didpay/shared/theme/grid.dart';
@@ -17,20 +16,17 @@ class SendDidPage extends HookConsumerWidget {
1716

1817
@override
1918
Widget build(BuildContext context, WidgetRef ref) {
20-
final did = ref.watch(didProvider);
21-
2219
final focusNode = useFocusNode();
2320
final isPhysicalDevice = useState(true);
2421
final errorText = useState<String?>(null);
2522
final recipientDidController = useTextEditingController();
2623

2724
useEffect(
2825
() {
29-
Future.microtask(() async {
30-
isPhysicalDevice.value =
31-
await ref.read(deviceInfoServiceProvider).isPhysicalDevice();
32-
});
33-
26+
Future.microtask(
27+
() async => isPhysicalDevice.value =
28+
await ref.read(deviceInfoServiceProvider).isPhysicalDevice(),
29+
);
3430
return null;
3531
},
3632
[],
@@ -48,12 +44,12 @@ class SendDidPage extends HookConsumerWidget {
4844
child: Column(
4945
crossAxisAlignment: CrossAxisAlignment.stretch,
5046
children: [
51-
_buildScanQr(
47+
DidQr.buildScanTile(
5248
context,
49+
Loc.of(context).scanRecipientQrCode,
5350
recipientDidController,
5451
errorText,
55-
isPhysicalDevice,
56-
did.uri,
52+
isPhysicalDevice: isPhysicalDevice.value,
5753
),
5854
_buildForm(
5955
context,
@@ -68,7 +64,6 @@ class SendDidPage extends HookConsumerWidget {
6864
),
6965
_buildSendButton(
7066
context,
71-
did.uri,
7267
recipientDidController.text,
7368
errorText.value,
7469
),
@@ -134,40 +129,8 @@ class SendDidPage extends HookConsumerWidget {
134129
),
135130
);
136131

137-
Widget _buildScanQr(
138-
BuildContext context,
139-
TextEditingController recipientDidController,
140-
ValueNotifier<String?> errorText,
141-
ValueNotifier<bool> isPhysicalDevice,
142-
String did,
143-
) =>
144-
Padding(
145-
padding: const EdgeInsets.symmetric(vertical: Grid.xxs),
146-
child: ListTile(
147-
leading: const Icon(Icons.qr_code),
148-
title: Text(
149-
Loc.of(context).scanQrCode,
150-
style: Theme.of(context).textTheme.bodyMedium,
151-
),
152-
trailing: const Icon(Icons.chevron_right),
153-
onTap: () => isPhysicalDevice.value
154-
? _scanQrCode(
155-
context,
156-
recipientDidController,
157-
errorText,
158-
Loc.of(context).noDidQrCodeFound,
159-
)
160-
: _simulateScanQrCode(
161-
context,
162-
recipientDidController,
163-
did,
164-
),
165-
),
166-
);
167-
168132
Widget _buildSendButton(
169133
BuildContext context,
170-
String senderDid,
171134
String recipientDid,
172135
String? errorText,
173136
) {
@@ -181,7 +144,7 @@ class SendDidPage extends HookConsumerWidget {
181144
context,
182145
MaterialPageRoute(
183146
builder: (context) => SendConfirmationPage(
184-
did: senderDid,
147+
did: recipientDid,
185148
amount: sendAmount,
186149
),
187150
),
@@ -197,33 +160,4 @@ class SendDidPage extends HookConsumerWidget {
197160
final result = await DidResolver.resolve(did);
198161
return !result.hasError();
199162
}
200-
201-
Future<void> _scanQrCode(
202-
BuildContext context,
203-
TextEditingController recipientDidController,
204-
ValueNotifier<String?> errorText,
205-
String errorMessage,
206-
) async {
207-
// ignore: use_build_context_synchronously
208-
final qrValue = await Navigator.of(context).push<String>(
209-
MaterialPageRoute(builder: (context) => const ScanQrPage()),
210-
);
211-
212-
final isValid = qrValue != null && await _isValidDid(qrValue);
213-
recipientDidController.text = isValid ? qrValue : '';
214-
errorText.value = isValid ? null : errorMessage;
215-
}
216-
217-
void _simulateScanQrCode(
218-
BuildContext context,
219-
TextEditingController recipientDidController,
220-
String did,
221-
) {
222-
ScaffoldMessenger.of(context).showSnackBar(
223-
SnackBar(
224-
content: Text(Loc.of(context).simulatedQrCodeScan),
225-
),
226-
);
227-
recipientDidController.text = did;
228-
}
229163
}

lib/l10n/app_en.arb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"deposit": "Deposit",
99
"send": "Send",
1010
"to": "To:",
11-
"scanQrCode": "Don't know the recipient's DID? Scan their QR code",
11+
"scanRecipientQrCode": "Don't know the recipient's DID? Scan their QR code",
1212
"withdraw": "Withdraw",
1313
"next": "Next",
1414
"accountBalance": "Account balance",

lib/l10n/app_localizations.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,11 @@ abstract class Loc {
145145
/// **'To:'**
146146
String get to;
147147

148-
/// No description provided for @scanQrCode.
148+
/// No description provided for @scanRecipientQrCode.
149149
///
150150
/// In en, this message translates to:
151151
/// **'Don\'t know the recipient\'s DID? Scan their QR code'**
152-
String get scanQrCode;
152+
String get scanRecipientQrCode;
153153

154154
/// No description provided for @withdraw.
155155
///

lib/l10n/app_localizations_en.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class LocEn extends Loc {
3232
String get to => 'To:';
3333

3434
@override
35-
String get scanQrCode => 'Don\'t know the recipient\'s DID? Scan their QR code';
35+
String get scanRecipientQrCode => 'Don\'t know the recipient\'s DID? Scan their QR code';
3636

3737
@override
3838
String get withdraw => 'Withdraw';

test/features/send/send_did_page_test.dart

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,30 +48,5 @@ void main() async {
4848

4949
expect(find.widgetWithText(FilledButton, 'Send 25 USDC'), findsOneWidget);
5050
});
51-
52-
testWidgets(
53-
'should show enabled send button when while recipient DID is set',
54-
(tester) async {
55-
await tester.pumpWidget(
56-
WidgetHelpers.testableWidget(
57-
child: SendDidPage(sendAmount: '25'),
58-
overrides: [
59-
didProvider.overrideWithValue(did),
60-
],
61-
),
62-
);
63-
64-
await tester.tap(
65-
find.text("Don't know the recipient's DID? Scan their QR code"),
66-
);
67-
await tester.pumpAndSettle();
68-
69-
final sendButton = find.widgetWithText(FilledButton, 'Send 25 USDC');
70-
71-
expect(
72-
tester.widget<FilledButton>(sendButton).onPressed,
73-
isNotNull,
74-
);
75-
});
7651
});
7752
}

0 commit comments

Comments
 (0)