Skip to content

Commit 188300e

Browse files
committed
Use FilterChip for scan QR code
1 parent f4264c4 commit 188300e

File tree

1 file changed

+124
-115
lines changed

1 file changed

+124
-115
lines changed

lib/oath/views/add_account_page.dart

Lines changed: 124 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
9393
List<int> _digitsValues = [6, 8];
9494
List<OathCredential>? _credentials;
9595
bool _submitting = false;
96+
bool _scanning = false;
9697
bool _qrScanError = false;
9798

9899
@override
@@ -112,7 +113,7 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
112113
void initState() {
113114
super.initState();
114115
_animationController = AnimationController(
115-
duration: const Duration(milliseconds: 900), vsync: this);
116+
duration: const Duration(milliseconds: 3000), vsync: this);
116117
final cred = widget.credentialData;
117118
if (cred != null) {
118119
_loadCredentialData(cred);
@@ -336,7 +337,6 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
336337
final withContext = ref.read(withContextProvider);
337338

338339
final theme = Theme.of(context);
339-
final textTheme = theme.textTheme;
340340
final colorScheme = theme.colorScheme;
341341

342342
return FileDropTarget(
@@ -370,40 +370,40 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
370370
),
371371
child: ResponsiveDialog(
372372
title: Text(l10n.s_add_account),
373-
infoText: RichText(
374-
text: TextSpan(
375-
children: [
376-
TextSpan(text: 'There is 3 ways of adding accounts.\n\n'),
377-
TextSpan(
378-
text: 'Scanning (recommended)\n',
379-
style:
380-
textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w700),
381-
),
382-
TextSpan(
383-
text:
384-
'Before scanning a QR code, make sure the full code is visible on the screen.\n\n',
385-
),
386-
TextSpan(
387-
text: 'Drag and Drop\n',
388-
style:
389-
textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w700),
390-
),
391-
TextSpan(
392-
text:
393-
'An image containing a QR code may be dropped anywhere in the Accounts application.\n\n',
394-
),
395-
TextSpan(
396-
text: 'Manually\n',
397-
style:
398-
textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w700),
399-
),
400-
TextSpan(
401-
text:
402-
'Account credential details may be entered manually in the form.',
403-
),
404-
],
405-
),
406-
),
373+
// infoText: RichText(
374+
// text: TextSpan(
375+
// children: [
376+
// TextSpan(text: 'There is 3 ways of adding accounts.\n\n'),
377+
// TextSpan(
378+
// text: 'Scanning (recommended)\n',
379+
// style:
380+
// textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w700),
381+
// ),
382+
// TextSpan(
383+
// text:
384+
// 'Before scanning a QR code, make sure the full code is visible on the screen.\n\n',
385+
// ),
386+
// TextSpan(
387+
// text: 'Drag and Drop\n',
388+
// style:
389+
// textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w700),
390+
// ),
391+
// TextSpan(
392+
// text:
393+
// 'An image containing a QR code may be dropped anywhere in the Accounts application.\n\n',
394+
// ),
395+
// TextSpan(
396+
// text: 'Manually\n',
397+
// style:
398+
// textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w700),
399+
// ),
400+
// TextSpan(
401+
// text:
402+
// 'Account credential details may be entered manually in the form.',
403+
// ),
404+
// ],
405+
// ),
406+
// ),
407407
actions: [
408408
TextButton(
409409
onPressed: isValid ? submit : null,
@@ -424,95 +424,104 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
424424
if (widget.credentialData == null)
425425
Column(
426426
children: [
427-
_animationController.isAnimating
428-
? ScaleTransition(
429-
scale: Tween(begin: 1.2, end: 0.8).animate(
430-
CurvedAnimation(
431-
parent: _animationController,
432-
curve: Curves.elasticOut,
433-
),
434-
),
435-
child: SizedBox(
436-
width: 64,
437-
height: 64,
438-
child: CircleAvatar(
439-
backgroundColor: _qrScanError
440-
? colorScheme.error
441-
: colorScheme.primary,
442-
child: Icon(
443-
_qrScanError
444-
? Symbols.close
445-
: Symbols.check,
446-
fill: 1,
447-
size: 48,
448-
color: _qrScanError
449-
? colorScheme.onError
450-
: colorScheme.onPrimary,
451-
),
452-
),
453-
),
454-
)
455-
: Icon(
456-
Symbols.qr_code_scanner,
457-
size: 64,
458-
color: colorScheme.onSurface,
427+
Row(
428+
mainAxisAlignment: MainAxisAlignment.center,
429+
spacing: 4.0,
430+
children: [
431+
FilterChip(
432+
avatar: _scanning
433+
? SizedBox(
434+
height: 16,
435+
width: 16,
436+
child: CircularProgressIndicator(
437+
strokeWidth: 2.0,
438+
),
439+
)
440+
: _animationController.isAnimating
441+
? Icon(
442+
_qrScanError
443+
? Symbols.error
444+
: Symbols.check_circle,
445+
fill: 1,
446+
color: _qrScanError
447+
? colorScheme.error
448+
: colorScheme.primary,
449+
)
450+
: Icon(Symbols.qr_code_scanner),
451+
label: Text(
452+
_animationController.isAnimating
453+
? _qrScanError
454+
? l10n.l_qr_not_found
455+
: 'QR code found'
456+
: l10n.s_qr_scan,
459457
),
460-
const SizedBox(height: 4.0),
461-
TextButton(
462-
style: TextButton.styleFrom(
463-
textStyle: textTheme.bodySmall),
464-
onPressed: () async {
465-
if (qrScanner != null) {
466-
final qrData = await qrScanner.scanQr();
467-
await withContext(
468-
(context) async {
469-
if (qrData != null) {
470-
try {
471-
final creds = CredentialData.fromUri(
472-
Uri.parse(qrData));
473-
if (creds.isEmpty) {
458+
onSelected: (_) async {
459+
if (qrScanner != null) {
460+
setState(() {
461+
_scanning = true;
462+
_qrScanError = false;
463+
});
464+
final qrData = await qrScanner.scanQr();
465+
await withContext(
466+
(context) async {
467+
if (qrData != null) {
468+
try {
469+
final creds =
470+
CredentialData.fromUri(
471+
Uri.parse(qrData));
472+
if (creds.isEmpty) {
473+
setState(() {
474+
_qrScanError = true;
475+
});
476+
}
477+
if (creds.length == 1) {
478+
_loadCredentialData(creds[0]);
479+
} else {
480+
Navigator.of(context).pop();
481+
await handleUri(
482+
context,
483+
widget.credentials,
484+
qrData,
485+
widget.devicePath,
486+
widget.state,
487+
l10n,
488+
);
489+
return;
490+
}
491+
} catch (_) {
492+
setState(() {
493+
_qrScanError = true;
494+
});
495+
}
496+
} else {
474497
setState(() {
475498
_qrScanError = true;
476499
});
477500
}
478-
if (creds.length == 1) {
479-
_loadCredentialData(creds[0]);
480-
} else {
481-
Navigator.of(context).pop();
482-
await handleUri(
483-
context,
484-
widget.credentials,
485-
qrData,
486-
widget.devicePath,
487-
widget.state,
488-
l10n,
489-
);
490-
return;
491-
}
492-
} catch (_) {
493501
setState(() {
494-
_qrScanError = true;
502+
_scanning = false;
495503
});
496-
}
497-
} else {
498-
setState(() {
499-
_qrScanError = true;
500-
});
501-
}
502-
await _animationController.forward();
503-
_animationController.reset();
504-
setState(() {
505-
_qrScanError = false;
506-
});
507-
},
508-
);
509-
}
510-
},
511-
child: const Text('Scan QR code on screen'),
504+
await _animationController.forward();
505+
_animationController.reset();
506+
setState(() {});
507+
},
508+
);
509+
}
510+
},
511+
),
512+
FilterChip(
513+
avatar: Icon(Symbols.help),
514+
label: Text(l10n.s_learn_more),
515+
onSelected: (_) {},
516+
)
517+
],
512518
),
513-
const SizedBox(height: 8.0)
519+
const SizedBox(height: 8.0),
520+
Text(
521+
'Scan (recommended) OR enter the credential details manually below.'),
514522
],
515523
),
524+
const SizedBox(height: 8.0),
516525
AppTextField(
517526
key: keys.issuerField,
518527
controller: _issuerController,

0 commit comments

Comments
 (0)