@@ -93,6 +93,7 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
93
93
List <int > _digitsValues = [6 , 8 ];
94
94
List <OathCredential >? _credentials;
95
95
bool _submitting = false ;
96
+ bool _scanning = false ;
96
97
bool _qrScanError = false ;
97
98
98
99
@override
@@ -112,7 +113,7 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
112
113
void initState () {
113
114
super .initState ();
114
115
_animationController = AnimationController (
115
- duration: const Duration (milliseconds: 900 ), vsync: this );
116
+ duration: const Duration (milliseconds: 3000 ), vsync: this );
116
117
final cred = widget.credentialData;
117
118
if (cred != null ) {
118
119
_loadCredentialData (cred);
@@ -336,7 +337,6 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
336
337
final withContext = ref.read (withContextProvider);
337
338
338
339
final theme = Theme .of (context);
339
- final textTheme = theme.textTheme;
340
340
final colorScheme = theme.colorScheme;
341
341
342
342
return FileDropTarget (
@@ -370,40 +370,40 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
370
370
),
371
371
child: ResponsiveDialog (
372
372
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
+ // ),
407
407
actions: [
408
408
TextButton (
409
409
onPressed: isValid ? submit : null ,
@@ -424,95 +424,104 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage>
424
424
if (widget.credentialData == null )
425
425
Column (
426
426
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,
459
457
),
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 {
474
497
setState (() {
475
498
_qrScanError = true ;
476
499
});
477
500
}
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 (_) {
493
501
setState (() {
494
- _qrScanError = true ;
502
+ _scanning = false ;
495
503
});
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
+ ],
512
518
),
513
- const SizedBox (height: 8.0 )
519
+ const SizedBox (height: 8.0 ),
520
+ Text (
521
+ 'Scan (recommended) OR enter the credential details manually below.' ),
514
522
],
515
523
),
524
+ const SizedBox (height: 8.0 ),
516
525
AppTextField (
517
526
key: keys.issuerField,
518
527
controller: _issuerController,
0 commit comments