import 'dart:async'; import 'dart:convert'; import 'package:checker/base/base_state.dart'; import 'package:checker/common.dart'; import 'package:checker/consts.dart'; import 'package:checker/db.dart'; import 'package:checker/network.dart'; import 'package:checker/resources.dart'; import 'package:checker/screens/finish_registration.dart'; import 'package:checker/screens/registration.dart'; import 'package:checker/strings.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:intl/intl.dart'; class SplashScreen extends StatefulWidget { @override State createState() => new _SplashScreenState(); } class _SplashScreenState extends BaseState { @override Widget build(BuildContext ctx) { if (helper == null) { helper = new SqliteHelper(); helper.open().then((_) { if (app == null) { platform.invokeMethod('getFlavor').then((flavor) { app = flavor; setState(() { onStart(); }); }); } }); } return getScreenContent(); } void onStart() { helper.getLocale().then((locale) { if (locale == null) { initWithSystemValue(); } else { initWithSavedValue(); } }); } void initWithSystemValue() { platform.invokeMethod('getLocale').then((locale) { helper.getSettings().then((settings) { if (settings == null) { createSettingsTable(locale); } else { initLocale(locale, () { showNext(); }); } }); }); } void initWithSavedValue() { helper.getLocale().then((locale) { initLocale(locale, () { showNext(); }); }); } void createSettingsTable(String locale) { platform.invokeMethod('getCurrency').then((currency) { helper.createAppInfo(locale, currency); initLocale(locale, () { showNext(); }); }); } void initLocale(String locale, Future onValue()) { Intl.defaultLocale = locale; StringsLocalization.load(locale).then((_) { onValue(); }); } void showNext() { new Future.delayed(const Duration(milliseconds: 1000), () { showNextScreen(); }); } @override Widget getScreenContent() { return app == null ? getBackground() : new Stack( children: [ getBackground(), 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))) ]); } /// Возвращает столбец с логотипом приложения и текстом под ним. /// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана. getLogo() { return new Center( child: new Column( mainAxisSize: MainAxisSize.min, children: [ new Image.asset( Resources.getLogo(app), height: 112.0, width: 252.0), new Image.asset( splash_text_png, height: 40.0, width: 240.0) ])); } /// Запуск следующего экрана приложения. showNextScreen() async { String token = await helper.getToken(); String locale = await helper.getLocale(); // В случае, если в приложении отсутствует токен, // необходимо запустить регистрацию кассы. if (token == null) { pushRouteReplacement(context, new RegistrationScreen(helper, app)); } else { if (await platform.invokeMethod('isOnline')) { checkTokenStatus(token, locale).then((statusResponse) { handleStatusResponse(statusResponse, helper); }).catchError((error) { handleError(error.toString()); }); } } } /// Обработка ответа. /// В случае, если токен был удален может прийти active: false, либо 404. /// Если токен не активен, попробовать создать его еще раз. handleStatusResponse(var statusResponse, SqliteHelper helper) async { int code = statusResponse.statusCode; if (code == 404) { helper.clear().then((result) { pushRouteReplacement(context, new RegistrationScreen(helper, app)); }); } else { Map status = JSON.decode(statusResponse.body); bool active = status['active'] == null ? false : status['active']; if (active) { startScanner(context, app, helper); } else { if (await platform.invokeMethod('isOnline')) { _createToken(helper); } } } } /// Отправляется запрос на создание токена. /// /// Если вернулся код 409, значит такой токен уже существует и активирован. /// Нужно направить пользователя на экран подтверждения активации. /// /// Если вернулся код 200, значит токен был ранее удален и только что снова создался. /// Нужно удалить его и направить пользователя на экран регистрации. _createToken(SqliteHelper helper) async { String merchantID = await helper.getMerchantID(); String posID = await helper.getPosID(); String locale = await helper.getLocale(); createToken(merchantID, posID, locale).then((response) { if (response.statusCode == 409) { pushRouteReplacement(context, new FinishRegistrationScreen(helper, app)); } else if (response.statusCode == 201) { clearToken(response, helper); } }).catchError((error) { handleError(error.toString()); }); } /// Очищаем бд, делаем запрос на удаление токена. Future clearToken(Response response, SqliteHelper helper) async { String locale = await helper.getLocale(); helper.clear().then((_) { Map parsedMap = JSON.decode(response.body); deleteToken(parsedMap['token'], locale).then((_) { Navigator.of(context).pop(); pushRouteReplacement(context, new RegistrationScreen(helper, app)); }).catchError((error) { handleError(error.toString()); }); }); } /// Закрываем соединение, логируем ошибку. void handleError(String error) { helper.close().then((_) { print(error.toString()); return false; }); } }