Сделал возможность переключаться между приложениями и добавлять новые приложения практически не меняя код
This commit is contained in:
13
README.md
13
README.md
@@ -1 +1,12 @@
|
|||||||
Кроссплатформенное приложение AUTOBONUS для Dinect.
|
Приложение Checker.
|
||||||
|
|
||||||
|
Для запуска необходимо установить [Dart](https://www.dartlang.org/install) - язык программирования и
|
||||||
|
[flutter](https://flutter.io/setup/) - фреймворк для создания кроссплатформенных мобильных приложений на этом языке.
|
||||||
|
|
||||||
|
# Перед тем, как собирать приложение, необходимо в файле lib/consts.dart установить правильное значение appName. Для автоклуба - это AutoBonus.
|
||||||
|
|
||||||
|
Для сборки и запуска приложения используются команды flutter run (собирает debug apk, устанавливает его на устройство) и
|
||||||
|
flutter build (собирает release apk, не устанавливает на устрйоство).
|
||||||
|
|
||||||
|
Команды run и build необходимо выполнять с опцией --flavor, чтобы apk файл собирался с необходимыми ресурсами и настройками.
|
||||||
|
Название конкретной flavor передается в аргументе. Все flavors перечислены в файле android/app/build.gradle.
|
||||||
@@ -38,29 +38,66 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Не смог разобраться, как коомбинировать flavors в flutter при запуске
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
|
||||||
en {
|
autobonus_en {
|
||||||
|
applicationId 'com.dinect.autobonus'
|
||||||
buildConfigField "String", "locale", "\"en\""
|
buildConfigField "String", "locale", "\"en\""
|
||||||
|
buildConfigField "String", "flavor", "\"autobonus\""
|
||||||
}
|
}
|
||||||
|
|
||||||
ru {
|
autobonus_ru {
|
||||||
|
applicationId 'com.dinect.autobonus'
|
||||||
buildConfigField "String", "locale", "\"ru\""
|
buildConfigField "String", "locale", "\"ru\""
|
||||||
|
buildConfigField "String", "flavor", "\"autobonus\""
|
||||||
}
|
}
|
||||||
|
|
||||||
ua {
|
autobonus_ua {
|
||||||
|
applicationId 'com.dinect.autobonus'
|
||||||
buildConfigField "String", "locale", "\"ua\""
|
buildConfigField "String", "locale", "\"ua\""
|
||||||
|
buildConfigField "String", "flavor", "\"autobonus\""
|
||||||
}
|
}
|
||||||
|
|
||||||
pip {
|
pip_en {
|
||||||
buildConfigField "String", "primary_color", "\"#008794\""
|
applicationId 'com.dinect.pip'
|
||||||
buildConfigField "String", "accent_color", "\"#f49935\""
|
buildConfigField "String", "locale", "\"en\""
|
||||||
|
buildConfigField "String", "flavor", "\"pip\""
|
||||||
|
}
|
||||||
|
|
||||||
|
pip_ru {
|
||||||
|
applicationId 'com.dinect.pip'
|
||||||
|
buildConfigField "String", "locale", "\"ru\""
|
||||||
|
buildConfigField "String", "flavor", "\"pip\""
|
||||||
|
}
|
||||||
|
|
||||||
|
pip_ua {
|
||||||
|
applicationId 'com.dinect.pip'
|
||||||
|
buildConfigField "String", "locale", "\"ua\""
|
||||||
|
buildConfigField "String", "flavor", "\"pip\""
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets.main {
|
sourceSets {
|
||||||
jniLibs.srcDir 'jniLibs'
|
|
||||||
|
main.jniLibs.srcDir 'jniLibs'
|
||||||
|
|
||||||
|
pip_ua {
|
||||||
|
res.srcDirs = ['src/pip/res']
|
||||||
|
manifest.srcFile 'src/pip/AndroidManifest.xml'
|
||||||
|
}
|
||||||
|
|
||||||
|
pip_ru {
|
||||||
|
res.srcDirs = ['src/pip/res']
|
||||||
|
manifest.srcFile 'src/pip/AndroidManifest.xml'
|
||||||
|
}
|
||||||
|
|
||||||
|
pip_en {
|
||||||
|
res.srcDirs = ['src/pip/res']
|
||||||
|
manifest.srcFile 'src/pip/AndroidManifest.xml'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +107,7 @@ flutter {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
compile 'com.android.support:appcompat-v7:25.0.0'
|
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||||
compile 'com.squareup.okhttp3:okhttp:3.8.1'
|
compile 'com.squareup.okhttp3:okhttp:3.8.1'
|
||||||
compile 'com.squareup.okio:okio:1.13.0'
|
compile 'com.squareup.okio:okio:1.13.0'
|
||||||
compile 'me.dm7.barcodescanner:zxing:1.9.7'
|
compile 'me.dm7.barcodescanner:zxing:1.9.7'
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import android.view.View;
|
|||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.dinect.checker.net.ApiClient;
|
import com.dinect.checker.net.ApiClient;
|
||||||
|
|
||||||
@@ -59,7 +60,9 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
|
|||||||
"Перестань!",
|
"Перестань!",
|
||||||
"Ну и зачем?..",
|
"Ну и зачем?..",
|
||||||
};
|
};
|
||||||
|
|
||||||
private final AtomicInteger counter = new AtomicInteger(0);
|
private final AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
private int mColor;
|
||||||
|
|
||||||
public static final String SCAN_MODES = "SCAN_MODES";
|
public static final String SCAN_MODES = "SCAN_MODES";
|
||||||
public static final String ERROR_INFO = "ERROR_INFO";
|
public static final String ERROR_INFO = "ERROR_INFO";
|
||||||
@@ -115,6 +118,8 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
|
|||||||
protected final void initToolbar(final int toolbarId, final @NonNull String title) {
|
protected final void initToolbar(final int toolbarId, final @NonNull String title) {
|
||||||
Log.d(TAG, "initToolbar");
|
Log.d(TAG, "initToolbar");
|
||||||
final Toolbar toolbar = (Toolbar) findViewById(toolbarId);
|
final Toolbar toolbar = (Toolbar) findViewById(toolbarId);
|
||||||
|
mColor = (int) getIntent().getLongExtra(MainActivity.PREF_APP_BAR_COLOR, 0xffffff);
|
||||||
|
toolbar.setBackgroundColor(mColor);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
final ActionBar actionBar = getSupportActionBar();
|
final ActionBar actionBar = getSupportActionBar();
|
||||||
@@ -295,7 +300,7 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == R.id.logout) {
|
if (item.getItemId() == R.id.logout) {
|
||||||
logoutDialog = new AbstractScannerActivity.LogoutDialogFragment();
|
logoutDialog = LogoutDialogFragment.newInstance(mColor);
|
||||||
logoutDialog.show(getFragmentManager(), "logout");
|
logoutDialog.show(getFragmentManager(), "logout");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.faq) {
|
} else if (item.getItemId() == R.id.faq) {
|
||||||
@@ -324,14 +329,25 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
public static class LogoutDialogFragment extends DialogFragment {
|
public static class LogoutDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
static LogoutDialogFragment newInstance(int color) {
|
||||||
|
LogoutDialogFragment f = new LogoutDialogFragment();
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putInt(MainActivity.PREF_APP_BAR_COLOR, color);
|
||||||
|
f.setArguments(bundle);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
final LayoutInflater inflater = getActivity().getLayoutInflater();
|
final LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||||
final View content = inflater.inflate(R.layout.f_logout_dialog, null);
|
final View content = inflater.inflate(R.layout.f_logout_dialog, null);
|
||||||
builder.setView(content);
|
builder.setView(content);
|
||||||
final View positiveButton = content.findViewById(R.id.positiveButton);
|
final TextView positiveButton = (TextView) content.findViewById(R.id.positiveButton);
|
||||||
final View negativeButton = content.findViewById(R.id.negativeButton);
|
final TextView negativeButton = (TextView) content.findViewById(R.id.negativeButton);
|
||||||
|
// Можно делать через стили, но я не уверен, что необходимо в нашем случае
|
||||||
|
positiveButton.setTextColor(getArguments().getInt(MainActivity.PREF_APP_BAR_COLOR));
|
||||||
|
negativeButton.setTextColor(getArguments().getInt(MainActivity.PREF_APP_BAR_COLOR));
|
||||||
|
|
||||||
negativeButton.setOnClickListener(new View.OnClickListener() {
|
negativeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,12 +29,14 @@ public class MainActivity extends FlutterActivity {
|
|||||||
static final String TAG = "Checker.MainActivity";
|
static final String TAG = "Checker.MainActivity";
|
||||||
|
|
||||||
private static final int START_SCANNER_REQUEST_CODE = 2017;
|
private static final int START_SCANNER_REQUEST_CODE = 2017;
|
||||||
|
|
||||||
private static final String PREF_POS_MERCHANT_ID = "pref_pos_merchant_id";
|
private static final String PREF_POS_MERCHANT_ID = "pref_pos_merchant_id";
|
||||||
private static final String PREF_DOC_ID = "pref_doc_id";
|
private static final String PREF_DOC_ID = "pref_doc_id";
|
||||||
private static final String PREF_POS_ID = "pref_pos_id";
|
private static final String PREF_POS_ID = "pref_pos_id";
|
||||||
static final String PREF_API_URL = "prefs_api_token";
|
static final String PREF_API_URL = "prefs_api_token";
|
||||||
static final String PREF_APP_TOKEN = "pres_app_token";
|
static final String PREF_APP_TOKEN = "pres_app_token";
|
||||||
static final String PREF_POS_TOKEN = "pref_pos_token";
|
static final String PREF_POS_TOKEN = "pref_pos_token";
|
||||||
|
static final String PREF_APP_BAR_COLOR = "pref_app_bar_color";
|
||||||
|
|
||||||
static final Class[] SCANNER_BACKEND = {
|
static final Class[] SCANNER_BACKEND = {
|
||||||
ScannerActivity.class,
|
ScannerActivity.class,
|
||||||
@@ -77,6 +79,9 @@ public class MainActivity extends FlutterActivity {
|
|||||||
case "getLocale":
|
case "getLocale":
|
||||||
result.success(BuildConfig.locale);
|
result.success(BuildConfig.locale);
|
||||||
break;
|
break;
|
||||||
|
case "getFlavor":
|
||||||
|
result.success(BuildConfig.flavor);
|
||||||
|
break;
|
||||||
case "getMerchantID":
|
case "getMerchantID":
|
||||||
result.success(mPreferences.getString(PREF_POS_MERCHANT_ID, null));
|
result.success(mPreferences.getString(PREF_POS_MERCHANT_ID, null));
|
||||||
break;
|
break;
|
||||||
@@ -88,6 +93,7 @@ public class MainActivity extends FlutterActivity {
|
|||||||
cameraIntent.putExtra(PREF_API_URL, (String) arguments.get("url"));
|
cameraIntent.putExtra(PREF_API_URL, (String) arguments.get("url"));
|
||||||
cameraIntent.putExtra(PREF_APP_TOKEN, (String) arguments.get("appToken"));
|
cameraIntent.putExtra(PREF_APP_TOKEN, (String) arguments.get("appToken"));
|
||||||
cameraIntent.putExtra(PREF_POS_TOKEN, (String) arguments.get("token"));
|
cameraIntent.putExtra(PREF_POS_TOKEN, (String) arguments.get("token"));
|
||||||
|
cameraIntent.putExtra(PREF_APP_BAR_COLOR, (Long) arguments.get("color"));
|
||||||
startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE);
|
startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE);
|
||||||
break;
|
break;
|
||||||
case "removeKeys":
|
case "removeKeys":
|
||||||
@@ -172,6 +178,10 @@ public class MainActivity extends FlutterActivity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getFlavor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void getLocale() {
|
public void getLocale() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:background="#eb0004"
|
|
||||||
app:titleTextColor="@android:color/white" />
|
app:titleTextColor="@android:color/white" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
android:id="@+id/zxingToolbar"
|
android:id="@+id/zxingToolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:background="#eb0004"
|
|
||||||
app:titleTextColor="@android:color/white" />
|
app:titleTextColor="@android:color/white" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
3
android/app/src/pip/res/values-ru/strings.xml
Normal file
3
android/app/src/pip/res/values-ru/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">PIP</string>
|
||||||
|
</resources>
|
||||||
3
android/app/src/pip/res/values-ua/strings.xml
Normal file
3
android/app/src/pip/res/values-ua/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">PIP</string>
|
||||||
|
</resources>
|
||||||
3
android/app/src/pip/res/values/strings.xml
Normal file
3
android/app/src/pip/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">PIP</string>
|
||||||
|
</resources>
|
||||||
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 359 KiB |
BIN
assets/pip_splash.png
Normal file
BIN
assets/pip_splash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 273 B |
@@ -1,7 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:checker/resources.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
import 'consts.dart';
|
import 'consts.dart';
|
||||||
@@ -9,6 +11,9 @@ import 'strings.dart';
|
|||||||
|
|
||||||
abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
||||||
|
|
||||||
|
/// Тип сборки. Определяет, какие брать ресурсы (цвета, картинки)
|
||||||
|
String app;
|
||||||
|
|
||||||
/// Ожидание ответа от сервера.
|
/// Ожидание ответа от сервера.
|
||||||
bool loading = false;
|
bool loading = false;
|
||||||
|
|
||||||
@@ -19,13 +24,42 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
String textFieldValue = '';
|
String textFieldValue = '';
|
||||||
|
|
||||||
@override Widget build(BuildContext ctx) {
|
@override Widget build(BuildContext ctx) {
|
||||||
return new Scaffold(appBar: getAppBar(),
|
|
||||||
|
platform.invokeMethod('getLocale').then((locale) {
|
||||||
|
Intl.defaultLocale = locale;
|
||||||
|
if (app == null) {
|
||||||
|
platform.invokeMethod('getFlavor').then((flavor) {
|
||||||
|
setState(() {
|
||||||
|
app = flavor;
|
||||||
|
onStart();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return getMainWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget getMainWidget() {
|
||||||
|
return app == null ? getBackground() : 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)
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget getBackground() {
|
||||||
|
return new Container(
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
image: new DecorationImage(
|
||||||
|
image: new ExactAssetImage(Resources.getSplash(app)),
|
||||||
|
fit: BoxFit.cover)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void onStart() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// Возвращает контейнер с всеми виджетами экрана.
|
/// Возвращает контейнер с всеми виджетами экрана.
|
||||||
Widget getScreenContent();
|
Widget getScreenContent();
|
||||||
|
|
||||||
@@ -34,7 +68,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
|
|
||||||
AppBar getAppBar() {
|
AppBar getAppBar() {
|
||||||
return new AppBar(title: new Text(getTitle(), style: new TextStyle(fontSize: 18.0)),
|
return new AppBar(title: new Text(getTitle(), style: new TextStyle(fontSize: 18.0)),
|
||||||
backgroundColor: primaryColor, actions: getMenuButtons());
|
backgroundColor: Resources.getPrimaryColor(app), actions: getMenuButtons());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> getMenuButtons() {
|
List<Widget> getMenuButtons() {
|
||||||
@@ -55,7 +89,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
return new Container(margin: new EdgeInsets.only(top: horizontalMargin, bottom: horizontalMargin, left: verticalMargin, right: verticalMargin),
|
return new Container(margin: new EdgeInsets.only(top: horizontalMargin, bottom: horizontalMargin, left: verticalMargin, right: verticalMargin),
|
||||||
child: new Row(crossAxisAlignment: CrossAxisAlignment.start,
|
child: new Row(crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[new Text(getHintString(), textAlign: TextAlign.left,
|
children: <Widget>[new Text(getHintString(), textAlign: TextAlign.left,
|
||||||
style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : primaryColor, fontSize: 14.0))]));
|
style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : Resources.getLogo(app), fontSize: 14.0))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны.
|
/// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны.
|
||||||
@@ -118,14 +152,14 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
|
|||||||
return new RaisedButton(child: new Text(text,
|
return new RaisedButton(child: new Text(text,
|
||||||
style: new TextStyle(color: Colors.white)),
|
style: new TextStyle(color: Colors.white)),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
color: buttonColor);
|
color: Resources.getButtonColor(app));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Метод возвращает контейнер с отступами, который содержит картинку с логотипом.
|
/// Метод возвращает контейнер с отступами, который содержит картинку с логотипом.
|
||||||
Widget getLogo() {
|
Widget getLogo() {
|
||||||
double containerHeight = 92.0;
|
double containerHeight = 92.0;
|
||||||
double imageWidth = 156.0;
|
double imageWidth = 156.0;
|
||||||
return new Container(height: containerHeight, child: new Image.asset(logo_png, width: imageWidth));
|
return new Container(height: containerHeight, child: new Image.asset(Resources.getLogo(app), width: imageWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Возвращает текстовое поле, с однострочным пояснением над ним.
|
/// Возвращает текстовое поле, с однострочным пояснением над ним.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'consts.dart';
|
import 'consts.dart';
|
||||||
import 'network.dart';
|
import 'network.dart';
|
||||||
|
import 'resources.dart';
|
||||||
import 'package:checker/registration.dart';
|
import 'package:checker/registration.dart';
|
||||||
import 'package:checker/purchase.dart';
|
import 'package:checker/purchase.dart';
|
||||||
import 'faq.dart';
|
import 'faq.dart';
|
||||||
@@ -62,7 +63,7 @@ forceLogout(BuildContext context) async {
|
|||||||
|
|
||||||
/// Запуск спецефичной для каждой платформы части приложения - сканера.
|
/// Запуск спецефичной для каждой платформы части приложения - сканера.
|
||||||
/// Может производиться с нескольких экранов (splash, finish_registration).
|
/// Может производиться с нескольких экранов (splash, finish_registration).
|
||||||
startScanner(BuildContext context) async {
|
startScanner(BuildContext context, String app) async {
|
||||||
|
|
||||||
String token = await platform.invokeMethod('getToken');
|
String token = await platform.invokeMethod('getToken');
|
||||||
// Канал ловит вызовы методов из "нативной" части приложения.
|
// Канал ловит вызовы методов из "нативной" части приложения.
|
||||||
@@ -88,6 +89,7 @@ startScanner(BuildContext context) async {
|
|||||||
'token' : token,
|
'token' : token,
|
||||||
'url': url,
|
'url': url,
|
||||||
'appToken': appToken,
|
'appToken': appToken,
|
||||||
|
'color': Resources.getPrimaryColor(app).value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
// Serious constants
|
// Serious constants
|
||||||
const String appName = "Dinect";
|
const String appName = "AutoBonus";
|
||||||
|
|
||||||
const String url = 'https://pos-api-int.dinect.com/20130701/';
|
const String url = 'https://pos-api-int.dinect.com/20130701/';
|
||||||
const String appToken = '9fec83cdca38c357e6b65dbb17514cdd36bf2a08';
|
const String appToken = '9fec83cdca38c357e6b65dbb17514cdd36bf2a08';
|
||||||
|
|
||||||
// Assets
|
// Assets
|
||||||
const String logo_png = 'assets/pip_logo.png';
|
|
||||||
const String splash_png = 'assets/splash.png';
|
|
||||||
const String logout_png = 'assets/logout.png';
|
const String logout_png = 'assets/logout.png';
|
||||||
const String activate_token_bg_png = 'assets/activate_token_message_background.png';
|
const String activate_token_bg_png = 'assets/activate_token_message_background.png';
|
||||||
const String active_token_bg_png = 'assets/active_token_message_background.png';
|
const String active_token_bg_png = 'assets/active_token_message_background.png';
|
||||||
@@ -17,12 +15,6 @@ const String powered_by_dinect_splash_png = 'assets/powered_by_dinect_splash.png
|
|||||||
const String powered_by_dinect_png = 'assets/powered_by_dinect.png';
|
const String powered_by_dinect_png = 'assets/powered_by_dinect.png';
|
||||||
const String splash_text_png = 'assets/splash_text.png';
|
const String splash_text_png = 'assets/splash_text.png';
|
||||||
|
|
||||||
// Colors
|
|
||||||
//const Color primaryColor = const Color(0xffeb0004);
|
|
||||||
//const Color buttonColor = const Color(0xffeb0004);
|
|
||||||
|
|
||||||
const Color primaryColor = const Color(0xff008794);
|
|
||||||
const Color buttonColor = const Color(0xfff49935);
|
|
||||||
const Color greyTextColor = const Color(0xffa5a5a5);
|
const Color greyTextColor = const Color(0xffa5a5a5);
|
||||||
const Color textBorderColor = const Color(0xffcfd8dc);
|
const Color textBorderColor = const Color(0xffcfd8dc);
|
||||||
const Color tokenActiveTextColor = const Color(0xff1f5a1f);
|
const Color tokenActiveTextColor = const Color(0xff1f5a1f);
|
||||||
@@ -31,6 +23,7 @@ const Color greenBackground = const Color(0xff8ae28a);
|
|||||||
const Color faqGrey = const Color(0xff5b5b5b);
|
const Color faqGrey = const Color(0xff5b5b5b);
|
||||||
const Color faqTitlesColor = const Color(0xff404040);
|
const Color faqTitlesColor = const Color(0xff404040);
|
||||||
const Color inputFieldBackground = const Color(0xffefefef);
|
const Color inputFieldBackground = const Color(0xffefefef);
|
||||||
|
|
||||||
// Dimens
|
// Dimens
|
||||||
const double verticalMargin = 28.0;
|
const double verticalMargin = 28.0;
|
||||||
const double buttonHeight = 48.0;
|
const double buttonHeight = 48.0;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class FAQScreenState<T> extends BaseState<FAQScreen> {
|
|||||||
|
|
||||||
onWillPop() {
|
onWillPop() {
|
||||||
if(returnToScanner) {
|
if(returnToScanner) {
|
||||||
return startScanner(context);
|
return startScanner(context, app);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
|||||||
// Если нет, то отправляется запрос на проверку статуса токена.
|
// Если нет, то отправляется запрос на проверку статуса токена.
|
||||||
handleTap() async {
|
handleTap() async {
|
||||||
if (_tokenActive) {
|
if (_tokenActive) {
|
||||||
startScanner(context);
|
startScanner(context, app);
|
||||||
} else {
|
} else {
|
||||||
if (await platform.invokeMethod('isOnline')) {
|
if (await platform.invokeMethod('isOnline')) {
|
||||||
String token = await platform.invokeMethod('getToken');
|
String token = await platform.invokeMethod('getToken');
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import 'package:flutter/services.dart';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
import 'package:checker/strings.dart';
|
import 'resources.dart';
|
||||||
import 'package:checker/common.dart';
|
import 'strings.dart';
|
||||||
import 'package:checker/consts.dart';
|
import 'common.dart';
|
||||||
import 'package:checker/network.dart';
|
import 'consts.dart';
|
||||||
import 'package:checker/base_state.dart';
|
import 'network.dart';
|
||||||
import 'package:checker/purchase_success.dart';
|
import 'base_state.dart';
|
||||||
|
import 'purchase_success.dart';
|
||||||
|
|
||||||
/// Экран проведения покупки.
|
/// Экран проведения покупки.
|
||||||
class PurchaseScreen extends StatefulWidget {
|
class PurchaseScreen extends StatefulWidget {
|
||||||
@@ -48,7 +49,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
getHintLabel(),
|
getHintLabel(),
|
||||||
getInputField(),
|
getInputField(),
|
||||||
wrapButton(getScreenMargins(36.0), getCompleteButton()),
|
wrapButton(getScreenMargins(36.0), getCompleteButton()),
|
||||||
wrapButton(getScreenMargins(24.0), getScanButton(context, StringsLocalization.scan(), primaryColor))
|
wrapButton(getScreenMargins(24.0), getScanButton(context, StringsLocalization.scan(), Resources.getPrimaryColor(app)))
|
||||||
]))]);
|
]))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,16 +63,16 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget getScanButton(BuildContext context, String title, Color textColor) {
|
Widget getScanButton(BuildContext context, String title, Color textColor) {
|
||||||
return new Container(height: buttonHeight, child: new FlatButton(child: new Text(title,
|
return new Container(
|
||||||
|
height: buttonHeight,
|
||||||
|
child: new FlatButton(
|
||||||
|
child: new Text(
|
||||||
|
title,
|
||||||
style: new TextStyle(color: textColor)),
|
style: new TextStyle(color: textColor)),
|
||||||
onPressed: () => startScanner(context)),
|
onPressed: () => startScanner(context, app)),
|
||||||
decoration: getDecorationForScanButton());
|
decoration: new BoxDecoration(
|
||||||
}
|
border: new Border.all(color: Resources.getButtonColor(app), width: 1.0),
|
||||||
|
borderRadius: new BorderRadius.all(new Radius.circular(4.0))));
|
||||||
getDecorationForScanButton() {
|
|
||||||
return new BoxDecoration(
|
|
||||||
border: new Border.all(color: buttonColor, width: 1.0),
|
|
||||||
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override String getTitle() {
|
@override String getTitle() {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class PurchaseSuccessScreenState<T> extends BaseState<PurchaseSuccessScreen> {
|
|||||||
|
|
||||||
getScanButton() {
|
getScanButton() {
|
||||||
String title = StringsLocalization.scan();
|
String title = StringsLocalization.scan();
|
||||||
return buildRaisedButton(title, () => startScanner(context));
|
return buildRaisedButton(title, () => startScanner(context, app));
|
||||||
}
|
}
|
||||||
|
|
||||||
getSuccessMessage() {
|
getSuccessMessage() {
|
||||||
|
|||||||
28
lib/resources.dart
Normal file
28
lib/resources.dart
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class Resources {
|
||||||
|
|
||||||
|
static String getLogo(String app) {
|
||||||
|
return app == null ? null : 'assets/${app}_logo.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getSplash(String app) {
|
||||||
|
return 'assets/${app != null ? app : 'pip'}_splash.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color getPrimaryColor(String app) {
|
||||||
|
switch (app) {
|
||||||
|
case 'pip': return new Color(0xff008794);
|
||||||
|
case 'autobonus': return new Color(0xffeb0004);
|
||||||
|
default: return new Color(0xffffffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color getButtonColor(String app) {
|
||||||
|
switch (app) {
|
||||||
|
case 'pip': return new Color(0xfff49935);
|
||||||
|
case 'autobonus': return new Color(0xffeb0004);
|
||||||
|
default: return new Color(0xffffffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +1,70 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:async';
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
import 'network.dart';
|
import 'network.dart';
|
||||||
import 'consts.dart';
|
import 'consts.dart';
|
||||||
import 'registration.dart';
|
import 'registration.dart';
|
||||||
import 'finish_registration.dart';
|
import 'finish_registration.dart';
|
||||||
import 'strings.dart';
|
import 'resources.dart';
|
||||||
|
import 'base_state.dart';
|
||||||
|
|
||||||
class SplashScreen extends StatelessWidget {
|
class SplashScreen extends StatefulWidget {
|
||||||
|
@override State createState() => new _SplashScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SplashScreenState extends BaseState<SplashScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget getScreenContent() {
|
||||||
// Появляется splash screen, проверяется токен.
|
return app == null
|
||||||
|
? getBackground()
|
||||||
|
: 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)))]);
|
||||||
|
}
|
||||||
|
|
||||||
new Future.delayed(const Duration(milliseconds: 500), () {
|
@override Widget getMainWidget() {
|
||||||
platform.invokeMethod("getLocale").then((locale) {
|
return getScreenContent();
|
||||||
Intl.defaultLocale = locale;
|
}
|
||||||
print(Intl.defaultLocale);
|
|
||||||
// showNextScreen(context);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Stack(children: <Widget>[getSplashBackground(), getLogo(),
|
@override
|
||||||
new Align(alignment: FractionalOffset.bottomRight, child:
|
String getTitle() {
|
||||||
new Container(margin: new EdgeInsets.only(right: 11.0, bottom: 5.0), child:
|
return null;
|
||||||
new Image.asset(powered_by_dinect_splash_png, height: 16.0, width: 122.0)))]);
|
}
|
||||||
|
|
||||||
|
@override void onStart() {
|
||||||
|
new Future.delayed(const Duration(milliseconds: 1000), () {
|
||||||
|
showNextScreen(context);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Возвращает столбец с логотипом приложения и текстом под ним.
|
/// Возвращает столбец с логотипом приложения и текстом под ним.
|
||||||
/// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана.
|
/// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана.
|
||||||
getLogo() {
|
getLogo() {
|
||||||
return new Center(child: new Column(mainAxisSize: MainAxisSize.min,
|
return new Center(
|
||||||
children: <Widget>[new Image.asset(logo_png, height: 112.0, width: 252.0),
|
child: new Column(
|
||||||
new Image.asset(splash_text_png, height: 40.0, width: 240.0)]));
|
mainAxisSize: MainAxisSize.min,
|
||||||
}
|
children: <Widget>[
|
||||||
|
new Image.asset(
|
||||||
/// Возвращает контейнер, который содержит decoration с фоновым изображением.
|
Resources.getLogo(app),
|
||||||
getSplashBackground() {
|
height: 112.0,
|
||||||
return new Container(decoration:
|
width: 252.0),
|
||||||
new BoxDecoration(image:
|
new Image.asset(
|
||||||
new DecorationImage(image: new ExactAssetImage(splash_png), fit: BoxFit.cover)));
|
splash_text_png,
|
||||||
|
height: 40.0,
|
||||||
|
width: 240.0)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Запуск следующего экрана приложения.
|
/// Запуск следующего экрана приложения.
|
||||||
@@ -85,7 +106,7 @@ class SplashScreen extends StatelessWidget {
|
|||||||
bool active = status['active'] == null ? false : status['active'];
|
bool active = status['active'] == null ? false : status['active'];
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
startScanner(context);
|
startScanner(context, app);
|
||||||
} else {
|
} else {
|
||||||
if (await platform.invokeMethod('isOnline')) {
|
if (await platform.invokeMethod('isOnline')) {
|
||||||
_createToken(context);
|
_createToken(context);
|
||||||
|
|||||||
10
pubspec.yaml
10
pubspec.yaml
@@ -23,16 +23,20 @@ flutter:
|
|||||||
# To add assets to your application, add an assets section here, in
|
# To add assets to your application, add an assets section here, in
|
||||||
# this "flutter" section, as in:
|
# this "flutter" section, as in:
|
||||||
assets:
|
assets:
|
||||||
- assets/autoclub_logo.png
|
|
||||||
|
- assets/autobonus_logo.png
|
||||||
- assets/pip_logo.png
|
- assets/pip_logo.png
|
||||||
- assets/splash.png
|
|
||||||
|
- assets/autobonus_splash.png
|
||||||
|
- assets/pip_splash.png
|
||||||
|
|
||||||
- assets/logout.png
|
- assets/logout.png
|
||||||
- assets/activate_token_message_background.png
|
- assets/activate_token_message_background.png
|
||||||
- assets/active_token_message_background.png
|
- assets/active_token_message_background.png
|
||||||
- assets/expansion_icon.png
|
- assets/expansion_icon.png
|
||||||
- assets/powered_by_dinect_splash.png
|
- assets/powered_by_dinect_splash.png
|
||||||
- assets/powered_by_dinect.png
|
- assets/powered_by_dinect.png
|
||||||
- assets/autoclub_logo.png
|
- assets/autobonus_logo.png
|
||||||
- assets/splash_text.png
|
- assets/splash_text.png
|
||||||
|
|
||||||
# To add assets from package dependencies, first ensure the asset
|
# To add assets from package dependencies, first ensure the asset
|
||||||
|
|||||||
Reference in New Issue
Block a user