pre release
parent
2e2033fec1
commit
d3d983ba3f
|
|
@ -47,7 +47,7 @@ android {
|
|||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.example.aman_kassa_flutter"
|
||||
minSdkVersion 16
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 28
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
|
|
|||
|
|
@ -6,9 +6,13 @@
|
|||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="aman_kassa_flutter"
|
||||
android:label="Аман Касса"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
|
|
|
|||
|
|
@ -1,12 +1,83 @@
|
|||
package com.example.aman_kassa_flutter
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build.VERSION
|
||||
import android.os.Build.VERSION_CODES
|
||||
import androidx.annotation.NonNull
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant
|
||||
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
private val CHANNEL = "samples.flutter.dev/battery"
|
||||
|
||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||
GeneratedPluginRegistrant.registerWith(flutterEngine);
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
|
||||
// Note: this method is invoked on the main thread.
|
||||
call, result ->
|
||||
if (call.method == "getBatteryLevel") {
|
||||
val batteryLevel = getBatteryLevel()
|
||||
|
||||
if (batteryLevel != -1) {
|
||||
result.success(batteryLevel)
|
||||
} else {
|
||||
result.error("UNAVAILABLE", "Battery level not available.", null)
|
||||
}
|
||||
} else if (call.method == "sendMessage") {
|
||||
val batteryLevel = sendMessage()
|
||||
|
||||
if (batteryLevel != -1) {
|
||||
result.success(batteryLevel)
|
||||
} else {
|
||||
result.error("UNAVAILABLE", "Battery level not available.", null)
|
||||
}
|
||||
} else {
|
||||
result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBatteryLevel(): Int {
|
||||
val batteryLevel: Int
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
|
||||
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
||||
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
||||
} else {
|
||||
val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||
}
|
||||
println("batteryLevel");
|
||||
println(batteryLevel);
|
||||
return batteryLevel
|
||||
}
|
||||
|
||||
private fun sendMessage(): Int {
|
||||
val packageManager: PackageManager = context.packageManager
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
try {
|
||||
val mobileNo: String = "77774904900" //call.argument("mobileNo")
|
||||
val message: String = "Hello world" //call.argument("message")
|
||||
//https://wa.me/919167370647?text=Yes%20We'll%20do%20this%20in%20frag4%20inOCW
|
||||
println("mobileNo: $mobileNo message: $message")
|
||||
val url = "https://wa.me/" + mobileNo.trim { it <= ' ' } + "?text=" + message.trim { it <= ' ' }
|
||||
i.setPackage("com.whatsapp")
|
||||
i.data = Uri.parse(url)
|
||||
if (i.resolveActivity(packageManager) != null) {
|
||||
context.startActivity(i)
|
||||
}
|
||||
println("finish method - 2")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return 25
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.3.50'
|
||||
ext.kotlin_version = '1.3.61'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Camera permission is required for barcode and qr-code scanning.</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
|
|
|||
|
|
@ -9,14 +9,27 @@ class User {
|
|||
|
||||
User({this.email, this.fullName, this.name, this.token, this.appCompanyId, this.kassaId});
|
||||
|
||||
factory User.fromJson(Map<String, dynamic> json) {
|
||||
return User (
|
||||
static User fromJson(Map<String, dynamic> json) {
|
||||
return json != null
|
||||
? User (
|
||||
name: json['name'],
|
||||
email: json['mail'],
|
||||
token: json['api_token'],
|
||||
fullName: json['fullname'],
|
||||
appCompanyId: json['app_company_id'] as int,
|
||||
kassaId: json['kassa_id'] as int,
|
||||
);
|
||||
}
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {
|
||||
"name": name,
|
||||
"mail": email,
|
||||
"api_token": token,
|
||||
"fullname": fullName,
|
||||
"app_company_id": appCompanyId,
|
||||
"kassa_id": kassaId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||
import 'package:device_info/device_info.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/smena.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import '../models/auth_response.dart';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
|
@ -13,6 +17,8 @@ import 'package:http/http.dart' as http;
|
|||
/// The service responsible for networking requests
|
||||
class ApiService extends BaseService {
|
||||
static const endpoint = 'https://kassa-test.aman.com.kz/ru/api/v2';
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
var client = new http.Client();
|
||||
|
||||
|
|
@ -27,16 +33,27 @@ class ApiService extends BaseService {
|
|||
return aman.body;
|
||||
}
|
||||
|
||||
Future<AuthBody> authenticate_token(String token, { bool statusCheck = true}) async {
|
||||
Map<String, String> requestBody = <String, String>{
|
||||
'token': token
|
||||
};
|
||||
String response = await requestFormData('/activate_token', requestBody, statusCheck: statusCheck );
|
||||
|
||||
AuthResponse aman = AuthResponse.fromJson(json.decode(response));
|
||||
return aman.body;
|
||||
}
|
||||
|
||||
Future<Response<Message>> isActive(String token) async {
|
||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||
var response = await requestFormData('/test_auth', requestBody);
|
||||
return Response.fromJson(json.decode(response), Message.fromJson);
|
||||
}
|
||||
|
||||
Future<Response<Message>> logout(String token) async {
|
||||
Future<Response<dynamic>> logout(String token) async {
|
||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||
var response = await requestFormData('/logout', requestBody);
|
||||
return Response.fromJson(json.decode(response), Message.fromJson);
|
||||
print(json.decode(response));
|
||||
return Response.fromJsonDynamic(json.decode(response));
|
||||
}
|
||||
|
||||
Future<Response<dynamic>> money(String token) async {
|
||||
|
|
@ -102,10 +119,28 @@ class ApiService extends BaseService {
|
|||
|
||||
|
||||
Future<String> requestFormData(String point, Map<String, String> requestBody, { bool statusCheck = true } ) async {
|
||||
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
|
||||
|
||||
Map<String, String> headers = <String, String>{
|
||||
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
||||
HttpHeaders.cacheControlHeader: "no-cache"
|
||||
};
|
||||
if(Platform.isAndroid) {
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
print(androidInfo.model);
|
||||
headers.addAll(<String, String>{
|
||||
HttpHeaders.userAgentHeader: androidInfo.model,
|
||||
});
|
||||
}
|
||||
|
||||
if(Platform.isIOS) {
|
||||
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
|
||||
print(iosInfo.utsname.machine);
|
||||
headers.addAll(<String, String>{
|
||||
HttpHeaders.userAgentHeader: iosInfo.utsname.machine,
|
||||
});
|
||||
}
|
||||
|
||||
var uri = Uri.parse('$endpoint$point');
|
||||
var request = http.MultipartRequest('POST', uri)
|
||||
|
|
@ -118,7 +153,8 @@ class ApiService extends BaseService {
|
|||
if(statusCheck) { //Проверка на авторизованный запрос, необязательный параметр
|
||||
Response check = Response.fromJsonDynamic(json.decode(body));
|
||||
if (!check.operation && check.status == 401) {
|
||||
print('object');
|
||||
_dialogService.showDialog(description: 'Необходимо пройти повторную авторизацию');
|
||||
_navigatorService.replace(LoginViewRoute);
|
||||
}
|
||||
}
|
||||
return body;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
|||
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_item.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||
|
|
@ -12,6 +13,7 @@ import 'package:aman_kassa_flutter/core/models/response.dart';
|
|||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
|
||||
import 'ApiService.dart';
|
||||
|
|
@ -38,9 +40,7 @@ class DataService extends BaseService {
|
|||
}
|
||||
|
||||
CheckData _transformProductsToCheckData(
|
||||
{String paymentType,
|
||||
String tradeType,
|
||||
List<ProductDao> items}) {
|
||||
{String paymentType, String tradeType, List<ProductDao> items}) {
|
||||
List<CheckItem> itemsList = [];
|
||||
int iterator = 1;
|
||||
num summ = 0.0;
|
||||
|
|
@ -67,16 +67,52 @@ class DataService extends BaseService {
|
|||
return checkData;
|
||||
}
|
||||
|
||||
CheckData _transformCalcModelToCheckData(
|
||||
{String paymentType, String tradeType, List<CalcModel> items}) {
|
||||
List<CheckItem> itemsList = [];
|
||||
int iterator = 1;
|
||||
num summ = 0.0;
|
||||
items.forEach((el) {
|
||||
int articul = iterator;
|
||||
CheckItem item = CheckItem(
|
||||
name: 'Позиция $iterator',
|
||||
cnt: el.num2 != null ? double.parse(el.num2) : 1.0,
|
||||
price: double.parse(el.num1) ,
|
||||
articul: articul);
|
||||
|
||||
summ += item.cnt * item.price;
|
||||
itemsList.add(item);
|
||||
iterator++;
|
||||
});
|
||||
CheckData checkData = CheckData(type: tradeType, items: itemsList);
|
||||
if ((paymentType ?? 'cash') == 'card') {
|
||||
checkData.card = summ;
|
||||
}
|
||||
print(checkData);
|
||||
return checkData;
|
||||
}
|
||||
|
||||
Future<Response<dynamic>> sellOrReturn(
|
||||
{String paymentType,
|
||||
String tradeType,
|
||||
String token,
|
||||
List<ProductDao> items,
|
||||
String operationType}) async {
|
||||
List<ProductDao> kassaItems,
|
||||
List<CalcModel> calcItems,
|
||||
String operationType,
|
||||
String mode}) async {
|
||||
try {
|
||||
CheckData checkData = _transformProductsToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: items);
|
||||
String data = jsonEncode(checkData.toJson());
|
||||
String data;
|
||||
if(mode == SettingModeKassa) {
|
||||
CheckData checkData = _transformProductsToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: kassaItems);
|
||||
data = jsonEncode(checkData.toJson());
|
||||
} else if(mode == SettingModeCalc) {
|
||||
CheckData checkData = _transformCalcModelToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: calcItems);
|
||||
data = jsonEncode(checkData.toJson());
|
||||
}
|
||||
|
||||
|
||||
log.i('token: $token');
|
||||
log.i('data: $data');
|
||||
Response<dynamic> response = await (operationType == OperationTypePay
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ Future<void> setEqual(Store<AppState> store) async {
|
|||
store.dispatch(SetCalcStateAction(CalcState(isEqual: true)));
|
||||
}
|
||||
|
||||
Future<void> cleanCalcItems(Store<AppState> store) async {
|
||||
store.dispatch(SetCalcStateAction(CalcState(calcItems: [])));
|
||||
}
|
||||
|
||||
ThunkAction<AppState> onTapAction(String value) {
|
||||
return (Store<AppState> store) async {
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ Future<void> backBottomElement(Store<AppState> store) async {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> cleanKassaItems(Store<AppState> store) async {
|
||||
store.dispatch(SetKassaStateAction(KassaState(kassaItems: [])));
|
||||
}
|
||||
|
||||
ThunkAction<AppState> addCustomProductToKassaItems(String name, int count, double price, double total) {
|
||||
return (Store<AppState> store) async {
|
||||
List<ProductDao> items = store.state.kassaState.kassaItems;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import 'package:aman_kassa_flutter/core/route_names.dart';
|
|||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/auth_type_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
|
@ -28,8 +29,14 @@ final DialogService _dialogService = locator<DialogService>();
|
|||
Future<void> checkUserAction(Store<AppState> store) async {
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||
try {
|
||||
Response<Message> session = await _api.isActive('test');
|
||||
bool isAuthenticated = "OK" == session.body.message;
|
||||
String token = store.state.userState.user?.token;
|
||||
bool isAuthenticated = false;
|
||||
if(token!=null) {
|
||||
Response<Message> session = await _api.isActive(token);
|
||||
isAuthenticated = "OK" == session.body.message;
|
||||
} else {
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
}
|
||||
store.dispatch(
|
||||
SetUserStateAction(
|
||||
UserState(
|
||||
|
|
@ -41,14 +48,59 @@ Future<void> checkUserAction(Store<AppState> store) async {
|
|||
|
||||
if(!isAuthenticated){
|
||||
_navigation.replace(LoginViewRoute);
|
||||
} else {
|
||||
_navigation.replace(HomeViewRoute);
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
print(error);
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> logoutAction(Store<AppState> store) async {
|
||||
try {
|
||||
store.dispatch(
|
||||
SetUserStateAction(
|
||||
UserState(
|
||||
isLoading: false,
|
||||
isAuthenticated: false,
|
||||
user: User(),
|
||||
),
|
||||
),
|
||||
);
|
||||
_navigation.replace(LoginViewRoute);
|
||||
} catch (error) {
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
||||
}
|
||||
}
|
||||
|
||||
ThunkAction<AppState> authenticateToken(String token) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||
try {
|
||||
AuthBody result = await _api.authenticate_token(token, statusCheck: false);
|
||||
store.dispatch(SetUserStateAction(UserState(
|
||||
isLoading: false,
|
||||
loginFormMessage: LoginFormMessage(email: result.email?.join(","), password: result.password?.join(","), message: result.message),
|
||||
user: result.user,
|
||||
authenticateType: AuthenticateTypeQr,
|
||||
isAuthenticated: result.user != null,
|
||||
)));
|
||||
if(result.user == null && result.message!=null){
|
||||
_dialogService.showDialog(title: 'Warning', buttonTitle: 'Ok', description: result.message);
|
||||
}
|
||||
if(result.user!=null) {
|
||||
_navigation.replace(HomeViewRoute);
|
||||
}
|
||||
} catch(e) {
|
||||
print(e);
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> authenticate(String email, String password) {
|
||||
return (Store<AppState> store) async {
|
||||
|
|
@ -58,7 +110,11 @@ ThunkAction<AppState> authenticate(String email, String password) {
|
|||
store.dispatch(SetUserStateAction(UserState(
|
||||
isLoading: false,
|
||||
loginFormMessage: LoginFormMessage(email: result.email?.join(","), password: result.password?.join(","), message: result.message),
|
||||
user: result.user
|
||||
user: result.user,
|
||||
login: email,
|
||||
password: password,
|
||||
authenticateType: AuthenticateTypeLogin,
|
||||
isAuthenticated: result.user != null,
|
||||
)));
|
||||
if(result.user == null && result.message!=null){
|
||||
_dialogService.showDialog(title: 'Warning', buttonTitle: 'Ok', description: result.message);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
const String AuthenticateTypeQr = 'AuthenticateTypeQr';
|
||||
const String AuthenticateTypeLogin = 'AuthenticateTypeLogin';
|
||||
|
|
@ -8,8 +8,14 @@ class SettingState {
|
|||
|
||||
SettingState({this.mode, this.tradeType});
|
||||
|
||||
factory SettingState.initial() => SettingState(mode: SettingModeCalc, tradeType: SettingTradeTypeGood);
|
||||
//read hive
|
||||
factory SettingState.initial(SettingState payload) {
|
||||
return SettingState(
|
||||
mode: payload?.mode ?? SettingModeCalc,
|
||||
tradeType: payload?.tradeType ?? SettingTradeTypeGood);
|
||||
}
|
||||
|
||||
//write hive
|
||||
SettingState copyWith({
|
||||
@required mode,
|
||||
@required tradeType,
|
||||
|
|
@ -19,4 +25,17 @@ class SettingState {
|
|||
tradeType: tradeType ?? this.tradeType,
|
||||
);
|
||||
}
|
||||
|
||||
static SettingState fromJson(dynamic json) {
|
||||
return json != null
|
||||
? SettingState(
|
||||
tradeType: json['tradeType'],
|
||||
mode: json['mode'],
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {"tradeType": tradeType, "mode": mode};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,49 +7,85 @@ class UserState {
|
|||
final bool isError;
|
||||
final bool isLoading;
|
||||
final bool isAuthenticated;
|
||||
final String authenticateType;
|
||||
final String login;
|
||||
final String password;
|
||||
final LoginFormMessage loginFormMessage;
|
||||
final User user;
|
||||
final Smena smena;
|
||||
|
||||
UserState({
|
||||
this.isError,
|
||||
this.isLoading,
|
||||
this.isAuthenticated,
|
||||
this.user,
|
||||
this.loginFormMessage,
|
||||
this.smena
|
||||
});
|
||||
UserState(
|
||||
{this.isError,
|
||||
this.isLoading,
|
||||
this.isAuthenticated,
|
||||
this.authenticateType,
|
||||
this.login,
|
||||
this.password,
|
||||
this.user,
|
||||
this.loginFormMessage,
|
||||
this.smena});
|
||||
|
||||
factory UserState.initial() => UserState(
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isAuthenticated: false,
|
||||
loginFormMessage: LoginFormMessage(),
|
||||
smena: Smena(),
|
||||
);
|
||||
factory UserState.initial(UserState payload) => UserState(
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isAuthenticated: false,
|
||||
loginFormMessage: LoginFormMessage(),
|
||||
smena: Smena(),
|
||||
user: payload?.user ?? User(),
|
||||
authenticateType: payload?.authenticateType ?? null,
|
||||
login: payload?.login ?? null,
|
||||
password: payload?.password ?? null,
|
||||
);
|
||||
|
||||
UserState copyWith({
|
||||
@required bool isError,
|
||||
@required bool isLoading,
|
||||
@required User user,
|
||||
@required bool isAuthenticated,
|
||||
@required LoginFormMessage loginFormMessage,
|
||||
@required Smena smena,
|
||||
}) {
|
||||
UserState copyWith(
|
||||
{@required bool isError,
|
||||
@required bool isLoading,
|
||||
@required User user,
|
||||
@required bool isAuthenticated,
|
||||
@required LoginFormMessage loginFormMessage,
|
||||
@required Smena smena,
|
||||
@required String authenticateType,
|
||||
@required String login,
|
||||
@required String password,
|
||||
}) {
|
||||
return UserState(
|
||||
isError: isError ?? this.isError,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||
user: user ?? this.user,
|
||||
loginFormMessage: loginFormMessage ?? this.loginFormMessage,
|
||||
smena: smena ?? this.smena,
|
||||
isError: isError ?? this.isError,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||
user: user ?? this.user,
|
||||
loginFormMessage: loginFormMessage ?? this.loginFormMessage,
|
||||
smena: smena ?? this.smena,
|
||||
authenticateType: authenticateType ?? this.authenticateType,
|
||||
login: login ?? this.login,
|
||||
password: password ?? this.password,
|
||||
);
|
||||
}
|
||||
|
||||
static UserState fromJson(dynamic json) {
|
||||
return json != null
|
||||
? UserState(
|
||||
user: User.fromJson(json['user']),
|
||||
authenticateType: json['authenticateType'],
|
||||
login: json['login'],
|
||||
password: json['password']
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {
|
||||
"user": user != null ? user.toJson() : null,
|
||||
"authenticateType": authenticateType,
|
||||
"login": login,
|
||||
"password": password,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class LoginFormMessage {
|
||||
final String email;
|
||||
final String password;
|
||||
final String message;
|
||||
|
||||
LoginFormMessage({this.email, this.password, this.message});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
|||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:redux_persist_flutter/redux_persist_flutter.dart';
|
||||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
import 'package:redux_persist/redux_persist.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import 'actions/calc_actions.dart';
|
||||
|
||||
|
|
@ -46,10 +49,10 @@ class AppState {
|
|||
final CalcState calcState;
|
||||
|
||||
AppState({
|
||||
@required this.userState,
|
||||
@required this.kassaState,
|
||||
@required this.settingState,
|
||||
@required this.calcState,
|
||||
this.userState,
|
||||
this.kassaState,
|
||||
this.settingState,
|
||||
this.calcState,
|
||||
});
|
||||
|
||||
//stable work
|
||||
|
|
@ -66,6 +69,23 @@ class AppState {
|
|||
calcState: calcState ?? this.calcState,
|
||||
);
|
||||
}
|
||||
|
||||
static AppState fromJson(dynamic json){
|
||||
print(json);
|
||||
return json !=null
|
||||
? AppState(
|
||||
settingState: SettingState.fromJson(json['settingState']),
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {
|
||||
"settingState": settingState.toJson(),
|
||||
"userState" : userState.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class Redux {
|
||||
|
|
@ -81,14 +101,22 @@ class Redux {
|
|||
|
||||
//initial context
|
||||
static Future<void> init() async {
|
||||
final userStateInitial = UserState.initial();
|
||||
// Create Persistor
|
||||
final persist = Persistor<AppState>(
|
||||
storage: FlutterStorage(), // Or use other engines
|
||||
serializer: JsonSerializer<AppState>(AppState.fromJson), // Or use other serializers
|
||||
);
|
||||
|
||||
final initialState = await persist.load();
|
||||
|
||||
final userStateInitial = UserState.initial(initialState?.userState);
|
||||
final kassaStateInitial = KassaState.initial();
|
||||
final settingStateInitial = SettingState.initial();
|
||||
final settingStateInitial = SettingState.initial(initialState?.settingState);
|
||||
final calcStateInitial = CalcState.initial();
|
||||
|
||||
_store = Store<AppState>(
|
||||
appReducer,
|
||||
middleware: [thunkMiddleware],
|
||||
middleware: [thunkMiddleware, persist.createMiddleware() ],
|
||||
initialState: AppState(
|
||||
userState: userStateInitial,
|
||||
kassaState: kassaStateInitial,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
import 'dart:convert';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
//import 'package:flutter/services.dart';
|
||||
|
||||
class ImageShowContainer extends StatelessWidget {
|
||||
final ImageShowModel data;
|
||||
|
||||
ImageShowContainer(this.data);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
|
@ -13,12 +19,12 @@ class ImageShowContainer extends StatelessWidget {
|
|||
title: Text(data.title),
|
||||
),
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
imageFromBase64String(data.data)
|
||||
],
|
||||
children: <Widget>[imageFromBase64String(data.data)],
|
||||
),
|
||||
floatingActionButton: MyFloatingActionButton(),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Padding imageFromBase64String(String base64String) {
|
||||
|
|
@ -28,9 +34,99 @@ Padding imageFromBase64String(String base64String) {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
class ImageShowModel {
|
||||
final String data;
|
||||
final String title;
|
||||
|
||||
ImageShowModel(this.data, this.title);
|
||||
}
|
||||
|
||||
class MyFloatingActionButton extends StatefulWidget {
|
||||
@override
|
||||
_MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
|
||||
}
|
||||
|
||||
class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||
bool showFab = true;
|
||||
// String _batteryLevel = 'Unknown battery level.';
|
||||
// static const platform = const MethodChannel('samples.flutter.dev/battery');
|
||||
//
|
||||
// Future<void> _getBatteryLevel() async {
|
||||
// String batteryLevel;
|
||||
// try {
|
||||
// final int result = await platform.invokeMethod('sendMessage');
|
||||
// print(result);
|
||||
// batteryLevel = 'Battery level at $result % .';
|
||||
// } on PlatformException catch (e) {
|
||||
// batteryLevel = "Failed to get battery level: '${e.message}'.";
|
||||
// }
|
||||
//
|
||||
// setState(() {
|
||||
// _batteryLevel = batteryLevel;
|
||||
// });
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return showFab
|
||||
? FloatingActionButton(
|
||||
child: Icon(Icons.share),
|
||||
onPressed: () {
|
||||
var bottomSheetController = showBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0 ),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)
|
||||
]),
|
||||
//color: Colors.grey[900],
|
||||
height: 280,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
verticalSpaceSmall,
|
||||
BusyButton(title: 'Электронная почта', onPressed: () {} , mainColor: primaryColor, icon: Icons.mail, ),
|
||||
verticalSpaceSmall,
|
||||
BusyButton(title: 'WhatsApp', onPressed: () {} , mainColor: greenColor, icon: MdiIcons.whatsapp, ),
|
||||
verticalSpaceSmall,
|
||||
BusyButton(title: '', onPressed: () {} , mainColor: yellowColor, icon: Icons.share,),
|
||||
],
|
||||
)
|
||||
));
|
||||
showFoatingActionButton(false);
|
||||
bottomSheetController.closed.then((value) {
|
||||
showFoatingActionButton(true);
|
||||
});
|
||||
},
|
||||
): Container() ;
|
||||
}
|
||||
void showFoatingActionButton(bool value) {
|
||||
setState(() {
|
||||
showFab = value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DecoratedTextField extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
//color: fillColor, borderRadius: BorderRadius.circular(10)
|
||||
),
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.mail_outline, color: primaryColor,),
|
||||
labelStyle: TextStyle(color: primaryColor),
|
||||
labelText: 'Отправить на Email',
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,12 @@
|
|||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||
|
|
@ -40,6 +45,8 @@ class _HomeViewState extends State<HomeView> {
|
|||
PageController pageController;
|
||||
int selectedTabIndex;
|
||||
DataService _dataService = locator<DataService>();
|
||||
ApiService _api = locator<ApiService>();
|
||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
|
||||
@override
|
||||
|
|
@ -58,7 +65,12 @@ class _HomeViewState extends State<HomeView> {
|
|||
|
||||
void _onSelectChoice(Choice choice) async {
|
||||
if (choice.command == 'exit') {
|
||||
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
Response<dynamic> result = await _api.logout(Redux.store.state.userState.user.token);
|
||||
if(result.operation && result.status == 200) {
|
||||
Redux.store.dispatch(logoutAction);
|
||||
}
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
} else if (choice.command == 'update') {
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user);
|
||||
|
|
|
|||
|
|
@ -40,12 +40,11 @@ class CalculatorTab extends StatelessWidget {
|
|||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
|
||||
child: RaisedButton(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
padding: EdgeInsets.all(8.0),
|
||||
color: redColor,
|
||||
child: Text(
|
||||
"Возврат",
|
||||
"возврат",
|
||||
style: buttonBigTitleTextStyle,
|
||||
),
|
||||
onPressed: () {
|
||||
|
|
@ -55,11 +54,11 @@ class CalculatorTab extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: RaisedButton(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
padding: EdgeInsets.all(8.0),
|
||||
|
||||
color: greenColor,
|
||||
child: Text(
|
||||
"Оплата",
|
||||
"оплата",
|
||||
style: buttonBigTitleTextStyle,
|
||||
),
|
||||
onPressed: () {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class KassaTab extends StatelessWidget {
|
|||
padding: EdgeInsets.all(8),
|
||||
color: redColor,
|
||||
child: Text(
|
||||
"Возврат",
|
||||
"возврат",
|
||||
style: buttonBigTitleTextStyle,
|
||||
),
|
||||
onPressed: () {
|
||||
|
|
@ -123,7 +123,7 @@ class KassaTab extends StatelessWidget {
|
|||
padding: EdgeInsets.all(8),
|
||||
color: greenColor,
|
||||
child: Text(
|
||||
"Оплата",
|
||||
"оплата",
|
||||
style: buttonBigTitleTextStyle,
|
||||
),
|
||||
onPressed: () {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
|
|
@ -5,9 +9,14 @@ import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
|||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/input_field.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/text_link.dart';
|
||||
import 'package:barcode_scan/gen/protos/protos.pb.dart';
|
||||
import 'package:barcode_scan/gen/protos/protos.pbenum.dart';
|
||||
import 'package:barcode_scan/model/scan_options.dart';
|
||||
import 'package:barcode_scan/platform_wrapper.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class LoginView extends StatelessWidget {
|
||||
final emailController = TextEditingController(text: 'test@kkm-kassa.kz');
|
||||
|
|
@ -15,10 +24,7 @@ class LoginView extends StatelessWidget {
|
|||
|
||||
final FocusNode passwordNode = new FocusNode();
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
_pressBtnEnter() async {
|
||||
Redux.store.dispatch(authenticate(emailController.text, passwordController.text));
|
||||
}
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -35,11 +41,17 @@ class LoginView extends StatelessWidget {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Image.asset('assets/images/logo.png'),
|
||||
//child: FlutterLogo(size: 120,),
|
||||
Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Image.asset('assets/images/logo.png'),
|
||||
),
|
||||
Positioned(child: Text('онлайн касса', style: TextStyle(fontWeight: FontWeight.bold),), bottom: 23.0,left: 25.0,),
|
||||
],
|
||||
),
|
||||
|
||||
InputField(
|
||||
placeholder: 'Электронная почта',
|
||||
controller: emailController,
|
||||
|
|
@ -68,9 +80,15 @@ class LoginView extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
verticalSpaceLarge,
|
||||
TextLink(
|
||||
'Регистрация',
|
||||
onPressed: () {},
|
||||
// TextLink(
|
||||
// 'Регистрация',
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
IconButton(
|
||||
icon: Icon(MdiIcons.qrcodeScan),
|
||||
iconSize: 40,
|
||||
tooltip: "Scan",
|
||||
onPressed: scan,
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -78,5 +96,42 @@ class LoginView extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
|
||||
_pressBtnEnter() async {
|
||||
Redux.store
|
||||
.dispatch(authenticate(emailController.text, passwordController.text));
|
||||
}
|
||||
|
||||
Future<void> scan() async {
|
||||
try {
|
||||
var options = ScanOptions(strings: {
|
||||
"cancel": 'Отмена',
|
||||
"flash_on": 'Вкл фонарик',
|
||||
"flash_off": 'Выкл фонарик',
|
||||
});
|
||||
var result = await BarcodeScanner.scan(options: options);
|
||||
print(result.type); // The result type (barcode, cancelled, failed)
|
||||
print(result.rawContent); // The barcode content
|
||||
print(result.format); // The barcode format (as enum)
|
||||
print(result
|
||||
.formatNote); // If a unknown format was scanned this field contains a note
|
||||
if (result.type == ResultType.Barcode &&
|
||||
result.rawContent?.length == 60) {
|
||||
Redux.store.dispatch(authenticateToken(result.rawContent));
|
||||
} else {
|
||||
_dialogService.showDialog(description: 'Не верный формат QR кода');
|
||||
}
|
||||
} on PlatformException catch (e) {
|
||||
var result = ScanResult.create();
|
||||
result.type = ResultType.Error;
|
||||
result.format = BarcodeFormat.unknown;
|
||||
if (e.code == BarcodeScanner.cameraAccessDenied) {
|
||||
result.rawContent = 'The user did not grant the camera permission!';
|
||||
_dialogService.showDialog(
|
||||
description: 'Нет доступа до камеры устройства');
|
||||
} else {
|
||||
result.rawContent = 'Unknown error: $e';
|
||||
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import 'package:aman_kassa_flutter/core/route_names.dart';
|
|||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||
|
|
@ -82,7 +84,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
if(widget.model.mode == SettingModeCalc) {
|
||||
return StoreConnector<AppState, CalcState>(
|
||||
converter: (store) => store.state.calcState,
|
||||
builder: (context, vm) {
|
||||
builder: (_, vm) {
|
||||
return Text('${totalCalc(vm.calcItems)} тнг', style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
|
|
@ -92,7 +94,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
}
|
||||
return StoreConnector<AppState, KassaState>(
|
||||
converter: (store) => store.state.kassaState,
|
||||
builder: (context, vm) {
|
||||
builder: (_, vm) {
|
||||
return Text('${totalKassa(vm.kassaItems)} тнг', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 35 ));
|
||||
}
|
||||
);
|
||||
|
|
@ -128,13 +130,24 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
AppState _state = Redux.store.state;
|
||||
String _token = _state.userState.user.token;
|
||||
String _tradeType = _state.settingState.tradeType;
|
||||
List<ProductDao> items = _state.kassaState.kassaItems;
|
||||
Response<dynamic> response = await _dataService.sellOrReturn(token: _token, items: items, paymentType: type, operationType: widget.model.operationType, tradeType: _tradeType );
|
||||
String _mode = _state.settingState.mode;
|
||||
if(_mode == SettingModeCalc){
|
||||
_tradeType = SettingTradeTypeGood;
|
||||
}
|
||||
List<ProductDao> kassaItems = _state.kassaState.kassaItems;
|
||||
List<CalcModel> calcItems = _state.calcState.calcItems;
|
||||
Response<dynamic> response = await _dataService.sellOrReturn(token: _token, kassaItems: kassaItems, paymentType: type, operationType: widget.model.operationType, tradeType: _tradeType, calcItems: calcItems, mode: _mode );
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
setState(() { isBusy = false; });
|
||||
if(response.operation){
|
||||
String message = response.body['message'];
|
||||
String check = response.body['check'];
|
||||
|
||||
// if(_mode == SettingModeCalc){
|
||||
// Redux.store.dispatch(cleanCalcItems);
|
||||
// } else if(_mode == SettingModeKassa) {
|
||||
// Redux.store.dispatch(cleanKassaItems);
|
||||
// }
|
||||
_navigatorService.pop();
|
||||
_navigatorService.push(ImageShowRoute, arguments: ImageShowModel(check, message));
|
||||
} else if(!response.operation && response.status !=500) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// A button that shows a busy indicator in place of title
|
||||
|
|
@ -9,13 +10,15 @@ class BusyButton extends StatefulWidget {
|
|||
final Function onPressed;
|
||||
final bool enabled;
|
||||
final Color mainColor;
|
||||
final IconData icon;
|
||||
const BusyButton(
|
||||
{
|
||||
@required this.title,
|
||||
this.busy = false,
|
||||
@required this.onPressed,
|
||||
this.enabled = true,
|
||||
this.mainColor
|
||||
this.mainColor,
|
||||
this.icon
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -46,14 +49,20 @@ class _BusyButtonState extends State<BusyButton> {
|
|||
margin: EdgeInsets.symmetric(
|
||||
horizontal: widget.busy ? 10 : 25,
|
||||
vertical: widget.busy ? 10 : 15),
|
||||
child: !widget.busy
|
||||
? Text(
|
||||
widget.title,
|
||||
style: buttonTitleTextStyle,
|
||||
)
|
||||
: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
widget.icon!=null ? Container(child: (Icon(widget.icon, color: whiteColor,)), margin: const EdgeInsets.only(right: 10.0 ),) : (Container()),
|
||||
!widget.busy
|
||||
? Text(
|
||||
widget.title,
|
||||
style: buttonTitleTextStyle,
|
||||
)
|
||||
: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
117
pubspec.lock
117
pubspec.lock
|
|
@ -22,6 +22,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
barcode_scan:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: barcode_scan
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -64,6 +71,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
device_info:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.2+4"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -71,18 +85,25 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
esys_flutter_share:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: esys_flutter_share
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_boom_menu:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_boom_menu
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
flutter_redux:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -95,6 +116,11 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
get_it:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -172,13 +198,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4"
|
||||
observable_ish:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: observable_ish
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -235,6 +254,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
protobuf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: protobuf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -242,13 +268,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
provider_architecture:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: provider_architecture
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1+1"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -263,6 +282,20 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
redux_persist:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: redux_persist
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.4"
|
||||
redux_persist_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: redux_persist_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
redux_thunk:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -277,18 +310,39 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.9"
|
||||
shared_preferences:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.7+3"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+10"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+7"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
sliding_up_panel:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sliding_up_panel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -317,13 +371,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
stacked:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: stacked
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ dependencies:
|
|||
redux: ^4.0.0
|
||||
flutter_redux: ^0.6.0
|
||||
redux_thunk: ^0.3.0
|
||||
stacked : ^1.5.2
|
||||
provider_architecture: ^1.0.3
|
||||
redux_persist: ^0.8.4
|
||||
redux_persist_flutter: ^0.8.2
|
||||
responsive_builder: ^0.1.4
|
||||
provider: ^4.1.2
|
||||
logger: ^0.9.1
|
||||
|
|
@ -21,10 +21,11 @@ dependencies:
|
|||
sqflite: ^1.3.0
|
||||
path_provider: ^1.6.9
|
||||
google_fonts: ^1.1.0
|
||||
flutter_boom_menu: ^1.0.2
|
||||
sliding_up_panel: ^1.0.2
|
||||
material_design_icons_flutter: ^4.0.5345
|
||||
intl: ^0.16.1
|
||||
barcode_scan: ^3.0.1
|
||||
device_info: ^0.4.2+4
|
||||
esys_flutter_share: ^1.0.2
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
|
|||
Loading…
Reference in New Issue