|
@@ -13,6 +13,7 @@ import 'pages/pages.dart';
|
|
|
import 'package:provider/provider.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
|
|
|
import 'config/routes.dart';
|
|
import 'config/routes.dart';
|
|
|
|
|
+import 'pages/lock_screen.dart';
|
|
|
|
|
|
|
|
void main() {
|
|
void main() {
|
|
|
var repository = Repository(FileStorage());
|
|
var repository = Repository(FileStorage());
|
|
@@ -22,7 +23,7 @@ void main() {
|
|
|
));
|
|
));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-class MainApp extends StatelessWidget {
|
|
|
|
|
|
|
+class MainApp extends StatefulWidget {
|
|
|
// Locale information
|
|
// Locale information
|
|
|
final Iterable<Locale> supportedLocales = [const Locale('en')];
|
|
final Iterable<Locale> supportedLocales = [const Locale('en')];
|
|
|
final Iterable<LocalizationsDelegate> localizationsDelegates = [
|
|
final Iterable<LocalizationsDelegate> localizationsDelegates = [
|
|
@@ -43,6 +44,35 @@ class MainApp extends StatelessWidget {
|
|
|
|
|
|
|
|
MainApp({super.key});
|
|
MainApp({super.key});
|
|
|
|
|
|
|
|
|
|
+ @override
|
|
|
|
|
+ State<MainApp> createState() => _MainAppState();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+class _MainAppState extends State<MainApp> {
|
|
|
|
|
+ bool _locked = false;
|
|
|
|
|
+ bool _initialCheckDone = false;
|
|
|
|
|
+
|
|
|
|
|
+ @override
|
|
|
|
|
+ void didChangeDependencies() {
|
|
|
|
|
+ super.didChangeDependencies();
|
|
|
|
|
+ _checkInitialAuth();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Future<void> _checkInitialAuth() async {
|
|
|
|
|
+ if (_initialCheckDone) return;
|
|
|
|
|
+ final appState = Provider.of<AppState>(context, listen: false);
|
|
|
|
|
+ if (appState.shouldRequireAuth()) {
|
|
|
|
|
+ setState(() { _locked = true; });
|
|
|
|
|
+ final unlocked = await Navigator.of(context).push(
|
|
|
|
|
+ MaterialPageRoute(builder: (_) => const LockScreenPage(), fullscreenDialog: true),
|
|
|
|
|
+ );
|
|
|
|
|
+ if (unlocked == true) {
|
|
|
|
|
+ setState(() { _locked = false; });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ _initialCheckDone = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@override
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
Widget build(BuildContext context) {
|
|
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
|
@@ -50,7 +80,7 @@ class MainApp extends StatelessWidget {
|
|
|
|
|
|
|
|
return Consumer<AppState>(
|
|
return Consumer<AppState>(
|
|
|
builder: (context, appState, _) {
|
|
builder: (context, appState, _) {
|
|
|
- _updateScreenCapture(appState.screenCapturePrevented);
|
|
|
|
|
|
|
+ widget._updateScreenCapture(appState.screenCapturePrevented);
|
|
|
return MaterialApp(
|
|
return MaterialApp(
|
|
|
onGenerateTitle: (context) => AppLocalizations.of(context)!.appName,
|
|
onGenerateTitle: (context) => AppLocalizations.of(context)!.appName,
|
|
|
theme: ThemeData.light(),
|
|
theme: ThemeData.light(),
|
|
@@ -58,19 +88,75 @@ class MainApp extends StatelessWidget {
|
|
|
themeMode: appState.themeMode,
|
|
themeMode: appState.themeMode,
|
|
|
initialRoute: AppRoutes.home,
|
|
initialRoute: AppRoutes.home,
|
|
|
routes: {
|
|
routes: {
|
|
|
- AppRoutes.home: (context) => const AndroidHomePage(),
|
|
|
|
|
- AppRoutes.edit: (context) => const AndroidEditPage(),
|
|
|
|
|
- AppRoutes.add: (context) => const AddPage(),
|
|
|
|
|
- AppRoutes.addScan: (context) => const ScanQRPage(),
|
|
|
|
|
- AppRoutes.settings: (context) => const SettingsPage(),
|
|
|
|
|
- AppRoutes.howItWorks: (context) => const HowItWorksPage(),
|
|
|
|
|
- AppRoutes.transferCodes: (context) => const TransferCodesPage(),
|
|
|
|
|
- AppRoutes.help: (context) => const HelpPage(),
|
|
|
|
|
|
|
+ AppRoutes.home: (context) => _AuthGate(child: const AndroidHomePage()),
|
|
|
|
|
+ AppRoutes.edit: (context) => _AuthGate(child: const AndroidEditPage()),
|
|
|
|
|
+ AppRoutes.add: (context) => _AuthGate(child: const AddPage()),
|
|
|
|
|
+ AppRoutes.addScan: (context) => _AuthGate(child: const ScanQRPage()),
|
|
|
|
|
+ AppRoutes.settings: (context) => _AuthGate(child: const SettingsPage()),
|
|
|
|
|
+ AppRoutes.howItWorks: (context) => _AuthGate(child: const HowItWorksPage()),
|
|
|
|
|
+ AppRoutes.transferCodes: (context) => _AuthGate(child: const TransferCodesPage()),
|
|
|
|
|
+ AppRoutes.help: (context) => _AuthGate(child: const HelpPage()),
|
|
|
|
|
+ },
|
|
|
|
|
+ localizationsDelegates: widget.localizationsDelegates,
|
|
|
|
|
+ supportedLocales: widget.supportedLocales,
|
|
|
|
|
+ builder: (context, child) {
|
|
|
|
|
+ if (_locked) return const SizedBox.shrink();
|
|
|
|
|
+ return child!;
|
|
|
},
|
|
},
|
|
|
- localizationsDelegates: localizationsDelegates,
|
|
|
|
|
- supportedLocales: supportedLocales,
|
|
|
|
|
);
|
|
);
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+class _AuthGate extends StatefulWidget {
|
|
|
|
|
+ final Widget child;
|
|
|
|
|
+ const _AuthGate({required this.child});
|
|
|
|
|
+ @override
|
|
|
|
|
+ State<_AuthGate> createState() => _AuthGateState();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+class _AuthGateState extends State<_AuthGate> with WidgetsBindingObserver {
|
|
|
|
|
+ bool _locked = false;
|
|
|
|
|
+
|
|
|
|
|
+ @override
|
|
|
|
|
+ void initState() {
|
|
|
|
|
+ super.initState();
|
|
|
|
|
+ WidgetsBinding.instance.addObserver(this);
|
|
|
|
|
+ _checkAuth();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @override
|
|
|
|
|
+ void dispose() {
|
|
|
|
|
+ WidgetsBinding.instance.removeObserver(this);
|
|
|
|
|
+ super.dispose();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @override
|
|
|
|
|
+ void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
|
|
|
+ if (state == AppLifecycleState.resumed) {
|
|
|
|
|
+ _checkAuth();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Future<void> _checkAuth() async {
|
|
|
|
|
+ final appState = Provider.of<AppState>(context, listen: false);
|
|
|
|
|
+ if (appState.shouldRequireAuth()) {
|
|
|
|
|
+ setState(() { _locked = true; });
|
|
|
|
|
+ final unlocked = await Navigator.of(context).push(
|
|
|
|
|
+ MaterialPageRoute(builder: (_) => const LockScreenPage(), fullscreenDialog: true),
|
|
|
|
|
+ );
|
|
|
|
|
+ if (unlocked == true) {
|
|
|
|
|
+ setState(() { _locked = false; });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @override
|
|
|
|
|
+ Widget build(BuildContext context) {
|
|
|
|
|
+ if (_locked) {
|
|
|
|
|
+ return const SizedBox.shrink();
|
|
|
|
|
+ }
|
|
|
|
|
+ return widget.child;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|