264 lines
9.7 KiB
Dart
264 lines
9.7 KiB
Dart
import 'dart:async';
|
||
import 'dart:convert';
|
||
|
||
import 'package:checker/base/base_screen.dart';
|
||
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/faq.dart';
|
||
import 'package:checker/screens/finish_registration.dart';
|
||
import 'package:checker/screens/purchase.dart';
|
||
import 'package:checker/screens/registration.dart';
|
||
import 'package:checker/screens/settings.dart';
|
||
import 'package:checker/strings.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:http/http.dart';
|
||
|
||
// FIXME: Сделать запуск всех экранов из одной точки через метод showNextScreen()
|
||
class SplashScreen extends BaseScreen {
|
||
|
||
SplashScreen(SqliteHelper helper, String app) : super(helper, app);
|
||
|
||
@override
|
||
State createState() => new _SplashScreenState(helper, app);
|
||
}
|
||
|
||
class _SplashScreenState extends BaseState<SplashScreen> {
|
||
|
||
_SplashScreenState(SqliteHelper helper, String app) : super(helper, app);
|
||
bool a = true;
|
||
|
||
bool isAutomaticallyImplyLeading() => false;
|
||
|
||
@override
|
||
void initState() {
|
||
init();
|
||
super.initState();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext ctx) {
|
||
return !a ? new Container(
|
||
decoration: new BoxDecoration(
|
||
image: new DecorationImage(
|
||
image: new ExactAssetImage(Resources.getSplash(null)),
|
||
fit: BoxFit.cover))) : getScreenContent();
|
||
}
|
||
|
||
@override
|
||
Widget getScreenContent() {
|
||
return new Stack(children: <Widget>[
|
||
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: <Widget>[
|
||
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(Widget screen) {
|
||
new Future.delayed(const Duration(milliseconds: 200), () {
|
||
var route = new MaterialPageRoute<String>(
|
||
builder: (BuildContext context) => screen, fullscreenDialog: true);
|
||
Navigator.of(context).push(route).then((token) {
|
||
if (token == '') {
|
||
showNextScreen(new RegistrationScreen(helper, app));
|
||
} else if (token != null) {
|
||
_initAndStartScanner(context, app, token, helper);
|
||
} else {
|
||
print('Произошла непредусмотренная ошибка в логике приложения');
|
||
helper.getToken().then((token) {
|
||
_initAndStartScanner(context, app, token, helper);
|
||
});
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/// Запуск следующего экрана приложения.
|
||
init() async {
|
||
String token = await helper.getToken();
|
||
// В случае, если в приложении отсутствует токен,
|
||
// необходимо запустить регистрацию кассы.
|
||
if (token == null) {
|
||
showNextScreen(new RegistrationScreen(helper, app));
|
||
} else {
|
||
if (await platform.invokeMethod('isOnline')) {
|
||
getCheckTokenStatusRequest(token).then((statusResponse) {
|
||
handleStatusResponse(statusResponse, helper);
|
||
}).catchError((error) {
|
||
print(error.toString());
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
/// Обработка ответа.
|
||
/// В случае, если токен был удален может прийти active: false, либо 404.
|
||
/// Если токен не активен, попробовать создать его еще раз.
|
||
handleStatusResponse(var statusResponse, SqliteHelper helper) async {
|
||
int code = statusResponse.statusCode;
|
||
if (code == 404) {
|
||
helper.clear().then((result) {
|
||
showNextScreen(new RegistrationScreen(helper, app));
|
||
});
|
||
} else {
|
||
Map status = JSON.decode(statusResponse.body);
|
||
bool active = status['active'] == null ? false : status['active'];
|
||
|
||
if (active) {
|
||
helper.getToken().then((token) {
|
||
_initAndStartScanner(context, app, token, 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();
|
||
|
||
getCreateTokenRequest({'merchant_shop': merchantID, 'pos': posID})
|
||
.then((response) {
|
||
if (response.statusCode == 409) {
|
||
showNextScreen(new FinishRegistrationScreen(helper, app));
|
||
} else if (response.statusCode == 201) {
|
||
clearToken(response, helper);
|
||
}
|
||
}).catchError((error) {
|
||
print(error.toString());
|
||
});
|
||
}
|
||
|
||
/// Очищаем бд, делаем запрос на удаление токена.
|
||
Future clearToken(Response response, SqliteHelper helper) async {
|
||
helper.clear().then((_) {
|
||
Map parsedMap = JSON.decode(response.body);
|
||
getDeleteTokenRequest(parsedMap['token']).then((_) {
|
||
showNextScreen(new RegistrationScreen(helper, app));
|
||
}).catchError((error) {
|
||
print(error.toString());
|
||
});
|
||
});
|
||
}
|
||
|
||
|
||
/// Запуск спецефичной для каждой платформы части приложения - сканера.
|
||
/// Может производиться с нескольких экранов (splash, finish_registration).
|
||
_initAndStartScanner(BuildContext context, String app, String token,
|
||
SqliteHelper helper) {
|
||
// Канал ловит вызовы методов из "нативной" части приложения.
|
||
// Могут быть вызваны либо exit либо faq, либо purchase.
|
||
|
||
setState(() {
|
||
a = false;
|
||
});
|
||
|
||
platform.setMethodCallHandler((MethodCall call) async {
|
||
print(this.toString());
|
||
if (call.method == 'findUser') {
|
||
|
||
try {
|
||
|
||
Response userResponse;
|
||
|
||
switch (call.arguments[1]) {
|
||
case 'card':
|
||
userResponse = await getUserByCard(call.arguments[0], token);
|
||
break;
|
||
case 'phone':
|
||
userResponse = await getUserByPhone(call.arguments[0], token);
|
||
break;
|
||
}
|
||
|
||
if (userResponse != null) {
|
||
print('I have user in method handler!');
|
||
List<Map> users = JSON.decode(userResponse.body);
|
||
if (users.length > 0) {
|
||
return users[0];
|
||
} else {
|
||
throw new FlutterError("Users not found");
|
||
}
|
||
} else {
|
||
throw new FlutterError("Users not found");
|
||
}
|
||
} catch (error) {
|
||
print(error.toString());
|
||
throw new FlutterError("Users not found");
|
||
}
|
||
|
||
} else if (call.method == 'faq') {
|
||
new Future.delayed(const Duration(milliseconds: 200), () {
|
||
var route = new MaterialPageRoute<Null>(
|
||
builder: (BuildContext context) => new FAQScreen(helper, app), fullscreenDialog: true);
|
||
Navigator.of(context).push(route).then((_) {
|
||
_initAndStartScanner(context, app, token, helper);
|
||
});
|
||
});
|
||
} else if (call.method == 'settings') {
|
||
new Future.delayed(const Duration(milliseconds: 200), () {
|
||
var route = new MaterialPageRoute<String>(
|
||
builder: (BuildContext context) => new SettingsScreen(helper, app, true), fullscreenDialog: true);
|
||
Navigator.of(context).push(route).then((result) {
|
||
if (result != null) {
|
||
showNextScreen(new RegistrationScreen(helper, app));
|
||
} else {
|
||
_initAndStartScanner(context, app, token, helper);
|
||
}
|
||
});
|
||
});
|
||
} else {
|
||
String userString = call.arguments[0] is String
|
||
? call.arguments[0]
|
||
: JSON.encode(call.arguments[0]);
|
||
print(userString);
|
||
String card = call.arguments[1];
|
||
showNextScreen(new PurchaseScreen(helper, app, userString, card));
|
||
}
|
||
});
|
||
|
||
platform.invokeMethod('getEndpoint').then((url) {
|
||
platform.invokeMethod('getAppToken').then((appToken) {
|
||
Map<String, String> args = StringsLocalization.strings;
|
||
args['token'] = token;
|
||
args['url'] = url;
|
||
args['appToken'] = appToken;
|
||
args['localeCode'] = StringsLocalization.localeCode;
|
||
args['color'] = Resources
|
||
.getPrimaryColor(app)
|
||
.value
|
||
.toString();
|
||
platform.invokeMethod('startScanner', args);
|
||
});
|
||
});
|
||
}
|
||
}
|