fix: crash on startup, which was not a crash, just a small error being thrown, also exchanged library for autologout

This commit is contained in:
henne 2024-01-31 20:16:36 +01:00
parent 90639d9918
commit 41bcd1ced6
8 changed files with 53 additions and 77 deletions

View File

@ -3,14 +3,12 @@
*/
import 'dart:async';
import 'dart:developer';
import 'package:catcher_2/catcher_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_session_timeout/local_session_timeout.dart';
import 'package:pref/pref.dart';
import 'package:provider/provider.dart';
import 'package:screen_state/screen_state.dart';
import 'package:snipe_scanner/utils/audio.dart';
import 'package:snipe_scanner/utils/zebra_scan.dart';
import 'package:snipe_scanner/widgets/audit.dart';
@ -69,76 +67,52 @@ class MyApp extends StatefulWidget {
}
class _MyAppState extends State<MyApp> {
// used toget the screen state
final Screen _screen = Screen();
// saves the next logout time
DateTime? logoutTime;
@override
void initState() {
// set everything up to see when the screen gets turned off, to logout the user after a specific timeframe set by the preferences
try {
_screen.screenStateStream!.listen((ScreenStateEvent e) {
//need to check if the widget is mounted, otherwise it will throw an error
if (mounted) return;
if (e == ScreenStateEvent.SCREEN_OFF &&
logoutTime == null &&
PrefService.of(context, listen: false).get('auto_logout')) {
// autologout is set via preferences and the screen got turned off, so mark the time when the app should be locked
Duration duration = Duration(
minutes: PrefService.of(context, listen: false)
.get('auto_logout_time'));
logoutTime = DateTime.now().add(duration);
} else if (e == ScreenStateEvent.SCREEN_UNLOCKED) {
// screen got unlocked, check if logoutTime is set, if so compare it to now and logout the user if logoutTime before now. after this set logoutTime to null to prevent further logouts
if (logoutTime != null && logoutTime!.isBefore(DateTime.now())) {
Provider.of<AppState>(context, listen: false).setToken("");
navigatorKey.currentState?.popUntil((route) => route.isFirst);
}
logoutTime = null;
}
});
} catch (err, stackTrace) {
// this catches the error and uses cather2 to ask the user if he wants to report it.
Catcher2.reportCheckedError(err, stackTrace);
}
super.initState();
}
// This widget is the root of the app.
@override
Widget build(BuildContext context) {
Duration? timeoutDuration;
if (service.get('auto_logout')) {
timeoutDuration = Duration(minutes: service.get('auto_logout_time'));
}
final sessionConfig =
SessionConfig(invalidateSessionForAppLostFocus: timeoutDuration);
sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
navigatorKey.currentState?.popUntil((route) => route.isFirst);
}
});
// set the orientation to always be portrait
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// initialize the material app
return MaterialApp(
title: 'SnipeIT Scanner',
debugShowCheckedModeBanner: false,
navigatorKey: navigatorKey,
theme: ThemeData(
primaryColor: const Color(0xFF2661FA),
scaffoldBackgroundColor: Colors.white,
visualDensity: VisualDensity.adaptivePlatformDensity,
bottomSheetTheme: const BottomSheetThemeData(
shape: BeveledRectangleBorder(
borderRadius: BorderRadiusDirectional.all(Radius.zero)))),
navigatorObservers: [routeObserver],
// this defines the first view.
home: const LoginWidget(),
// here are all the views within the app, so you can navigate through them using named routes
routes: <String, WidgetBuilder>{
'/dashboard': (BuildContext context) => const DashboardWidget(),
'/assetDetail': (BuildContext context) => const AssetDetail(),
'/checkoutAsset': (BuildContext context) => const CheckoutAsset(),
'/checkinAsset': (BuildContext context) => const CheckinAsset(),
'/bulkCheckin': (BuildContext context) => const BulkCheckin(),
'/bulkCheckout': (BuildContext context) => const BulkCheckout(),
'/searchAsset': (BuildContext context) => const SearchAsset(),
'/userDetail': (BuildContext context) => const UserDetail(),
'/auditAsset': (BuildContext context) => const Audit(),
'/preferences': (BuildContext context) => const PreferencesWidget(),
},
);
return SessionTimeoutManager(
sessionConfig: sessionConfig,
child: MaterialApp(
title: 'SnipeIT Scanner',
debugShowCheckedModeBanner: false,
navigatorKey: navigatorKey,
theme: ThemeData(
primaryColor: const Color(0xFF2661FA),
scaffoldBackgroundColor: Colors.white,
visualDensity: VisualDensity.adaptivePlatformDensity,
bottomSheetTheme: const BottomSheetThemeData(
shape: BeveledRectangleBorder(
borderRadius: BorderRadiusDirectional.all(Radius.zero)))),
navigatorObservers: [routeObserver],
// this defines the first view.
home: const LoginWidget(),
// here are all the views within the app, so you can navigate through them using named routes
routes: <String, WidgetBuilder>{
'/dashboard': (BuildContext context) => const DashboardWidget(),
'/assetDetail': (BuildContext context) => const AssetDetail(),
'/checkoutAsset': (BuildContext context) => const CheckoutAsset(),
'/checkinAsset': (BuildContext context) => const CheckinAsset(),
'/bulkCheckin': (BuildContext context) => const BulkCheckin(),
'/bulkCheckout': (BuildContext context) => const BulkCheckout(),
'/searchAsset': (BuildContext context) => const SearchAsset(),
'/userDetail': (BuildContext context) => const UserDetail(),
'/auditAsset': (BuildContext context) => const Audit(),
'/preferences': (BuildContext context) => const PreferencesWidget(),
},
));
}
}

View File

@ -1,4 +1,3 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:snipe_scanner/main.dart';

View File

@ -2,7 +2,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/services.dart';

View File

@ -1,4 +1,3 @@
import 'package:catcher_2/catcher_2.dart';
import 'package:flutter/material.dart';
import 'package:html_unescape/html_unescape.dart';
import 'package:provider/provider.dart';

View File

@ -1,4 +1,3 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@ -1,6 +1,4 @@
import 'dart:developer';
import 'package:catcher_2/catcher_2.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:provider/provider.dart';
@ -12,7 +10,6 @@ import 'package:snipe_scanner/service/login_user.dart';
import 'package:snipe_scanner/utils/api_key_encryption.dart';
import 'package:snipe_scanner/utils/audio.dart';
import 'package:snipe_scanner/utils/scan_aware_state.dart';
import 'package:snipe_scanner/widgets/preferences.dart';
class LoginWidget extends StatefulWidget {
const LoginWidget({super.key});

View File

@ -464,6 +464,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
local_session_timeout:
dependency: "direct main"
description:
name: local_session_timeout
sha256: "8655e3ec5e56eab6ee67bd6246414c993f928320bfde5e221739697981ce3641"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
logging:
dependency: transitive
description:

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.4.3+20
version: 1.4.4+21
environment:
sdk: ">=3.0.0"
@ -31,7 +31,7 @@ dependencies:
json_annotation: ^4.3.0
dropdown_search: ^5.0.6
provider:
pref: ^2.5.0
pref: ^2.8.0
screen_state: ^3.0.1
encrypt: ^5.0.1
flutter:
@ -47,6 +47,7 @@ dependencies:
sentry: ^7.14.0
assets_audio_player: ^3.1.1
beep_player: ^0.0.1
local_session_timeout: ^2.3.2
dev_dependencies: