diff --git a/android/app/build.gradle b/android/app/build.gradle index 04a9920..d9f013c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -38,6 +38,22 @@ android { } } + productFlavors { + + en { + buildConfigField "String", "locale", "\"en\"" + } + + ru { + buildConfigField "String", "locale", "\"ru\"" + } + + ua { + buildConfigField "String", "locale", "\"ua\"" + } + + } + sourceSets.main { jniLibs.srcDir 'jniLibs' } diff --git a/android/app/src/main/java/com/dinect/checker/MainActivity.java b/android/app/src/main/java/com/dinect/checker/MainActivity.java index 65a9037..69c1af0 100644 --- a/android/app/src/main/java/com/dinect/checker/MainActivity.java +++ b/android/app/src/main/java/com/dinect/checker/MainActivity.java @@ -6,9 +6,11 @@ import android.util.Log; import android.widget.Toast; import android.content.Context; import android.content.SharedPreferences; - +import android.content.res.Configuration; +import android.content.res.Resources; import com.dinect.checker.zbar.CameraActivity; import com.dinect.checker.zxing.ScannerActivity; +import java.util.Locale; import io.flutter.app.FlutterActivity; import io.flutter.plugins.GeneratedPluginRegistrant; @@ -47,7 +49,7 @@ public class MainActivity extends FlutterActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); - + loadLocale(this); mPreferences = getPreferences(Context.MODE_PRIVATE); Log.d(TAG, "application prefs:"); @@ -144,6 +146,29 @@ public class MainActivity extends FlutterActivity { } } + public static void loadLocale(Context context) { + Resources res = context.getResources(); + Configuration configuration = new Configuration(res.getConfiguration()); + switch (BuildConfig.locale) { + case "en": + configuration.locale = new Locale("en"); + Locale.setDefault(configuration.locale); + res.updateConfiguration(configuration, res.getDisplayMetrics()); + break; + case "ru": + configuration.locale = new Locale("ru"); + Locale.setDefault(configuration.locale); + res.updateConfiguration(configuration, res.getDisplayMetrics()); + break; + case "ua": + configuration.locale = new Locale("ua"); + Locale.setDefault(configuration.locale); + res.updateConfiguration(configuration, res.getDisplayMetrics()); + break; + } + + } + public void handleItemClick() { } diff --git a/lib/base_state.dart b/lib/base_state.dart index aba4d61..297931b 100644 --- a/lib/base_state.dart +++ b/lib/base_state.dart @@ -1,148 +1,154 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'common.dart'; import 'consts.dart'; +import 'strings.dart'; -abstract class BaseState extends State { +abstract class BaseState extends State { + /// Ожидание ответа от сервера. bool loading = false; + + /// Текст ошибки, подставляется в подсказку, либо появляется над текстовым полем. String error; + + /// Введенное пользователем значение. String textFieldValue = ''; - TextEditingController controller = new TextEditingController(); + Strings s; - @override Widget build(BuildContext context) { - return new Scaffold(appBar: getAppBar(context), body: getBody(context)); + @override Widget build(BuildContext ctx) { + return new Scaffold(appBar: getAppBar(ctx), + body: new Stack(children: [ + getScreenContent(ctx), + new Center(child: loading ? new CircularProgressIndicator() : null) + ])); } - AppBar getAppBar(BuildContext context) { - return new AppBar(title: new Text(getTitle(), style: new TextStyle(fontSize: 18.0)), - backgroundColor: primaryColor, actions: getMenuButtons(context)); + /// Возвращает контейнер с всеми виджетами экрана. + Widget getScreenContent(BuildContext ctx); + + /// Возвращает заголовок для AppBar + String getTitle(BuildContext ctx); + + AppBar getAppBar(BuildContext ctx) { + return new AppBar(title: new Text(getTitle(ctx), style: new TextStyle(fontSize: 18.0)), + backgroundColor: primaryColor, actions: getMenuButtons(ctx)); } - getMenuButtons(BuildContext context) { + List getMenuButtons(BuildContext context) { return [getFaqButton()]; } - getFaqButton() { + Widget getFaqButton() { return new IconButton(icon: new Icon(Icons.help_outline), onPressed: () => faq(context, false)); } - getLogoutButton() { + Widget getLogoutButton() { return new IconButton(icon: new Image.asset(logout_png, height: iconHeight, width: iconHeight), onPressed: () => logout(context)); } - Widget getBody(BuildContext context) { - return new Stack(children: [getScreenContent(), getProgressIndicator()]); - } - - Widget getScreenContent(); - - String getTitle(); - - String getHint(); - - /// Метод возвращает контейнер с отступами, который содержит картинку с логотипом. - getLogo() { - double containerHeight = 92.0; - double imageWidth = 156.0; - return new Container(height: containerHeight, child: new Image.asset(logo_png, width: imageWidth)); - } - - getHintLabel() { + /// Возврвщает контейнер, внутри которого Text с подсказкой. + Widget getHintLabel(BuildContext ctx) { double horizontalMargin = 8.0; return new Container(margin: new EdgeInsets.only(top: horizontalMargin, bottom: horizontalMargin, left: verticalMargin, right: verticalMargin), - child: new Row(crossAxisAlignment: CrossAxisAlignment.start, - children: [new Text(getHintText(), textAlign: TextAlign.left, - style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : primaryColor, fontSize: 14.0))])); + child: new Row(crossAxisAlignment: CrossAxisAlignment.start, + children: [new Text(getHintString(ctx), textAlign: TextAlign.left, + style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : primaryColor, fontSize: 14.0))])); } - getHintText() { + /// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны. + String getHintString(BuildContext ctx) { if (textFieldValue.length == 0 && error == null) { return ' '; } else if (error != null) { return error; } else { - return getHint(); + return getHint(ctx); } } + /// Возвращает текст подсказки для поля ввода. + /// Должен быть переопределен на экранах, на которых есть поле ввода. + String getHint(BuildContext ctx) { + return null; + } + /// Смена состояния экрана при изменении текста в поле ввода. - handleUserInput(String text) { + void handleUserInput(String text) { setState(() { textFieldValue = text; }); } - /// Метод возвращает контейнер с установленными отступами, в котором размещен TextField обернутый в BoxDecoration. - getDecoratedTextWidget() { + /// Метод возвращает контейнер с полем ввода внутри. + Widget getInputField(BuildContext ctx) { return new Container(margin: new EdgeInsets.only(left: verticalMargin, right: verticalMargin), - padding: getPaddingForTextWidget(), - decoration: getDecorationForTextWidget(), - child: getTextWidget()); + padding: getInputFieldContainerPadding(), + decoration: getInputFieldContainerDecoration(), + child: new TextField(keyboardType: TextInputType.number, + decoration: new InputDecoration.collapsed(hintText: getHint(ctx), + hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)), + onChanged: (text) => handleUserInput(text))); } - getPaddingForTextWidget() { + /// Возвращат паддинги для поля ввода. + EdgeInsets getInputFieldContainerPadding() { const double verticalPadding = 12.0; const double horizontalPadding = 16.0; return new EdgeInsets.only(top: verticalPadding, - bottom: verticalPadding, - left: horizontalPadding, - right: horizontalPadding); + bottom: verticalPadding, + left: horizontalPadding, + right: horizontalPadding); } /// Метод возвращает BoxDecoration для _getDecoratedInputField - getDecorationForTextWidget() { - return new BoxDecoration(color: getTextFilledBackground(), - border: new Border.all(color: textBorderColor, width: 1.0), - borderRadius: new BorderRadius.all(new Radius.circular(4.0))); + BoxDecoration getInputFieldContainerDecoration() { + return new BoxDecoration(color: inputFieldBackground, + border: new Border.all(color: textBorderColor, width: 1.0), + borderRadius: new BorderRadius.all(new Radius.circular(4.0))); } - Color getTextFilledBackground() { - return const Color(0xffefefef); + /// Возвращает выпуклую залитую фирменным цветом кнопку + Widget buildRaisedButton(BuildContext context, String text, VoidCallback onPressed) { + return new RaisedButton(child: new Text(text, + style: new TextStyle(color: Colors.white)), + onPressed: onPressed, + color: primaryColor); } - Widget getTextWidget() { - return new TextField(keyboardType: TextInputType.number, - decoration: new InputDecoration.collapsed(hintText: getHint(), - hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)), - onChanged: (text) => handleUserInput(text)); + /// Метод возвращает контейнер с отступами, который содержит картинку с логотипом. + Widget getLogo() { + double containerHeight = 92.0; + double imageWidth = 156.0; + return new Container(height: containerHeight, child: new Image.asset(logo_png, width: imageWidth)); } - Widget getProgressIndicator() { - return new Center(child: loading ? new CircularProgressIndicator() : null); - } - - Widget getValueWithTitle(String title, String value) { + /// Возвращает текстовое поле, с однострочным пояснением над ним. + Widget getValueWithDescription(String title, String value) { return new Container(padding: new EdgeInsets.only(left: verticalMargin, right: verticalMargin, top: 18.0), - child: new Column(children: [ - new Row(crossAxisAlignment: CrossAxisAlignment.start, children: [new Text(title, textAlign: TextAlign.left, style: new TextStyle(color: greyTextColor, fontSize: 14.0))]), - new Row(crossAxisAlignment: CrossAxisAlignment.start, children: [new Expanded(child: new Text(value, textAlign: TextAlign.left, style: new TextStyle(color: Colors.black, fontSize: 20.0)))]) - ])); + child: new Column(children: [ + new Row(crossAxisAlignment: CrossAxisAlignment.start, children: getDescriptionWidget(title)), + new Row(crossAxisAlignment: CrossAxisAlignment.start, children: getValueWidget(value)) + ])); } + /// Возвращает список, единственный элемент которого - Text с заголовком для текстового поля. + List getDescriptionWidget(String title) { + return [new Text(title, textAlign: TextAlign.left, style: new TextStyle(color: greyTextColor, fontSize: 14.0))] + } + + /// Возвращает список, единственный элемент которого - Text с информацией (размер скидки, сумма проведенной покупки). + List getValueWidget(String value) { + return [new Expanded(child: new Text(value, textAlign: TextAlign.left, style: new TextStyle(color: Colors.black, fontSize: 20.0)))]; + } + + /// Возвращает кнопку, обернутую набором специфичных контейнеров. Widget buildButton(EdgeInsets margin, Widget widget) { return new Container(margin: margin, height: buttonHeight, child: new Row(children: [new Expanded(child: widget)])); } - Widget buildRaisedButton(BuildContext context, String text, VoidCallback onPressed) { - return new RaisedButton(child: new Text(text, - style: new TextStyle(color: Colors.white)), - onPressed: onPressed, - color: primaryColor); - } - - Widget buildFlatButton(BuildContext context, String title, Color textColor) { - return new Container(height: buttonHeight, child: new FlatButton(child: new Text(title, - style: new TextStyle(color: textColor)), - onPressed: () => startScanner(context)), - decoration: getDecorationForScanButton()); - } - - getDecorationForScanButton() { - return new BoxDecoration( - border: new Border.all(color: primaryColor, width: 1.0), - borderRadius: new BorderRadius.all(new Radius.circular(4.0))); - } } diff --git a/lib/common.dart b/lib/common.dart index e7f3efd..d87b03d 100644 --- a/lib/common.dart +++ b/lib/common.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'consts.dart'; import 'network.dart'; -import 'package:checker/registration/registration.dart'; -import 'package:checker/purchase/purchase.dart'; +import 'package:checker/registration.dart'; +import 'package:checker/purchase.dart'; import 'faq.dart'; import 'strings.dart'; diff --git a/lib/consts.dart b/lib/consts.dart index 666d9dc..7234267 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -26,7 +26,7 @@ const Color tokenActivateTextColor = const Color(0xff4e3a19); const Color greenBackground = const Color(0xff8ae28a); const Color faqGrey = const Color(0xff5b5b5b); const Color faqTitlesColor = const Color(0xff404040); - +const Color inputFieldBackground = const Color(0xffefefef); // Dimens const double verticalMargin = 28.0; const double buttonHeight = 48.0; diff --git a/lib/registration/activate_token.dart b/lib/finish_registration.dart similarity index 99% rename from lib/registration/activate_token.dart rename to lib/finish_registration.dart index 364528c..38199cf 100644 --- a/lib/registration/activate_token.dart +++ b/lib/finish_registration.dart @@ -35,7 +35,7 @@ class _RegistrationScreenState extends BaseState { return new Column(children: [ getLogo(), getHintLabel(), - getDecoratedTextWidget(), + getInputField(), getMessage(), buildRaisedButton(context, _tokenActive ? Strings.of(context).completeRegistration() diff --git a/lib/main.dart b/lib/main.dart index 8b2228d..677587e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,29 +3,22 @@ import 'splash.dart'; import 'consts.dart'; import 'strings.dart'; import 'dart:async'; -import 'i18n/messages_all.dart'; -import 'package:intl/intl.dart'; - -Future _onLocaleChanged(Locale locale) async { - final String localeString = locale.toString(); - await initializeMessages(localeString); - Intl.defaultLocale = localeString; - return Strings.instance; -} /// Точка входа в приложение. void main() { runApp(new Checker()); } -class Checker extends StatelessWidget { +class Checker extends StatefulWidget { + @override CheckerState createState() => new CheckerState(); +} + +class CheckerState extends State { + @override Widget build(BuildContext context) { - return new MaterialApp(title: appName, - home: new SplashScreen(), - onLocaleChanged: _onLocaleChanged, - theme: new ThemeData( - primaryColor: primaryColor, - accentColor: primaryColor - )); + return new MaterialApp( + title: appName, + home: new SplashScreen() + ); } } diff --git a/lib/purchase/purchase.dart b/lib/purchase.dart similarity index 80% rename from lib/purchase/purchase.dart rename to lib/purchase.dart index 5175045..b71fd87 100644 --- a/lib/purchase/purchase.dart +++ b/lib/purchase.dart @@ -8,7 +8,7 @@ import 'package:checker/common.dart'; import 'package:checker/consts.dart'; import 'package:checker/network.dart'; import 'package:checker/base_state.dart'; -import 'purchase_success.dart'; +import 'package:checker/purchase_success.dart'; /// Экран проведения покупки. class PurchaseScreen extends StatefulWidget { @@ -23,6 +23,11 @@ class PurchaseScreen extends StatefulWidget { class PurchaseScreenState extends BaseState { + /// Объект, помогающий вручную изменять введенный пользователем текст. + /// Используется для форматирования введенных пользователем данных + /// (удаляет запрещенные символы до их отображаения). + TextEditingController controller = new TextEditingController(); + PurchaseScreenState(String userString, String card) { this.user = JSON.decode(userString); this.card = card; @@ -37,13 +42,13 @@ class PurchaseScreenState extends BaseState { @override Widget getScreenContent() { return new Column( children: [new Expanded(child: new ListView(children: [ - getValueWithTitle(Strings.of(context).userName(), user['first_name'] == null ? '' : user['first_name']), - getValueWithTitle(Strings.of(context).card(), card), - getValueWithTitle(Strings.of(context).reward(), loyality), + getValueWithDescription(Strings.of(context).userName(), user['first_name'] == null ? '' : user['first_name']), + getValueWithDescription(Strings.of(context).card(), card), + getValueWithDescription(Strings.of(context).reward(), loyality), getHintLabel(), - getDecoratedTextWidget(), + getInputField(), buildButton(getScreenMargins(36.0), getCompleteButton()), - buildButton(getScreenMargins(24.0), getScanButton()) + buildButton(getScreenMargins(24.0), getScanButton(context, Strings.of(context).scan(), primaryColor)) ]))]); } @@ -57,8 +62,17 @@ class PurchaseScreenState extends BaseState { return buildRaisedButton(context, title, () => onPurchaseClick(context)); } - getScanButton() { - return buildFlatButton(context, Strings.of(context).scan(), primaryColor); + Widget getScanButton(BuildContext context, String title, Color textColor) { + return new Container(height: buttonHeight, child: new FlatButton(child: new Text(title, + style: new TextStyle(color: textColor)), + onPressed: () => startScanner(context)), + decoration: getDecorationForScanButton()); + } + + getDecorationForScanButton() { + return new BoxDecoration( + border: new Border.all(color: primaryColor, width: 1.0), + borderRadius: new BorderRadius.all(new Radius.circular(4.0))); } @override String getTitle() { @@ -183,7 +197,7 @@ class PurchaseScreenState extends BaseState { } getContentMessage(String val) { - return Strings.of(context).confirmPurchase(val); + return Strings.of(context).confirmPurchase(); } purchase(String sumTotal) async { diff --git a/lib/purchase/purchase_success.dart b/lib/purchase_success.dart similarity index 96% rename from lib/purchase/purchase_success.dart rename to lib/purchase_success.dart index 6f0d45c..25fff7e 100644 --- a/lib/purchase/purchase_success.dart +++ b/lib/purchase_success.dart @@ -36,7 +36,7 @@ class PurchaseSuccessScreenState extends BaseState { @override Widget getScreenContent() { return new Column(children: [ - getValueWithTitle(Strings.of(context).buyer(), username), + getValueWithDescription(Strings.of(context).buyer(), username), getSuccessMessage(), new Expanded(child: new Center()), buildButton(getScreenMargins(74.0), getScanButton()) diff --git a/lib/registration/registration.dart b/lib/registration.dart similarity index 77% rename from lib/registration/registration.dart rename to lib/registration.dart index ce98c12..9f1e945 100644 --- a/lib/registration/registration.dart +++ b/lib/registration.dart @@ -1,3 +1,4 @@ +import 'package:checker/finish_registration.dart'; import 'package:flutter/material.dart'; import 'dart:convert'; // Пакет для обработки json с ответом от сервера. @@ -5,7 +6,6 @@ import 'package:checker/common.dart'; import 'package:checker/network.dart'; import 'package:checker/base_state.dart'; import 'package:checker/strings.dart'; -import 'activate_token.dart'; /// Экран регистрации магазина и кассы. class RegistrationScreen extends StatefulWidget { @@ -14,35 +14,36 @@ class RegistrationScreen extends StatefulWidget { class _RegistrationScreenState extends BaseState { - @override String getTitle() { - return Strings.of(context).registration(); + @override String getTitle(BuildContext ctx) { + return "registration"; } - @override getHint() { - return Strings.of(context).idStore(); + @override getHint(BuildContext ctx) { + return "idStore()"; } // Список виджетов, автоматически прокручиваемый вверх при открытии клавиатуры. - @override Widget getScreenContent() { + @override Widget getScreenContent(BuildContext ctx) { + print(new Strings().registration()); return new Container( child: new ListView(children: [ new Column(children: [ getLogo(), - getHintLabel(), - getDecoratedTextWidget(), - getButton()]) + getHintLabel(ctx), + getInputField(ctx), + getButton(ctx)]) ])); } - // Возвращает кнопку регистрации. - getButton() { + /// Возвращает кнопку регистрации. + getButton(BuildContext ctx) { return new Container(margin: new EdgeInsets.only(top: 36.0), child: - buildRaisedButton(context, Strings.of(context).signUp(), getOnPressed())); + buildRaisedButton(ctx, "signUp()", getOnPressed(ctx))); } // Возвращает обработчик нажатий на кнопку регистрации. - getOnPressed() { - return _isValidMerchantID() && !loading ? () => _registerShop(context) : null; + getOnPressed(BuildContext ctx) { + return _isValidMerchantID() && !loading ? () => _registerShop(ctx) : null; } /// Токен кассы - это DIN код. DIN код - это специальный код динекта, максимальная его длина - 25 символов. @@ -52,15 +53,15 @@ class _RegistrationScreenState extends BaseState { } /// Показать progressBar, запросить токен. - _registerShop(BuildContext context) { + _registerShop(BuildContext ctx) { setState(() { loading = true; - _register(context); + _register(ctx); }); } /// Получение от платформы id установки, формирование запроса на получение токена, сохранение токена. - _register(BuildContext context) async { + _register(BuildContext ctx) async { if (await platform.invokeMethod('isOnline')) { createToken(textFieldValue, await platform.invokeMethod('getPosID')).then((response) { @@ -75,7 +76,7 @@ class _RegistrationScreenState extends BaseState { token = parsedMap['token']; platform.invokeMethod('saveToken', {'token' : token}); platform.invokeMethod('saveMerchantID', {'merchantID' : textFieldValue}); - pushRoute(context, new FinishRegistrationScreen()); + pushRoute(ctx, new FinishRegistrationScreen()); } else { setState(() { error = parsedMap['errors'][0]; diff --git a/lib/splash.dart b/lib/splash.dart index d15dae1..bf33796 100644 --- a/lib/splash.dart +++ b/lib/splash.dart @@ -1,49 +1,54 @@ import 'package:flutter/material.dart'; + import 'dart:async'; import 'dart:convert'; import 'common.dart'; import 'network.dart'; import 'consts.dart'; -import 'package:checker/registration/registration.dart'; -import 'package:checker/registration/activate_token.dart'; +import 'registration.dart'; +import 'finish_registration.dart'; +import 'strings.dart'; class SplashScreen extends StatelessWidget { @override Widget build(BuildContext context) { - // Появляется splash screen, проверяется токен. - new Future.delayed(const Duration(milliseconds: 500), () { + + Strings s = new Strings(); + s.load("ru").then((_) { showNextScreen(context); }); +// new Future.delayed(const Duration(milliseconds: 500), () { +// }); + return new Stack(children: [getSplashBackground(), getLogo(), - new Align(alignment: FractionalOffset.bottomRight, child: - new Container(margin: new EdgeInsets.only(right: 11.0, bottom: 5.0), child: - new Image.asset(powered_by_dinect_splash_png, height: 16.0, width: 122.0)))]); + new Align(alignment: FractionalOffset.bottomRight, child: + new Container(margin: new EdgeInsets.only(right: 11.0, bottom: 5.0), child: + new Image.asset(powered_by_dinect_splash_png, height: 16.0, width: 122.0)))]); } - // Возвращает столбец с логотипом приложения и текстом под ним. - // Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана. + /// Возвращает столбец с логотипом приложения и текстом под ним. + /// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана. getLogo() { return new Center(child: new Column(mainAxisSize: MainAxisSize.min, - children: [new Image.asset(logo_png, height: 112.0, width: 252.0), - new Image.asset(splash_text_png, height: 40.0, width: 240.0)])); + children: [new Image.asset(logo_png, height: 112.0, width: 252.0), + new Image.asset(splash_text_png, height: 40.0, width: 240.0)])); } - // Возвращает контейнер, который содержит decoration с фоновым изображением. + /// Возвращает контейнер, который содержит decoration с фоновым изображением. getSplashBackground() { return new Container(decoration: - new BoxDecoration(image: - new DecorationImage(image: new ExactAssetImage(splash_png), fit: BoxFit.cover))); + new BoxDecoration(image: + new DecorationImage(image: new ExactAssetImage(splash_png), fit: BoxFit.cover))); } - // Запуск следующего экрана приложения. + /// Запуск следующего экрана приложения. showNextScreen(BuildContext context) async { token = await platform.invokeMethod('getToken'); - print('token: $token'); // В случае, если в приложении отсутствует токен, // необходимо запустить регистрацию кассы. @@ -61,9 +66,9 @@ class SplashScreen extends StatelessWidget { } } - // Обработка ответа. - // В случае, если токен был удален может прийти active: false, либо 404. - // Если токен не активен, попробовать создать его еще раз. В случае успешного создания токена удалить его и перейти на экран регистрации + /// Обработка ответа. + /// В случае, если токен был удален может прийти active: false, либо 404. + /// Если токен не активен, попробовать создать его еще раз. handleStatusResponse(BuildContext context, var statusResponse) async { int code = statusResponse.statusCode; print('resp: ${code}'); @@ -75,32 +80,44 @@ class SplashScreen extends StatelessWidget { }); } else { - Map statusResponseMap = JSON.decode(statusResponse.body); - bool active = statusResponseMap['active'] == null ? false : statusResponseMap['active']; + Map status = JSON.decode(statusResponse.body); + bool active = status['active'] == null ? false : status['active']; if (active) { startScanner(context); } else { if (await platform.invokeMethod('isOnline')) { - createToken(await platform.invokeMethod('getMerchantID'), await platform.invokeMethod('getPosID')).then((response) { - if (response.statusCode == 409) { - pushRoute(context, new FinishRegistrationScreen()); - } else if (response.statusCode == 201) { - platform.invokeMethod('removeKeys').then((result) { - Map parsedMap = JSON.decode(result); - String t = parsedMap['token']; - deleteToken(t).then((response) { - print(response.body); - Navigator.of(context).pop(); // Убираем текущий route - pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию - }).catchError((error) { - print(error.toString()); - }); - }); - } - }).catchError((error) => print(error.toString())); + _createToken(context); } } } } + + /// Отправляется запрос на создание токена. + /// + /// Если вернулся код 409, значит такой токен уже существует и активирован. + /// Нужно направить пользователя на экран подтверждения активации. + /// + /// Если вернулся код 200, значит токен был ранее удален и только что снова создался. + /// Нужно удалить его и направить пользователя на экран регистрации. + _createToken(BuildContext ctx) async { + String merchantID = await platform.invokeMethod('getMerchantID'); + String posID = await platform.invokeMethod('getPosID'); + createToken(merchantID, posID).then((response) { + if (response.statusCode == 409) { + pushRoute(ctx, new FinishRegistrationScreen()); + } else if (response.statusCode == 201) { + platform.invokeMethod('removeKeys').then((result) { + Map parsedMap = JSON.decode(result); + deleteToken(parsedMap['token']).then((response) { + print(response.body); + Navigator.of(ctx).pop(); // Убираем текущий route + pushRoute(ctx, new RegistrationScreen()); // Запускаем регистрацию + }).catchError((error) { + print(error.toString()); + }); + }); + } + }).catchError((error) => print(error.toString())); + } } diff --git a/lib/strings.dart b/lib/strings.dart index 5909ac8..8f1eae0 100644 --- a/lib/strings.dart +++ b/lib/strings.dart @@ -1,43 +1,45 @@ import 'package:intl/intl.dart'; -import 'package:flutter/widgets.dart'; -import 'package:sprintf/sprintf.dart'; +import 'i18n/messages_all.dart'; +import 'dart:async'; -class Strings extends LocaleQueryData { +class Strings { - static Strings of(BuildContext context) { - return LocaleQuery.of(context); + static final Strings _singleton = new Strings._internal(); + + String _localeName; + + factory Strings(){ + return _singleton; } - static final Strings instance = new Strings(); + Strings._internal(); - String confirmPurchase(String val) { - return sprintf(Intl.message('confirm_purchase'), val); + Future load(String locale) async { + _localeName = locale; + return initializeMessages(locale); } - String purchaseCompleted(String val) { - return sprintf(Intl.message('purchase_complite'), val); - } - - String idStore() => Intl.message('ID_Store'); - String signUp() => Intl.message('sign_up'); - String registration() => Intl.message('registration'); - String specifyDinStore() => Intl.message('specify_din_store'); - String confirmation() => Intl.message('confirmation'); - String askChangeStore() => Intl.message('ask_change_store'); - String yes() => Intl.message('yes'); - String no() => Intl.message('no'); - String requestSentWaitActivation() => Intl.message('request_sent_wait_activ'); - String refreshActivationStatus() => Intl.message('update_activ_status'); - String appActivated() => Intl.message('app_activ'); - String completeRegistration() => Intl.message('complite_activ'); - String cardScanner() => Intl.message('card_scaner'); - String userName() => Intl.message('user_name'); - String card() => Intl.message('card'); - String reward() => Intl.message('reward'); - String sum() => Intl.message('sum'); - String carryingPurchase() => Intl.message('carry_purchase'); - String completePurchase() => Intl.message('complite_purchase'); - String scan() => Intl.message('scan'); - String buyer() => Intl.message('buyer'); - String idNotFound() => Intl.message('ID_not_found'); + String registration() => Intl.message('registration', name: 'registration', locale: _localeName); + String idStore() => Intl.message('ID_Store', name: 'ID_Store', locale: _localeName); + String signUp() => Intl.message('sign_up', name: 'sign_up', locale: _localeName); + String specifyDinStore() => Intl.message('specify_din_store', name: 'specify_din_store', locale: _localeName); + String confirmation() => Intl.message('confirmation', name: 'confirmation', locale: _localeName); + String askChangeStore() => Intl.message('ask_change_store', name: 'ask_change_store', locale: _localeName); + String yes() => Intl.message('yes', name: 'yes', locale: _localeName); + String no() => Intl.message('no', name: 'no', locale: _localeName); + String requestSentWaitActivation() => Intl.message('request_sent_wait_activ', name: 'request_sent_wait_activ', locale: _localeName); + String refreshActivationStatus() => Intl.message('update_activ_status', name: 'update_activ_status', locale: _localeName); + String appActivated() => Intl.message('app_activ', name: 'app_activ', locale: _localeName); + String completeRegistration() => Intl.message('complite_activ', name: 'complite_activ', locale: _localeName); + String cardScanner() => Intl.message('card_scaner', name: 'card_scaner', locale: _localeName); + String userName() => Intl.message('user_name', name: 'user_name', locale: _localeName); + String card() => Intl.message('card', name: 'card', locale: _localeName); + String reward() => Intl.message('reward', name: 'reward', locale: _localeName); + String sum() => Intl.message('sum', name: 'sum', locale: _localeName); + String carryingPurchase() => Intl.message('carry_purchase', name: 'carry_purchase', locale: _localeName); + String completePurchase() => Intl.message('complite_purchase', name: 'complite_purchase', locale: _localeName); + String scan() => Intl.message('scan', name: 'scan', locale: _localeName); + String buyer() => Intl.message('buyer', name: 'buyer', locale: _localeName); + String confirmPurchase() => Intl.message('confirm_purchase', name: 'confirm_purchase', locale: _localeName); + String idNotFound() => Intl.message('ID_not_found', name: 'ID_not_found', locale: _localeName); } \ No newline at end of file