203 lines
7.3 KiB
Dart
203 lines
7.3 KiB
Dart
import 'package:aman_kassa_flutter/core/locator.dart';
|
|
import 'package:aman_kassa_flutter/core/logger.dart';
|
|
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
|
import 'package:aman_kassa_flutter/core/models/response.dart';
|
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
|
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
|
|
import 'package:aman_kassa_flutter/views/lockscreen/passcodescreen.dart';
|
|
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_redux/flutter_redux.dart';
|
|
import 'package:logger/logger.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import './tabs/KassaTab.dart';
|
|
import './tabs/AdditionalTab.dart';
|
|
import './tabs/CalculatorTab.dart';
|
|
|
|
import './components/popup_menu.dart';
|
|
import './components/bottom_bar.dart';
|
|
|
|
class HomeView extends StatefulWidget {
|
|
@override
|
|
_HomeViewState createState() => _HomeViewState();
|
|
}
|
|
|
|
class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
|
Logger log = getLogger('HomeView');
|
|
late PageController pageController;
|
|
late int selectedTabIndex;
|
|
DataService _dataService = locator<DataService>();
|
|
ApiService _api = locator<ApiService>();
|
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
|
|
|
final lastKnownStateKey = 'lastKnownStateKey';
|
|
final backgroundedTimeKey = 'backgroundedTimeKey';
|
|
final pinLockMillis = 2000; // 2 seconds
|
|
|
|
Future _paused() async {
|
|
final sp = await SharedPreferences.getInstance();
|
|
sp.setInt(lastKnownStateKey, AppLifecycleState.paused.index);
|
|
}
|
|
|
|
Future _inactive() async {
|
|
final sp = await SharedPreferences.getInstance();
|
|
final prevState = sp.getInt(lastKnownStateKey);
|
|
final prevStateIsNotPaused = prevState != null &&
|
|
AppLifecycleState.values[prevState] != AppLifecycleState.paused;
|
|
final bool pinIsExist = Redux.store!.state.settingState?.pinCode != null && Redux.store!.state.settingState!.pinCode!.length > 3;
|
|
final bool pinSkipped = Redux.store!.state.settingState?.pinSkip == true;
|
|
print('prevStateIsNotPaused=$prevStateIsNotPaused, pinIsExist=$pinIsExist, pinSkipped=$pinSkipped');
|
|
if(prevStateIsNotPaused && pinSkipped == false && pinIsExist == true) {
|
|
// save App backgrounded time to Shared preferences
|
|
sp.setInt(backgroundedTimeKey, DateTime.now().millisecondsSinceEpoch);
|
|
}
|
|
// update previous state as inactive
|
|
sp.setInt(lastKnownStateKey, AppLifecycleState.inactive.index);
|
|
}
|
|
|
|
Future _resumed() async {
|
|
final sp = await SharedPreferences.getInstance();
|
|
final bgTime = sp.getInt(backgroundedTimeKey) ?? 0;
|
|
final allowedBackgroundTime = bgTime + pinLockMillis;
|
|
final shouldShowPIN = DateTime.now().millisecondsSinceEpoch > allowedBackgroundTime;
|
|
if(shouldShowPIN && bgTime > 0) {
|
|
await Redux.store!.dispatch(changePinLockedFromSetting(true));
|
|
pushToLockScreen();
|
|
}
|
|
sp.remove(backgroundedTimeKey); // clean
|
|
sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
|
|
}
|
|
|
|
void pushToLockScreen() {
|
|
Navigator.of(context).push(MaterialPageRoute(
|
|
builder: (_) =>
|
|
WillPopScope(
|
|
onWillPop: () async {
|
|
return false;
|
|
},
|
|
child: PassCodeScreen( title: 'Безопасность',)
|
|
)
|
|
));
|
|
}
|
|
|
|
_checkLockPin () async {
|
|
final bool pinIsExist = Redux.store!.state.settingState?.pinCode != null && Redux.store!.state.settingState!.pinCode!.length > 3;
|
|
final bool pinLocked = Redux.store!.state.settingState?.pinLocked == true;
|
|
final sp = await SharedPreferences.getInstance();
|
|
sp.remove(backgroundedTimeKey);
|
|
sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
|
|
if ( pinIsExist == true && pinLocked == true ) {
|
|
await Future.delayed(Duration(milliseconds: 50));
|
|
pushToLockScreen();
|
|
}
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addObserver(this);
|
|
selectedTabIndex = 0;
|
|
pageController = new PageController(initialPage: selectedTabIndex);
|
|
Redux.store!.dispatch(checkSmena);
|
|
_dataService.checkDbFill(Redux.store!.state.userState!.user!);
|
|
_checkLockPin();
|
|
}
|
|
|
|
@override
|
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
super.didChangeAppLifecycleState(state);
|
|
print('state = $state');
|
|
switch(state) {
|
|
case AppLifecycleState.resumed:
|
|
_resumed();
|
|
break;
|
|
case AppLifecycleState.paused:
|
|
_paused();
|
|
break;
|
|
case AppLifecycleState.inactive:
|
|
_inactive();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
WidgetsBinding.instance.removeObserver(this);
|
|
pageController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _onSelectChoice(Choice choice) async {
|
|
if (choice.command == 'exit') {
|
|
Dialogs.showLoadingDialog(context, _keyLoader);
|
|
Response<dynamic> result = await _api.logout(Redux.store!.state.userState!.user!.token!);
|
|
if(result.operation && result.status == 200) {
|
|
Redux.store!.dispatch(logoutAction);
|
|
}
|
|
Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
|
|
} else if (choice.command == 'infokkm') {
|
|
_navigatorService.push(InfoKkmViewRoute);
|
|
} else if (choice.command == 'settings') {
|
|
_navigatorService.push(SettingsViewRoute);
|
|
} else if (choice.command == 'print') {
|
|
_navigatorService.push(SettingsPrinterRoute);
|
|
} else if (choice.command == 'bank') {
|
|
_navigatorService.push(BankViewRoute);
|
|
} else if (choice.command == 'tap2phone') {
|
|
_navigatorService.push(BankSettingViewRoute);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
titleSpacing: 5.0,
|
|
brightness: Brightness.light,
|
|
title: HeaderTitle(),
|
|
actions: <Widget>[
|
|
PopupMenu(
|
|
onSelectChoice: _onSelectChoice,
|
|
)
|
|
],
|
|
backgroundColor: fillColor,
|
|
),
|
|
body:StoreConnector<AppState, SettingState>(
|
|
converter: (store) => store.state.settingState!,
|
|
builder: (context, vm) {
|
|
return PageView(
|
|
pageSnapping: true,
|
|
onPageChanged: (index) {
|
|
setState(() {
|
|
selectedTabIndex = index;
|
|
});
|
|
},
|
|
controller: pageController,
|
|
children: <Widget>[
|
|
vm.mode == SettingModeKassa ? KassaTab(0) : CalculatorTab(0),
|
|
AdditionalTab(1),
|
|
],
|
|
);
|
|
}
|
|
),
|
|
bottomNavigationBar: BottomBar(
|
|
pageController: pageController,
|
|
selectedTabIndex: selectedTabIndex,
|
|
),
|
|
);
|
|
}
|
|
}
|