diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8d0d5b4..7097adf 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -30,6 +30,8 @@ PODS: - SwiftProtobuf (1.9.0) - url_launcher (0.0.1): - Flutter + - url_launcher_linux (0.0.1): + - Flutter - url_launcher_macos (0.0.1): - Flutter - url_launcher_web (0.0.1): @@ -48,6 +50,7 @@ DEPENDENCIES: - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) + - url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`) - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`) - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`) @@ -82,6 +85,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqflite/ios" url_launcher: :path: ".symlinks/plugins/url_launcher/ios" + url_launcher_linux: + :path: ".symlinks/plugins/url_launcher_linux/ios" url_launcher_macos: :path: ".symlinks/plugins/url_launcher_macos/ios" url_launcher_web: @@ -103,6 +108,7 @@ SPEC CHECKSUMS: sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef + url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0 url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index fbf1f74..27c4d75 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -392,7 +392,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 94BM6VL7L8; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -531,7 +531,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 94BM6VL7L8; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -563,7 +563,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 94BM6VL7L8; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/lib/core/models/dialog_models.dart b/lib/core/models/dialog_models.dart index 52a195f..bc7a325 100644 --- a/lib/core/models/dialog_models.dart +++ b/lib/core/models/dialog_models.dart @@ -5,12 +5,14 @@ class DialogRequest { final String description; final String buttonTitle; final String cancelTitle; + final String formatType; DialogRequest( {@required this.title, @required this.description, @required this.buttonTitle, - this.cancelTitle}); + this.cancelTitle, + this.formatType}); } class DialogResponse { diff --git a/lib/core/services/ApiService.dart b/lib/core/services/ApiService.dart index d3fd170..2d67aa9 100644 --- a/lib/core/services/ApiService.dart +++ b/lib/core/services/ApiService.dart @@ -132,10 +132,12 @@ class ApiService extends BaseService { HttpHeaders.contentTypeHeader: "multipart/form-data", HttpHeaders.cacheControlHeader: "no-cache" }; + if(Platform.isAndroid) { AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; headers.addAll({ HttpHeaders.userAgentHeader: androidInfo.model, + "mob_agent" : "e40c519e7a24d0c93530fd362023afa0", }); } @@ -143,8 +145,10 @@ class ApiService extends BaseService { IosDeviceInfo iosInfo = await deviceInfo.iosInfo; headers.addAll({ HttpHeaders.userAgentHeader: iosInfo.utsname.machine, + "mob_agent" : "fbd69e994b6251837ba82a08c6f68307", }); } + String url = '$endpoint$point'; if(this._test) { url = '$test_endpoint$point'; @@ -161,7 +165,7 @@ class ApiService extends BaseService { Response check = Response.fromJsonDynamic(json.decode(body)); if (!check.operation && ( [401,402,403,412].contains(check.status) ) ) { - var future = new Future.delayed(const Duration(milliseconds: 1000), (){ + new Future.delayed(const Duration(milliseconds: 1000), (){ _dialogService.showDialog(description: 'Необходимо пройти повторную авторизацию'); UserState state = Redux.store.state.userState; _navigatorService.replace(LoginViewRoute, arguments: LoginModel(authType: state.authenticateType, login: state.login, password: state.password )); diff --git a/lib/core/services/dialog_service.dart b/lib/core/services/dialog_service.dart index bdb495b..aaedcf4 100644 --- a/lib/core/services/dialog_service.dart +++ b/lib/core/services/dialog_service.dart @@ -14,7 +14,8 @@ class DialogService { GlobalKey get dialogNavigationKey => _dialogNavigationKey; /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener, Function(DialogRequest) showDialogInputListener) { + void registerDialogListener(Function(DialogRequest) showDialogListener, + Function(DialogRequest) showDialogInputListener) { _showDialogListener = showDialogListener; _showDialogInputListener = showDialogInputListener; } @@ -50,16 +51,18 @@ class DialogService { } Future showConfirmationDialogInput( - {String title =' Aman Касса', - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { + {String title = ' Aman Касса', + String description, + String confirmationTitle = 'Ok', + String cancelTitle = 'Cancel', + String formatType}) { _dialogCompleter = Completer(); _showDialogInputListener(DialogRequest( title: title, description: description, buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); + cancelTitle: cancelTitle, + formatType: formatType)); return _dialogCompleter.future; } @@ -69,6 +72,4 @@ class DialogService { _dialogCompleter.complete(response); _dialogCompleter = null; } - - } diff --git a/lib/redux/actions/user_actions.dart b/lib/redux/actions/user_actions.dart index 3eae93b..048b49d 100644 --- a/lib/redux/actions/user_actions.dart +++ b/lib/redux/actions/user_actions.dart @@ -186,3 +186,7 @@ Future openSmena(Store store) async { store.dispatch(checkMoney); } } + +Future openSmenaPseudo(Store store) async { + store.dispatch(SetUserStateAction(UserState(smena: Smena(startedAt: DateTime.now() )))); +} diff --git a/lib/views/check/image_show_container.dart b/lib/views/check/image_show_container.dart index 59926a6..ddad8e3 100644 --- a/lib/views/check/image_show_container.dart +++ b/lib/views/check/image_show_container.dart @@ -128,6 +128,7 @@ class _MyFloatingActionButtonState extends State { description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', + formatType: 'phone' ); if (response.confirmed) { String phoneNumber = response.responseText; diff --git a/lib/views/home/components/header_title.dart b/lib/views/home/components/header_title.dart index 466b5eb..7e92489 100644 --- a/lib/views/home/components/header_title.dart +++ b/lib/views/home/components/header_title.dart @@ -11,36 +11,56 @@ class HeaderTitle extends StatelessWidget { @override Widget build(BuildContext context) { return StoreConnector( - converter: (store) => store.state.userState, - builder: (context, vm) { - return Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 75, - child: Image( - image: AssetImage('assets/images/logo.png'), - fit: BoxFit.fitWidth, + converter: (store) => store.state.userState, + builder: (context, vm) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 75, + child: Image( + image: AssetImage('assets/images/logo.png'), + fit: BoxFit.fitWidth, + ), + margin: const EdgeInsets.only(right: 15), ), - margin: const EdgeInsets.only(right: 15), - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Пользователь: ${vm.user.email}', overflow: TextOverflow.fade, maxLines: 1, softWrap: false, style: TextStyle(fontSize: 13, color: Colors.black, ),), - vm.smena.message !=null - ? Text(vm.smena.message, style: TextStyle(fontSize: 13, color: redColor) ) - : vm.smena.startedAt !=null - ? Text('Смена от: ${dateFormat.format(vm.smena.startedAt)}', overflow: TextOverflow.fade, maxLines: 1, softWrap: false , style: TextStyle(fontSize: 13, color: Colors.black),) - : Text('Смена от:', style: TextStyle(fontSize: 13, color: Colors.black),), - ], - ), - ) - ], - ); - } - ); + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Пользователь: ${vm.user.email}', + overflow: TextOverflow.fade, + maxLines: 1, + softWrap: false, + style: TextStyle( + fontSize: 13, + color: Colors.black, + ), + ), + vm.smena.message != null + ? Text(vm.smena.message, + style: TextStyle(fontSize: 13, color: redColor)) + : vm.smena.startedAt != null + ? Text( + 'Смена открыта', + overflow: TextOverflow.fade, + maxLines: 1, + softWrap: false, + style: TextStyle( + fontSize: 13, color: Colors.black), + ) + : Text( + '', + style: TextStyle( + fontSize: 13, color: Colors.black), + ), + ], + ), + ) + ], + ); + }); } } diff --git a/lib/views/login/login_view.dart b/lib/views/login/login_view.dart index e86303b..e6b122d 100644 --- a/lib/views/login/login_view.dart +++ b/lib/views/login/login_view.dart @@ -104,19 +104,21 @@ class _LoginViewState extends State { ), verticalSpaceSmall, InputField( - placeholder: 'Пароль', - password: true, - controller: passwordController, - fieldFocusNode: passwordNode, - additionalNote: vm.loginFormMessage.password, - enterPressed: _pressBtnEnter), + placeholder: 'Пароль', + password: true, + controller: passwordController, + fieldFocusNode: passwordNode, + additionalNote: vm.loginFormMessage.password, + enterPressed: _pressBtnEnter, + textInputAction: TextInputAction.done, + ), verticalSpaceMedium, Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, children: [ SizedBox( - width: 100, + width: 150, child: BusyButton( title: 'Войти', busy: vm.isLoading, diff --git a/lib/views/payment/payment_view.dart b/lib/views/payment/payment_view.dart index c0d7e7a..4355b6c 100644 --- a/lib/views/payment/payment_view.dart +++ b/lib/views/payment/payment_view.dart @@ -203,6 +203,7 @@ class _PaymentViewState extends State { Redux.store.dispatch(cleanKassaItems); } Redux.store.dispatch(checkMoney); + Redux.store.dispatch(openSmenaPseudo); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); _navigatorService.pop(); _navigatorService.push(ImageShowRoute, diff --git a/lib/widgets/dialog_manager.dart b/lib/widgets/dialog_manager.dart index 115d682..8380062 100644 --- a/lib/widgets/dialog_manager.dart +++ b/lib/widgets/dialog_manager.dart @@ -4,6 +4,7 @@ import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; class DialogManager extends StatefulWidget { final Widget child; @@ -15,18 +16,18 @@ class DialogManager extends StatefulWidget { class _DialogManagerState extends State { final DialogService _dialogService = locator(); - TextEditingController controller; + TextEditingController _controller; @override void initState() { super.initState(); - controller = new TextEditingController(); + _controller = new TextEditingController(); _dialogService.registerDialogListener(_showDialog, _showDialogInput); } @override void dispose() { - controller.dispose(); + _controller.dispose(); super.dispose(); } @@ -77,7 +78,13 @@ class _DialogManagerState extends State { void _showDialogInput(DialogRequest request) { var isConfirmationDialog = request.cancelTitle != null; - controller.clear(); + + _controller.clear(); + + var maskFormatter = new MaskTextInputFormatter( + mask: '+% (###) ###-##-##', + filter: {"#": RegExp(r'[0-9]'), "%": RegExp(r'[7]')}); + var dialogController = showDialog( context: context, builder: (context) => AlertDialog( @@ -101,15 +108,21 @@ class _DialogManagerState extends State { //Text(request.description), TextField( autofocus: true, - decoration: InputDecoration(labelText: request.description), - controller: controller, + decoration: InputDecoration( + labelText: request.description, + hintText: request.formatType == "phone" + ? "+7 (123) 456-78-90" + : ""), + controller: _controller, onSubmitted: (value) { _dialogService .dialogComplete(DialogResponse(confirmed: false)); }, keyboardType: TextInputType.phone, inputFormatters: [ - WhitelistingTextInputFormatter(RegExp("^[0-9.]*")), + if (request.formatType == "phone") maskFormatter, + if (request.formatType == null) + WhitelistingTextInputFormatter(RegExp("^[0-9.]*")), ], ) ], @@ -137,8 +150,12 @@ class _DialogManagerState extends State { style: TextStyle(fontSize: 18), ), onPressed: () { - _dialogService.dialogComplete(DialogResponse( - confirmed: true, responseText: controller.text)); + String _result = _controller.text; + if (request.formatType == "phone") { + _result = maskFormatter.getUnmaskedText(); + } + _dialogService.dialogComplete( + DialogResponse(confirmed: true, responseText: _result)); }, ), ], diff --git a/lib/widgets/fields/busy_button.dart b/lib/widgets/fields/busy_button.dart index 2a4d3c2..f12b958 100644 --- a/lib/widgets/fields/busy_button.dart +++ b/lib/widgets/fields/busy_button.dart @@ -41,40 +41,46 @@ class _BusyButtonState extends State { child: InkWell( onTap: widget.busy || !widget.enabled ? null : widget.onPressed, child: AnimatedContainer( - height: widget.busy ? 40 : 40, + height: widget.busy ? 45 : 45, //width: widget.busy ? 40 : 40, duration: const Duration(milliseconds: 300), alignment: Alignment.center, margin: EdgeInsets.symmetric( horizontal: widget.busy ? 10 : 25, - vertical: widget.busy ? 10 : 15), + vertical: widget.busy ? 10 : 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ !widget.busy - ? Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - widget.icon != null - ? Container( - child: (Icon( - widget.icon, - color: whiteColor, - )), - margin: const EdgeInsets.only(right: 10.0), - ) - : (Container()), - AutoSizeText( - widget.title, - textAlign: TextAlign.center, - style: buttonTitleTextStyle, - ), - ], + ? Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + widget.icon != null + ? Container( + child: (Icon( + widget.icon, + color: whiteColor, + )), + margin: const EdgeInsets.only(right: 10.0), + ) + : (Container()), + AutoSizeText( + widget.title, + textAlign: TextAlign.center, + style: buttonTitleTextStyle, + ), + ], + ), ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: - AlwaysStoppedAnimation(Colors.white)), + : SizedBox( + width: 30, + height: 30, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: + AlwaysStoppedAnimation(Colors.white)), + ), ], ), ), diff --git a/pubspec.lock b/pubspec.lock index a2cf305..b724983 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -91,7 +91,7 @@ packages: name: equatable url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.2" esys_flutter_share: dependency: "direct main" description: @@ -309,7 +309,7 @@ packages: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.3.0" + version: "4.3.1" pub_semver: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5db20e1..a374d44 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: aman_kassa_flutter description: A new Flutter project. -version: 1.0.1+22 +version: 1.0.1+21 environment: sdk: '>=2.3.0 <3.0.0' dependencies: