Smoth screen changes. Step 1

This commit is contained in:
Ivan Murashov
2018-03-08 23:53:31 +03:00
parent cfdf5dcca2
commit 58e58671de
13 changed files with 238 additions and 209 deletions

View File

@@ -164,6 +164,8 @@ public abstract class AbstractScannerActivity extends AppCompatActivity impleme
EditText manualInput = (EditText) findViewById(R.id.manual_input); EditText manualInput = (EditText) findViewById(R.id.manual_input);
// для удобства, чтоб не вводить постоянно руками при разработке // для удобства, чтоб не вводить постоянно руками при разработке
manualInput.setText("9990010009012057060904229");
// manualInput.setText("4620011139016337050236302"); // manualInput.setText("4620011139016337050236302");
manualInput.setHint(getIntent().getStringExtra("enter_manual")); manualInput.setHint(getIntent().getStringExtra("enter_manual"));

View File

@@ -25,8 +25,10 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
/// Введенное пользователем значение. /// Введенное пользователем значение.
String merchantID = ''; String merchantID = '';
BaseState(this.helper, this.app);
Widget getMainWidget() { Widget getMainWidget() {
return app == null ? getBackground() : new Scaffold(appBar: getAppBar(), return new Scaffold(appBar: getAppBar(),
body: new Stack(children: <Widget>[ body: new Stack(children: <Widget>[
getScreenContent(), getScreenContent(),
new Center(child: loading ? new CircularProgressIndicator() : null) new Center(child: loading ? new CircularProgressIndicator() : null)

View File

@@ -4,13 +4,9 @@ import 'package:checker/db.dart';
import 'package:checker/strings.dart'; import 'package:checker/strings.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
abstract class SettingsBaseState<T extends StatefulWidget> abstract class SettingsBaseState<T extends StatefulWidget> extends BaseState<T> {
extends BaseState<T> {
SettingsBaseState(SqliteHelper helper, String app) { SettingsBaseState(SqliteHelper helper, String app) : super(helper, app);
this.helper = helper;
this.app = app;
}
int selectedItem; int selectedItem;

View File

@@ -69,83 +69,6 @@ logout(BuildContext context, SqliteHelper helper) async {
StringsLocalization.askChangeStore(), positiveCallback); StringsLocalization.askChangeStore(), positiveCallback);
} }
/// Запуск спецефичной для каждой платформы части приложения - сканера.
/// Может производиться с нескольких экранов (splash, finish_registration).
startScanner(BuildContext context, String app, SqliteHelper helper) async {
String token = await helper.getToken();
// Канал ловит вызовы методов из "нативной" части приложения.
// Могут быть вызваны либо exit либо faq, либо purchase.
if (token != null) {
platform.setMethodCallHandler((MethodCall call) async {
if (call.method == 'findUser') {
var userResponse;
String cardPhone = call.arguments[0];
try {
switch (call.arguments[1]) {
case 'card':
userResponse = await getUserByCard(cardPhone, token);
break;
case 'phone':
userResponse = await getUserByPhone(cardPhone, token);
break;
}
} catch (error) {
print(error.toString());
}
List<Map> users;
try {
users = JSON.decode(userResponse.body);
} catch (error) {
print(error);
}
if (users.length > 0) {
return users[0];
} else {
startScanner(context, app, helper);
throw new FlutterError("Users not found");
}
} else if (call.method == 'faq') {
faq(helper, app, context, true);
} else if (call.method == 'settings') {
pushRoute(context, new SettingsScreen(helper, app, true));
} else {
String userString;
if (call.arguments[0] is String) {
userString = call.arguments[0];
} else {
userString = JSON.encode(call.arguments[0]);
}
print(userString);
String card = call.arguments[1];
print('$userString, $card');
pushRouteReplacement(context, new PurchaseScreen(helper, app, userString, card));
}
});
Map<String, String> args = StringsLocalization.strings;
args.addAll({
'token': token,
'url': await platform.invokeMethod('getEndpoint'),
'appToken': await platform.invokeMethod('getAppToken'),
'localeCode': StringsLocalization.localeCode,
'color': Resources
.getPrimaryColor(app)
.value
.toString()
});
platform.invokeMethod('startScanner', args);
}
}
// Запуск диалога с двумя кнопками // Запуск диалога с двумя кнопками
showYesNoDialog(BuildContext context, String title, String content, showYesNoDialog(BuildContext context, String title, String content,
VoidCallback positiveCallback) { VoidCallback positiveCallback) {

View File

@@ -1,23 +1,99 @@
import 'package:checker/db.dart';
import 'package:checker/strings.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:checker/screens/splash.dart'; import 'package:checker/screens/splash.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
const platform = const MethodChannel('com.dinect.checker/instance_id'); const platform = const MethodChannel('com.dinect.checker/instance_id');
void main() { main() {
platform.invokeMethod('getFlavor').then((flavor) {
platform.invokeMethod('getAppTitle').then((title) { platform.invokeMethod('getAppTitle').then((title) {
runApp(new Checker(appName: title));
String app = flavor; // dinect, autobonus
String appName= title; // Dinect, Dinect (INT), Autobonus
SqliteHelper helper = new SqliteHelper();
helper.open().then((_) {
helper.getLocale().then((locale) {
if (locale == null) {
initWithSystemValue(app, appName, helper);
} else {
start(app, appName, locale, helper);
}
});
});
});
}); });
} }
class Checker extends StatelessWidget { initWithSystemValue(String app, String name, SqliteHelper helper) {
Checker({this.appName}); platform.invokeMethod('getLocale').then((locale) {
helper.getSettings(false).then((settings) {
if (settings == null) {
createSettingsTable(app, name, locale, helper);
} else {
start(app, name, locale, helper);
}
});
});
}
createSettingsTable(String app, String name, String locale, SqliteHelper helper) {
platform.invokeMethod('getCurrency').then((currency) {
helper.createAppInfo(currency);
start(app, name, locale, helper);
});
}
start(String app, String name, String locale, SqliteHelper helper) {
StringsLocalization.load(locale).then((_) {
runApp(new Checker(app, name, locale, helper));
});
}
class Checker extends StatefulWidget {
/// Класс для работы с бд
final SqliteHelper helper;
/// Тип сборки. Определяет, какие брать ресурсы (цвета, картинки)
final String app;
/// Отображаемое в заголовке приложения названия (когда показывается список запущенных приложений)
final String appName; final String appName;
@override Widget build (BuildContext context) { /// Локаль приложения
final String locale;
Checker(this.app, this.appName, this.locale, this.helper);
@override
State<StatefulWidget> createState() => new CheckerState(
this.app,
this.appName,
this.locale,
this.helper);
}
class CheckerState extends State<Checker> {
SqliteHelper helper;
String app;
String appName;
String locale;
String token;
CheckerState(this.app, this.appName, this.locale, this.helper);
@override
Widget build(BuildContext context) {
return new MaterialApp( return new MaterialApp(
title: appName, title: appName,
home: new SplashScreen() home: new SplashScreen(helper, app)
); );
} }
} }

View File

@@ -2,9 +2,7 @@ import 'package:flutter/material.dart';
class Resources { class Resources {
static String getLogo(String app) { static String getLogo(String app) => 'assets/${app}_logo.png';
return app == null ? null : 'assets/${app}_logo.png';
}
static String getSplash(String app) { static String getSplash(String app) {
if (app == 'autobonus') { if (app == 'autobonus') {

View File

@@ -76,10 +76,7 @@ class FAQScreen extends BaseScreen {
class FAQScreenState<T> extends BaseState<FAQScreen> { class FAQScreenState<T> extends BaseState<FAQScreen> {
FAQScreenState(this.returnToScanner, SqliteHelper helper, String app) { FAQScreenState(this.returnToScanner, SqliteHelper helper, String app) : super(helper, app);
this.helper = helper;
this.app = app;
}
bool returnToScanner; bool returnToScanner;
@@ -129,18 +126,18 @@ class FAQScreenState<T> extends BaseState<FAQScreen> {
if (data == null) { if (data == null) {
return getBackground(); return getBackground();
} else { } else {
return new WillPopScope(onWillPop: onWillPop, child: new ListView.builder( return new ListView.builder(
itemBuilder: (BuildContext context, int index) => itemBuilder: (BuildContext context, int index) =>
new EntryItem(data[index]), new EntryItem(data[index]),
itemCount: data.length)); itemCount: data.length);
} }
} }
onWillPop() { // onWillPop() {
if(returnToScanner) { // if(returnToScanner) {
return startScanner(context, app, helper); // return startScanner(context, app, helper);
} else { // } else {
return true; // return true;
} // }
} // }
} }

View File

@@ -18,10 +18,7 @@ class FinishRegistrationScreen extends BaseScreen {
class RegistrationScreenState extends BaseState<FinishRegistrationScreen> { class RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
RegistrationScreenState(SqliteHelper helper, String app) { RegistrationScreenState(SqliteHelper helper, String app) : super(helper, app);
this.helper = helper;
this.app = app;
}
bool _tokenActive = false; bool _tokenActive = false;
String _merchantID = ''; String _merchantID = '';
@@ -62,7 +59,7 @@ class RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
handleTap() async { handleTap() async {
if (_tokenActive) { if (_tokenActive) {
Navigator.of(context).pop(); Navigator.of(context).pop();
startScanner(context, app, helper); // FIXME: startScanner(context, app, helper);
} else { } else {
if (await platform.invokeMethod('isOnline')) { if (await platform.invokeMethod('isOnline')) {
String token = await helper.getToken(); String token = await helper.getToken();

View File

@@ -33,11 +33,9 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
TextEditingController bonusController = new TextEditingController(); TextEditingController bonusController = new TextEditingController();
PurchaseScreenState(SqliteHelper helper, String app, String userString, String card) { PurchaseScreenState(SqliteHelper helper, String app, String userString, String card) : super(helper, app) {
this.user = JSON.decode(userString); this.user = JSON.decode(userString);
this.card = card; this.card = card;
this.helper = helper;
this.app = app;
} }
@override @override
@@ -45,7 +43,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
setState(() { setState(() {
requestAsyncData(user); requestAsyncData(user);
}); });
return new WillPopScope(onWillPop: onWillPop, child: getMainWidget()); return getMainWidget();
} }
bool purchaseInProgress = false; bool purchaseInProgress = false;
@@ -173,15 +171,14 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
height: buttonHeight, height: buttonHeight,
child: new FlatButton( child: new FlatButton(
child: new Text(title, style: new TextStyle(color: textColor)), child: new Text(title, style: new TextStyle(color: textColor)),
onPressed: () => startScanner(context, app, helper)), // FIXME: onPressed: () => startScanner(context, app, helper)),
onPressed: () => print('startScanner')),
decoration: new BoxDecoration( decoration: new BoxDecoration(
border: new Border.all( border: new Border.all(
color: Resources.getButtonColor(app), width: 1.0), color: Resources.getButtonColor(app), width: 1.0),
borderRadius: new BorderRadius.all(new Radius.circular(4.0)))); borderRadius: new BorderRadius.all(new Radius.circular(4.0))));
} }
@override @override
String getTitle() { String getTitle() {
return StringsLocalization.carryingPurchase(); return StringsLocalization.carryingPurchase();
@@ -424,7 +421,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
print('bonus ' + this.bonus); print('bonus ' + this.bonus);
} }
onWillPop() { // onWillPop() {
return startScanner(context, app, helper); // return startScanner(context, app, helper);
} // }
} }

View File

@@ -26,11 +26,9 @@ class PurchaseSuccessScreenState<T> extends BaseState<PurchaseSuccessScreen> {
PurchaseSuccessScreenState( PurchaseSuccessScreenState(
String sum, String username, SqliteHelper helper, String sum, String username, SqliteHelper helper,
String app, Map details, List<Map> coupons String app, Map details, List<Map> coupons
){ ) : super(helper, app) {
this.sum = sum; this.sum = sum;
this.username = username; this.username = username;
this.helper = helper;
this.app = app;
this.details = details; this.details = details;
this.coupons = coupons; this.coupons = coupons;
} }
@@ -131,7 +129,8 @@ class PurchaseSuccessScreenState<T> extends BaseState<PurchaseSuccessScreen> {
getScanButton() { getScanButton() {
String title = StringsLocalization.scan(); String title = StringsLocalization.scan();
return buildRaisedButton(title, () => startScanner(context, app, helper)); // FIXME: return buildRaisedButton(title, () => startScanner(context, app, helper));
return buildRaisedButton(title, () => print('startScanner'));
} }

View File

@@ -20,10 +20,8 @@ class RegistrationScreen extends BaseScreen {
} }
class RegistrationScreenState extends BaseState<RegistrationScreen> { class RegistrationScreenState extends BaseState<RegistrationScreen> {
RegistrationScreenState(SqliteHelper helper, String app) {
this.helper = helper; RegistrationScreenState(SqliteHelper helper, String app) : super(helper, app);
this.app = app;
}
@override @override
Widget build(BuildContext ctx) { Widget build(BuildContext ctx) {

View File

@@ -36,9 +36,7 @@ class SettingsState extends BaseState<SettingsScreen> {
bool returnToScanner; bool returnToScanner;
SettingsState(SqliteHelper helper, String app, bool returnToScanner) { SettingsState(SqliteHelper helper, String app, bool returnToScanner) : super(helper, app) {
this.helper = helper;
this.app = app;
this.returnToScanner = returnToScanner; this.returnToScanner = returnToScanner;
} }
@@ -55,7 +53,7 @@ class SettingsState extends BaseState<SettingsScreen> {
info['token'] == null ? '' : getTokenSuffix(info['token']); info['token'] == null ? '' : getTokenSuffix(info['token']);
}); });
}); });
return new WillPopScope(onWillPop: onWillPop, child: getMainWidget()); return getMainWidget();
} }
String getTokenSuffix(String token) { String getTokenSuffix(String token) {
@@ -159,11 +157,11 @@ class SettingsState extends BaseState<SettingsScreen> {
return StringsLocalization.settings(); return StringsLocalization.settings();
} }
onWillPop() { // onWillPop() {
if (returnToScanner) { // if (returnToScanner) {
return startScanner(context, app, helper); // return startScanner(context, app, helper);
} else { // } else {
return true; // return true;
} // }
} // }
} }

View File

@@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:checker/base/base_screen.dart';
import 'package:checker/base/base_state.dart'; import 'package:checker/base/base_state.dart';
import 'package:checker/common.dart'; import 'package:checker/common.dart';
import 'package:checker/consts.dart'; import 'package:checker/consts.dart';
@@ -8,91 +9,37 @@ import 'package:checker/db.dart';
import 'package:checker/network.dart'; import 'package:checker/network.dart';
import 'package:checker/resources.dart'; import 'package:checker/resources.dart';
import 'package:checker/screens/finish_registration.dart'; import 'package:checker/screens/finish_registration.dart';
import 'package:checker/screens/purchase.dart';
import 'package:checker/screens/registration.dart'; import 'package:checker/screens/registration.dart';
import 'package:checker/screens/settings.dart';
import 'package:checker/strings.dart'; import 'package:checker/strings.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
class SplashScreen extends StatefulWidget { class SplashScreen extends BaseScreen {
SplashScreen(SqliteHelper helper, String app) : super(helper, app);
@override @override
State createState() => new _SplashScreenState(); State createState() => new _SplashScreenState(helper, app);
} }
class _SplashScreenState extends BaseState<SplashScreen> { class _SplashScreenState extends BaseState<SplashScreen> {
_SplashScreenState(SqliteHelper helper, String app) : super(helper, app);
@override @override
Widget build(BuildContext ctx) { 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(locale);
}
});
}
void initWithSystemValue() {
platform.invokeMethod('getLocale').then((locale) {
helper.getSettings(false).then((settings) {
if (settings == null) {
createSettingsTable(locale);
} else {
initLocale(locale, () {
showNext();
});
}
});
});
}
void initWithSavedValue(String locale) {
initLocale(locale, () {
showNext();
});
}
void createSettingsTable(String locale) {
platform.invokeMethod('getCurrency').then((currency) {
helper.createAppInfo(currency);
initLocale(locale, () {
showNext();
});
});
}
void initLocale<T>(String locale, Future<T> onValue()) {
StringsLocalization.load(locale).then((_) {
onValue();
});
}
void showNext() {
new Future.delayed(const Duration(milliseconds: 1000), () { new Future.delayed(const Duration(milliseconds: 1000), () {
showNextScreen(); showNextScreen();
}); });
return getScreenContent();
} }
@override @override
Widget getScreenContent() { Widget getScreenContent() {
return app == null return new Stack(children: <Widget>[
? getBackground()
: new Stack(children: <Widget>[
getBackground(), getBackground(),
getLogo(), getLogo(),
new Align( new Align(
@@ -148,7 +95,9 @@ class _SplashScreenState extends BaseState<SplashScreen> {
bool active = status['active'] == null ? false : status['active']; bool active = status['active'] == null ? false : status['active'];
if (active) { if (active) {
startScanner(context, app, helper); helper.getToken().then((token) {
_initAndStartScanner(context, app, token, helper);
});
} else { } else {
if (await platform.invokeMethod('isOnline')) { if (await platform.invokeMethod('isOnline')) {
_createToken(helper); _createToken(helper);
@@ -193,4 +142,101 @@ class _SplashScreenState extends BaseState<SplashScreen> {
}); });
}); });
} }
/// Запуск спецефичной для каждой платформы части приложения - сканера.
/// Может производиться с нескольких экранов (splash, finish_registration).
_initAndStartScanner(BuildContext context, String app, String token,
SqliteHelper helper) {
// Канал ловит вызовы методов из "нативной" части приложения.
// Могут быть вызваны либо exit либо faq, либо purchase.
platform.setMethodCallHandler((MethodCall call) {
if (call.method == 'findUser') {
String cardPhone = call.arguments[0];
var userResponse = getUser(call.arguments[1], cardPhone, token);
if (userResponse != null) {
userResponse.then((response) {
List<Map> users;
try {
users = JSON.decode(response.body);
} catch (error) {
print(error);
} }
if (users.length > 0) {
return users[0];
} else {
throw new FlutterError("Users not found");
}
});
}
} else if (call.method == 'faq') {
faq(helper, app, context, true);
} else if (call.method == 'settings') {
pushRoute(context, new SettingsScreen(helper, app, true));
} else {
String userString;
if (call.arguments[0] is String) {
userString = call.arguments[0];
} else {
userString = JSON.encode(call.arguments[0]);
}
print(userString);
String card = call.arguments[1];
print('$userString, $card');
new Future.delayed(const Duration(milliseconds: 200), () {
var route = new MaterialPageRoute<bool>(
builder: (BuildContext context) => new PurchaseScreen(helper, app, userString, card),
fullscreenDialog: true);
Navigator.of(context).push(route).then((b) {
if (b) {
setState(() {
print('restart scanner!');
});
}
});
});
}
});
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);
});
});
}
Future<Response> getUser(String type, String cardPhone, String token) {
try {
switch (type) {
case 'card':
return getUserByCard(cardPhone, token);
break;
case 'phone':
return getUserByPhone(cardPhone, token);
break;
default:
return null;
}
} catch (error) {
print(error.toString());
return null;
}
}
}