pin release
parent
923e32274a
commit
839432d011
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
|
|
@ -4,5 +4,6 @@ const String ImageShowRoute = "ImageShowRoute";
|
||||||
const String PaymentViewRoute = "PaymentView";
|
const String PaymentViewRoute = "PaymentView";
|
||||||
const String HistoryViewRoute = "HistoryView";
|
const String HistoryViewRoute = "HistoryView";
|
||||||
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
||||||
|
const String SettingsViewRoute = "SettingsViewRoute";
|
||||||
const String QrViewRoute = "QrViewRoute";
|
const String QrViewRoute = "QrViewRoute";
|
||||||
// Generate the views here
|
// Generate the views here
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:aman_kassa_flutter/views/history/history_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_view.dart';
|
import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/qr_view/qr_view.dart';
|
import 'package:aman_kassa_flutter/views/qr_view/qr_view.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/settings/settings_view.dart';
|
||||||
|
|
||||||
import './route_names.dart';
|
import './route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
||||||
|
|
@ -38,6 +39,11 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: InfoKkmView(),
|
viewToShow: InfoKkmView(),
|
||||||
);
|
);
|
||||||
|
case SettingsViewRoute:
|
||||||
|
return _getPageRoute(
|
||||||
|
routeName: settings.name,
|
||||||
|
viewToShow: SettingView(),
|
||||||
|
);
|
||||||
case QrViewRoute:
|
case QrViewRoute:
|
||||||
ImageShowModel data = settings.arguments as ImageShowModel;
|
ImageShowModel data = settings.arguments as ImageShowModel;
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,22 @@ ThunkAction<AppState> changeTradeTypeFromSetting(String tradeType) {
|
||||||
return (Store<AppState> store) async {
|
return (Store<AppState> store) async {
|
||||||
store.dispatch(SetSettingStateAction(SettingState(tradeType: tradeType )));
|
store.dispatch(SetSettingStateAction(SettingState(tradeType: tradeType )));
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> changePinCodeFromSetting(String pinCode) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetSettingStateAction(SettingState(pinCode: pinCode)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> changePinLockedFromSetting(bool locked) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetSettingStateAction(SettingState(pinLocked: locked)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> changePinSkipFromSetting(bool skip) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetSettingStateAction(SettingState(pinSkip: skip)));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ Future<void> logoutAction(Store<AppState> store) async {
|
||||||
UserState(
|
UserState(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
user: User(),
|
user: User()
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ settingReducer(SettingState prevState, SetSettingStateAction action) {
|
||||||
final payload = action.settingState;
|
final payload = action.settingState;
|
||||||
return prevState.copyWith(
|
return prevState.copyWith(
|
||||||
mode: payload.mode,
|
mode: payload.mode,
|
||||||
tradeType: payload.tradeType
|
tradeType: payload.tradeType,
|
||||||
|
pinCode: payload.pinCode,
|
||||||
|
pinLocked: payload.pinLocked,
|
||||||
|
pinSkip: payload.pinSkip,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,38 @@ import 'package:meta/meta.dart';
|
||||||
class SettingState {
|
class SettingState {
|
||||||
final String mode;
|
final String mode;
|
||||||
final String tradeType;
|
final String tradeType;
|
||||||
|
final String pinCode;
|
||||||
|
final bool pinLocked;
|
||||||
|
final bool pinSkip;
|
||||||
|
|
||||||
SettingState({this.mode, this.tradeType});
|
|
||||||
|
SettingState({this.mode, this.tradeType, this.pinCode, this.pinLocked, this.pinSkip});
|
||||||
|
|
||||||
//read hive
|
//read hive
|
||||||
factory SettingState.initial(SettingState payload) {
|
factory SettingState.initial(SettingState payload) {
|
||||||
return SettingState(
|
return SettingState(
|
||||||
mode: payload?.mode ?? SettingModeKassa,
|
mode: payload?.mode ?? SettingModeKassa,
|
||||||
tradeType: payload?.tradeType ?? SettingTradeTypeGood);
|
tradeType: payload?.tradeType ?? SettingTradeTypeGood,
|
||||||
|
pinCode: payload.pinCode ?? null,
|
||||||
|
pinLocked: payload.pinLocked ?? false,
|
||||||
|
pinSkip: false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//write hive
|
//write hive
|
||||||
SettingState copyWith({
|
SettingState copyWith({
|
||||||
@required mode,
|
@required mode,
|
||||||
@required tradeType,
|
@required tradeType,
|
||||||
|
@required pinCode,
|
||||||
|
@required pinLocked,
|
||||||
|
@required pinSkip,
|
||||||
}) {
|
}) {
|
||||||
return SettingState(
|
return SettingState(
|
||||||
mode: mode ?? this.mode,
|
mode: mode ?? this.mode,
|
||||||
tradeType: tradeType ?? this.tradeType,
|
tradeType: tradeType ?? this.tradeType,
|
||||||
|
pinCode: pinCode ?? this.pinCode,
|
||||||
|
pinLocked: pinLocked ?? this.pinLocked,
|
||||||
|
pinSkip: pinSkip ?? this.pinSkip
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,11 +45,20 @@ class SettingState {
|
||||||
? SettingState(
|
? SettingState(
|
||||||
tradeType: json['tradeType'],
|
tradeType: json['tradeType'],
|
||||||
mode: json['mode'],
|
mode: json['mode'],
|
||||||
|
pinCode: json['pinCode'],
|
||||||
|
pinLocked: json['pinLocked'],
|
||||||
|
pinSkip: json['pinSkip'],
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic toJson() {
|
dynamic toJson() {
|
||||||
return {"tradeType": tradeType, "mode": mode};
|
return {
|
||||||
|
"tradeType": tradeType,
|
||||||
|
"mode": mode,
|
||||||
|
"pinCode": pinCode,
|
||||||
|
"pinLocked" : pinLocked,
|
||||||
|
"pinSkip" : pinSkip,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class UserState {
|
||||||
final Smena smena;
|
final Smena smena;
|
||||||
final Money money;
|
final Money money;
|
||||||
|
|
||||||
|
|
||||||
UserState(
|
UserState(
|
||||||
{this.isError,
|
{this.isError,
|
||||||
this.isLoading,
|
this.isLoading,
|
||||||
|
|
@ -26,7 +27,8 @@ class UserState {
|
||||||
this.user,
|
this.user,
|
||||||
this.loginFormMessage,
|
this.loginFormMessage,
|
||||||
this.smena,
|
this.smena,
|
||||||
this.money});
|
this.money,
|
||||||
|
});
|
||||||
|
|
||||||
factory UserState.initial(UserState payload) => UserState(
|
factory UserState.initial(UserState payload) => UserState(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|
@ -73,7 +75,8 @@ class UserState {
|
||||||
user: User.fromJson(json['user']),
|
user: User.fromJson(json['user']),
|
||||||
authenticateType: json['authenticateType'],
|
authenticateType: json['authenticateType'],
|
||||||
login: json['login'],
|
login: json['login'],
|
||||||
password: json['password'])
|
password: json['password'],
|
||||||
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const List<Choice> choices = const <Choice>[
|
||||||
//const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
//const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
||||||
const Choice(
|
const Choice(
|
||||||
title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
|
title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
|
||||||
//const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
|
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
|
||||||
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,21 @@ 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/ApiService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/DataService.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/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/actions/user_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.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/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.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/home/components/header_title.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/lockscreen/passcodescreen.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/start_up/start_up_view.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import './tabs/KassaTab.dart';
|
import './tabs/KassaTab.dart';
|
||||||
import './tabs/AdditionalTab.dart';
|
import './tabs/AdditionalTab.dart';
|
||||||
|
|
@ -30,7 +34,7 @@ class HomeView extends StatefulWidget {
|
||||||
_HomeViewState createState() => _HomeViewState();
|
_HomeViewState createState() => _HomeViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomeViewState extends State<HomeView> {
|
class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
||||||
Logger log = getLogger('HomeView');
|
Logger log = getLogger('HomeView');
|
||||||
PageController pageController;
|
PageController pageController;
|
||||||
int selectedTabIndex;
|
int selectedTabIndex;
|
||||||
|
|
@ -39,6 +43,68 @@ class _HomeViewState extends State<HomeView> {
|
||||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
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;
|
||||||
|
if(prevStateIsNotPaused && Redux.store.state.settingState.pinSkip == false) {
|
||||||
|
// 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;
|
||||||
|
print(shouldShowPIN);
|
||||||
|
if(shouldShowPIN && bgTime > 0) {
|
||||||
|
Redux.store.dispatch(changePinLockedFromSetting(true));
|
||||||
|
// show PIN screen
|
||||||
|
// Navigator.pushReplacement(context, MaterialPageRoute(
|
||||||
|
// builder: (_) => PassCodeScreen( title: 'Безопасность',)));
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (_) =>
|
||||||
|
WillPopScope(
|
||||||
|
onWillPop: () async {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: PassCodeScreen( title: 'Безопасность',)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
sp.remove(backgroundedTimeKey); // clean
|
||||||
|
sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkLockPin () async {
|
||||||
|
if ( Redux.store.state.settingState.pinLocked == true) {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (_) =>
|
||||||
|
WillPopScope(
|
||||||
|
onWillPop: () async {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: PassCodeScreen( title: 'Безопасность',)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
@ -46,10 +112,32 @@ class _HomeViewState extends State<HomeView> {
|
||||||
pageController = new PageController(initialPage: selectedTabIndex);
|
pageController = new PageController(initialPage: selectedTabIndex);
|
||||||
Redux.store.dispatch(checkSmena);
|
Redux.store.dispatch(checkSmena);
|
||||||
_dataService.checkDbFill(Redux.store.state.userState.user);
|
_dataService.checkDbFill(Redux.store.state.userState.user);
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
_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
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
pageController.dispose();
|
pageController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -64,6 +152,8 @@ class _HomeViewState extends State<HomeView> {
|
||||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
} else if (choice.command == 'infokkm') {
|
} else if (choice.command == 'infokkm') {
|
||||||
_navigatorService.push(InfoKkmViewRoute);
|
_navigatorService.push(InfoKkmViewRoute);
|
||||||
|
} else if (choice.command == 'settings') {
|
||||||
|
_navigatorService.push(SettingsViewRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
|
@ -183,6 +184,7 @@ class KassaTab extends StatelessWidget {
|
||||||
|
|
||||||
Future<void> scan() async {
|
Future<void> scan() async {
|
||||||
try {
|
try {
|
||||||
|
Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
var options = ScanOptions(strings: {
|
var options = ScanOptions(strings: {
|
||||||
"cancel": 'Отмена',
|
"cancel": 'Отмена',
|
||||||
"flash_on": 'Вкл фонарик',
|
"flash_on": 'Вкл фонарик',
|
||||||
|
|
@ -238,6 +240,8 @@ class KassaTab extends StatelessWidget {
|
||||||
result.rawContent = 'Unknown error: $e';
|
result.rawContent = 'Unknown error: $e';
|
||||||
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_lock_screen/flutter_lock_screen.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
|
||||||
|
class PassCodeScreen extends StatefulWidget {
|
||||||
|
PassCodeScreen({Key key, this.title}) : super(key: key);
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PassCodeScreenState createState() => new _PassCodeScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PassCodeScreenState extends State<PassCodeScreen> {
|
||||||
|
// bool isFingerprint = false;
|
||||||
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
final backgroundedTimeKey = 'backgroundedTimeKey';
|
||||||
|
|
||||||
|
|
||||||
|
// Future<Null> biometrics() async {
|
||||||
|
// final LocalAuthentication auth = new LocalAuthentication();
|
||||||
|
// bool authenticated = false;
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// authenticated = await auth.authenticateWithBiometrics(
|
||||||
|
// localizedReason: 'Scan your fingerprint to authenticate',
|
||||||
|
// useErrorDialogs: true,
|
||||||
|
// stickyAuth: false);
|
||||||
|
// } on PlatformException catch (e) {
|
||||||
|
// print(e);
|
||||||
|
// }
|
||||||
|
// if (!mounted) return;
|
||||||
|
// if (authenticated) {
|
||||||
|
// setState(() {
|
||||||
|
// isFingerprint = true;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var myPass = [];
|
||||||
|
String _pinCode = Redux.store.state.settingState.pinCode;
|
||||||
|
for (var i = 0; i < _pinCode.length; i++) {
|
||||||
|
myPass.add(int.parse(_pinCode[i]));
|
||||||
|
}
|
||||||
|
return LockScreen(
|
||||||
|
title: "Введите ПИН-код",
|
||||||
|
passLength: myPass.length,
|
||||||
|
bgImage: "assets/images/secBg.jpg",
|
||||||
|
// fingerPrintImage: "assets/images/finger.png",
|
||||||
|
// showFingerPass: true,
|
||||||
|
// fingerFunction: biometrics,
|
||||||
|
// fingerVerify: isFingerprint,
|
||||||
|
borderColor: Colors.white,
|
||||||
|
showWrongPassDialog: true,
|
||||||
|
wrongPassContent: "Неверный код, повторите попытку",
|
||||||
|
wrongPassTitle: "Aman Kassa",
|
||||||
|
wrongPassCancelButtonText: "Отмена",
|
||||||
|
passCodeVerify: (passcode) async {
|
||||||
|
for (int i = 0; i < myPass.length; i++) {
|
||||||
|
if (passcode[i] != myPass[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onSuccess: () {
|
||||||
|
Redux.store.dispatch(changePinLockedFromSetting(false));
|
||||||
|
_navigatorService.replace(HomeViewRoute);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.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/shared/ui_helpers.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class SettingView extends StatefulWidget {
|
||||||
|
SettingView();
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SettingViewState createState() => _SettingViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SettingViewState extends State<SettingView> {
|
||||||
|
TextEditingController _pinController;
|
||||||
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
SettingState state = Redux.store.state.settingState;
|
||||||
|
_pinController = new TextEditingController(text: state.pinCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_pinController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setPinCode(BuildContext _context) async {
|
||||||
|
FocusScope.of(_context).unfocus();
|
||||||
|
var value = _pinController.text;
|
||||||
|
if(value.isEmpty || value.length !=4){
|
||||||
|
_dialogService.showDialog(description: 'Необходимо указать 4-х значный числовой код');
|
||||||
|
} else {
|
||||||
|
await Redux.store.dispatch(changePinCodeFromSetting(_pinController.text));
|
||||||
|
_dialogService.showDialog(description: 'Данные успешно сохранены');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: Text('Настройка HalykPos'),
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 14.0),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
verticalSpaceTiny,
|
||||||
|
Text(
|
||||||
|
'Ддя блокировки приложения пин-кодом, укажите 4-ех значный числовой код',
|
||||||
|
style: TextStyle(fontSize: 15.0),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
verticalSpaceTiny,
|
||||||
|
TextField(
|
||||||
|
controller: _pinController,
|
||||||
|
maxLength: 4,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Пин-код', hintText: "Укажите пин-код"),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
verticalSpaceMedium,
|
||||||
|
RaisedButton(
|
||||||
|
onPressed: () => this._setPinCode(context),
|
||||||
|
child: Text(
|
||||||
|
'Cохранить настройки',
|
||||||
|
style: TextStyle(color: whiteColor, fontSize: 20.0),
|
||||||
|
),
|
||||||
|
color: primaryColor,
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
pubspec.lock
23
pubspec.lock
|
|
@ -139,6 +139,20 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_lock_screen:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_lock_screen
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.8"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.11"
|
||||||
flutter_redux:
|
flutter_redux:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -198,6 +212,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.16.1"
|
version: "0.16.1"
|
||||||
|
local_auth:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: local_auth
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.3+4"
|
||||||
logger:
|
logger:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -374,7 +395,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.3.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ dependencies:
|
||||||
qr_flutter: ^3.2.0
|
qr_flutter: ^3.2.0
|
||||||
mask_text_input_formatter: ^1.2.1
|
mask_text_input_formatter: ^1.2.1
|
||||||
flutter_screenutil: ^2.3.1
|
flutter_screenutil: ^2.3.1
|
||||||
|
shared_preferences: ^0.5.12+4
|
||||||
|
flutter_lock_screen: ^1.0.8
|
||||||
|
local_auth: ^0.6.3+4
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
@ -40,8 +43,7 @@ flutter:
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- assets/images/logo.png
|
- assets/images/
|
||||||
- assets/images/icon_large.png
|
|
||||||
- assets/lang/en.json
|
- assets/lang/en.json
|
||||||
- assets/lang/ru.json
|
- assets/lang/ru.json
|
||||||
- assets/google_fonts/
|
- assets/google_fonts/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue