final
This commit is contained in:
@@ -21,9 +21,9 @@ class DoubleBackToCloseApp extends StatefulWidget {
|
||||
/// Creates a widget that allows the user to close the app by double tapping
|
||||
/// the back-button.
|
||||
const DoubleBackToCloseApp({
|
||||
Key key,
|
||||
@required this.snackBar,
|
||||
@required this.child,
|
||||
Key? key,
|
||||
required this.snackBar,
|
||||
required this.child,
|
||||
}) : assert(snackBar != null),
|
||||
assert(child != null),
|
||||
super(key: key);
|
||||
@@ -34,7 +34,7 @@ class DoubleBackToCloseApp extends StatefulWidget {
|
||||
|
||||
class _DoubleBackToCloseAppState extends State<DoubleBackToCloseApp> {
|
||||
/// The last time the user tapped Android's back-button.
|
||||
DateTime _lastTimeBackButtonWasTapped;
|
||||
DateTime? _lastTimeBackButtonWasTapped;
|
||||
|
||||
/// Returns whether the current platform is Android.
|
||||
bool get _isAndroid => Theme.of(context).platform == TargetPlatform.android;
|
||||
@@ -50,7 +50,7 @@ class _DoubleBackToCloseAppState extends State<DoubleBackToCloseApp> {
|
||||
bool get _isSnackBarVisible =>
|
||||
(_lastTimeBackButtonWasTapped != null) &&
|
||||
(widget.snackBar.duration >
|
||||
DateTime.now().difference(_lastTimeBackButtonWasTapped));
|
||||
DateTime.now().difference(_lastTimeBackButtonWasTapped!));
|
||||
|
||||
/// Returns whether the next back navigation of this route will be handled
|
||||
/// internally.
|
||||
@@ -59,7 +59,7 @@ class _DoubleBackToCloseAppState extends State<DoubleBackToCloseApp> {
|
||||
/// local-history of the current route, in order to handle pop. This is done
|
||||
/// by [Drawer], for example, so it can close on pop.
|
||||
bool get _willHandlePopInternally =>
|
||||
ModalRoute.of(context).willHandlePopInternally;
|
||||
ModalRoute.of(context)!.willHandlePopInternally;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class IFrameWeb extends StatefulWidget {
|
||||
final String width;
|
||||
final String height;
|
||||
final String src;
|
||||
final String? width;
|
||||
final String? height;
|
||||
final String? src;
|
||||
|
||||
const IFrameWeb({this.width, this.height, this.src});
|
||||
|
||||
|
||||
@@ -7,14 +7,12 @@ import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import '../store/store.dart';
|
||||
import 'utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
|
||||
typedef void PostCallback(Response response);
|
||||
|
||||
String generateSignature(String string, {String key}) {
|
||||
String generateSignature(String string, {String? key}) {
|
||||
if (key == null) {
|
||||
key = Constants.API_SECRET;
|
||||
}
|
||||
@@ -37,17 +35,17 @@ class HttpUtil {
|
||||
'Http-Contact-Authorization': '',
|
||||
'Http-Device-Type': Utils.getOs(checkWeb: true),
|
||||
'Http-Api-Branch': 'flutter',
|
||||
'Http-Language-Code': store.state.locale.languageCode,
|
||||
'Http-Country-Code': store.state.locale.countryCode,
|
||||
'Http-Language-Code': (store == null || store.state == null || store.state.locale == null) ? 'en' : store.state.locale!.languageCode,
|
||||
'Http-Country-Code': (store == null || store.state == null || store.state.locale == null) ? 'US' : store.state.locale!.countryCode!,
|
||||
};
|
||||
|
||||
static Future<dynamic> httpGet(String url,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
int businessId = 0,
|
||||
Function(int, int) receiveProgress,
|
||||
Function(int, int)? receiveProgress,
|
||||
bool returnError = false,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, String>? additionalHeaders,
|
||||
}) async {
|
||||
Map<String, dynamic> localHeaders = json.decode(json.encode(headers));
|
||||
if (additionalHeaders != null) {
|
||||
@@ -59,8 +57,7 @@ class HttpUtil {
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-Contact-Authorization'] = Utils.prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
String requestUrl = Constants.BASE_API_URL + url;
|
||||
@@ -69,7 +66,9 @@ class HttpUtil {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Utils.jsonPrettyPrint(queryParameters);
|
||||
if (queryParameters != null) {
|
||||
Utils.jsonPrettyPrint(queryParameters!);
|
||||
}
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
@@ -84,9 +83,9 @@ class HttpUtil {
|
||||
// print('response data: ${response.data}');
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
int statusCode = response.statusCode!;
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
} on DioException catch(e) {
|
||||
print('HttpGet failed, request: $requestUrl, headers: $localHeaders, error ${e.response}');
|
||||
if (returnError) {
|
||||
return e;
|
||||
@@ -95,16 +94,16 @@ class HttpUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpPost(String url, PostCallback callback,
|
||||
static Future<dynamic> httpPost(String url, PostCallback? callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
int businessId = 0,
|
||||
bool isFormData = false,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
FormData formData,
|
||||
Function(int, int) sendProgress,
|
||||
Function(int, int) receiveProgress,
|
||||
Map<String, String>? additionalHeaders,
|
||||
Map<String, dynamic>? body,
|
||||
FormData? formData,
|
||||
Function(int, int)? sendProgress,
|
||||
Function(int, int)? receiveProgress,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
@@ -116,8 +115,7 @@ class HttpUtil {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-Contact-Authorization'] = Utils.prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
@@ -138,7 +136,7 @@ class HttpUtil {
|
||||
Response response = await dio.post(
|
||||
requestUrl,
|
||||
queryParameters: queryParameters == null ? {} : queryParameters,
|
||||
data: isFormData ? ((formData != null)?formData:FormData.fromMap(body)) : json.encode(body),
|
||||
data: isFormData ? ((formData != null)?formData:FormData.fromMap(body!)) : json.encode(body),
|
||||
options: Options(
|
||||
headers: localHeaders,
|
||||
contentType: isFormData ? Headers.formUrlEncodedContentType : Headers.jsonContentType,
|
||||
@@ -149,17 +147,17 @@ class HttpUtil {
|
||||
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
int statusCode = response.statusCode!;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e, stacktrace) {
|
||||
} on DioException catch(e, stacktrace) {
|
||||
if (e.response != null) {
|
||||
try {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
Utils.jsonPrettyPrint(e.response?.data);
|
||||
} catch (err) {
|
||||
print(e.response.data);
|
||||
print(e.response?.data);
|
||||
}
|
||||
}
|
||||
if (returnError) {
|
||||
@@ -169,14 +167,14 @@ class HttpUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpPut(String url, PostCallback callback,
|
||||
static Future<dynamic> httpPut(String url, PostCallback? callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
int businessId = 0,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
Function(int, int) sendProgress,
|
||||
Function(int, int) receiveProgress,
|
||||
Map<String, String>? additionalHeaders,
|
||||
Map<String, dynamic>? body,
|
||||
Function(int, int)? sendProgress,
|
||||
Function(int, int)? receiveProgress,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
@@ -190,8 +188,7 @@ class HttpUtil {
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-Contact-Authorization'] = Utils.prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
@@ -218,14 +215,14 @@ class HttpUtil {
|
||||
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
int statusCode = response.statusCode!;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
} on DioException catch(e) {
|
||||
if (e.response != null) {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
Utils.jsonPrettyPrint(e.response!.data);
|
||||
}
|
||||
if (returnError) {
|
||||
return e;
|
||||
@@ -234,14 +231,14 @@ class HttpUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpPatch(String url, PostCallback callback,
|
||||
static Future<dynamic> httpPatch(String url, PostCallback? callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
int businessId = 0,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
Function(int, int) sendProgress,
|
||||
Function(int, int) receiveProgress,
|
||||
Map<String, String>? additionalHeaders,
|
||||
Map<String, dynamic>? body,
|
||||
Function(int, int)? sendProgress,
|
||||
Function(int, int)? receiveProgress,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
@@ -255,8 +252,7 @@ class HttpUtil {
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-Contact-Authorization'] = Utils.prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
@@ -268,7 +264,9 @@ class HttpUtil {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Utils.jsonPrettyPrint(body);
|
||||
if (body != null) {
|
||||
Utils.jsonPrettyPrint(body!);
|
||||
}
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
@@ -285,14 +283,14 @@ class HttpUtil {
|
||||
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
int statusCode = response.statusCode!;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
} on DioException catch(e) {
|
||||
if (e.response != null) {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
Utils.jsonPrettyPrint(e.response!.data);
|
||||
}
|
||||
if (returnError) {
|
||||
return e;
|
||||
@@ -301,12 +299,12 @@ class HttpUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpDelete(String url, PostCallback callback,
|
||||
static Future<dynamic> httpDelete(String url, PostCallback? callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
int businessId = 0,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
Map<String, String>? additionalHeaders,
|
||||
Map<String, dynamic>? body,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
@@ -320,8 +318,7 @@ class HttpUtil {
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId == 0 ? '${Constants.BUSINESS_ID}' : businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-Contact-Authorization'] = Utils.prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
@@ -333,7 +330,9 @@ class HttpUtil {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Utils.jsonPrettyPrint(body);
|
||||
if (body != null) {
|
||||
Utils.jsonPrettyPrint(body);
|
||||
}
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
@@ -348,14 +347,14 @@ class HttpUtil {
|
||||
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
int statusCode = response.statusCode!;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
} on DioException catch(e) {
|
||||
if (e.response != null) {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
Utils.jsonPrettyPrint(e.response!.data);
|
||||
}
|
||||
if(returnError) {
|
||||
return e;
|
||||
|
||||
@@ -14,7 +14,7 @@ class ShopScrollController extends ScrollController {
|
||||
this.coordinator, {
|
||||
double initialScrollOffset = 0.0,
|
||||
this.keepScrollOffset = true,
|
||||
this.debugLabel,
|
||||
required this.debugLabel,
|
||||
}) : assert(initialScrollOffset != null),
|
||||
assert(keepScrollOffset != null),
|
||||
_initialScrollOffset = initialScrollOffset;
|
||||
@@ -61,7 +61,7 @@ class ShopScrollController extends ScrollController {
|
||||
'ScrollController not attached to any scroll views.');
|
||||
assert(_positions.length == 1,
|
||||
'ScrollController attached to multiple scroll views.');
|
||||
return _positions.single;
|
||||
return _positions.single as ShopScrollPosition;
|
||||
}
|
||||
|
||||
/// 可滚动小部件的当前滚动偏移量
|
||||
@@ -83,12 +83,12 @@ class ShopScrollController extends ScrollController {
|
||||
/// 持续时间不能为零。 要在没有动画的情况下跳至特定值,请使用[jumpTo]。
|
||||
Future<void> animateTo(
|
||||
double offset, {
|
||||
@required Duration duration,
|
||||
@required Curve curve,
|
||||
required Duration duration,
|
||||
required Curve curve,
|
||||
}) {
|
||||
assert(_positions.isNotEmpty,
|
||||
'ScrollController not attached to any scroll views.');
|
||||
final List<Future<void>> animations = List<Future<void>>(_positions.length);
|
||||
final List<Future<void>> animations = List<Future<void>>.filled(_positions.length, Future<void>.value());
|
||||
for (int i = 0; i < _positions.length; i += 1)
|
||||
animations[i] =
|
||||
_positions[i].animateTo(offset, duration: duration, curve: curve);
|
||||
@@ -149,7 +149,7 @@ class ShopScrollController extends ScrollController {
|
||||
/// 则它将是前一个实例。 当环境已更改并且[Scrollable]需要重新创建[ScrollPosition]
|
||||
/// 对象时,将使用此方法。 第一次创建[ScrollPosition]时为null。
|
||||
ScrollPosition createScrollPosition(ScrollPhysics physics,
|
||||
ScrollContext context, ScrollPosition oldPosition) {
|
||||
ScrollContext context, ScrollPosition? oldPosition) {
|
||||
return ShopScrollPosition(
|
||||
coordinator: coordinator,
|
||||
physics: physics,
|
||||
|
||||
@@ -12,15 +12,15 @@ class ShopScrollCoordinator {
|
||||
/// 页面主 CustomScrollView 控制
|
||||
final String pageLabel = "page";
|
||||
|
||||
ShopScrollController _pageScrollController;
|
||||
double Function() pinnedHeaderSliverHeightBuilder;
|
||||
ShopScrollController? _pageScrollController;
|
||||
double Function()? pinnedHeaderSliverHeightBuilder;
|
||||
|
||||
ShopScrollPosition get _pageScrollPosition => _pageScrollController.position;
|
||||
ShopScrollPosition get _pageScrollPosition => _pageScrollController!.position;
|
||||
|
||||
ScrollDragController scrollDragController;
|
||||
ScrollDragController? scrollDragController;
|
||||
|
||||
/// 主页面滑动部件默认位置
|
||||
double _pageInitialOffset;
|
||||
double? _pageInitialOffset;
|
||||
|
||||
/// 获取主页面滑动控制器
|
||||
ShopScrollController pageScrollController([double initialOffset = 0.0]) {
|
||||
@@ -28,27 +28,27 @@ class ShopScrollCoordinator {
|
||||
_pageInitialOffset = initialOffset;
|
||||
_pageScrollController = ShopScrollController(this,
|
||||
debugLabel: pageLabel, initialScrollOffset: initialOffset);
|
||||
return _pageScrollController;
|
||||
return _pageScrollController!;
|
||||
}
|
||||
|
||||
/// 创建并获取一个子滑动控制器
|
||||
ShopScrollController newChildScrollController([String debugLabel]) =>
|
||||
ShopScrollController(this, debugLabel: debugLabel);
|
||||
ShopScrollController newChildScrollController([String? debugLabel]) =>
|
||||
ShopScrollController(this, debugLabel: debugLabel ?? '');
|
||||
|
||||
/// 子部件滑动数据协调
|
||||
/// [userScrollDirection]用户滑动方向
|
||||
/// [position]被滑动的子部件的位置信息
|
||||
void applyUserOffset(double delta,
|
||||
[ScrollDirection userScrollDirection, ShopScrollPosition position]) {
|
||||
[ScrollDirection? userScrollDirection, ShopScrollPosition? position]) {
|
||||
if (userScrollDirection == ScrollDirection.reverse) {
|
||||
updateUserScrollDirection(_pageScrollPosition, userScrollDirection);
|
||||
updateUserScrollDirection(_pageScrollPosition, userScrollDirection!);
|
||||
final innerDelta = _pageScrollPosition.applyClampedDragUpdate(delta);
|
||||
if (innerDelta != 0.0) {
|
||||
updateUserScrollDirection(position, userScrollDirection);
|
||||
updateUserScrollDirection(position!, userScrollDirection);
|
||||
position.applyFullDragUpdate(innerDelta);
|
||||
}
|
||||
} else {
|
||||
updateUserScrollDirection(position, userScrollDirection);
|
||||
updateUserScrollDirection(position!, userScrollDirection!);
|
||||
final outerDelta = position.applyClampedDragUpdate(delta);
|
||||
if (outerDelta != 0.0) {
|
||||
updateUserScrollDirection(_pageScrollPosition, userScrollDirection);
|
||||
@@ -60,7 +60,7 @@ class ShopScrollCoordinator {
|
||||
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent,
|
||||
ShopScrollPosition position) {
|
||||
if (pinnedHeaderSliverHeightBuilder != null) {
|
||||
maxScrollExtent = maxScrollExtent - pinnedHeaderSliverHeightBuilder();
|
||||
maxScrollExtent = maxScrollExtent - pinnedHeaderSliverHeightBuilder!();
|
||||
maxScrollExtent = math.max(0.0, maxScrollExtent);
|
||||
}
|
||||
return position.applyContentDimensions(
|
||||
@@ -77,9 +77,9 @@ class ShopScrollCoordinator {
|
||||
/// 当手指离开屏幕
|
||||
void onPointerUp(PointerUpEvent event) {
|
||||
final double _pagePixels = _pageScrollPosition.pixels;
|
||||
if (0.0 < _pagePixels && _pagePixels < _pageInitialOffset) {
|
||||
if (0.0 < _pagePixels && _pagePixels < _pageInitialOffset!) {
|
||||
if (pageExpand == PageExpandState.NotExpand &&
|
||||
_pageInitialOffset - _pagePixels > _scrollRedundancy) {
|
||||
_pageInitialOffset! - _pagePixels > _scrollRedundancy) {
|
||||
_pageScrollPosition
|
||||
.animateTo(0.0,
|
||||
duration: const Duration(milliseconds: 400), curve: Curves.ease)
|
||||
@@ -87,7 +87,7 @@ class ShopScrollCoordinator {
|
||||
} else {
|
||||
pageExpand = PageExpandState.Expanding;
|
||||
_pageScrollPosition
|
||||
.animateTo(_pageInitialOffset,
|
||||
.animateTo(_pageInitialOffset!,
|
||||
duration: const Duration(milliseconds: 400), curve: Curves.ease)
|
||||
.then((value) => pageExpand = PageExpandState.NotExpand);
|
||||
}
|
||||
|
||||
@@ -11,17 +11,17 @@ import 'shop_scroll_coordinator.dart';
|
||||
class ShopScrollPosition extends ScrollPosition
|
||||
implements ScrollActivityDelegate {
|
||||
final ShopScrollCoordinator coordinator; // 协调器
|
||||
ScrollDragController _currentDrag;
|
||||
ScrollDragController? _currentDrag;
|
||||
double _heldPreviousVelocity = 0.0;
|
||||
|
||||
ShopScrollPosition(
|
||||
{@required ScrollPhysics physics,
|
||||
@required ScrollContext context,
|
||||
{required ScrollPhysics physics,
|
||||
required ScrollContext context,
|
||||
double initialPixels = 0.0,
|
||||
bool keepScrollOffset = true,
|
||||
ScrollPosition oldPosition,
|
||||
String debugLabel,
|
||||
@required this.coordinator})
|
||||
ScrollPosition? oldPosition,
|
||||
String? debugLabel,
|
||||
required this.coordinator})
|
||||
: super(
|
||||
physics: physics,
|
||||
context: context,
|
||||
@@ -40,7 +40,7 @@ class ShopScrollPosition extends ScrollPosition
|
||||
|
||||
@override
|
||||
double setPixels(double newPixels) {
|
||||
assert(activity.isScrolling);
|
||||
assert(activity!.isScrolling);
|
||||
return super.setPixels(newPixels);
|
||||
}
|
||||
|
||||
@@ -51,13 +51,13 @@ class ShopScrollPosition extends ScrollPosition
|
||||
goIdle();
|
||||
return;
|
||||
}
|
||||
activity.updateDelegate(this);
|
||||
activity!.updateDelegate(this);
|
||||
final ShopScrollPosition typedOther = other as ShopScrollPosition;
|
||||
_userScrollDirection = typedOther._userScrollDirection;
|
||||
assert(_currentDrag == null);
|
||||
if (typedOther._currentDrag != null) {
|
||||
_currentDrag = typedOther._currentDrag;
|
||||
_currentDrag.updateDelegate(this);
|
||||
_currentDrag?.updateDelegate(this);
|
||||
typedOther._currentDrag = null;
|
||||
}
|
||||
}
|
||||
@@ -131,14 +131,14 @@ class ShopScrollPosition extends ScrollPosition
|
||||
}
|
||||
|
||||
@override
|
||||
void beginActivity(ScrollActivity newActivity) {
|
||||
void beginActivity(ScrollActivity? newActivity) {
|
||||
_heldPreviousVelocity = 0.0;
|
||||
if (newActivity == null) return;
|
||||
assert(newActivity.delegate == this);
|
||||
super.beginActivity(newActivity);
|
||||
_currentDrag?.dispose();
|
||||
_currentDrag = null;
|
||||
if (!activity.isScrolling) updateUserScrollDirection(ScrollDirection.idle);
|
||||
if (!activity!.isScrolling) updateUserScrollDirection(ScrollDirection.idle);
|
||||
}
|
||||
|
||||
/// 将[用户滚动方向]设置为给定值。
|
||||
@@ -154,7 +154,7 @@ class ShopScrollPosition extends ScrollPosition
|
||||
|
||||
@override
|
||||
ScrollHoldController hold(VoidCallback holdCancelCallback) {
|
||||
final double previousVelocity = activity.velocity;
|
||||
final double previousVelocity = activity!.velocity;
|
||||
final HoldScrollActivity holdActivity =
|
||||
HoldScrollActivity(delegate: this, onHoldCanceled: holdCancelCallback);
|
||||
beginActivity(holdActivity);
|
||||
@@ -195,10 +195,10 @@ class ShopScrollPosition extends ScrollPosition
|
||||
if (coordinator.pageExpand == PageExpandState.Expanding) return;
|
||||
}
|
||||
assert(pixels != null);
|
||||
final Simulation simulation =
|
||||
final Simulation? simulation =
|
||||
physics.createBallisticSimulation(this, velocity);
|
||||
if (simulation != null) {
|
||||
beginActivity(BallisticScrollActivity(this, simulation, context.vsync));
|
||||
beginActivity(BallisticScrollActivity(this, simulation, context.vsync, true));
|
||||
} else {
|
||||
goIdle();
|
||||
}
|
||||
@@ -220,8 +220,8 @@ class ShopScrollPosition extends ScrollPosition
|
||||
@override
|
||||
Future<void> animateTo(
|
||||
double to, {
|
||||
@required Duration duration,
|
||||
@required Curve curve,
|
||||
required Duration duration,
|
||||
required Curve curve,
|
||||
}) {
|
||||
if (nearEqual(to, pixels, physics.tolerance.distance)) {
|
||||
// 跳过动画,直接移到我们已经靠近的位置。
|
||||
|
||||
@@ -6,15 +6,11 @@ import 'dart:ui' as ui;
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
// import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:stripe_payment/stripe_payment.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
@@ -42,174 +38,17 @@ class Util {
|
||||
}
|
||||
Util._internal();
|
||||
|
||||
// final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
|
||||
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
|
||||
static bool notificationTapped = false;
|
||||
|
||||
init() {
|
||||
// initLocalNotification();
|
||||
// initFirebaseMessaging();
|
||||
|
||||
// ePmqRwRUTmKuFNfbHA-6zq:APA91bEFEQx1YgJqfx0V0VYo86uRDGjG6SP1SPCAZW4OvQ7gMOeKWDQ47bfuEM00YavtKq7ZGpsWfFL7B3ypm00ZA6crjJJLK_-j_H8bS_dnQbLFwyRcW67IXCs5sRkro71bRZv7L1WM
|
||||
|
||||
// eventBus.on<SubscribeToTopic>().listen((event) {
|
||||
// if (firebaseMessaging != null) {
|
||||
// firebaseMessaging.subscribeToTopic(event.topic);
|
||||
// }
|
||||
// });
|
||||
// eventBus.on<UnSubscribeToTopic>().listen((event) {
|
||||
// if (firebaseMessaging != null) {
|
||||
// firebaseMessaging.unsubscribeFromTopic(event.topic);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
initLocalNotification() async {
|
||||
var initializationSettingsAndroid = new AndroidInitializationSettings('ic_launcher');
|
||||
var initializationSettingsIOS = new IOSInitializationSettings(
|
||||
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
|
||||
var initializationSettings = new InitializationSettings(
|
||||
android: initializationSettingsAndroid,
|
||||
iOS: initializationSettingsIOS,
|
||||
);
|
||||
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
|
||||
onSelectNotification: onSelectNotification);
|
||||
}
|
||||
|
||||
Future onSelectNotification(String payload, {bool replace=false}) async {
|
||||
print('payload: $payload');
|
||||
if (payload != null && payload.isNotEmpty) {
|
||||
Routes.router.navigateTo(store.state.context, payload, replace: replace);
|
||||
}
|
||||
}
|
||||
|
||||
// initFirebaseMessaging() {
|
||||
// if (Platform.isIOS) {
|
||||
// iosPermission();
|
||||
// }
|
||||
// firebaseMessaging.getToken().then((token) {
|
||||
// print('FCM token: $token');
|
||||
// store.dispatch(UpdateFcmToken(token));
|
||||
// });
|
||||
// firebaseMessaging.configure(
|
||||
// onMessage: (Map<String, dynamic> message) {
|
||||
// print('FCM onMessage: $message');
|
||||
// // eventBus.fire(OnFcmReceived(message));
|
||||
// showNotificationWithDefaultSound(message);
|
||||
// return;
|
||||
// },
|
||||
// onBackgroundMessage: Platform.isIOS ? null : backgroundMessageHandler,
|
||||
// onResume: (Map<String, dynamic> message) {
|
||||
// print('FCM onResume: $message');
|
||||
// if (Platform.isAndroid) {
|
||||
// if (message != null && message['data'] != null && message['data']['route'] != null) {
|
||||
// notificationTapped = true;
|
||||
// onSelectNotification(message['data']['route']);
|
||||
// }
|
||||
// } else {
|
||||
// if (message != null && message['route'] != null) {
|
||||
// notificationTapped = true;
|
||||
// onSelectNotification(message['route']);
|
||||
// }
|
||||
// }
|
||||
// return;
|
||||
// },
|
||||
// onLaunch: (Map<String, dynamic> message) {
|
||||
// print('FCM onLaunch: $message');
|
||||
// if (Platform.isAndroid) {
|
||||
// if (message != null && message['data'] != null && message['data']['route'] != null) {
|
||||
// notificationTapped = true;
|
||||
// onSelectNotification(message['data']['route'], replace: true);
|
||||
// }
|
||||
// } else {
|
||||
// if (message != null && message['route'] != null) {
|
||||
// notificationTapped = true;
|
||||
// onSelectNotification(message['route'], replace: true);
|
||||
// }
|
||||
// }
|
||||
// return;
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
Future onDidReceiveLocalNotification(int id, String title, String body, String payload) async {
|
||||
showDialog(
|
||||
context: store.state.context,
|
||||
builder: (BuildContext context) => CupertinoAlertDialog(
|
||||
title: Text(title),
|
||||
content: Text(body),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () async {
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
if (payload != null && payload.isNotEmpty) {
|
||||
Routes.router.navigateTo(context, payload);
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future showNotificationWithDefaultSound(Map<String, dynamic> message) async {
|
||||
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
|
||||
'channelId',
|
||||
'channelName',
|
||||
'channelDescription',
|
||||
importance: Importance.max,
|
||||
priority: Priority.high,
|
||||
);
|
||||
var iOSPlatformChannelSpecifics = new IOSNotificationDetails(presentSound: true, badgeNumber: 1);
|
||||
var platformChannelSpecifics = new NotificationDetails(
|
||||
android: androidPlatformChannelSpecifics,
|
||||
iOS: iOSPlatformChannelSpecifics,
|
||||
);
|
||||
await flutterLocalNotificationsPlugin.show(
|
||||
0,
|
||||
Platform.isAndroid ? message['notification']['title'] : message['title'],
|
||||
Platform.isAndroid ? message['notification']['body'] : message['body'],
|
||||
platformChannelSpecifics,
|
||||
payload: Platform.isAndroid ? message['data']['route'] : message['route'],
|
||||
);
|
||||
}
|
||||
|
||||
// iosPermission() {
|
||||
// firebaseMessaging.requestNotificationPermissions(
|
||||
// const IosNotificationSettings(
|
||||
// sound: true,
|
||||
// badge: true,
|
||||
// alert: true,
|
||||
// )
|
||||
// );
|
||||
// firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
|
||||
// print('IOS settings registered: $settings');
|
||||
// });
|
||||
// }
|
||||
|
||||
static Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) {
|
||||
print('FCM background message handler: $message');
|
||||
return Future<void>.value();
|
||||
}
|
||||
|
||||
static Future<Box> getBox() async {
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
Hive.init(dir.path);
|
||||
Box box = await Hive.openBox('app_data');
|
||||
return box;
|
||||
}
|
||||
|
||||
static Widget showImage(String imageUrl, {double width, double height,
|
||||
BoxFit fit, Widget Function(BuildContext, String, dynamic) errorWidget}) {
|
||||
if (imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('https:')) {
|
||||
static Widget showImage(String imageUrl, {double? width, double? height,
|
||||
BoxFit? fit, Widget Function(BuildContext, String, dynamic)? errorWidget}) {
|
||||
if (imageUrl.isNotEmpty && imageUrl.startsWith('https:')) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
width: width,
|
||||
height: width,
|
||||
fit: fit,
|
||||
placeholder: (context, url) => Utils.imageLoadingIndicator(width: width, height: height),
|
||||
placeholder: (context, url) => Utils.imageLoadingIndicator(width: width ?? 30, height: height ?? 30),
|
||||
errorWidget: errorWidget != null ? errorWidget : (context, url, error) {
|
||||
return Image.asset(
|
||||
'assets/images/not_found.png',
|
||||
@@ -219,13 +58,13 @@ class Util {
|
||||
);
|
||||
},
|
||||
);
|
||||
} else if (imageUrl != null && imageUrl.isNotEmpty) {
|
||||
} else if (imageUrl.isNotEmpty) {
|
||||
return Image.file(
|
||||
File(imageUrl),
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
errorBuilder: (BuildContext context, Object object, StackTrace stackTrace) {
|
||||
errorBuilder: (BuildContext context, Object object, StackTrace? stackTrace) {
|
||||
return Image.asset(
|
||||
'assets/images/not_found.png',
|
||||
width: width,
|
||||
@@ -319,14 +158,14 @@ class Util {
|
||||
final picker = ImagePicker();
|
||||
var image = await picker.pickImage(source: ImageSource.gallery);
|
||||
Navigator.of(context).pop();
|
||||
uploadPicture(context, File(image.path), user, commentId: commentId, orderId: orderId);
|
||||
uploadPicture(context, File(image!.path), user, commentId: commentId, orderId: orderId);
|
||||
}
|
||||
|
||||
void getPictureFromCamera(BuildContext context, User user, {int commentId = -1, int orderId = 0}) async {
|
||||
final picker = ImagePicker();
|
||||
var image = await picker.pickImage(source: ImageSource.camera);
|
||||
Navigator.of(context).pop();
|
||||
uploadPicture(context, File(image.path), user, commentId: commentId, orderId: orderId);
|
||||
uploadPicture(context, File(image!.path), user, commentId: commentId, orderId: orderId);
|
||||
}
|
||||
|
||||
void uploadPicture(BuildContext context, File image, User user, {int commentId = -1, int orderId = 0}) async {
|
||||
@@ -456,18 +295,18 @@ class Util {
|
||||
ImagePicker picker = ImagePicker();
|
||||
var image = await picker.pickImage(source: ImageSource.gallery);
|
||||
Navigator.of(context).pop();
|
||||
onGotFile(imageId, image.path);
|
||||
onGotFile(imageId, image!.path);
|
||||
}
|
||||
|
||||
void getPictureFromCamera2(BuildContext context, int imageId, OnGotFile onGotFile) async {
|
||||
ImagePicker picker = ImagePicker();
|
||||
var image = await picker.pickImage(source: ImageSource.camera);
|
||||
Navigator.of(context).pop();
|
||||
onGotFile(imageId, image.path);
|
||||
onGotFile(imageId, image!.path);
|
||||
}
|
||||
|
||||
Future<void> createTicket(BuildContext context, String msg, List<Map<String, dynamic>> images,
|
||||
OnSuccess onSuccess, OnError onError, {int id}) {
|
||||
OnSuccess onSuccess, OnError onError, {int? id}) async {
|
||||
var formData = FormData();
|
||||
formData.fields.add(MapEntry("msg", msg));
|
||||
formData.fields.add(MapEntry('id', id == null ? '0' : id.toString()));
|
||||
@@ -562,7 +401,7 @@ class Util {
|
||||
PaymentPlatform paymentPlatform, {
|
||||
bool googlePay=false,
|
||||
bool applePay=false,
|
||||
StripePaymentMethod stripePaymentMethod,
|
||||
StripePaymentMethod? stripePaymentMethod,
|
||||
}) {
|
||||
switch(paymentPlatform.code) {
|
||||
case Constants.PAYMENT_METHOD_CODE_SQUARE:
|
||||
@@ -587,7 +426,7 @@ class Util {
|
||||
StripePayment.setOptions(
|
||||
StripeOptions(publishableKey: paymentPlatform.publishableKey,
|
||||
merchantId: paymentPlatform.merchantId,
|
||||
androidPayMode: paymentPlatform.publishableKey.contains('_test_')
|
||||
androidPayMode: paymentPlatform.publishableKey!.contains('_test_')
|
||||
? 'test'
|
||||
: 'production'
|
||||
)
|
||||
@@ -595,14 +434,14 @@ class Util {
|
||||
StripePayment.paymentRequestWithNativePay(
|
||||
androidPayOptions: AndroidPayPaymentRequest(
|
||||
totalPrice: order.totalPrice.toStringAsFixed(2),
|
||||
currencyCode: order.businessInfo.currency,
|
||||
currencyCode: order.businessInfo!.currency,
|
||||
),
|
||||
applePayOptions: ApplePayPaymentOptions(
|
||||
currencyCode: order.businessInfo.currency,
|
||||
countryCode: order.businessInfo.address.country,
|
||||
currencyCode: order.businessInfo!.currency,
|
||||
countryCode: order.businessInfo!.address.country,
|
||||
items: [
|
||||
ApplePayItem(
|
||||
label: order.businessInfo.name,
|
||||
label: order.businessInfo!.name,
|
||||
amount: order.totalPrice.toStringAsFixed(2),
|
||||
),
|
||||
],
|
||||
@@ -633,7 +472,7 @@ class Util {
|
||||
),
|
||||
);
|
||||
if (paymentMethod != null) {
|
||||
Utils.stripePaymentIntent(order, null, paymentMethod.id, paymentMethod.type, (response) {
|
||||
Utils.stripePaymentIntent(order, null, paymentMethod.id!, paymentMethod.type!, (response) {
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
StripePayment.confirmPaymentIntent(
|
||||
PaymentIntent(
|
||||
@@ -643,8 +482,8 @@ class Util {
|
||||
).then((paymentIntentResult) {
|
||||
if (paymentIntentResult.status == Constants.STRIPE_STATUS_SUCCEDED) {
|
||||
Utils.stripeChargedSuccess(order,
|
||||
paymentMethod.id,
|
||||
paymentIntentResult.paymentIntentId,
|
||||
paymentMethod.id!,
|
||||
paymentIntentResult.paymentIntentId!,
|
||||
(response) {
|
||||
StripePayment.completeNativePayRequest().then((_) {
|
||||
eventBus.fire(OnOrderUpdated());
|
||||
@@ -680,10 +519,10 @@ class Util {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Uint8List> getBytesFromAsset(String path, int width) async {
|
||||
static Future<Uint8List?> getBytesFromAsset(String path, int width) async {
|
||||
ByteData data = await rootBundle.load(path);
|
||||
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
|
||||
ui.FrameInfo fi = await codec.getNextFrame();
|
||||
return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
|
||||
return (await fi.image.toByteData(format: ui.ImageByteFormat.png))?.buffer.asUint8List();
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ import 'dart:typed_data';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
@@ -36,27 +34,21 @@ class Util {
|
||||
|
||||
}
|
||||
|
||||
static Future<Box> getBox() async {
|
||||
Hive.initFlutter();
|
||||
Box box = await Hive.openBox('wisetronic_app_data');
|
||||
return box;
|
||||
}
|
||||
|
||||
static Widget showImage(String imageUrl, {double width, double height,
|
||||
BoxFit fit, Widget Function(BuildContext, String, dynamic) errorWidget}) {
|
||||
static Widget showImage(String imageUrl, {double? width, double? height,
|
||||
BoxFit? fit, Widget Function(BuildContext, String?, dynamic)? errorWidget}) {
|
||||
return Image.network(imageUrl,
|
||||
fit: fit,
|
||||
width: width,
|
||||
height: height,
|
||||
cacheWidth: width != null ? width.round() : null,
|
||||
cacheHeight: height != null ? height.round() : null,
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return Center(
|
||||
child: Utils.imageLoadingIndicator(),
|
||||
);
|
||||
},
|
||||
errorBuilder: (BuildContext context, Object object, StackTrace stackTrace) {
|
||||
errorBuilder: (BuildContext context, Object object, StackTrace? stackTrace) {
|
||||
print('StackTrace: $stackTrace');
|
||||
if (errorWidget != null) {
|
||||
return errorWidget(context, null, null);
|
||||
@@ -106,16 +98,16 @@ class Util {
|
||||
}
|
||||
|
||||
void startFilePicker(BuildContext context, User user, {int commentId = -1, int orderId = 0}) async {
|
||||
InputElement uploadInput = FileUploadInputElement();
|
||||
InputElement uploadInput = FileUploadInputElement() as InputElement;
|
||||
uploadInput.click();
|
||||
uploadInput.onChange.listen((e) {
|
||||
final files = uploadInput.files;
|
||||
if (files.length >= 1) {
|
||||
if (files!.length >= 1) {
|
||||
final File file = files[0];
|
||||
final FileReader reader = new FileReader();
|
||||
|
||||
reader.onLoadEnd.listen((e) {
|
||||
uploadPicture(context, reader.result, file.name, user, commentId: commentId, orderId: orderId);
|
||||
uploadPicture(context, reader.result as Uint8List, file.name, user, commentId: commentId, orderId: orderId);
|
||||
});
|
||||
reader.onError.listen((e) {
|
||||
Fluttertoast.showToast(
|
||||
@@ -210,11 +202,11 @@ class Util {
|
||||
|
||||
void startFilePicker2(BuildContext context, int imageId, OnGotFile onGotFile) async {
|
||||
final _image = await WebImagePicker().pickImage();
|
||||
onGotFile(imageId, _image.dataScheme);
|
||||
onGotFile(imageId, _image!.dataScheme);
|
||||
}
|
||||
|
||||
void createTicket(BuildContext context, String msg, List<Map<String, dynamic>> images,
|
||||
OnSuccess onSuccess, OnError onError, {int id}) {
|
||||
OnSuccess onSuccess, OnError onError, {int? id}) {
|
||||
var formData = FormData();
|
||||
formData.fields.add(MapEntry("msg", msg));
|
||||
formData.fields.add(MapEntry('id', id == null ? '0' : id.toString()));
|
||||
@@ -252,7 +244,7 @@ class Util {
|
||||
PaymentPlatform paymentPlatform, {
|
||||
bool googlePay=false,
|
||||
bool applePay=false,
|
||||
StripePaymentMethod stripePaymentMethod,
|
||||
StripePaymentMethod? stripePaymentMethod,
|
||||
}) {
|
||||
switch(paymentPlatform.code) {
|
||||
case Constants.PAYMENT_METHOD_CODE_SQUARE:
|
||||
@@ -293,36 +285,36 @@ class Util {
|
||||
}
|
||||
|
||||
class ImageInfo {
|
||||
String name;
|
||||
String data;
|
||||
String dataScheme;
|
||||
String path;
|
||||
String name = '';
|
||||
String data = '';
|
||||
String dataScheme = '';
|
||||
String path = '';
|
||||
}
|
||||
|
||||
class WebImagePicker {
|
||||
Future<ImageInfo> pickImage() async {
|
||||
Future<ImageInfo?> pickImage() async {
|
||||
print('pickImage');
|
||||
final ImageInfo data = ImageInfo();
|
||||
final FileUploadInputElement input = FileUploadInputElement();
|
||||
document.body.children.add(input);
|
||||
document.body!.children.add(input);
|
||||
input..accept = 'image/*';
|
||||
input.click();
|
||||
await input.onChange.first;
|
||||
if (input.files.isEmpty) return null;
|
||||
if (input.files!.isEmpty) return null;
|
||||
final reader = FileReader();
|
||||
reader.readAsDataUrl(input.files[0]);
|
||||
reader.readAsDataUrl(input.files![0]);
|
||||
await reader.onLoad.first;
|
||||
final encoded = reader.result as String;
|
||||
// remove data:image/*;base64 preambule
|
||||
final stripped =
|
||||
encoded.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), '');
|
||||
//final imageBase64 = base64.decode(stripped);
|
||||
final imageName = input.files?.first?.name;
|
||||
final imagePath = input.files?.first?.relativePath;
|
||||
data.name = imageName;
|
||||
final imageName = input.files?.first.name;
|
||||
final imagePath = input.files?.first.relativePath;
|
||||
data.name = imageName!;
|
||||
data.data = stripped;
|
||||
data.dataScheme = encoded;
|
||||
data.path = imagePath;
|
||||
data.path = imagePath!;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_wisetronic/models/product.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:universal_io/io.dart';
|
||||
@@ -28,6 +27,7 @@ import '../store/actions.dart';
|
||||
import '../store/store.dart';
|
||||
import 'http_util.dart';
|
||||
import 'util_web.dart' if (dart.library.io) 'util_io.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
typedef void OnSuccess(Response response);
|
||||
typedef void OnError(dynamic error);
|
||||
@@ -37,16 +37,25 @@ typedef void OnOk();
|
||||
typedef void OnLoadImageError();
|
||||
|
||||
class Utils {
|
||||
static StreamSubscription onProductWillAddToCartSubscription;
|
||||
static StreamSubscription onProductWillRemoveFromCartSubscription;
|
||||
static final Utils _utils = Utils._internal();
|
||||
static SharedPreferences? prefs;
|
||||
|
||||
static StreamSubscription? onProductWillAddToCartSubscription;
|
||||
static StreamSubscription? onProductWillRemoveFromCartSubscription;
|
||||
|
||||
factory Utils() {
|
||||
return _utils;
|
||||
}
|
||||
Utils._internal();
|
||||
|
||||
init() async {
|
||||
prefs = await SharedPreferences.getInstance();
|
||||
onProductWillAddToCartSubscription =
|
||||
eventBus.on<OnProductWillAddToCart>().listen((event) {
|
||||
CartInfo cartInfo =
|
||||
CartInfo? cartInfo =
|
||||
getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
|
||||
if (cartInfo == null || cartInfo.productList.length == 0) {
|
||||
if (cartInfo == null || cartInfo.productList!.length == 0) {
|
||||
cartInfo = CartInfo();
|
||||
cartInfo.id = 0;
|
||||
cartInfo.amountPaid = 0.0;
|
||||
@@ -57,7 +66,7 @@ class Utils {
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
name: event.product.name!,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList = [lineItem];
|
||||
@@ -67,15 +76,15 @@ class Utils {
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
print('#1');
|
||||
} else {
|
||||
if (event.product.productAttributes.length > 0) {
|
||||
if (event.product.productAttributes!.length > 0) {
|
||||
CartLineItem lineItem = newCartLineItem(
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
name: event.product.name!,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList.add(lineItem);
|
||||
cartInfo.productList!.add(lineItem);
|
||||
addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
@@ -83,8 +92,8 @@ class Utils {
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
int found = -1;
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (event.product.id == cartInfo.productList[i].product.id) {
|
||||
for (var i = 0; i < cartInfo.productList!.length; i++) {
|
||||
if (event.product.id == cartInfo.productList![i].product!.id) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
@@ -94,18 +103,18 @@ class Utils {
|
||||
id: 0,
|
||||
price: event.price,
|
||||
product: event.product,
|
||||
name: event.product.name,
|
||||
name: event.product.name!,
|
||||
description: event.description,
|
||||
quantity: 1.0);
|
||||
cartInfo.productList.add(lineItem);
|
||||
cartInfo.productList!.add(lineItem);
|
||||
addSubproductToCard(cartInfo, lineItem);
|
||||
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
print('#3');
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
} else {
|
||||
if (cartInfo.productList[found].quantity + 1.0 >
|
||||
event.product.leftNum) {
|
||||
if (cartInfo.productList![found].quantity! + 1.0 >
|
||||
event.product.leftNum!) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: S.of(context).product_insufficient,
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
@@ -113,8 +122,8 @@ class Utils {
|
||||
// backgroundColor: Colors.red,
|
||||
// textColor: Colors.white);
|
||||
} else {
|
||||
cartInfo.productList[found].quantity += 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList[found]);
|
||||
cartInfo.productList![found].quantity = cartInfo.productList![found].quantity! + 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList![found]);
|
||||
store.dispatch(new UpdateCartInfo(
|
||||
addCartInfoToCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
@@ -127,41 +136,41 @@ class Utils {
|
||||
});
|
||||
onProductWillRemoveFromCartSubscription =
|
||||
eventBus.on<OnProductWillRemoveFromCart>().listen((event) {
|
||||
CartInfo cartInfo =
|
||||
CartInfo? cartInfo =
|
||||
getCartInfoByBusiness(store.state.cartInfos, event.business);
|
||||
if (cartInfo != null) {
|
||||
if (cartInfo.productList.length > 0) {
|
||||
if (cartInfo.productList!.length > 0) {
|
||||
if (event.productListIndex != -1) {
|
||||
if (cartInfo.productList[event.productListIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[event.productListIndex].uuid;
|
||||
cartInfo.productList.removeAt(event.productListIndex);
|
||||
if (cartInfo.productList![event.productListIndex].quantity! <= 1) {
|
||||
String uuid = cartInfo.productList![event.productListIndex].uuid!;
|
||||
cartInfo.productList!.removeAt(event.productListIndex);
|
||||
removeSubproduct(cartInfo, uuid);
|
||||
} else {
|
||||
cartInfo.productList[event.productListIndex].quantity -= 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList[event.productListIndex], remove: true);
|
||||
cartInfo.productList![event.productListIndex].quantity = cartInfo.productList![event.productListIndex].quantity! - 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList![event.productListIndex], remove: true);
|
||||
}
|
||||
} else {
|
||||
int productListIndex = -1;
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.id == event.product.id) {
|
||||
for (var i = 0; i < cartInfo.productList!.length; i++) {
|
||||
if (cartInfo.productList![i].product!.id == event.product.id) {
|
||||
productListIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (productListIndex != -1) {
|
||||
if (cartInfo.productList[productListIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[productListIndex].uuid;
|
||||
cartInfo.productList.removeAt(productListIndex);
|
||||
if (cartInfo.productList![productListIndex].quantity! <= 1) {
|
||||
String uuid = cartInfo.productList![productListIndex].uuid!;
|
||||
cartInfo.productList!.removeAt(productListIndex);
|
||||
removeSubproduct(cartInfo, uuid);
|
||||
} else {
|
||||
cartInfo.productList[productListIndex].quantity -= 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList[productListIndex], remove: true);
|
||||
cartInfo.productList![productListIndex].quantity = cartInfo.productList![productListIndex].quantity! - 1;
|
||||
addSubproductQty(cartInfo, cartInfo.productList![productListIndex], remove: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cartInfo.productList.length <= 0) {
|
||||
if (cartInfo.productList!.length <= 0) {
|
||||
store.dispatch(UpdateCartInfo(removeCartInfoFromCartInfoList(
|
||||
store.state.cartInfos, cartInfo)));
|
||||
} else {
|
||||
@@ -211,7 +220,7 @@ class Utils {
|
||||
return false;
|
||||
}
|
||||
|
||||
static Map<String, dynamic> stringToJson(String string) {
|
||||
static Map<String, dynamic>? stringToJson(String? string) {
|
||||
if (string == null || string.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
@@ -244,10 +253,6 @@ class Utils {
|
||||
return platformName;
|
||||
}
|
||||
|
||||
static Future<Box> getBox() async {
|
||||
return Util.getBox();
|
||||
}
|
||||
|
||||
static Widget imageLoadingIndicator(
|
||||
{double width = 30.0, double height = 30.0}) {
|
||||
return SizedBox(
|
||||
@@ -365,7 +370,7 @@ class Utils {
|
||||
);
|
||||
}
|
||||
|
||||
static showLoadingDialog(BuildContext context, {String message}) {
|
||||
static showLoadingDialog(BuildContext context, {String? message}) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
@@ -468,46 +473,45 @@ class Utils {
|
||||
}
|
||||
|
||||
static void getCurrentUser() {
|
||||
getBox().then((box) {
|
||||
int userId = box.get(Constants.KEY_USER_ID, defaultValue: 0);
|
||||
String accessToken =
|
||||
box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
if (userId == 0 || accessToken.isEmpty) {
|
||||
eventBus.fire(new OnGetCurrentUserFailed(Error()));
|
||||
} else {
|
||||
HttpUtil.httpGet(
|
||||
'v1/users/$userId',
|
||||
queryParameters: {},
|
||||
businessId: Constants.BUSINESS_ID,
|
||||
).then((value) {
|
||||
User user = User.fromJson(value);
|
||||
store.dispatch(UpdateCurrentUser(user));
|
||||
eventBus.fire(OnCurrentUserUpdated());
|
||||
}).catchError((err) {
|
||||
eventBus.fire(new OnGetCurrentUserFailed(err));
|
||||
});
|
||||
}
|
||||
}).catchError((err) {
|
||||
eventBus.fire(new OnGetCurrentUserFailed(err));
|
||||
});
|
||||
if (store.state.user != null) {
|
||||
eventBus.fire(OnCurrentUserUpdated());
|
||||
return;
|
||||
}
|
||||
int? userId = prefs?.getInt(Constants.KEY_USER_ID) ?? 0;
|
||||
String? accessToken = prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
|
||||
if (userId == 0 || accessToken.isEmpty) {
|
||||
eventBus.fire(new OnGetCurrentUserFailed(Error()));
|
||||
} else {
|
||||
HttpUtil.httpGet(
|
||||
'v1/users/$userId',
|
||||
queryParameters: {},
|
||||
businessId: Constants.BUSINESS_ID,
|
||||
).then((value) {
|
||||
User user = User.fromJson(value);
|
||||
store.dispatch(UpdateCurrentUser(user));
|
||||
eventBus.fire(OnCurrentUserUpdated());
|
||||
}).catchError((err) {
|
||||
eventBus.fire(new OnGetCurrentUserFailed(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void showMessageDialog(BuildContext context, dynamic error,
|
||||
{String title, List<Widget> actions, OnOk onOk}) {
|
||||
{String? title, List<Widget>? actions, OnOk? onOk}) {
|
||||
String message = '';
|
||||
print('error $error');
|
||||
if (error is DioError && error.response != null) {
|
||||
if (error.response.data['message'] != null) {
|
||||
message = error.response.data['message'];
|
||||
} else if (error.response.data['error'] != null) {
|
||||
if (error.response.data['error'] is String) {
|
||||
message = error.response.data['error'];
|
||||
} else if (error.response.data['error']['errmsg'] != null) {
|
||||
message = error.response.data['error']['errmsg'];
|
||||
} else if (error.response.data['error']['message'] != null) {
|
||||
message = error.response.data['error']['message'];
|
||||
if (error is DioException && error.response != null) {
|
||||
if (error.response!.data['message'] != null) {
|
||||
message = error.response!.data['message'];
|
||||
} else if (error.response!.data['error'] != null) {
|
||||
if (error.response!.data['error'] is String) {
|
||||
message = error.response!.data['error'];
|
||||
} else if (error.response!.data['error']['errmsg'] != null) {
|
||||
message = error.response!.data['error']['errmsg'];
|
||||
} else if (error.response!.data['error']['message'] != null) {
|
||||
message = error.response!.data['error']['message'];
|
||||
} else {
|
||||
message = error.response.data.toString();
|
||||
message = error.response!.data.toString();
|
||||
}
|
||||
}
|
||||
} else if (error is String) {
|
||||
@@ -540,20 +544,15 @@ class Utils {
|
||||
}
|
||||
|
||||
static Future<List<int>> getLastVisit() async {
|
||||
Box box = await getBox();
|
||||
List<dynamic> lastVisit =
|
||||
json.decode(box.get(Constants.KEY_LAST_VISIT, defaultValue: '[]'));
|
||||
json.decode(prefs?.getString(Constants.KEY_LAST_VISIT) ?? '[]');
|
||||
List<int> lv = lastVisit.map((e) => e as int).toList();
|
||||
store.dispatch(UpdateLastVisit(lv));
|
||||
return lv;
|
||||
}
|
||||
|
||||
static void saveLastVisit(List<int> lastVisit) {
|
||||
getBox().then((box) {
|
||||
box.put(Constants.KEY_LAST_VISIT, lastVisit.toString());
|
||||
}).catchError((error) {
|
||||
print('Error occurred: $error');
|
||||
});
|
||||
prefs?.setString(Constants.KEY_LAST_VISIT, lastVisit.toString());
|
||||
}
|
||||
|
||||
static String utcDatetimeStringToLocalDatetimeString(
|
||||
@@ -656,26 +655,26 @@ class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
static CartInfo getCartInfoByBusiness(
|
||||
List<CartInfo> cartInfos, Business business) {
|
||||
static CartInfo? getCartInfoByBusiness(
|
||||
List<CartInfo>? cartInfos, Business business) {
|
||||
if (cartInfos == null || cartInfos.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (var i = 0; i < cartInfos.length; i++) {
|
||||
if (cartInfos[i].businessInfo.id == business.id) {
|
||||
if (cartInfos[i].businessInfo!.id == business.id) {
|
||||
return cartInfos[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static CartInfo getCartInfoByBusinessId(
|
||||
List<CartInfo> cartInfos, int businessId) {
|
||||
static CartInfo? getCartInfoByBusinessId(
|
||||
List<CartInfo>? cartInfos, int businessId) {
|
||||
if (cartInfos == null || cartInfos.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (var i = 0; i < cartInfos.length; i++) {
|
||||
if (cartInfos[i].businessInfo.id == businessId) {
|
||||
if (cartInfos[i].businessInfo!.id == businessId) {
|
||||
return cartInfos[i];
|
||||
}
|
||||
}
|
||||
@@ -683,13 +682,13 @@ class Utils {
|
||||
}
|
||||
|
||||
static List<CartInfo> addCartInfoToCartInfoList(
|
||||
List<CartInfo> cartInfos, CartInfo cartInfo) {
|
||||
List<CartInfo>? cartInfos, CartInfo cartInfo) {
|
||||
if (cartInfos == null || cartInfos.length <= 0) {
|
||||
cartInfos = [cartInfo];
|
||||
} else {
|
||||
bool found = false;
|
||||
for (var i = 0; i < cartInfos.length; i++) {
|
||||
if (cartInfos[i].businessInfo.id == cartInfo.businessInfo.id) {
|
||||
if (cartInfos[i].businessInfo!.id == cartInfo.businessInfo!.id) {
|
||||
cartInfos[i] = cartInfo;
|
||||
found = true;
|
||||
break;
|
||||
@@ -699,22 +698,19 @@ class Utils {
|
||||
cartInfos.add(cartInfo);
|
||||
}
|
||||
}
|
||||
Utils.getBox().then((box) {
|
||||
box.put(Constants.KEY_CARTINFOS, cartInfos.toString());
|
||||
}).catchError((error) {
|
||||
print('Error occurred: $error');
|
||||
});
|
||||
prefs?.setString(Constants.KEY_CARTINFOS, cartInfos.toString());
|
||||
return cartInfos;
|
||||
}
|
||||
|
||||
static List<CartInfo> removeCartInfoFromCartInfoList(
|
||||
List<CartInfo> cartInfos, CartInfo cartInfo) {
|
||||
List<CartInfo>? cartInfos, CartInfo? cartInfo) {
|
||||
if (cartInfos == null || cartInfos.length <= 0 || cartInfo == null) {
|
||||
prefs?.setString(Constants.KEY_CARTINFOS, cartInfos.toString());
|
||||
return [];
|
||||
}
|
||||
int removeIndex = -1;
|
||||
for (var i = 0; i < cartInfos.length; i++) {
|
||||
if (cartInfo.businessInfo.id == cartInfos[i].businessInfo.id) {
|
||||
if (cartInfo.businessInfo!.id == cartInfos[i].businessInfo!.id) {
|
||||
removeIndex = i;
|
||||
break;
|
||||
}
|
||||
@@ -722,17 +718,13 @@ class Utils {
|
||||
if (removeIndex != -1) {
|
||||
cartInfos.removeAt(removeIndex);
|
||||
}
|
||||
getBox().then((box) {
|
||||
box.put(Constants.KEY_CARTINFOS, cartInfos.toString());
|
||||
}).catchError((error) {
|
||||
print('Error occurred: $error');
|
||||
});
|
||||
prefs?.setString(Constants.KEY_CARTINFOS, cartInfos.toString());
|
||||
return cartInfos;
|
||||
}
|
||||
|
||||
static void clearCart(BuildContext context, CartInfo cartInfo,
|
||||
{OnComplete onComplete}) {
|
||||
if (cartInfo != null && cartInfo.productList.length > 0) {
|
||||
{OnComplete? onComplete}) {
|
||||
if (cartInfo != null && cartInfo.productList!.length > 0) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
@@ -766,7 +758,7 @@ class Utils {
|
||||
}
|
||||
|
||||
static void requireLogin(BuildContext context,
|
||||
{String returnUrl, bool replace = true, int delayMilliseconds = 400}) {
|
||||
{String? returnUrl, bool replace = true, int delayMilliseconds = 400}) {
|
||||
Future.delayed(Duration(milliseconds: delayMilliseconds), () {
|
||||
if (returnUrl != null) {
|
||||
store.dispatch(UpdateRedirectRoute(returnUrl));
|
||||
@@ -775,9 +767,9 @@ class Utils {
|
||||
});
|
||||
}
|
||||
|
||||
static String getFirstNumberFromString(String numString) {
|
||||
static String? getFirstNumberFromString(String numString) {
|
||||
final intInStr = RegExp(r'\d+');
|
||||
return intInStr.firstMatch(numString).group(0);
|
||||
return intInStr.firstMatch(numString)?.group(0);
|
||||
}
|
||||
|
||||
static void loadProducts(int businessId, int categoryId, int page, bool more,
|
||||
@@ -845,7 +837,7 @@ class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
static String getWeekDayName(BuildContext context, int timestamp, bool shortName) {
|
||||
static String? getWeekDayName(BuildContext context, int timestamp, bool shortName) {
|
||||
DateTime date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
||||
switch(date.weekday) {
|
||||
case 1:
|
||||
@@ -854,61 +846,54 @@ class Utils {
|
||||
} else {
|
||||
return S.of(context).monday;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (shortName) {
|
||||
return S.of(context).tue;
|
||||
} else {
|
||||
return S.of(context).tuesday;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (shortName) {
|
||||
return S.of(context).wed;
|
||||
} else {
|
||||
return S.of(context).wednesday;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (shortName) {
|
||||
return S.of(context).thu;
|
||||
} else {
|
||||
return S.of(context).thursday;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (shortName) {
|
||||
return S.of(context).fri;
|
||||
} else {
|
||||
return S.of(context).friday;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (shortName) {
|
||||
return S.of(context).sat;
|
||||
} else {
|
||||
return S.of(context).saturday;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (shortName) {
|
||||
return S.of(context).sun;
|
||||
} else {
|
||||
return S.of(context).sunday;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void stripePaymentIntent(Order order, String customerId, String paymentMethodId, String cardType,
|
||||
static void stripePaymentIntent(Order order, String? customerId, String paymentMethodId, String cardType,
|
||||
OnSuccess onSuccess, OnError onError,
|
||||
{
|
||||
String cardBrand,
|
||||
String cardCountry,
|
||||
int cardExpMonth,
|
||||
int cardExpYear,
|
||||
String cardFunding,
|
||||
String cardLast4,
|
||||
String? cardBrand,
|
||||
String? cardCountry,
|
||||
int? cardExpMonth,
|
||||
int? cardExpYear,
|
||||
String? cardFunding,
|
||||
String? cardLast4,
|
||||
}) {
|
||||
|
||||
HttpUtil.httpPost('v1/stripe-payment-intent',
|
||||
@@ -919,12 +904,12 @@ class Utils {
|
||||
'customer_id': customerId == null ? '' : customerId,
|
||||
'payment_method_id': paymentMethodId,
|
||||
'payment_method_type': cardType,
|
||||
'card_brand': cardBrand,
|
||||
'card_country': cardCountry,
|
||||
'card_exp_month': cardExpMonth,
|
||||
'card_exp_year': cardExpYear,
|
||||
'card_funding': cardFunding,
|
||||
'card_last4': cardLast4,
|
||||
'card_brand': cardBrand ?? '',
|
||||
'card_country': cardCountry ?? '',
|
||||
'card_exp_month': cardExpMonth ?? 0,
|
||||
'card_exp_year': cardExpYear ?? 0,
|
||||
'card_funding': cardFunding ?? '',
|
||||
'card_last4': cardLast4 ?? '',
|
||||
},
|
||||
isFormData: true,
|
||||
).catchError(onError);
|
||||
@@ -945,8 +930,8 @@ class Utils {
|
||||
|
||||
static int getProductLineInOrder(CartInfo cartInfo) {
|
||||
int qty = 0;
|
||||
for (CartLineItem lineItem in cartInfo.productList) {
|
||||
if (lineItem.product.id != null) {
|
||||
for (CartLineItem lineItem in cartInfo.productList!) {
|
||||
if (lineItem.product?.id != null) {
|
||||
qty += 1;
|
||||
}
|
||||
}
|
||||
@@ -954,10 +939,10 @@ class Utils {
|
||||
}
|
||||
|
||||
static void orderAgain(BuildContext context, CartInfo cartInfo) {
|
||||
cartInfo.productList.removeWhere((element) => element.product == null || element.product.id == null);
|
||||
cartInfo.productList!.removeWhere((element) => element.product == null || element.product!.id == null);
|
||||
store.dispatch(UpdateCartInfo(Utils.addCartInfoToCartInfoList(store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
Routes.router.navigateTo(context, '/checkout/${cartInfo.businessInfo.id}');
|
||||
Routes.router.navigateTo(context, '/checkout/${cartInfo.businessInfo!.id}');
|
||||
}
|
||||
|
||||
static String getOrderStatus(BuildContext context, int statusCode) {
|
||||
@@ -978,42 +963,42 @@ class Utils {
|
||||
}
|
||||
|
||||
static CartLineItem newCartLineItem(
|
||||
{int id,
|
||||
double price,
|
||||
Product product,
|
||||
String name,
|
||||
String description,
|
||||
double quantity,
|
||||
String parentUuid,
|
||||
{int? id,
|
||||
double? price,
|
||||
Product? product,
|
||||
String? name,
|
||||
String? description,
|
||||
double? quantity,
|
||||
String? parentUuid,
|
||||
}) {
|
||||
CartLineItem lineItem = CartLineItem();
|
||||
lineItem.unitPrice = price;
|
||||
lineItem.product = product;
|
||||
lineItem.name = product.name;
|
||||
lineItem.name = product?.name ?? '';
|
||||
lineItem.description = description;
|
||||
lineItem.quantity = quantity;
|
||||
lineItem.parentUuid = parentUuid;
|
||||
lineItem.parentUuid = parentUuid ?? '';
|
||||
return lineItem;
|
||||
}
|
||||
|
||||
static void addSubproductToCard(CartInfo cartInfo, CartLineItem lineItem) {
|
||||
if (lineItem.product.subproducts.length > 0) {
|
||||
for (int j = 0; j < lineItem.product.subproducts.length; j++) {
|
||||
cartInfo.productList.add(
|
||||
if (lineItem.product!.subproducts!.length > 0) {
|
||||
for (int j = 0; j < lineItem.product!.subproducts!.length; j++) {
|
||||
cartInfo.productList!.add(
|
||||
newCartLineItem(
|
||||
id: 0,
|
||||
price: 0.0,
|
||||
product: Product(
|
||||
lineItem.product.subproducts[j].product.id,
|
||||
lineItem.product.businessId,
|
||||
lineItem.product.subproducts[j].product.name,
|
||||
lineItem.product.subproducts[j].product.price,
|
||||
lineItem.product.subproducts[j].product.description,
|
||||
lineItem.product.subproducts[j].product.image,
|
||||
lineItem.product.subproducts[j].product.productAttributes
|
||||
lineItem.product!.subproducts![j].product.id,
|
||||
lineItem.product!.businessId!,
|
||||
lineItem.product!.subproducts![j].product.name,
|
||||
lineItem.product!.subproducts![j].product.price,
|
||||
lineItem.product!.subproducts![j].product.description,
|
||||
lineItem.product!.subproducts![j].product.image,
|
||||
lineItem.product!.subproducts![j].product.productAttributes
|
||||
),
|
||||
name: lineItem.product.subproducts[j].product.name,
|
||||
description: lineItem.product.subproducts[j].product.description,
|
||||
name: lineItem.product!.subproducts![j].product.name,
|
||||
description: lineItem.product!.subproducts![j].product.description,
|
||||
quantity: 1.0,
|
||||
parentUuid: lineItem.uuid
|
||||
)
|
||||
@@ -1024,16 +1009,16 @@ class Utils {
|
||||
|
||||
static void addSubproductQty(CartInfo cartInfo, CartLineItem lineItem,
|
||||
{bool remove = false}) {
|
||||
if (lineItem.product.subproducts.length > 0) {
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
CartLineItem lineItem1 = cartInfo.productList[i];
|
||||
if (lineItem.product!.subproducts!.length > 0) {
|
||||
for (var i = 0; i < cartInfo.productList!.length; i++) {
|
||||
CartLineItem lineItem1 = cartInfo.productList![i];
|
||||
if (lineItem1.parentUuid == lineItem.uuid) {
|
||||
for (var j = 0; j < lineItem.product.subproducts.length; j++) {
|
||||
if (lineItem.product.subproducts[j].product.id == lineItem1.product.id) {
|
||||
for (var j = 0; j < lineItem.product!.subproducts!.length; j++) {
|
||||
if (lineItem.product!.subproducts![j].product.id == lineItem1.product!.id) {
|
||||
if (remove) {
|
||||
lineItem1.quantity -= lineItem.product.subproducts[j].quantity;
|
||||
lineItem1.quantity = lineItem1.quantity! - lineItem.product!.subproducts![j].quantity;
|
||||
} else {
|
||||
lineItem1.quantity += lineItem.product.subproducts[j].quantity;
|
||||
lineItem1.quantity = lineItem1.quantity! + lineItem.product!.subproducts![j].quantity;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1044,7 +1029,7 @@ class Utils {
|
||||
}
|
||||
|
||||
static void removeSubproduct(CartInfo cartInfo, String uuid) {
|
||||
cartInfo.productList.removeWhere((element) => element.parentUuid == uuid);
|
||||
cartInfo.productList!.removeWhere((element) => element.parentUuid == uuid);
|
||||
}
|
||||
|
||||
static void openEmail(String email) async {
|
||||
@@ -1069,7 +1054,7 @@ class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
static Widget buildLine(String name, dynamic value, {double nameSize, double valueSize}) {
|
||||
static Widget buildLine(String name, dynamic value, {double? nameSize, double? valueSize}) {
|
||||
Row row = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -1119,7 +1104,7 @@ class Utils {
|
||||
}
|
||||
|
||||
class RuntimeError extends Error {
|
||||
final int code;
|
||||
final int? code;
|
||||
final String message;
|
||||
RuntimeError(this.message, {this.code});
|
||||
String toString() => "Runtime Error: $message";
|
||||
|
||||
Reference in New Issue
Block a user