199 lines
7.0 KiB
Dart
199 lines
7.0 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');
|
||
PageController pageController;
|
||
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?.isNotEmpty;
|
||
final bool pinSkipped = Redux.store.state.settingState.pinSkip;
|
||
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: '<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',)
|
||
)
|
||
));
|
||
}
|
||
|
||
_checkLockPin () async {
|
||
final bool pinIsExist = Redux.store.state.settingState?.pinCode?.isNotEmpty;
|
||
final bool pinLocked = Redux.store.state.settingState?.pinLocked;
|
||
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);
|
||
}
|
||
}
|
||
|
||
@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,
|
||
),
|
||
);
|
||
}
|
||
}
|