11import 'package:flutter/material.dart' ;
2+ import 'package:flutter/services.dart' ;
23import 'package:flutter_riverpod/flutter_riverpod.dart' ;
34import 'package:open_authenticator/i18n/translations.g.dart' ;
45import 'package:open_authenticator/pages/totp.dart' ;
5- import 'package:open_authenticator/widgets/centered_circular_progress_indicator.dart' ;
6- import 'package:open_authenticator/widgets/code_scan.dart' ;
7- import 'package:open_authenticator/widgets/dialog/confirmation_dialog.dart' ;
6+ import 'package:open_authenticator/widgets/scan/scanner.dart' ;
87import 'package:open_authenticator/widgets/snackbar_icon.dart' ;
98import 'package:open_authenticator/widgets/waiting_overlay.dart' ;
9+ import 'package:wakelock_plus/wakelock_plus.dart' ;
1010
1111/// Allows to scan QR codes.
12- class ScanPage extends ConsumerWidget {
12+ class ScanPage extends ConsumerStatefulWidget {
1313 /// The scan page name.
1414 static const String name = '/scan' ;
1515
@@ -19,16 +19,30 @@ class ScanPage extends ConsumerWidget {
1919 });
2020
2121 @override
22- Widget build (BuildContext context, WidgetRef ref) => Scaffold (
23- body: CodeScanner (
24- once: true ,
25- formats: const [BarcodeFormat .qrCode],
26- loading: const CenteredCircularProgressIndicator (),
27- onScan: (code, details, listener) async {
28- if (code == null || ! context.mounted) {
22+ ConsumerState <ConsumerStatefulWidget > createState () => _ScanPageState ();
23+ }
24+
25+ /// The scan page state.
26+ class _ScanPageState extends ConsumerState <ScanPage > {
27+ @override
28+ void initState () {
29+ super .initState ();
30+ WakelockPlus .enable ();
31+ SystemChrome .setPreferredOrientations ([
32+ DeviceOrientation .portraitUp,
33+ DeviceOrientation .portraitDown,
34+ ]);
35+ }
36+
37+ @override
38+ Widget build (BuildContext context) => Scaffold (
39+ body: QrCodeScanner (
40+ onScan: (code) async {
41+ String ? data = code.barcodes.firstOrNull? .rawValue;
42+ if (data == null || ! context.mounted) {
2943 return ;
3044 }
31- Uri ? uri = Uri .tryParse (code );
45+ Uri ? uri = Uri .tryParse (data );
3246 if (uri == null ) {
3347 Navigator .pop (context);
3448 SnackBarIcon .showErrorSnackBar (context, text: translations.error.scan.noUri);
@@ -39,25 +53,23 @@ class ScanPage extends ConsumerWidget {
3953 future: TotpPage .openFromUri (context, ref, uri),
4054 );
4155 },
42- onAccessDenied: (exception, listener) async {
43- bool result = await ConfirmationDialog .ask (
44- context,
45- title: translations.error.scan.accessDeniedDialog.title,
46- message: translations.error.scan.accessDeniedDialog.message (exception: exception),
47- );
48- if (result) {
49- return true ;
50- }
51- if (context.mounted) {
52- Navigator .pop (context);
53- }
54- return false ;
55- },
5656 onError: (exception, listener) => SnackBarIcon .showErrorSnackBar (context, text: translations.error.generic.withException (exception: exception)),
5757 ),
5858 floatingActionButton: FloatingActionButton (
59- child: const BackButtonIcon ( ),
59+ child: Icon ( Icons .close ),
6060 onPressed: () => Navigator .pop (context),
6161 ),
6262 );
63+
64+ @override
65+ void dispose () {
66+ SystemChrome .setPreferredOrientations ([
67+ DeviceOrientation .landscapeRight,
68+ DeviceOrientation .landscapeLeft,
69+ DeviceOrientation .portraitUp,
70+ DeviceOrientation .portraitDown,
71+ ]);
72+ WakelockPlus .disable ();
73+ super .dispose ();
74+ }
6375}
0 commit comments