final
This commit is contained in:
@@ -13,9 +13,9 @@ import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
class DesktopBuyService extends StatefulWidget {
|
||||
final Map<String, dynamic> data;
|
||||
final Map<String, dynamic>? data;
|
||||
|
||||
const DesktopBuyService(this.data, {Key key})
|
||||
const DesktopBuyService(this.data, {Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
||||
@@ -5,7 +5,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/breadcrumbs.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:gender_selection/gender_selection.dart';
|
||||
import 'package:gender_picker/gender_picker.dart';
|
||||
import 'package:gender_picker/source/enums.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
@@ -20,10 +21,9 @@ import '../../utils/utils.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
class DesktopEditAddress extends StatefulWidget {
|
||||
final Key key;
|
||||
final Address address;
|
||||
final Address? address;
|
||||
final int businessId;
|
||||
const DesktopEditAddress(this.address, {this.key, int businessId}) :
|
||||
const DesktopEditAddress(this.address, {Key? key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
@@ -45,12 +45,12 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
final emailController = TextEditingController();
|
||||
final faxController = TextEditingController();
|
||||
|
||||
String country;
|
||||
Gender _selectedGender;
|
||||
String? country;
|
||||
Gender? _selectedGender;
|
||||
|
||||
String _selectedProvince;
|
||||
String? _selectedProvince;
|
||||
|
||||
bool showLoading;
|
||||
bool showLoading = false;
|
||||
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
@@ -105,8 +105,8 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
.of(context)
|
||||
.contact_name,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -117,27 +117,25 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
},
|
||||
),
|
||||
),
|
||||
GenderSelection(
|
||||
maleText: S
|
||||
.of(context)
|
||||
.mr,
|
||||
femaleText: S
|
||||
.of(context)
|
||||
.ms,
|
||||
selectedGenderIconBackgroundColor: Colors.indigo,
|
||||
checkIconAlignment: Alignment.bottomRight,
|
||||
selectedGenderCheckIcon: Icons.check,
|
||||
onChanged: (Gender gender) {
|
||||
GenderPickerWithImage(
|
||||
onChanged: (Gender? gender) {
|
||||
_selectedGender = gender;
|
||||
},
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 400),
|
||||
isCircular: true,
|
||||
isSelectedGenderIconCircular: true,
|
||||
opacityOfGradient: 0.6,
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
size: 50,
|
||||
maleText: S.of(context).mr,
|
||||
femaleText: S.of(context).ms,
|
||||
selectedGender: _selectedGender,
|
||||
showOtherGender: false,
|
||||
verticalAlignedText: false,
|
||||
selectedGenderTextStyle: TextStyle(
|
||||
color: Color(0xFF8b32a8), fontWeight: FontWeight.bold),
|
||||
unSelectedGenderTextStyle: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.normal),
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 200),
|
||||
isCircular: true,
|
||||
opacityOfGradient: 0.5,
|
||||
padding: const EdgeInsets.all(3),
|
||||
size: 50,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
@@ -160,8 +158,8 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
.of(context)
|
||||
.mobile_phone_number,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -192,8 +190,8 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
.of(context)
|
||||
.street_line_1,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -246,8 +244,8 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
.of(context)
|
||||
.city,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -316,8 +314,8 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
.of(context)
|
||||
.postal_code,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -361,8 +359,8 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
.of(context)
|
||||
.email,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
validator: (String? value) {
|
||||
if (value != null && value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
return S
|
||||
.of(context)
|
||||
.email_is_not_valid;
|
||||
@@ -496,29 +494,29 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
super.initState();
|
||||
setState(() {
|
||||
showLoading = false;
|
||||
_selectedProvince = widget.address.state;
|
||||
cityController.text = widget.address.city;
|
||||
postalCodeController.text = widget.address.zip;
|
||||
streetLine1Controller.text = widget.address.addressLine1;
|
||||
streetLine2Controller.text = widget.address.addressLine2;
|
||||
_selectedGender = widget.address.gender == 1 ? Gender.Male : Gender.Female;
|
||||
country = widget.address.country;
|
||||
contactNameController.text = widget.address.contactName;
|
||||
phoneController.text = widget.address.phone;
|
||||
emailController.text = widget.address.email;
|
||||
faxController.text = widget.address.fax;
|
||||
_selectedProvince = widget.address?.state;
|
||||
cityController.text = widget.address?.city ?? '';
|
||||
postalCodeController.text = widget.address?.zip ?? '';
|
||||
streetLine1Controller.text = widget.address?.addressLine1 ?? '';
|
||||
streetLine2Controller.text = widget.address?.addressLine2 ?? '';
|
||||
_selectedGender = widget.address?.gender == 1 ? Gender.Male : Gender.Female;
|
||||
country = widget.address?.country;
|
||||
contactNameController.text = widget.address?.contactName ?? '';
|
||||
phoneController.text = widget.address?.phone ?? '';
|
||||
emailController.text = widget.address?.email ?? '';
|
||||
faxController.text = widget.address?.fax ?? '';
|
||||
});
|
||||
}
|
||||
|
||||
void _saveEditAddress() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
showLoading = true;
|
||||
});
|
||||
}
|
||||
HttpUtil.httpPatch('v1/addresses/${widget.address.id}', (response) {
|
||||
HttpUtil.httpPatch('v1/addresses/${widget.address?.id}', (response) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
showLoading = false;
|
||||
@@ -532,7 +530,7 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
}
|
||||
},
|
||||
body: {
|
||||
'id': widget.address.id,
|
||||
'id': widget.address?.id,
|
||||
'name': contactNameController.text.trim(),
|
||||
'address_line1': streetLine1Controller.text.trim(),
|
||||
'address_line2': streetLine2Controller.text.trim(),
|
||||
@@ -562,7 +560,7 @@ class DesktopEditAddressState extends State<DesktopEditAddress> {
|
||||
showLoading = true;
|
||||
});
|
||||
}
|
||||
HttpUtil.httpDelete('v1/addresses/${widget.address.id}', (response) {
|
||||
HttpUtil.httpDelete('v1/addresses/${widget.address?.id}', (response) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
showLoading = false;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
|
||||
class DesktopIndexMainContent1 extends StatefulWidget {
|
||||
final String message;
|
||||
const DesktopIndexMainContent1(this.message, {Key key}) : super(key: key);
|
||||
final String? message;
|
||||
const DesktopIndexMainContent1(this.message, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -37,7 +36,7 @@ class DesktopIndexMainContent1State extends State<DesktopIndexMainContent1> {
|
||||
padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 30.0),
|
||||
child: Container(
|
||||
child: Text(
|
||||
widget.message,
|
||||
widget.message ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
||||
@@ -5,8 +5,8 @@ import '../../widgets/general/text_link.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class DesktopIndexMainContent2 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const DesktopIndexMainContent2(this.content, {Key key}) : super(key: key);
|
||||
final Map<String, dynamic>? content;
|
||||
const DesktopIndexMainContent2(this.content, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -54,7 +54,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['minipos']}',
|
||||
'${widget.content?['minipos']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -66,7 +66,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
width: mainSpace / 2 - 100.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['point_of_sale_system_solution']}',
|
||||
'${widget.content?['point_of_sale_system_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
@@ -80,7 +80,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'https:${widget.content['minipos_image']['image']}',
|
||||
'https:${widget.content?['minipos_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
@@ -101,7 +101,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow']}',
|
||||
'${widget.content?['igoshow']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -113,7 +113,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
width: mainSpace / 2 - 100.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow_solution']}',
|
||||
'${widget.content?['igoshow_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
@@ -127,7 +127,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'https:${widget.content['igoshow_image']['image']}',
|
||||
'https:${widget.content?['igoshow_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
@@ -149,7 +149,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['minipos_features'] as List).length; i++) {
|
||||
for (int i = 0; i < (widget.content?['minipos_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -166,7 +166,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
width: width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['minipos_features'] as List)[i]}',
|
||||
'${(widget.content?['minipos_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
@@ -195,7 +195,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['igoshow_features'] as List).length; i++) {
|
||||
for (int i = 0; i < (widget.content?['igoshow_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -212,7 +212,7 @@ class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
width: width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['igoshow_features'] as List)[i]}',
|
||||
'${(widget.content?['igoshow_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
|
||||
@@ -6,8 +6,8 @@ import 'package:flutter_wisetronic/widgets/general/text_link.dart';
|
||||
import '../../constants.dart';
|
||||
|
||||
class DesktopIndexMainContent3 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const DesktopIndexMainContent3(this.content, {Key key}) : super(key: key);
|
||||
final Map<String, dynamic>? content;
|
||||
const DesktopIndexMainContent3(this.content, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
|
||||
@@ -14,12 +14,12 @@ import '../../widgets/general/breadcrumbs.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
class DesktopNavigationBar extends StatefulWidget {
|
||||
final bool hasBack;
|
||||
final List<BreadCrumb> breadCrumbs;
|
||||
final Widget shoppingCart;
|
||||
final OnBackPress onBackPress;
|
||||
final bool? hasBack;
|
||||
final List<BreadCrumb>? breadCrumbs;
|
||||
final Widget? shoppingCart;
|
||||
final OnBackPress? onBackPress;
|
||||
|
||||
const DesktopNavigationBar({Key key, this.hasBack, this.breadCrumbs,
|
||||
const DesktopNavigationBar({Key? key, this.hasBack, this.breadCrumbs,
|
||||
this.shoppingCart, this.onBackPress}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -30,13 +30,13 @@ class DesktopNavigationBar extends StatefulWidget {
|
||||
}
|
||||
|
||||
class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
User _user;
|
||||
User? _user;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget sc = SizedBox.shrink();
|
||||
if (widget.shoppingCart != null) {
|
||||
sc = widget.shoppingCart;
|
||||
sc = widget.shoppingCart!;
|
||||
}
|
||||
Widget breadCrumbBar = SizedBox.shrink();
|
||||
if (widget.breadCrumbs != null && widget.breadCrumbs.length > 0) {
|
||||
@@ -51,8 +51,8 @@ class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
Expanded(
|
||||
child: BreadCrumbs(
|
||||
widget.hasBack ?? false,
|
||||
onBackPress: widget.onBackPress,
|
||||
breadCrumbs: widget.breadCrumbs,
|
||||
onBackPress: widget.onBackPress!,
|
||||
breadCrumbs: widget.breadCrumbs!,
|
||||
),
|
||||
),
|
||||
sc,
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import 'package:email_validator/email_validator.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/breadcrumbs.dart';
|
||||
import 'package:gender_selection/gender_selection.dart';
|
||||
import 'package:gender_picker/gender_picker.dart';
|
||||
import 'package:gender_picker/source/enums.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
@@ -14,10 +15,9 @@ import '../../utils/http_util.dart';
|
||||
import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
class DesktopNewAddress extends StatefulWidget {
|
||||
final Key key;
|
||||
final LocatedAddress locatedAddress;
|
||||
final int businessId;
|
||||
const DesktopNewAddress({this.key, this.locatedAddress, this.businessId}) : super(key: key);
|
||||
final LocatedAddress? locatedAddress;
|
||||
final int? businessId;
|
||||
const DesktopNewAddress({Key? key, this.locatedAddress, this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -39,9 +39,9 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
final faxController = TextEditingController();
|
||||
|
||||
String country = 'CA';
|
||||
Gender _selectedGender;
|
||||
Gender? _selectedGender;
|
||||
|
||||
String _selectedProvince;
|
||||
String? _selectedProvince;
|
||||
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
@@ -97,31 +97,33 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).contact_name,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).contact_name_is_required;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
GenderSelection(
|
||||
maleText: S.of(context).mr,
|
||||
femaleText: S.of(context).ms,
|
||||
selectedGenderIconBackgroundColor: Colors.indigo,
|
||||
checkIconAlignment: Alignment.bottomRight,
|
||||
selectedGenderCheckIcon: Icons.check,
|
||||
onChanged: (Gender gender) {
|
||||
GenderPickerWithImage(
|
||||
onChanged: (Gender? gender) {
|
||||
_selectedGender = gender;
|
||||
},
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 400),
|
||||
isCircular: true,
|
||||
isSelectedGenderIconCircular: true,
|
||||
opacityOfGradient: 0.6,
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
size: 50,
|
||||
maleText: S.of(context).mr,
|
||||
femaleText: S.of(context).ms,
|
||||
selectedGender: _selectedGender,
|
||||
showOtherGender: false,
|
||||
verticalAlignedText: false,
|
||||
selectedGenderTextStyle: TextStyle(
|
||||
color: Color(0xFF8b32a8), fontWeight: FontWeight.bold),
|
||||
unSelectedGenderTextStyle: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.normal),
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 200),
|
||||
isCircular: true,
|
||||
opacityOfGradient: 0.5,
|
||||
padding: const EdgeInsets.all(3),
|
||||
size: 50,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 0.0),
|
||||
@@ -141,8 +143,8 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).mobile_phone_number,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).mobile_phone_number_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -166,8 +168,8 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).street_line_1,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).street_line_1_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -210,8 +212,8 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).city,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).city_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -256,8 +258,8 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).postal_code,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).postal_code_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -291,8 +293,8 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).email,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
return S.of(context).email_is_not_valid;
|
||||
}
|
||||
return null;
|
||||
@@ -377,15 +379,15 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
super.initState();
|
||||
setState(() {
|
||||
if (widget.locatedAddress != null) {
|
||||
if (provinces.contains(widget.locatedAddress.province)) {
|
||||
_selectedProvince = widget.locatedAddress.province;
|
||||
if (provinces.contains(widget.locatedAddress?.province)) {
|
||||
_selectedProvince = widget.locatedAddress?.province;
|
||||
}
|
||||
cityController.text = widget.locatedAddress.city;
|
||||
postalCodeController.text = widget.locatedAddress.postalCode;
|
||||
streetLine1Controller.text = (widget.locatedAddress.streetNumber != null
|
||||
&& widget.locatedAddress.streetNumber.isNotEmpty
|
||||
? widget.locatedAddress.streetNumber + ' ' : '')
|
||||
+ widget.locatedAddress.streetName;
|
||||
cityController.text = widget.locatedAddress?.city ?? '';
|
||||
postalCodeController.text = widget.locatedAddress?.postalCode ?? '';
|
||||
streetLine1Controller.text = (widget.locatedAddress?.streetNumber != null
|
||||
&& widget.locatedAddress!.streetNumber.isNotEmpty
|
||||
? widget.locatedAddress!.streetNumber + ' ' : '')
|
||||
+ widget.locatedAddress!.streetName;
|
||||
} else {
|
||||
_selectedProvince = 'Ontario';
|
||||
}
|
||||
@@ -395,11 +397,11 @@ class DesktopNewAddressState extends State<DesktopNewAddress> {
|
||||
}
|
||||
|
||||
void _saveNewAddress() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
|
||||
HttpUtil.httpPost('v1/addresses', (response) {
|
||||
if (widget.businessId > 0) {
|
||||
if (widget.businessId != null && widget.businessId! > 0) {
|
||||
Routes.router.navigateTo(context, '/checkout/${widget.businessId}', replace: true);
|
||||
} else {
|
||||
Routes.router.navigateTo(context, '/my-addresses/${widget.businessId}', replace: true);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stripe_sdk/stripe_sdk.dart';
|
||||
import 'package:stripe_sdk/stripe_sdk_ui.dart';
|
||||
import '../../vendor/stripe_sdk/lib/stripe_sdk_ui.dart';
|
||||
import '../../utils/mini_stripe_api.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
@@ -20,11 +20,10 @@ import '../../widgets/general/navigationbar.dart';
|
||||
|
||||
|
||||
class DesktopStripePayWeb extends StatefulWidget {
|
||||
final Key key;
|
||||
final Order order;
|
||||
final PaymentPlatform paymentPlatform;
|
||||
final StripePaymentMethod stripePaymentMethod;
|
||||
const DesktopStripePayWeb(this.order, this.paymentPlatform, {this.key, this.stripePaymentMethod});
|
||||
final StripePaymentMethod? stripePaymentMethod;
|
||||
const DesktopStripePayWeb(this.order, this.paymentPlatform, {Key? key, this.stripePaymentMethod});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -39,9 +38,9 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
final formKey = GlobalKey<FormState>();
|
||||
final card = StripeCard();
|
||||
|
||||
CardForm form;
|
||||
CardForm? form;
|
||||
|
||||
bool isSubmitting;
|
||||
bool isSubmitting = false;
|
||||
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
@@ -69,23 +68,37 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
form = CardForm(card: card, formKey: formKey, displayPostalCode: false,);
|
||||
body = ListView(
|
||||
children: <Widget>[
|
||||
form,
|
||||
form!,
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0, right: 16.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: ElevatedButton(
|
||||
child: ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Colors.green,
|
||||
foregroundColor: Colors.white,
|
||||
padding:
|
||||
EdgeInsets.only(left: 32, right: 32, top: 20, bottom: 20),
|
||||
elevation: 2.0,
|
||||
shape: new RoundedRectangleBorder(
|
||||
borderRadius: new BorderRadius.circular(10.0),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).submit,
|
||||
icon: Icon(
|
||||
Icons.check,
|
||||
size: 32.0,
|
||||
color: Colors.yellow,
|
||||
),
|
||||
label: Text(
|
||||
S.of(context).pay,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (formKey.currentState.validate()) {
|
||||
formKey.currentState.save();
|
||||
if (formKey.currentState != null && formKey.currentState!.validate()) {
|
||||
formKey.currentState!.save();
|
||||
_paymentRequestWithCard(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -131,7 +144,7 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
isSubmitting = false;
|
||||
StripeApi.init(widget.paymentPlatform.publishableKey);
|
||||
MiniStripeApi.init(widget.paymentPlatform.publishableKey!);
|
||||
}
|
||||
|
||||
SnackBar messageSnackBar(BuildContext context, String message) {
|
||||
@@ -160,12 +173,12 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
}
|
||||
|
||||
_paymentWithPaymentMethod(BuildContext context) async {
|
||||
Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod.customerId,
|
||||
widget.stripePaymentMethod.paymentMethodId,
|
||||
widget.stripePaymentMethod.paymentMethodType, (response) async {
|
||||
Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod?.customerId,
|
||||
widget.stripePaymentMethod!.paymentMethodId,
|
||||
widget.stripePaymentMethod!.paymentMethodType, (response) async {
|
||||
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
await StripeApi.instance.confirmPaymentIntent(
|
||||
await MiniStripeApi.instance.confirmPaymentIntent(
|
||||
response.data[Constants.STRIPE_CLIENT_SECRET],
|
||||
data: {
|
||||
'payment_method': response.data['payment_method'],
|
||||
@@ -173,7 +186,7 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
).then((result2) {
|
||||
if (result2['status'] == Constants.STRIPE_STATUS_SUCCEDED) {
|
||||
Utils.stripeChargedSuccess(widget.order,
|
||||
widget.stripePaymentMethod.paymentMethodId,
|
||||
widget.stripePaymentMethod!.paymentMethodId,
|
||||
result2['id'], (response) {
|
||||
if (isSubmitting) {
|
||||
Navigator.of(context).pop();
|
||||
@@ -198,11 +211,11 @@ class DesktopStripePayWebState extends State<DesktopStripePayWeb> {
|
||||
_paymentRequestWithCard(BuildContext context) async {
|
||||
isSubmitting = true;
|
||||
Utils.showSubmitDialog(context);
|
||||
await StripeApi.instance.createPaymentMethodFromCard(card)
|
||||
await MiniStripeApi.instance.createPaymentMethodFromCard(card)
|
||||
.then((result) {
|
||||
Utils.stripePaymentIntent(widget.order, null, result['id'], result['type'], (response) async {
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
await StripeApi.instance.confirmPaymentIntent(
|
||||
await MiniStripeApi.instance.confirmPaymentIntent(
|
||||
response.data[Constants.STRIPE_CLIENT_SECRET],
|
||||
data: {
|
||||
'payment_method': response.data['payment_method'],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
@@ -17,16 +17,16 @@ import '../../store/store.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class AddRemoveButton extends StatefulWidget {
|
||||
final Product product;
|
||||
final Product? product;
|
||||
final Business business;
|
||||
final bool addOnly;
|
||||
final int cartLineItemIndex;
|
||||
final bool addToBasket;
|
||||
final bool onHovor;
|
||||
final bool? addOnly;
|
||||
final int? cartLineItemIndex;
|
||||
final bool? addToBasket;
|
||||
final bool? onHovor;
|
||||
|
||||
AddRemoveButton({
|
||||
this.product,
|
||||
this.business,
|
||||
required this.business,
|
||||
this.addOnly = false,
|
||||
this.cartLineItemIndex = -1,
|
||||
this.addToBasket = false,
|
||||
@@ -40,7 +40,7 @@ class AddRemoveButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
int _qty;
|
||||
int? _qty;
|
||||
var zeroColor = const Color(0xFFEFEFEF);
|
||||
var qtyColor = const Color(0xFFFF6666);
|
||||
var zeroFontColor = const Color(0xFF888888);
|
||||
@@ -48,7 +48,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
|
||||
var d = 1;
|
||||
|
||||
CartInfo cartInfo;
|
||||
CartInfo? cartInfo;
|
||||
|
||||
GlobalKey startKey = GlobalKey();
|
||||
|
||||
@@ -59,14 +59,14 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.product.leftNum == null) {
|
||||
if (widget.product?.leftNum == null) {
|
||||
_qty = 0;
|
||||
cartInfo = Utils.getCartInfoByBusiness(store.state.cartInfos, widget.business);
|
||||
if (cartInfo != null) {
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.id == widget.product.id
|
||||
&& cartInfo.productList[i].unitPrice == 0.0) {
|
||||
_qty = cartInfo.productList[i].quantity.round();
|
||||
for (var i = 0; i < cartInfo!.productList!.length; i++) {
|
||||
if (cartInfo!.productList?[i].product?.id == widget.product?.id
|
||||
&& cartInfo!.productList?[i].unitPrice == 0.0) {
|
||||
_qty = cartInfo!.productList?[i].quantity?.round();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
),
|
||||
);
|
||||
}
|
||||
if (widget.product.leftNum <= 0) {
|
||||
if (widget.product!.leftNum! <= 0) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 8.0, right: 8.0),
|
||||
child: Text(
|
||||
@@ -100,19 +100,19 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
),
|
||||
);
|
||||
}
|
||||
if (widget.addToBasket) {
|
||||
if (widget.addToBasket!) {
|
||||
_qty = 0;
|
||||
cartInfo = Utils.getCartInfoByBusiness(store.state.cartInfos, widget.business);
|
||||
if (cartInfo != null) {
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.id == widget.product.id) {
|
||||
_qty = cartInfo.productList[i].quantity.round();
|
||||
for (var i = 0; i < cartInfo!.productList!.length; i++) {
|
||||
if (cartInfo!.productList?[i].product?.id == widget.product?.id) {
|
||||
_qty = cartInfo!.productList?[i].quantity?.round();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_qty > 0) {
|
||||
return Badge(
|
||||
if (_qty! > 0) {
|
||||
return badges.Badge(
|
||||
badgeContent: Text(
|
||||
'$_qty',
|
||||
style: TextStyle(
|
||||
@@ -120,14 +120,17 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
fontSize: 17.0,
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.all(10),
|
||||
position: BadgePosition.topEnd(top: -15, end: -10),
|
||||
badgeColor: Colors.lightBlueAccent,
|
||||
badgeStyle: badges.BadgeStyle(
|
||||
padding: EdgeInsets.all(10),
|
||||
badgeColor: Colors.lightBlueAccent,
|
||||
),
|
||||
position: badges.BadgePosition.topEnd(top: -15, end: -10),
|
||||
child: ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.redAccent,
|
||||
onPrimary: Colors.white,
|
||||
padding: EdgeInsets.only(left: 32, right: 32, top: 20, bottom: 20),
|
||||
backgroundColor: Colors.redAccent,
|
||||
foregroundColor: Colors.white,
|
||||
padding:
|
||||
EdgeInsets.only(left: 32, right: 32, top: 20, bottom: 20),
|
||||
elevation: 2.0,
|
||||
shape: new RoundedRectangleBorder(
|
||||
borderRadius: new BorderRadius.circular(10.0),
|
||||
@@ -154,7 +157,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
} else {
|
||||
return ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.redAccent,
|
||||
backgroundColor: Colors.redAccent,
|
||||
padding: EdgeInsets.only(left: 32, right: 32, top: 20, bottom: 20),
|
||||
elevation: 2.0,
|
||||
shape: new RoundedRectangleBorder(
|
||||
@@ -179,7 +182,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
},
|
||||
);
|
||||
}
|
||||
} else if (widget.addOnly) {
|
||||
} else if (widget.addOnly!) {
|
||||
return Container(
|
||||
key: startKey,
|
||||
padding: EdgeInsets.all(0.0),
|
||||
@@ -197,15 +200,15 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
_qty = 0;
|
||||
cartInfo = Utils.getCartInfoByBusiness(store.state.cartInfos, widget.business);
|
||||
if (cartInfo != null) {
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
if (cartInfo.productList[i].product.id == widget.product.id) {
|
||||
_qty = cartInfo.productList[i].quantity.round();
|
||||
for (var i = 0; i < cartInfo!.productList!.length; i++) {
|
||||
if (cartInfo!.productList?[i].product?.id == widget.product?.id) {
|
||||
_qty = cartInfo!.productList?[i].quantity?.round();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (widget.product.productAttributes != null &&
|
||||
widget.product.productAttributes.length > 0 && widget.cartLineItemIndex == -1) {
|
||||
if (widget.product!.productAttributes != null &&
|
||||
widget.product!.productAttributes!.length > 0 && widget.cartLineItemIndex == -1) {
|
||||
return new Row(
|
||||
key: startKey,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
@@ -219,13 +222,13 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
style: new TextStyle(
|
||||
fontSize: 13.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: _qty > 0 ? qtyFontColor : zeroFontColor
|
||||
color: _qty! > 0 ? qtyFontColor : zeroFontColor
|
||||
),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.all(5.0).copyWith(left: 10.0, right: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: _qty > 0 ? qtyColor : zeroColor,
|
||||
color: _qty! > 0 ? qtyColor : zeroColor,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(10.0),
|
||||
@@ -242,7 +245,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
],
|
||||
);
|
||||
} else {
|
||||
if (!widget.onHovor && _qty == 0) {
|
||||
if (!widget.onHovor! && _qty == 0) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return new Row(
|
||||
@@ -258,13 +261,13 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
style: new TextStyle(
|
||||
fontSize: 13.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: _qty > 0 ? qtyFontColor : zeroFontColor
|
||||
color: _qty! > 0 ? qtyFontColor : zeroFontColor
|
||||
),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.all(5.0).copyWith(left: 10.0, right: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: _qty > 0 ? qtyColor : zeroColor,
|
||||
color: _qty! > 0 ? qtyColor : zeroColor,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(10.0),
|
||||
@@ -299,7 +302,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (_qty > 0) {
|
||||
if (_qty! > 0) {
|
||||
_removeFromCart(context);
|
||||
}
|
||||
},
|
||||
@@ -312,7 +315,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
|
||||
void _addToCart(BuildContext context) {
|
||||
if (widget.cartLineItemIndex != -1) {
|
||||
if (cartInfo.productList[widget.cartLineItemIndex].quantity + 1.0 > widget.product.leftNum) {
|
||||
if (cartInfo!.productList![widget.cartLineItemIndex!].quantity! + 1.0 > widget.product!.leftNum!) {
|
||||
Fluttertoast.showToast(
|
||||
msg: S.of(context).product_insufficient,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
@@ -321,23 +324,23 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
textColor: Colors.white
|
||||
);
|
||||
} else {
|
||||
cartInfo.productList[widget.cartLineItemIndex].quantity += 1.0;
|
||||
Utils.addSubproductQty(cartInfo, cartInfo.productList[widget.cartLineItemIndex]);
|
||||
cartInfo!.productList![widget.cartLineItemIndex!].quantity = cartInfo!.productList![widget.cartLineItemIndex!].quantity! + 1.0;
|
||||
Utils.addSubproductQty(cartInfo!, cartInfo!.productList![widget.cartLineItemIndex!]);
|
||||
store.dispatch(UpdateCartInfo(
|
||||
Utils.addCartInfoToCartInfoList(store.state.cartInfos, cartInfo)));
|
||||
Utils.addCartInfoToCartInfoList(store.state.cartInfos, cartInfo!)));
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
}
|
||||
} else {
|
||||
if (widget.product.productAttributes.length > 0) {
|
||||
if (widget.product!.productAttributes!.length > 0) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) =>
|
||||
new AttributeSelection(
|
||||
product: widget.product, business: widget.business, startKey: startKey,)),
|
||||
product: widget.product!, business: widget.business, startKey: startKey,)),
|
||||
);
|
||||
} else {
|
||||
eventBus.fire(new OnProductWillAddToCart(widget.product, {},
|
||||
widget.product.price, widget.product.description,
|
||||
eventBus.fire(new OnProductWillAddToCart(widget.product!, {},
|
||||
widget.product!.price!, widget.product!.description!,
|
||||
widget.business, buttonKey: startKey));
|
||||
}
|
||||
}
|
||||
@@ -345,7 +348,7 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
|
||||
void _removeFromCart(BuildContext context) {
|
||||
if (widget.cartLineItemIndex != -1) {
|
||||
if (cartInfo.productList[widget.cartLineItemIndex].quantity <= 1) {
|
||||
if (cartInfo!.productList![widget.cartLineItemIndex!].quantity! <= 1) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
@@ -375,23 +378,23 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
||||
}
|
||||
} else {
|
||||
eventBus.fire(new OnProductWillRemoveFromCart(
|
||||
widget.product, -1, widget.business));
|
||||
widget.product!, -1, widget.business));
|
||||
}
|
||||
}
|
||||
|
||||
void _removeCartLineItem() {
|
||||
if (cartInfo.productList[widget.cartLineItemIndex].quantity <= 1) {
|
||||
String uuid = cartInfo.productList[widget.cartLineItemIndex].uuid;
|
||||
cartInfo.productList.removeAt(widget.cartLineItemIndex);
|
||||
Utils.removeSubproduct(cartInfo, uuid);
|
||||
if (cartInfo!.productList![widget.cartLineItemIndex!].quantity! <= 1) {
|
||||
String uuid = cartInfo!.productList![widget.cartLineItemIndex!].uuid!;
|
||||
cartInfo!.productList?.removeAt(widget.cartLineItemIndex!);
|
||||
Utils.removeSubproduct(cartInfo!, uuid);
|
||||
} else {
|
||||
cartInfo.productList[widget.cartLineItemIndex].quantity -= 1;
|
||||
Utils.addSubproductQty(cartInfo, cartInfo.productList[widget.cartLineItemIndex], remove: true);
|
||||
cartInfo!.productList![widget.cartLineItemIndex!].quantity = cartInfo!.productList![widget.cartLineItemIndex!].quantity! - 1;
|
||||
Utils.addSubproductQty(cartInfo!, cartInfo!.productList![widget.cartLineItemIndex!], remove: true);
|
||||
}
|
||||
if (cartInfo.productList.length <= 0) {
|
||||
if (cartInfo!.productList!.length <= 0) {
|
||||
store.dispatch(new UpdateCartInfo(Utils.removeCartInfoFromCartInfoList(store.state.cartInfos, cartInfo)));
|
||||
} else {
|
||||
store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(store.state.cartInfos, cartInfo)));
|
||||
store.dispatch(new UpdateCartInfo(Utils.addCartInfoToCartInfoList(store.state.cartInfos, cartInfo!)));
|
||||
}
|
||||
eventBus.fire(new OnCartInfoUpdated());
|
||||
}
|
||||
|
||||
@@ -5,23 +5,23 @@ import 'popup_animation_widget.dart';
|
||||
|
||||
class AnimationPointManager {
|
||||
List<AnimatedWidget> list = [];
|
||||
static AnimationController controller1;
|
||||
static AnimationController controller2;
|
||||
static AnimationController? controller1;
|
||||
static AnimationController? controller2;
|
||||
|
||||
Future<void> addParabolicAniamtion({
|
||||
@required TickerProvider vsync,
|
||||
@required GlobalKey stackKey,
|
||||
@required GlobalKey startKey,
|
||||
@required GlobalKey endKey,
|
||||
@required Duration duration,
|
||||
@required AnimationStatusListener statusListener,
|
||||
required TickerProvider vsync,
|
||||
required GlobalKey stackKey,
|
||||
required GlobalKey startKey,
|
||||
required GlobalKey endKey,
|
||||
required Duration duration,
|
||||
required AnimationStatusListener statusListener,
|
||||
Color color = Colors.red,
|
||||
double size = 20,
|
||||
Offset startAdjustOffset = Offset.zero,
|
||||
Offset endAdjustOffset = Offset.zero,
|
||||
}) async {
|
||||
controller1 = createController(vsync, duration);
|
||||
Animation animation = createAnimation(controller1);
|
||||
Animation<double> animation = createAnimation(controller1);
|
||||
|
||||
AnimatedWidget animatedWidget = ParabolicAnimationWidget(
|
||||
animation: animation,
|
||||
@@ -37,9 +37,9 @@ class AnimationPointManager {
|
||||
statusListener(AnimationStatus.dismissed);
|
||||
|
||||
try {
|
||||
await controller1.forward().orCancel;
|
||||
await controller1?.forward().orCancel;
|
||||
list.remove(animatedWidget);
|
||||
controller1.dispose();
|
||||
controller1?.dispose();
|
||||
print('Controller1 disposed');
|
||||
} on TickerCanceled {
|
||||
print("Ticker Canceled");
|
||||
@@ -51,31 +51,31 @@ class AnimationPointManager {
|
||||
}
|
||||
|
||||
Future<void> addPopupAniamtion({
|
||||
@required TickerProvider vsync,
|
||||
@required GlobalKey stackKey,
|
||||
@required GlobalKey startKey,
|
||||
@required Widget child,
|
||||
Duration duration,
|
||||
required TickerProvider vsync,
|
||||
required GlobalKey stackKey,
|
||||
required GlobalKey startKey,
|
||||
required Widget child,
|
||||
required Duration duration,
|
||||
Offset popupOffset = Offset.zero,
|
||||
AnimationStatusListener statusListener,
|
||||
AnimationStatusListener? statusListener,
|
||||
}) async {
|
||||
controller2 = createController(vsync, duration);
|
||||
|
||||
AnimatedWidget animatedWidget = PopupAnimationWidget(
|
||||
animation: controller2.view,
|
||||
animation: controller2!.view,
|
||||
stackKey: stackKey,
|
||||
startKey: startKey,
|
||||
child: child,
|
||||
popupOffset: popupOffset,
|
||||
);
|
||||
list.add(animatedWidget);
|
||||
statusListener(AnimationStatus.dismissed);
|
||||
if (statusListener != null) statusListener(AnimationStatus.dismissed);
|
||||
|
||||
try {
|
||||
await controller2.forward().orCancel;
|
||||
await controller2.reverse().orCancel;
|
||||
await controller2?.forward().orCancel;
|
||||
await controller2?.reverse().orCancel;
|
||||
list.remove(animatedWidget);
|
||||
controller2.dispose();
|
||||
controller2?.dispose();
|
||||
print('Controller2 disposed');
|
||||
} on TickerCanceled {
|
||||
print("Ticker Canceled");
|
||||
@@ -83,7 +83,7 @@ class AnimationPointManager {
|
||||
print('Error: $error');
|
||||
}
|
||||
|
||||
statusListener(AnimationStatus.completed);
|
||||
if (statusListener != null) statusListener(AnimationStatus.completed);
|
||||
}
|
||||
|
||||
static AnimationController createController(
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'rules.dart';
|
||||
import 'options_base.dart';
|
||||
|
||||
class CheckOptions extends OptionsBase {
|
||||
CheckOptions({@required Product product, @required int index, @required Map<String, dynamic> selections})
|
||||
CheckOptions({required Product product, required int index, required Map<String, dynamic> selections})
|
||||
: super(product: product, index: index, selections: selections);
|
||||
|
||||
@override
|
||||
@@ -50,14 +50,14 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
S.of(context).check_option_select_token(product.productAttributes[this.index].name),
|
||||
S.of(context).check_option_select_token(product!.productAttributes![this.index!].name),
|
||||
style: new TextStyle(
|
||||
fontSize: 12.5,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
new Text(
|
||||
product.productAttributes[this.index].required ? S.of(context).check_option_is_required : S.of(context).check_option_is_optional,
|
||||
product!.productAttributes![this.index!].required ? S.of(context).check_option_is_required : S.of(context).check_option_is_optional,
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: new Color(0xFF999999)
|
||||
@@ -95,25 +95,25 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
'adjust_amount': adjustAmount
|
||||
};
|
||||
var cloneSelections = json.decode(json.encode(selections));
|
||||
int idx = Utils.selectionsContains(cloneSelections, product.productAttributes[index].name, name);
|
||||
int idx = Utils.selectionsContains(cloneSelections, product!.productAttributes![index!].name, name);
|
||||
if (idx != -1) {
|
||||
(cloneSelections[product.productAttributes[index].name.toUpperCase()] as List).removeAt(idx);
|
||||
} else if (cloneSelections.containsKey(product.productAttributes[index].name.toUpperCase())) {
|
||||
(cloneSelections[product.productAttributes[index].name.toUpperCase()] as List).add(opt);
|
||||
(cloneSelections[product!.productAttributes![index!].name.toUpperCase()] as List).removeAt(idx);
|
||||
} else if (cloneSelections.containsKey(product!.productAttributes![index!].name.toUpperCase())) {
|
||||
(cloneSelections[product!.productAttributes![index!].name.toUpperCase()] as List).add(opt);
|
||||
} else {
|
||||
cloneSelections[product.productAttributes[index].name.toUpperCase()] = [opt];
|
||||
cloneSelections[product!.productAttributes![index!].name.toUpperCase()] = [opt];
|
||||
}
|
||||
|
||||
if (idx != -1 && (cloneSelections[product.productAttributes[index].name.toUpperCase()] as List).length == 0) {
|
||||
cloneSelections.remove(product.productAttributes[index].name.toUpperCase());
|
||||
if (idx != -1 && (cloneSelections[product!.productAttributes![index!].name.toUpperCase()] as List).length == 0) {
|
||||
cloneSelections.remove(product!.productAttributes![index!].name.toUpperCase());
|
||||
}
|
||||
|
||||
setOptionsStateDisabled(product.productAttributes[index].name, false);
|
||||
setOptionsStateDisabled(product!.productAttributes![index!].name, false);
|
||||
|
||||
setState(() {
|
||||
selections = cloneSelections;
|
||||
});
|
||||
eventBus.fire(new OnAttributeSelectionsChanged(selections));
|
||||
eventBus.fire(new OnAttributeSelectionsChanged(selections!));
|
||||
}
|
||||
|
||||
Widget _getOptionWidget() {
|
||||
@@ -121,20 +121,20 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
children: <Widget>[],
|
||||
);
|
||||
|
||||
List<ProductOption> productOptions = product.productAttributes[index].productOptions;
|
||||
List<ProductOption> productOptions = product!.productAttributes![index!].productOptions;
|
||||
|
||||
if (!optionsState.containsKey(product.productAttributes[index].name)) {
|
||||
if (!optionsState.containsKey(product!.productAttributes![index!].name)) {
|
||||
List<Map<String, dynamic>> optionState = [];
|
||||
for (var i = 0; i < productOptions.length; i++) {
|
||||
optionState.add({'name': product.productAttributes[index].productOptions[i].name, 'disabled': false, 'check': false});
|
||||
optionState.add({'name': product!.productAttributes![index!].productOptions[i].name, 'disabled': false, 'check': false});
|
||||
}
|
||||
optionsState[product.productAttributes[index].name] = optionState;
|
||||
optionsState[product!.productAttributes![index!].name] = optionState;
|
||||
}
|
||||
|
||||
if (selections.containsKey(product.productAttributes[index].name.toUpperCase())) {
|
||||
if (selections!.containsKey(product!.productAttributes![index!].name.toUpperCase())) {
|
||||
|
||||
Map<String, dynamic> attrExtraJson = Utils.stringToJson(
|
||||
product.productAttributes[index].extra);
|
||||
Map<String, dynamic>? attrExtraJson = Utils.stringToJson(
|
||||
product!.productAttributes![index!].extra);
|
||||
if (attrExtraJson != null) {
|
||||
var selectLimitIfFieldEqualsTo = Rule.getRule(
|
||||
attrExtraJson, Rule.RULE_SELECT_LIMIT_IF_FIELD_EQUALS_TO);
|
||||
@@ -147,15 +147,15 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
int limitQty = selectLimitIfFieldEqualsTo1[Rule
|
||||
.RULE_KEY_FORCE_LIMITED];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
} else if (Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo1.containsKey(Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo1[Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
} else if (Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo1.containsKey(Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo1[Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
@@ -168,15 +168,15 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
int limitQty = selectLimitIfFieldEqualsTo[Rule
|
||||
.RULE_KEY_FORCE_LIMITED];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
} else if (Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo.containsKey(Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo[Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
} else if (Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo.containsKey(Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo[Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
@@ -187,7 +187,7 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
}
|
||||
|
||||
for (var i = 0; i < productOptions.length; i++) {
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(
|
||||
productOptions[i].extra);
|
||||
if (extraJson != null) {
|
||||
Map<String, dynamic> exclusiveRule = Rule.getRule(
|
||||
@@ -195,12 +195,12 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
Map<String, dynamic> multiItemRule = Rule.getRule(extraJson, Rule.RULE_ACTUAL_QTY_IS);
|
||||
if (exclusiveRule != null) {
|
||||
if (thisLimitQty > 0 && !_checkOptionIsCheck(productOptions[i].name)) {
|
||||
optionsState[product.productAttributes[index].name][i]['disabled'] = true;
|
||||
optionsState[product!.productAttributes![index!].name][i]['disabled'] = true;
|
||||
} else {
|
||||
if (_checkOptionIsCheck(productOptions[i].name)) {
|
||||
setOptionsStateDisabled(
|
||||
product.productAttributes[index].name, true);
|
||||
optionsState[product.productAttributes[index]
|
||||
product!.productAttributes![index!].name, true);
|
||||
optionsState[product!.productAttributes![index!]
|
||||
.name][i]['disabled'] = false;
|
||||
break;
|
||||
}
|
||||
@@ -208,12 +208,12 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
}
|
||||
if (multiItemRule != null) {
|
||||
if (_checkOptionIsCheck(productOptions[i].name)) {
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections[product.productAttributes[index].name.toUpperCase()] as List).length) {
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections![product!.productAttributes![index!].name.toUpperCase()] as List).length) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
} else {
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections[product.productAttributes[index].name.toUpperCase()] as List).length) {
|
||||
optionsState[product.productAttributes[index]
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections![product!.productAttributes![index!].name.toUpperCase()] as List).length) {
|
||||
optionsState[product!.productAttributes![index!]
|
||||
.name][i]['disabled'] = true;
|
||||
}
|
||||
}
|
||||
@@ -222,26 +222,26 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> optionState = optionsState[product.productAttributes[index].name];
|
||||
List<Map<String, dynamic>> optionState = optionsState[product!.productAttributes![index!].name];
|
||||
for (var i = 0; i < optionState.length; i++) {
|
||||
Widget optionWidget = _getOptionCheck(
|
||||
product.productAttributes[index].productOptions[i], optionState[i]['disabled'], i);
|
||||
product!.productAttributes![index!].productOptions[i], optionState[i]['disabled'], i);
|
||||
row.children.add(optionWidget);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
void disableOptionIfNotSelected() {
|
||||
setOptionsStateDisabled(product.productAttributes[index].name, true);
|
||||
for (var i = 0; i < optionsState[product.productAttributes[index].name].length; i++) {
|
||||
if (Utils.selectionsContains(selections, product.productAttributes[index].name, optionsState[product.productAttributes[index].name][i]['name']) != -1) {
|
||||
optionsState[product.productAttributes[index].name][i]['disabled'] = false;
|
||||
setOptionsStateDisabled(product!.productAttributes![index!].name, true);
|
||||
for (var i = 0; i < optionsState[product!.productAttributes![index!].name].length; i++) {
|
||||
if (Utils.selectionsContains(selections!, product!.productAttributes![index!].name, optionsState[product!.productAttributes![index!].name][i]['name']) != -1) {
|
||||
optionsState[product!.productAttributes![index!].name][i]['disabled'] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _checkOptionIsCheck(String name) {
|
||||
if (Utils.selectionsContains(selections, product.productAttributes[index].name, name) != -1) {
|
||||
if (Utils.selectionsContains(selections!, product!.productAttributes![index!].name, name) != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -251,7 +251,7 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
bool disabled = optDisabled;
|
||||
bool check = _checkOptionIsCheck(productOption.name);
|
||||
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(productOption.extra);
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(productOption.extra);
|
||||
// Utils.jsonPrettyPrint(extraJson);
|
||||
|
||||
double extraAdjustAmount = 0.0;
|
||||
@@ -262,13 +262,13 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
if (sizeBaseAdjustment is List) {
|
||||
for (var i = 0; i < (sizeBaseAdjustment as List).length; i++) {
|
||||
Map<String, dynamic> sizeBaseAdjustment1 = sizeBaseAdjustment[i];
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections!, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 && sizeBaseAdjustment1.containsKey(attValues[0])) {
|
||||
extraAdjustAmount += sizeBaseAdjustment1[attValues[0]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections!, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 && sizeBaseAdjustment.containsKey(attValues[0])) {
|
||||
extraAdjustAmount += sizeBaseAdjustment[attValues[0]];
|
||||
}
|
||||
@@ -282,7 +282,7 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
for (var i = 0; i < (disabledRule as List).length; i++) {
|
||||
Map<String, dynamic> disabledRule1 = disabledRule[i];
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(
|
||||
selections, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
selections!, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 &&
|
||||
disabledRule1.containsKey(attValues[0])) {
|
||||
disabled = true;
|
||||
@@ -301,7 +301,7 @@ class CheckOptionsState extends OptionsBaseState<CheckOptions> {
|
||||
}
|
||||
} else {
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(
|
||||
selections, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
||||
selections!, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0) {
|
||||
for (String s in attValues) {
|
||||
if (disabledRule.containsKey(s) && disabledRule[s]) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/product.dart';
|
||||
import '../../../models/product.dart';
|
||||
|
||||
typedef void OnOptionTapped(String name, int quantity, double adjustAmount);
|
||||
|
||||
@@ -9,16 +9,16 @@ abstract class OptionsBase extends StatefulWidget {
|
||||
final Product product;
|
||||
final int index;
|
||||
final Map<String, dynamic> selections;
|
||||
OptionsBase({@required Product product, @required int index, @required Map<String, dynamic> selections})
|
||||
OptionsBase({required Product product, required int index, required Map<String, dynamic> selections})
|
||||
: product = product,
|
||||
index = index,
|
||||
selections = selections;
|
||||
}
|
||||
|
||||
abstract class OptionsBaseState<Base extends OptionsBase> extends State<Base> {
|
||||
Product product;
|
||||
Map<String, dynamic> selections;
|
||||
int index;
|
||||
Product? product;
|
||||
Map<String, dynamic>? selections;
|
||||
int? index;
|
||||
|
||||
final Color disabledBackgroundColor = new Color(0xFFBCBCBC);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'options_base.dart';
|
||||
import 'rules.dart';
|
||||
|
||||
class QtyOptions extends OptionsBase {
|
||||
QtyOptions({@required Product product, @required int index, @required Map<String, dynamic> selections})
|
||||
QtyOptions({required Product product, required int index, required Map<String, dynamic> selections})
|
||||
: super(product: product, index: index, selections: selections);
|
||||
|
||||
@override
|
||||
@@ -41,14 +41,14 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
S.of(context).check_option_select_token(product.productAttributes[this.index].name),
|
||||
S.of(context).check_option_select_token(product!.productAttributes![this.index!].name),
|
||||
style: new TextStyle(
|
||||
fontSize: 12.5,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
new Text(
|
||||
product.productAttributes[this.index].required ? S.of(context).check_option_is_required : S.of(context).check_option_is_optional,
|
||||
product!.productAttributes![this.index!].required ? S.of(context).check_option_is_required : S.of(context).check_option_is_optional,
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: new Color(0xFF999999)
|
||||
@@ -86,38 +86,38 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
'adjust_amount': adjustAmount
|
||||
};
|
||||
var cloneSelections = json.decode(json.encode(selections));
|
||||
int idx = Utils.selectionsContains(cloneSelections, product.productAttributes[index].name, name);
|
||||
int idx = Utils.selectionsContains(cloneSelections, product!.productAttributes![index!].name, name);
|
||||
if (idx != -1) {
|
||||
if (quantity == 1) {
|
||||
cloneSelections[product.productAttributes[index].name.toUpperCase()][idx]['quantity'] += 1;
|
||||
optionsState[product.productAttributes[index].name][optIndex]['quantity'] = cloneSelections[product.productAttributes[index].name.toUpperCase()][idx]['quantity'];
|
||||
cloneSelections[product!.productAttributes![index!].name.toUpperCase()][idx]['quantity'] += 1;
|
||||
optionsState[product!.productAttributes![index!].name][optIndex]['quantity'] = cloneSelections[product!.productAttributes![index!].name.toUpperCase()][idx]['quantity'];
|
||||
} else {
|
||||
if (cloneSelections[product.productAttributes[index].name.toUpperCase()][idx]['quantity'] - 1 > 0) {
|
||||
cloneSelections[product.productAttributes[index].name.toUpperCase()][idx]['quantity'] -= 1;
|
||||
optionsState[product.productAttributes[index].name][optIndex]['quantity'] = cloneSelections[product.productAttributes[index].name.toUpperCase()][idx]['quantity'];
|
||||
if (cloneSelections[product!.productAttributes![index!].name.toUpperCase()][idx]['quantity'] - 1 > 0) {
|
||||
cloneSelections[product!.productAttributes![index!].name.toUpperCase()][idx]['quantity'] -= 1;
|
||||
optionsState[product!.productAttributes![index!].name][optIndex]['quantity'] = cloneSelections[product!.productAttributes![index!].name.toUpperCase()][idx]['quantity'];
|
||||
} else {
|
||||
(cloneSelections[product.productAttributes[index].name.toUpperCase()] as List).removeAt(idx);
|
||||
optionsState[product.productAttributes[index].name][optIndex]['quantity'] = 0;
|
||||
(cloneSelections[product!.productAttributes![index!].name.toUpperCase()] as List).removeAt(idx);
|
||||
optionsState[product!.productAttributes![index!].name][optIndex]['quantity'] = 0;
|
||||
}
|
||||
}
|
||||
} else if (cloneSelections.containsKey(product.productAttributes[index].name.toUpperCase())) {
|
||||
(cloneSelections[product.productAttributes[index].name.toUpperCase()] as List).add(opt);
|
||||
optionsState[product.productAttributes[index].name][optIndex]['quantity'] = 1;
|
||||
} else if (cloneSelections.containsKey(product!.productAttributes![index!].name.toUpperCase())) {
|
||||
(cloneSelections[product!.productAttributes![index!].name.toUpperCase()] as List).add(opt);
|
||||
optionsState[product!.productAttributes![index!].name][optIndex]['quantity'] = 1;
|
||||
} else {
|
||||
cloneSelections[product.productAttributes[index].name.toUpperCase()] = [opt];
|
||||
optionsState[product.productAttributes[index].name][optIndex]['quantity'] = 1;
|
||||
cloneSelections[product!.productAttributes![index!].name.toUpperCase()] = [opt];
|
||||
optionsState[product!.productAttributes![index!].name][optIndex]['quantity'] = 1;
|
||||
}
|
||||
|
||||
if (idx != -1 && (cloneSelections[product.productAttributes[index].name.toUpperCase()] as List).length == 0) {
|
||||
cloneSelections.remove(product.productAttributes[index].name.toUpperCase());
|
||||
if (idx != -1 && (cloneSelections[product!.productAttributes![index!].name.toUpperCase()] as List).length == 0) {
|
||||
cloneSelections.remove(product!.productAttributes![index!].name.toUpperCase());
|
||||
}
|
||||
|
||||
setOptionsStateDisabled(product.productAttributes[index].name, false);
|
||||
setOptionsStateDisabled(product!.productAttributes![index!].name, false);
|
||||
|
||||
setState(() {
|
||||
selections = cloneSelections;
|
||||
});
|
||||
eventBus.fire(new OnAttributeSelectionsChanged(selections));
|
||||
eventBus.fire(new OnAttributeSelectionsChanged(selections!));
|
||||
}
|
||||
|
||||
Widget _getOptionWidget() {
|
||||
@@ -125,24 +125,24 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
children: <Widget>[],
|
||||
);
|
||||
|
||||
List<ProductOption> productOptions = product.productAttributes[index].productOptions;
|
||||
List<ProductOption> productOptions = product!.productAttributes![index!].productOptions;
|
||||
|
||||
if (!optionsState.containsKey(product.productAttributes[index].name)) {
|
||||
if (!optionsState.containsKey(product!.productAttributes![index!].name)) {
|
||||
List<Map<String, dynamic>> optionState = [];
|
||||
for (var i = 0; i < productOptions.length; i++) {
|
||||
int qty = 0;
|
||||
int idx = Utils.selectionsContains(selections, product.productAttributes[index].name, productOptions[i].name);
|
||||
int idx = Utils.selectionsContains(selections!, product!.productAttributes![index!].name, productOptions[i].name);
|
||||
if (idx != -1) {
|
||||
qty = selections[product.productAttributes[index].name.toUpperCase()][idx]['quantity'];
|
||||
qty = selections![product!.productAttributes![index!].name.toUpperCase()][idx]['quantity'];
|
||||
}
|
||||
optionState.add({'name': product.productAttributes[index].productOptions[i].name, 'disabled': false, 'quantity': qty, 'check': false});
|
||||
optionState.add({'name': product!.productAttributes![index!].productOptions[i].name, 'disabled': false, 'quantity': qty, 'check': false});
|
||||
}
|
||||
optionsState[product.productAttributes[index].name] = optionState;
|
||||
optionsState[product!.productAttributes![index!].name] = optionState;
|
||||
}
|
||||
|
||||
if (selections.containsKey(product.productAttributes[index].name.toUpperCase())) {
|
||||
Map<String, dynamic> attrExtraJson = Utils.stringToJson(
|
||||
product.productAttributes[index].extra);
|
||||
if (selections!.containsKey(product!.productAttributes![index!].name.toUpperCase())) {
|
||||
Map<String, dynamic>? attrExtraJson = Utils.stringToJson(
|
||||
product!.productAttributes![index!].extra);
|
||||
if (attrExtraJson != null) {
|
||||
var selectLimitIfFieldEqualsTo = Rule.getRule(
|
||||
attrExtraJson, Rule.RULE_SELECT_LIMIT_IF_FIELD_EQUALS_TO);
|
||||
@@ -155,15 +155,15 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
int limitQty = selectLimitIfFieldEqualsTo1[Rule
|
||||
.RULE_KEY_FORCE_LIMITED];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
} else if (Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo1.containsKey(Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo1[Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
} else if (Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo1.containsKey(Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo1[Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo1[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
@@ -176,15 +176,15 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
int limitQty = selectLimitIfFieldEqualsTo[Rule
|
||||
.RULE_KEY_FORCE_LIMITED];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
} else if (Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo.containsKey(Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo[Utils.getSelectedAttributeValue(selections, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
} else if (Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY]).length > 0) {
|
||||
if (selectLimitIfFieldEqualsTo.containsKey(Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0])) {
|
||||
int limitQty = selectLimitIfFieldEqualsTo[Utils.getSelectedAttributeValue(selections!, selectLimitIfFieldEqualsTo[Rule.RULE_KEY_FIELD_KEY])[0]];
|
||||
thisLimitQty = limitQty;
|
||||
if ((selections[product.productAttributes[index].name
|
||||
if ((selections![product!.productAttributes![index!].name
|
||||
.toUpperCase()] as List).length >= limitQty) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
@@ -195,7 +195,7 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
}
|
||||
|
||||
for (var i = 0; i < productOptions.length; i++) {
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(
|
||||
productOptions[i].extra);
|
||||
if (extraJson != null) {
|
||||
Map<String, dynamic> exclusiveRule = Rule.getRule(
|
||||
@@ -203,12 +203,12 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
Map<String, dynamic> multiItemRule = Rule.getRule(extraJson, Rule.RULE_ACTUAL_QTY_IS);
|
||||
if (exclusiveRule != null) {
|
||||
if (thisLimitQty > 0 && !_checkOptionIsCheck(productOptions[i].name)) {
|
||||
optionsState[product.productAttributes[index].name][i]['disabled'] = true;
|
||||
optionsState[product!.productAttributes![index!].name][i]['disabled'] = true;
|
||||
} else {
|
||||
if (_checkOptionIsCheck(productOptions[i].name)) {
|
||||
setOptionsStateDisabled(
|
||||
product.productAttributes[index].name, true);
|
||||
optionsState[product.productAttributes[index]
|
||||
product!.productAttributes![index!].name, true);
|
||||
optionsState[product!.productAttributes![index!]
|
||||
.name][i]['disabled'] = false;
|
||||
break;
|
||||
}
|
||||
@@ -216,12 +216,12 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
}
|
||||
if (multiItemRule != null) {
|
||||
if (_checkOptionIsCheck(productOptions[i].name)) {
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections[product.productAttributes[index].name.toUpperCase()] as List).length) {
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections![product!.productAttributes![index!].name.toUpperCase()] as List).length) {
|
||||
disableOptionIfNotSelected();
|
||||
}
|
||||
} else {
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections[product.productAttributes[index].name.toUpperCase()] as List).length) {
|
||||
optionsState[product.productAttributes[index]
|
||||
if (multiItemRule[Rule.RULE_ACTUAL_QTY_IS] > thisLimitQty - (selections![product!.productAttributes![index!].name.toUpperCase()] as List).length) {
|
||||
optionsState[product!.productAttributes![index!]
|
||||
.name][i]['disabled'] = true;
|
||||
}
|
||||
}
|
||||
@@ -230,26 +230,26 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> optionState = optionsState[product.productAttributes[index].name];
|
||||
List<Map<String, dynamic>> optionState = optionsState[product!.productAttributes![index!].name];
|
||||
for (var i = 0; i < optionState.length; i++) {
|
||||
Widget optionWidget = _getOptionQty(
|
||||
product.productAttributes[index].productOptions[i], optionState[i]['disabled'], optionState[i]['quantity'], i);
|
||||
product!.productAttributes![index!].productOptions[i], optionState[i]['disabled'], optionState[i]['quantity'], i);
|
||||
row.children.add(optionWidget);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
void disableOptionIfNotSelected() {
|
||||
setOptionsStateDisabled(product.productAttributes[index].name, true);
|
||||
for (var i = 0; i < optionsState[product.productAttributes[index].name].length; i++) {
|
||||
if (Utils.selectionsContains(selections, product.productAttributes[index].name, optionsState[product.productAttributes[index].name][i]['name']) != -1) {
|
||||
optionsState[product.productAttributes[index].name][i]['disabled'] = false;
|
||||
setOptionsStateDisabled(product!.productAttributes![index!].name, true);
|
||||
for (var i = 0; i < optionsState[product!.productAttributes![index!].name].length; i++) {
|
||||
if (Utils.selectionsContains(selections!, product!.productAttributes![index!].name, optionsState[product!.productAttributes![index!].name][i]['name']) != -1) {
|
||||
optionsState[product!.productAttributes![index!].name][i]['disabled'] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _checkOptionIsCheck(String name) {
|
||||
if (Utils.selectionsContains(selections, product.productAttributes[index].name, name) != -1) {
|
||||
if (Utils.selectionsContains(selections!, product!.productAttributes![index!].name, name) != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -259,7 +259,7 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
bool disabled = optDisabled;
|
||||
bool check = _checkOptionIsCheck(productOption.name);
|
||||
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(productOption.extra);
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(productOption.extra);
|
||||
// Utils.jsonPrettyPrint(extraJson);
|
||||
|
||||
double extraAdjustAmount = 0.0;
|
||||
@@ -270,13 +270,13 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
if (sizeBaseAdjustment is List) {
|
||||
for (var i = 0; i < (sizeBaseAdjustment as List).length; i++) {
|
||||
Map<String, dynamic> sizeBaseAdjustment1 = sizeBaseAdjustment[i];
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections!, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 && sizeBaseAdjustment1.containsKey(attValues[0])) {
|
||||
extraAdjustAmount += sizeBaseAdjustment1[attValues[0]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections!, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 && sizeBaseAdjustment.containsKey(attValues[0])) {
|
||||
extraAdjustAmount += sizeBaseAdjustment[attValues[0]];
|
||||
}
|
||||
@@ -290,7 +290,7 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
for (var i = 0; i < (disabledRule as List).length; i++) {
|
||||
Map<String, dynamic> disabledRule1 = disabledRule[i];
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(
|
||||
selections, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
selections!, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 &&
|
||||
disabledRule1.containsKey(attValues[0])) {
|
||||
disabled = true;
|
||||
@@ -309,7 +309,7 @@ class QtyOptionsState extends OptionsBaseState<QtyOptions> {
|
||||
}
|
||||
} else {
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(
|
||||
selections, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
||||
selections!, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0) {
|
||||
for (String s in attValues) {
|
||||
if (disabledRule.containsKey(s) && disabledRule[s]) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'options_base.dart';
|
||||
import 'rules.dart';
|
||||
|
||||
class RadioOptions extends OptionsBase {
|
||||
RadioOptions({@required Product product, @required int index, @required Map<String, dynamic> selections})
|
||||
RadioOptions({required Product product, required int index, required Map<String, dynamic> selections})
|
||||
: super(product: product, index: index, selections: selections);
|
||||
|
||||
@override
|
||||
@@ -40,14 +40,14 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
S.of(context).radio_option_select_token(product.productAttributes[this.index].name),
|
||||
S.of(context).radio_option_select_token(product!.productAttributes![this.index!].name),
|
||||
style: new TextStyle(
|
||||
fontSize: 12.5,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
new Text(
|
||||
product.productAttributes[this.index].required ? S.of(context).radio_option_is_required : S.of(context).radio_option_is_optional,
|
||||
product!.productAttributes![this.index!].required ? S.of(context).radio_option_is_required : S.of(context).radio_option_is_optional,
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: new Color(0xFF999999)
|
||||
@@ -85,24 +85,24 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
'adjust_amount': adjustAmount
|
||||
};
|
||||
var cloneSelections = json.decode(json.encode(selections));
|
||||
if (product.productAttributes[index].required) {
|
||||
cloneSelections[product.productAttributes[index].name.toUpperCase()] = [opt];
|
||||
if (product!.productAttributes![index!].required) {
|
||||
cloneSelections[product!.productAttributes![index!].name.toUpperCase()] = [opt];
|
||||
} else {
|
||||
if (cloneSelections.containsKey(product.productAttributes[index].name.toUpperCase())
|
||||
&& Utils.equalsIgnoreCase(cloneSelections[product.productAttributes[index].name.toUpperCase()][0]['name'], name)) {
|
||||
cloneSelections.remove(product.productAttributes[index].name.toUpperCase());
|
||||
if (cloneSelections.containsKey(product!.productAttributes![index!].name.toUpperCase())
|
||||
&& Utils.equalsIgnoreCase(cloneSelections[product!.productAttributes![index!].name.toUpperCase()][0]['name'], name)) {
|
||||
cloneSelections.remove(product!.productAttributes![index!].name.toUpperCase());
|
||||
} else {
|
||||
cloneSelections[product.productAttributes[index].name.toUpperCase()] = [opt];
|
||||
cloneSelections[product!.productAttributes![index!].name.toUpperCase()] = [opt];
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(productOption.extra);
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(productOption.extra);
|
||||
if (extraJson != null) {
|
||||
Map<String, dynamic> exclusiveRule = Rule.getRule(
|
||||
extraJson, Rule.RULE_EXCLUSIVE_SELECTION);
|
||||
if (exclusiveRule != null) {
|
||||
if (_checkOptionIsCheck(productOption.name)) {
|
||||
setOptionsStateDisabled(product.productAttributes[index].name, false);
|
||||
setOptionsStateDisabled(product!.productAttributes![index!].name, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
setState(() {
|
||||
selections = cloneSelections;
|
||||
});
|
||||
eventBus.fire(new OnAttributeSelectionsChanged(selections));
|
||||
eventBus.fire(new OnAttributeSelectionsChanged(selections!));
|
||||
}
|
||||
|
||||
Widget _getOptionWidget() {
|
||||
@@ -118,42 +118,42 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
children: <Widget>[],
|
||||
);
|
||||
|
||||
List<ProductOption> productOptions = product.productAttributes[index].productOptions;
|
||||
List<ProductOption> productOptions = product!.productAttributes![index!].productOptions;
|
||||
|
||||
if (!optionsState.containsKey(product.productAttributes[index].name)) {
|
||||
if (!optionsState.containsKey(product!.productAttributes![index!].name)) {
|
||||
List<Map<String, dynamic>> optionState = [];
|
||||
for (var i = 0; i < productOptions.length; i++) {
|
||||
optionState.add({'name': product.productAttributes[index].productOptions[i].name, 'disabled': false, 'check': false});
|
||||
optionState.add({'name': product!.productAttributes![index!].productOptions[i].name, 'disabled': false, 'check': false});
|
||||
}
|
||||
optionsState[product.productAttributes[index].name] = optionState;
|
||||
optionsState[product!.productAttributes![index!].name] = optionState;
|
||||
}
|
||||
|
||||
for (var i = 0; i < productOptions.length; i++) {
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(productOptions[i].extra);
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(productOptions[i].extra);
|
||||
if (extraJson != null) {
|
||||
Map<String, dynamic> exclusiveRule = Rule.getRule(
|
||||
extraJson, Rule.RULE_EXCLUSIVE_SELECTION);
|
||||
if (exclusiveRule != null) {
|
||||
if (_checkOptionIsCheck(productOptions[i].name)) {
|
||||
setOptionsStateDisabled(product.productAttributes[index].name, true);
|
||||
optionsState[product.productAttributes[index].name][i]['disabled'] = false;
|
||||
setOptionsStateDisabled(product!.productAttributes![index!].name, true);
|
||||
optionsState[product!.productAttributes![index!].name][i]['disabled'] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> optionState = optionsState[product.productAttributes[index].name];
|
||||
List<Map<String, dynamic>> optionState = optionsState[product!.productAttributes![index!].name];
|
||||
for (var i = 0; i < optionState.length; i++) {
|
||||
Widget optionWidget = _getOptionRadio(
|
||||
product.productAttributes[index].productOptions[i], optionState[i]['disabled'], i);
|
||||
product!.productAttributes![index!].productOptions[i], optionState[i]['disabled'], i);
|
||||
row.children.add(optionWidget);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
bool _checkOptionIsCheck(String name) {
|
||||
if (Utils.selectionsContains(selections, product.productAttributes[index].name, name) != -1) {
|
||||
if (Utils.selectionsContains(selections!, product!.productAttributes![index!].name, name) != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -163,7 +163,7 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
bool disabled = optDisabled;
|
||||
bool check = _checkOptionIsCheck(productOption.name);
|
||||
|
||||
Map<String, dynamic> extraJson = Utils.stringToJson(productOption.extra);
|
||||
Map<String, dynamic>? extraJson = Utils.stringToJson(productOption.extra);
|
||||
// Utils.jsonPrettyPrint(extraJson);
|
||||
|
||||
double extraAdjustAmount = 0.0;
|
||||
@@ -174,13 +174,13 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
if (sizeBaseAdjustment is List) {
|
||||
for (var i = 0; i < (sizeBaseAdjustment as List).length; i++) {
|
||||
Map<String, dynamic> sizeBaseAdjustment1 = sizeBaseAdjustment[i];
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections!, sizeBaseAdjustment1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 && sizeBaseAdjustment1.containsKey(attValues[0])) {
|
||||
extraAdjustAmount += sizeBaseAdjustment1[attValues[0]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(selections!, sizeBaseAdjustment[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 && sizeBaseAdjustment.containsKey(attValues[0])) {
|
||||
extraAdjustAmount += sizeBaseAdjustment[attValues[0]];
|
||||
}
|
||||
@@ -194,7 +194,7 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
for (var i = 0; i < (disabledRule as List).length; i++) {
|
||||
Map<String, dynamic> disabledRule1 = disabledRule[i];
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(
|
||||
selections, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
selections!, disabledRule1[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0 &&
|
||||
disabledRule1.containsKey(attValues[0])) {
|
||||
disabled = true;
|
||||
@@ -213,7 +213,7 @@ class RadioOptionsState extends OptionsBaseState<RadioOptions> {
|
||||
}
|
||||
} else {
|
||||
List<String> attValues = Utils.getSelectedAttributeValue(
|
||||
selections, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
||||
selections!, disabledRule[Rule.RULE_KEY_FIELD_KEY]);
|
||||
if (attValues.length > 0) {
|
||||
for (String s in attValues) {
|
||||
if (disabledRule.containsKey(s) && disabledRule[s]) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BottomNav extends StatefulWidget {
|
||||
const BottomNav({Key key}) : super(key: key);
|
||||
const BottomNav({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
|
||||
@@ -7,10 +7,10 @@ import '../../routes.dart';
|
||||
import 'navigationbar.dart';
|
||||
|
||||
class BreadCrumbs extends StatelessWidget {
|
||||
final List<BreadCrumb> breadCrumbs;
|
||||
final List<BreadCrumb>? breadCrumbs;
|
||||
final bool hasBack;
|
||||
final OnBackPress onBackPress;
|
||||
const BreadCrumbs(this.hasBack, {this.breadCrumbs, Key key, this.onBackPress}) : super(key: key);
|
||||
final OnBackPress? onBackPress;
|
||||
const BreadCrumbs(this.hasBack, {this.breadCrumbs, Key? key, this.onBackPress}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -49,17 +49,17 @@ class BreadCrumbs extends StatelessWidget {
|
||||
));
|
||||
}
|
||||
if (breadCrumbs != null) {
|
||||
for (int i = 0; i < breadCrumbs.length; i++) {
|
||||
BreadCrumb breadCrumb = breadCrumbs[i];
|
||||
for (int i = 0; i < breadCrumbs!.length; i++) {
|
||||
BreadCrumb breadCrumb = breadCrumbs![i];
|
||||
if (breadCrumb.text == null && breadCrumb.item != null) {
|
||||
if (breadCrumb.onTap == null) {
|
||||
widgets.add(breadCrumb.item);
|
||||
widgets.add(breadCrumb.item!);
|
||||
} else {
|
||||
widgets.add(MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
child: breadCrumb.item,
|
||||
onTap: breadCrumb.onTap,
|
||||
child: breadCrumb.item!,
|
||||
onTap: breadCrumb.onTap as GestureTapCallback?,
|
||||
),
|
||||
));
|
||||
}
|
||||
@@ -94,7 +94,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
color: Colors.blueAccent,
|
||||
),
|
||||
Text(
|
||||
breadCrumb.text,
|
||||
breadCrumb.text ?? '',
|
||||
style: TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
fontSize: 14.0,
|
||||
@@ -103,7 +103,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
],
|
||||
) :
|
||||
Text(
|
||||
breadCrumb.text,
|
||||
breadCrumb.text ?? '',
|
||||
style: TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
fontSize: 14.0,
|
||||
@@ -113,7 +113,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
Routes.router.navigateTo(context, breadCrumb.route);
|
||||
Routes.router.navigateTo(context, breadCrumb.route ?? '');
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -145,7 +145,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
color: Colors.lightBlueAccent,
|
||||
),
|
||||
Text(
|
||||
breadCrumb.text,
|
||||
breadCrumb.text ?? '',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
fontSize: 14.0,
|
||||
@@ -155,7 +155,7 @@ class BreadCrumbs extends StatelessWidget {
|
||||
],
|
||||
) :
|
||||
Text(
|
||||
breadCrumb.text,
|
||||
breadCrumb.text ?? '',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
fontSize: 14.0,
|
||||
@@ -184,11 +184,11 @@ class BreadCrumbs extends StatelessWidget {
|
||||
}
|
||||
|
||||
class BreadCrumb {
|
||||
final String text;
|
||||
final String route;
|
||||
final IconData icon;
|
||||
final Widget item;
|
||||
final Function onTap;
|
||||
final String? text;
|
||||
final String? route;
|
||||
final IconData? icon;
|
||||
final Widget? item;
|
||||
final Function? onTap;
|
||||
|
||||
BreadCrumb(this.text, this.route, {this.icon, this.item, this.onTap});
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import 'style.dart';
|
||||
class Carousel extends StatefulWidget {
|
||||
Carousel({
|
||||
double height = 200.0,
|
||||
List<Widget> pages,
|
||||
bool autoPlay,
|
||||
List<Widget>? pages,
|
||||
bool autoPlay = false,
|
||||
Duration duration = const Duration(seconds: 2),
|
||||
Duration animationDuration = const Duration(milliseconds: 1000),
|
||||
})
|
||||
@@ -17,11 +17,11 @@ class Carousel extends StatefulWidget {
|
||||
duration = duration,
|
||||
animationDuration = animationDuration;
|
||||
|
||||
final double height;
|
||||
final List<Widget> pages;
|
||||
final bool autoPlay;
|
||||
final Duration duration;
|
||||
final Duration animationDuration;
|
||||
final double? height;
|
||||
final List<Widget>? pages;
|
||||
final bool? autoPlay;
|
||||
final Duration? duration;
|
||||
final Duration? animationDuration;
|
||||
|
||||
@override
|
||||
createState() => new CarouselState();
|
||||
@@ -30,7 +30,7 @@ class Carousel extends StatefulWidget {
|
||||
class CarouselState extends State<Carousel> {
|
||||
final _pageController = new PageController();
|
||||
|
||||
Timer _timer;
|
||||
Timer? _timer;
|
||||
int _currentPage = 0;
|
||||
bool reverse = false;
|
||||
GlobalKey<IndicatorState> _indicatorStateKey = new GlobalKey();
|
||||
@@ -38,13 +38,13 @@ class CarouselState extends State<Carousel> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.autoPlay) {
|
||||
_timer = new Timer.periodic(widget.duration, (timer) {
|
||||
if (widget.autoPlay!) {
|
||||
_timer = new Timer.periodic(widget.duration!, (timer) {
|
||||
_pageController.animateToPage(_currentPage,
|
||||
duration: widget.animationDuration, curve: Curves.linear);
|
||||
duration: widget.animationDuration!, curve: Curves.linear);
|
||||
if (!reverse) {
|
||||
_currentPage += 1;
|
||||
if (_currentPage == widget.pages.length) {
|
||||
if (_currentPage == widget.pages?.length) {
|
||||
_currentPage -= 1;
|
||||
reverse = true;
|
||||
}
|
||||
@@ -61,9 +61,9 @@ class CarouselState extends State<Carousel> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController?.dispose();
|
||||
_pageController.dispose();
|
||||
if (_timer != null) {
|
||||
_timer.cancel();
|
||||
_timer!.cancel();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
@@ -77,10 +77,10 @@ class CarouselState extends State<Carousel> {
|
||||
color: Style.backgroundColor,
|
||||
child: new PageView(
|
||||
controller: _pageController,
|
||||
children: widget.pages,
|
||||
children: widget.pages!,
|
||||
onPageChanged: (index) {
|
||||
_currentPage = index;
|
||||
_indicatorStateKey.currentState.changeIndex(index);
|
||||
_indicatorStateKey.currentState?.changeIndex(index);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -91,7 +91,7 @@ class CarouselState extends State<Carousel> {
|
||||
child: new Align(
|
||||
child: new Indicator(
|
||||
key: _indicatorStateKey,
|
||||
count: widget.pages.length,
|
||||
count: widget.pages!.length,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
@@ -102,11 +102,11 @@ class CarouselState extends State<Carousel> {
|
||||
}
|
||||
|
||||
class Indicator extends StatefulWidget {
|
||||
Indicator({Key key, int count})
|
||||
Indicator({Key? key, int? count})
|
||||
: count = count,
|
||||
super(key: key);
|
||||
|
||||
final int count;
|
||||
final int? count;
|
||||
|
||||
@override
|
||||
createState() => new IndicatorState();
|
||||
@@ -124,7 +124,7 @@ class IndicatorState extends State<Indicator> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var indicators = <Widget>[];
|
||||
for (var i = 0; i < widget.count; ++i) {
|
||||
for (var i = 0; i < widget.count!; ++i) {
|
||||
indicators.add(new Container(
|
||||
width: 5.0,
|
||||
height: 5.0,
|
||||
@@ -135,7 +135,7 @@ class IndicatorState extends State<Indicator> {
|
||||
));
|
||||
}
|
||||
return new SizedBox(
|
||||
width: widget.count * 15.0,
|
||||
width: widget.count! * 15.0,
|
||||
height: 30.0,
|
||||
child: new Row(
|
||||
children: indicators,
|
||||
|
||||
@@ -4,9 +4,9 @@ import '../../generated/l10n.dart';
|
||||
import '../../utils/double_back_to_close_app.dart';
|
||||
|
||||
class DoubleBackToCloseAppWrapper extends StatelessWidget {
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
|
||||
const DoubleBackToCloseAppWrapper({Key key, this.child}) : super(key: key);
|
||||
const DoubleBackToCloseAppWrapper({Key? key, this.child}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -20,7 +20,7 @@ class DoubleBackToCloseAppWrapper extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
child: child!,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ import '../../utils/utils.dart';
|
||||
|
||||
class DownloadItem extends StatefulWidget {
|
||||
final dynamic desc;
|
||||
final double width;
|
||||
const DownloadItem(this.desc, {Key key, this.width}) : super(key: key);
|
||||
final double? width;
|
||||
const DownloadItem(this.desc, {Key? key, this.width}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -52,7 +52,7 @@ class DownloadItemState extends State<DownloadItem> {
|
||||
margin: EdgeInsets.only(right: 16.0),
|
||||
),
|
||||
Container(
|
||||
width: widget.width != null ? widget.width - iconWidth - buttonWidth - 60 : MediaQuery.of(context).size.width - iconWidth - buttonWidth - 60,
|
||||
width: widget.width != null ? widget.width! - iconWidth - buttonWidth - 60 : MediaQuery.of(context).size.width - iconWidth - buttonWidth - 60,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -186,9 +186,9 @@ class DownloadItemState extends State<DownloadItem> {
|
||||
}
|
||||
|
||||
Widget getDownloadButton() {
|
||||
String downloadUrl;
|
||||
String os = Utils.getOs();
|
||||
String selectedOs;
|
||||
String? downloadUrl;
|
||||
String? os = Utils.getOs();
|
||||
String? selectedOs;
|
||||
List<String> supportedOss = [];
|
||||
for (int i = 0; i < (widget.desc['urls'] as List).length; i++) {
|
||||
supportedOss.add((widget.desc['urls'] as List)[i]['os']);
|
||||
@@ -244,7 +244,7 @@ class DownloadItemState extends State<DownloadItem> {
|
||||
} else if (downloadUrl != null && downloadUrl.isNotEmpty) {
|
||||
return ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
padding: EdgeInsets.all(8)
|
||||
),
|
||||
child: Row(
|
||||
@@ -255,7 +255,7 @@ class DownloadItemState extends State<DownloadItem> {
|
||||
padding: EdgeInsets.only(right: 0.0, left: 6.0, top: 6.0, bottom: 6.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
Utils.getOsFontHex(selectedOs),
|
||||
Utils.getOsFontHex(selectedOs!),
|
||||
fontFamily: 'wisetronic',
|
||||
fontPackage: null
|
||||
),
|
||||
|
||||
@@ -7,14 +7,14 @@ import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexCarousel extends StatelessWidget {
|
||||
final List<Gallery> galleries;
|
||||
const IndexCarousel(this.galleries, {Key key}) : super(key: key);
|
||||
const IndexCarousel(this.galleries, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexCarousel(galleries),
|
||||
tablet: DesktopIndexCarousel(galleries),
|
||||
desktop: DesktopIndexCarousel(galleries),
|
||||
return ScreenTypeLayout.builder(
|
||||
mobile: (context) => MobileIndexCarousel(galleries),
|
||||
tablet: (context) => DesktopIndexCarousel(galleries),
|
||||
desktop: (context) => DesktopIndexCarousel(galleries),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexMainContent1 extends StatelessWidget {
|
||||
final String message;
|
||||
const IndexMainContent1(this.message, {Key key}) : super(key: key);
|
||||
const IndexMainContent1(this.message, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexMainContent1(message),
|
||||
tablet: DesktopIndexMainContent1(message),
|
||||
desktop: DesktopIndexMainContent1(message),
|
||||
return ScreenTypeLayout.builder(
|
||||
mobile: (context) => MobileIndexMainContent1(message),
|
||||
tablet: (context) => DesktopIndexMainContent1(message),
|
||||
desktop: (context) => DesktopIndexMainContent1(message),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexMainContent2 extends StatelessWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const IndexMainContent2(this.content, {Key key}) : super(key: key);
|
||||
const IndexMainContent2(this.content, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexMainContent2(content),
|
||||
tablet: DesktopIndexMainContent2(content),
|
||||
desktop: DesktopIndexMainContent2(content),
|
||||
return ScreenTypeLayout.builder(
|
||||
mobile: (context) => MobileIndexMainContent2(content),
|
||||
tablet: (context) => DesktopIndexMainContent2(content),
|
||||
desktop: (context) => DesktopIndexMainContent2(content),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexMainContent3 extends StatelessWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const IndexMainContent3(this.content, {Key key}) : super(key: key);
|
||||
const IndexMainContent3(this.content, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexMainContent3(content),
|
||||
tablet: DesktopIndexMainContent3(content),
|
||||
desktop: DesktopIndexMainContent3(content),
|
||||
return ScreenTypeLayout.builder(
|
||||
mobile: (context) => MobileIndexMainContent3(content),
|
||||
tablet: (context) => DesktopIndexMainContent3(content),
|
||||
desktop: (context) => DesktopIndexMainContent3(content),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,17 +9,17 @@ import 'breadcrumbs.dart';
|
||||
typedef OnBackPress();
|
||||
|
||||
class MiniNavigationBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
final Key key;
|
||||
final Key? key;
|
||||
final String title;
|
||||
final bool back;
|
||||
final bool toHome;
|
||||
final bool showMe;
|
||||
final List<BreadCrumb> breadCrumbs;
|
||||
final double breadCrumbHeight;
|
||||
final Widget shoppingCart;
|
||||
final List<BreadCrumb>? breadCrumbs;
|
||||
final double? breadCrumbHeight;
|
||||
final Widget? shoppingCart;
|
||||
|
||||
MiniNavigationBar({Key key, PreferredSizeWidget bottom, String title,
|
||||
bool back, bool toHome, bool showMe, this.breadCrumbs,
|
||||
MiniNavigationBar({Key? key, PreferredSizeWidget? bottom, String? title,
|
||||
bool? back, bool? toHome, bool? showMe, this.breadCrumbs,
|
||||
this.breadCrumbHeight, this.shoppingCart})
|
||||
: key = key,
|
||||
preferredSize = breadCrumbHeight != null ? Size.fromHeight(kToolbarHeight + breadCrumbHeight) :
|
||||
@@ -43,12 +43,12 @@ class MiniNavigationBarState extends State<MiniNavigationBar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileNavigationBar(title: widget.title, back: widget.back,
|
||||
return ScreenTypeLayout.builder(
|
||||
mobile: (context) => MobileNavigationBar(title: widget.title, back: widget.back,
|
||||
toHome: widget.toHome, showMe: widget.showMe,),
|
||||
tablet: DesktopNavigationBar(hasBack: widget.back,
|
||||
tablet: (context) => DesktopNavigationBar(hasBack: widget.back,
|
||||
breadCrumbs: widget.breadCrumbs, shoppingCart: widget.shoppingCart,),
|
||||
desktop: DesktopNavigationBar(hasBack: widget.back,
|
||||
desktop: (context) => DesktopNavigationBar(hasBack: widget.back,
|
||||
breadCrumbs: widget.breadCrumbs, shoppingCart: widget.shoppingCart,),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import '../../constants.dart';
|
||||
|
||||
class NavigationBarLogo extends StatelessWidget {
|
||||
const NavigationBarLogo({Key key}) : super(key: key);
|
||||
const NavigationBarLogo({Key? key}) : super(key: key);
|
||||
|
||||
static const IconData logoData = IconData(
|
||||
Constants.FONT_WISETRONIC,
|
||||
|
||||
@@ -6,30 +6,30 @@ class ParabolicAnimationWidget extends AnimatedWidget {
|
||||
final GlobalKey stackKey;
|
||||
final GlobalKey startKey;
|
||||
final GlobalKey endKey;
|
||||
final double size;
|
||||
final Color color;
|
||||
final Offset startAdjustOffset;
|
||||
final Offset endAdjustOffset;
|
||||
final double? size;
|
||||
final Color? color;
|
||||
final Offset? startAdjustOffset;
|
||||
final Offset? endAdjustOffset;
|
||||
|
||||
ParabolicAnimationWidget({
|
||||
@required Animation<double> animation,
|
||||
@required this.stackKey,
|
||||
@required this.startKey,
|
||||
@required this.endKey,
|
||||
required Animation<double> animation,
|
||||
required this.stackKey,
|
||||
required this.startKey,
|
||||
required this.endKey,
|
||||
this.size = 20.0,
|
||||
this.color = Colors.red,
|
||||
this.startAdjustOffset = Offset.zero,
|
||||
this.endAdjustOffset = Offset.zero,
|
||||
}) : super(listenable: animation);
|
||||
|
||||
Offset _startOffset;
|
||||
Offset _endOffset;
|
||||
Offset _startOffset = Offset.zero;
|
||||
Offset _endOffset = Offset.zero;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_calPoints();
|
||||
|
||||
final Animation<double> animation = listenable;
|
||||
final Animation<double> animation = listenable as Animation<double>;
|
||||
final double time = animation.value;
|
||||
|
||||
// 设time=1 已知两点坐标 和 初速度 可求出 加速度 a
|
||||
@@ -58,7 +58,7 @@ class ParabolicAnimationWidget extends AnimatedWidget {
|
||||
width: size,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.all(Radius.circular(size / 2.0))),
|
||||
borderRadius: BorderRadius.all(Radius.circular(size! / 2.0))),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -66,26 +66,26 @@ class ParabolicAnimationWidget extends AnimatedWidget {
|
||||
|
||||
void _calPoints() {
|
||||
if (_startOffset == null) {
|
||||
RenderBox stackBox = stackKey.currentContext.findRenderObject();
|
||||
RenderBox stackBox = stackKey.currentContext?.findRenderObject() as RenderBox;
|
||||
Offset stackBoxOffset = stackBox.globalToLocal(Offset.zero);
|
||||
|
||||
EdgeInsets startMargin = _margin(startKey);
|
||||
RenderBox startBox = startKey.currentContext.findRenderObject();
|
||||
RenderBox startBox = startKey.currentContext?.findRenderObject() as RenderBox;
|
||||
_startOffset = startBox.localToGlobal(Offset(
|
||||
startMargin.left + startAdjustOffset.dx,
|
||||
stackBoxOffset.dy + startMargin.top + startAdjustOffset.dy));
|
||||
startMargin.left + startAdjustOffset!.dx,
|
||||
stackBoxOffset.dy + startMargin.top + startAdjustOffset!.dy));
|
||||
|
||||
EdgeInsets endMargin = _margin(endKey);
|
||||
RenderBox endBox = endKey.currentContext.findRenderObject();
|
||||
RenderBox endBox = endKey.currentContext?.findRenderObject() as RenderBox;
|
||||
_endOffset = endBox.localToGlobal(Offset(
|
||||
endMargin.left + endAdjustOffset.dx,
|
||||
stackBoxOffset.dy + endMargin.top + endAdjustOffset.dy));
|
||||
endMargin.left + endAdjustOffset!.dx,
|
||||
stackBoxOffset.dy + endMargin.top + endAdjustOffset!.dy));
|
||||
}
|
||||
}
|
||||
|
||||
EdgeInsets _margin(GlobalKey key) {
|
||||
final Widget widget = key.currentContext.widget;
|
||||
EdgeInsets margin = (widget is Container) ? widget.margin : EdgeInsets.zero;
|
||||
final Widget widget = key.currentContext!.widget;
|
||||
EdgeInsets margin = (widget is Container) ? widget.margin as EdgeInsets : EdgeInsets.zero;
|
||||
return margin ?? EdgeInsets.zero;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
import 'package:countdown/countdown.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pinput/pin_put/pin_put.dart';
|
||||
|
||||
@@ -7,17 +5,17 @@ import '../../generated/l10n.dart';
|
||||
import '../../models/user.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../../vendor/countdown/src/countdown_base.dart';
|
||||
|
||||
typedef OnCodeVerified();
|
||||
typedef OnCancel();
|
||||
|
||||
class PaymentVerificationCodeDialog extends StatefulWidget {
|
||||
final Key key;
|
||||
final User user;
|
||||
final OnCodeVerified onCodeVerified;
|
||||
final OnCancel onCancel;
|
||||
|
||||
const PaymentVerificationCodeDialog(this.user, this.onCodeVerified, this.onCancel, {this.key});
|
||||
const PaymentVerificationCodeDialog(this.user, this.onCodeVerified, this.onCancel, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -33,8 +31,8 @@ class PaymentVerificationCodeDialogState extends State<PaymentVerificationCodeDi
|
||||
String getCodeText = '';
|
||||
String paymentCodeEncrypt = '';
|
||||
|
||||
String verifyMethod;
|
||||
String verifyName;
|
||||
String verifyMethod = '';
|
||||
String verifyName = '';
|
||||
|
||||
final TextEditingController _pinPutController = TextEditingController();
|
||||
final FocusNode _pinPutFocusNode = FocusNode();
|
||||
@@ -115,7 +113,7 @@ class PaymentVerificationCodeDialogState extends State<PaymentVerificationCodeDi
|
||||
followingFieldDecoration: _pinPutDecoration.copyWith(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(
|
||||
color: Colors.deepPurpleAccent.withOpacity(.5),
|
||||
color: Colors.deepPurpleAccent.withAlpha(50),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -10,15 +10,15 @@ class PopupAnimationWidget extends AnimatedWidget {
|
||||
final Animation<double> animation;
|
||||
|
||||
PopupAnimationWidget({
|
||||
@required this.animation,
|
||||
@required this.stackKey,
|
||||
@required this.startKey,
|
||||
@required this.child,
|
||||
required this.animation,
|
||||
required this.stackKey,
|
||||
required this.startKey,
|
||||
required this.child,
|
||||
this.color = Colors.yellow,
|
||||
this.popupOffset = Offset.zero,
|
||||
}) : super(listenable: animation);
|
||||
|
||||
Offset _startOffset;
|
||||
Offset _startOffset = Offset.zero;
|
||||
Offset _offset = Offset.zero;
|
||||
|
||||
@override
|
||||
@@ -49,11 +49,11 @@ class PopupAnimationWidget extends AnimatedWidget {
|
||||
|
||||
void _calAnimation() {
|
||||
if (_startOffset == null) {
|
||||
final RenderBox stackBox = stackKey.currentContext.findRenderObject();
|
||||
final RenderBox stackBox = stackKey.currentContext?.findRenderObject() as RenderBox;
|
||||
final Offset stackBoxOffset = stackBox.globalToLocal(Offset.zero);
|
||||
|
||||
final EdgeInsets startMargin = _margin(startKey);
|
||||
final RenderBox startBox = startKey.currentContext.findRenderObject();
|
||||
final RenderBox startBox = startKey.currentContext?.findRenderObject() as RenderBox;
|
||||
|
||||
_startOffset = startBox.localToGlobal(Offset(
|
||||
startMargin.left + popupOffset.dx,
|
||||
@@ -62,9 +62,9 @@ class PopupAnimationWidget extends AnimatedWidget {
|
||||
}
|
||||
|
||||
EdgeInsets _margin(GlobalKey key) {
|
||||
final Widget widget = key.currentContext.widget;
|
||||
final Widget widget = key.currentContext!.widget;
|
||||
final EdgeInsets margin =
|
||||
(widget is Container) ? widget.margin : EdgeInsets.zero;
|
||||
(widget is Container) ? widget.margin as EdgeInsets : EdgeInsets.zero;
|
||||
return margin ?? EdgeInsets.zero;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ enum TrimMode {
|
||||
class ReadMoreText extends StatefulWidget {
|
||||
const ReadMoreText(
|
||||
this.data, {
|
||||
Key key,
|
||||
Key? key,
|
||||
this.trimExpandedText = ' read less',
|
||||
this.trimCollapsedText = ' ...read more',
|
||||
this.colorClickableText,
|
||||
@@ -28,16 +28,16 @@ class ReadMoreText extends StatefulWidget {
|
||||
final String data;
|
||||
final String trimExpandedText;
|
||||
final String trimCollapsedText;
|
||||
final Color colorClickableText;
|
||||
final Color? colorClickableText;
|
||||
final int trimLength;
|
||||
final int trimLines;
|
||||
final TrimMode trimMode;
|
||||
final TextStyle style;
|
||||
final TextAlign textAlign;
|
||||
final TextDirection textDirection;
|
||||
final Locale locale;
|
||||
final double textScaleFactor;
|
||||
final String semanticsLabel;
|
||||
final TextStyle? style;
|
||||
final TextAlign? textAlign;
|
||||
final TextDirection? textDirection;
|
||||
final Locale? locale;
|
||||
final double? textScaleFactor;
|
||||
final String? semanticsLabel;
|
||||
|
||||
@override
|
||||
ReadMoreTextState createState() => ReadMoreTextState();
|
||||
@@ -57,8 +57,8 @@ class ReadMoreTextState extends State<ReadMoreText> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
|
||||
TextStyle effectiveTextStyle = widget.style;
|
||||
if (widget.style == null || widget.style.inherit) {
|
||||
TextStyle? effectiveTextStyle = widget.style;
|
||||
if (widget.style == null || widget.style!.inherit) {
|
||||
effectiveTextStyle = defaultTextStyle.style.merge(widget.style);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class ReadMoreTextState extends State<ReadMoreText> {
|
||||
widget.textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start;
|
||||
final textDirection = widget.textDirection ?? Directionality.of(context);
|
||||
final textScaleFactor =
|
||||
widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context);
|
||||
widget.textScaleFactor ?? MediaQuery.textScalerOf(context).scale(1);
|
||||
final overflow = defaultTextStyle.overflow;
|
||||
final locale =
|
||||
widget.locale ?? Localizations.localeOf(context);
|
||||
@@ -76,7 +76,7 @@ class ReadMoreTextState extends State<ReadMoreText> {
|
||||
|
||||
TextSpan link = TextSpan(
|
||||
text: _readMore ? widget.trimCollapsedText : widget.trimExpandedText,
|
||||
style: effectiveTextStyle.copyWith(
|
||||
style: effectiveTextStyle?.copyWith(
|
||||
color: colorClickableText,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()..onTap = _onTapLink,
|
||||
@@ -98,7 +98,7 @@ class ReadMoreTextState extends State<ReadMoreText> {
|
||||
text: link,
|
||||
textAlign: textAlign,
|
||||
textDirection: textDirection,
|
||||
textScaleFactor: textScaleFactor,
|
||||
textScaler: TextScaler.linear(textScaleFactor),
|
||||
maxLines: widget.trimLines,
|
||||
ellipsis: overflow == TextOverflow.ellipsis ? _kEllipsis : null,
|
||||
locale: locale,
|
||||
@@ -115,7 +115,7 @@ class ReadMoreTextState extends State<ReadMoreText> {
|
||||
|
||||
// Get the endIndex of data
|
||||
bool linkLongerThanLine = false;
|
||||
int endIndex;
|
||||
int? endIndex;
|
||||
|
||||
if (linkSize.width < maxWidth) {
|
||||
final pos = textPainter.getPositionForOffset(Offset(
|
||||
|
||||
@@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class ShowPrice extends StatelessWidget {
|
||||
final double price;
|
||||
final double regularPrice;
|
||||
final double? regularPrice;
|
||||
final double largeFontSize;
|
||||
final double smallFontSize;
|
||||
final String currencySign;
|
||||
final String? currencySign;
|
||||
final Color color;
|
||||
final FontWeight fontWeight;
|
||||
|
||||
@@ -36,7 +36,7 @@ class ShowPrice extends StatelessWidget {
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: largeFontSize / 10.0),
|
||||
child: Text(
|
||||
currencySign,
|
||||
currencySign!,
|
||||
style: TextStyle(
|
||||
fontSize: smallFontSize,
|
||||
color: color,
|
||||
@@ -65,12 +65,12 @@ class ShowPrice extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
regularPrice == null || price.round() >= regularPrice.round() ?
|
||||
regularPrice == null || price.round() >= regularPrice!.round() ?
|
||||
SizedBox.shrink() :
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: largeFontSize / 2),
|
||||
child: Text(
|
||||
regularPrice.toStringAsFixed(0),
|
||||
'${regularPrice?.toStringAsFixed(0)}',
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
fontSize: smallFontSize,
|
||||
|
||||
@@ -30,7 +30,7 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
/// otherwise, [collapsed] will be displayed overtop
|
||||
/// of this Widget. If [panel] and [panelBuilder] are both non-null,
|
||||
/// [panel] will be used.
|
||||
final Widget panel;
|
||||
final Widget? panel;
|
||||
|
||||
/// WARNING: This feature is still in beta and is subject to change without
|
||||
/// notice. Stability is not gauranteed. Provides a [ScrollController] and
|
||||
@@ -38,28 +38,28 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
/// the panel position with the scroll position. Useful for implementing an
|
||||
/// infinite scroll behavior. If [panel] and [panelBuilder] are both non-null,
|
||||
/// [panel] will be used.
|
||||
final Widget Function(ScrollController sc) panelBuilder;
|
||||
final Widget? Function(ScrollController sc)? panelBuilder;
|
||||
|
||||
/// The Widget displayed overtop the [panel] when collapsed.
|
||||
/// This fades out as the panel is opened.
|
||||
final Widget collapsed;
|
||||
final Widget? collapsed;
|
||||
|
||||
/// The Widget that lies underneath the sliding panel.
|
||||
/// This Widget automatically sizes itself
|
||||
/// to fill the screen.
|
||||
final Widget body;
|
||||
final Widget? body;
|
||||
|
||||
/// Optional persistent widget that floats above the [panel] and attaches
|
||||
/// to the top of the [panel]. Content at the top of the panel will be covered
|
||||
/// by this widget. Add padding to the bottom of the `panel` to
|
||||
/// avoid coverage.
|
||||
final Widget header;
|
||||
final Widget? header;
|
||||
|
||||
/// Optional persistent widget that floats above the [panel] and
|
||||
/// attaches to the bottom of the [panel]. Content at the bottom of the panel
|
||||
/// will be covered by this widget. Add padding to the bottom of the `panel`
|
||||
/// to avoid coverage.
|
||||
final Widget footer;
|
||||
final Widget? footer;
|
||||
|
||||
/// The height of the sliding panel when fully collapsed.
|
||||
final double minHeight;
|
||||
@@ -72,13 +72,13 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
/// and go directly to the open/close position. This value is represented as a
|
||||
/// percentage of the total animation distance ([maxHeight] - [minHeight]),
|
||||
/// so it must be between 0.0 and 1.0, exclusive.
|
||||
final double snapPoint;
|
||||
final double? snapPoint;
|
||||
|
||||
/// A border to draw around the sliding panel sheet.
|
||||
final Border border;
|
||||
final Border? border;
|
||||
|
||||
/// If non-null, the corners of the sliding panel sheet are rounded by this [BorderRadiusGeometry].
|
||||
final BorderRadiusGeometry borderRadius;
|
||||
final BorderRadiusGeometry? borderRadius;
|
||||
|
||||
/// A list of shadows cast behind the sliding panel sheet.
|
||||
final List<BoxShadow> boxShadow;
|
||||
@@ -87,10 +87,10 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
final Color color;
|
||||
|
||||
/// The amount to inset the children of the sliding panel sheet.
|
||||
final EdgeInsetsGeometry padding;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
/// Empty space surrounding the sliding panel sheet.
|
||||
final EdgeInsetsGeometry margin;
|
||||
final EdgeInsetsGeometry? margin;
|
||||
|
||||
/// Set to false to not to render the sheet the [panel] sits upon.
|
||||
/// This means that only the [body], [collapsed], and the [panel]
|
||||
@@ -104,7 +104,7 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
final bool panelSnapping;
|
||||
|
||||
/// If non-null, this can be used to control the state of the panel.
|
||||
final PanelController controller;
|
||||
final PanelController? controller;
|
||||
|
||||
/// If non-null, shows a darkening shadow over the [body] as the panel slides open.
|
||||
final bool backdropEnabled;
|
||||
@@ -125,15 +125,15 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
/// is called as the panel slides around with the
|
||||
/// current position of the panel. The position is a double
|
||||
/// between 0.0 and 1.0 where 0.0 is fully collapsed and 1.0 is fully open.
|
||||
final void Function(double position) onPanelSlide;
|
||||
final void Function(double position)? onPanelSlide;
|
||||
|
||||
/// If non-null, this callback is called when the
|
||||
/// panel is fully opened
|
||||
final VoidCallback onPanelOpened;
|
||||
final VoidCallback? onPanelOpened;
|
||||
|
||||
/// If non-null, this callback is called when the panel
|
||||
/// is fully collapsed.
|
||||
final VoidCallback onPanelClosed;
|
||||
final VoidCallback? onPanelClosed;
|
||||
|
||||
/// If non-null and true, the SlidingUpPanel exhibits a
|
||||
/// parallax effect as the panel slides up. Essentially,
|
||||
@@ -164,7 +164,7 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
final PanelState defaultPanelState;
|
||||
|
||||
SlidingUpPanel({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.panel,
|
||||
this.panelBuilder,
|
||||
this.body,
|
||||
@@ -211,9 +211,9 @@ class SlidingUpPanel extends StatefulWidget {
|
||||
|
||||
class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProviderStateMixin{
|
||||
|
||||
AnimationController _ac;
|
||||
AnimationController? _ac;
|
||||
|
||||
ScrollController _sc;
|
||||
ScrollController? _sc;
|
||||
bool _scrollingEnabled = false;
|
||||
VelocityTracker _vt = VelocityTracker.withKind(PointerDeviceKind.touch);
|
||||
|
||||
@@ -228,19 +228,19 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
duration: const Duration(milliseconds: 300),
|
||||
value: widget.defaultPanelState == PanelState.CLOSED ? 0.0 : 1.0 //set the default panel state (i.e. set initial value of _ac)
|
||||
)..addListener((){
|
||||
if(widget.onPanelSlide != null) widget.onPanelSlide(_ac.value);
|
||||
if(widget.onPanelSlide != null) widget.onPanelSlide!(_ac!.value);
|
||||
|
||||
if(widget.onPanelOpened != null && _ac.value == 1.0) widget.onPanelOpened();
|
||||
if(widget.onPanelOpened != null && _ac!.value == 1.0) widget.onPanelOpened!();
|
||||
|
||||
if(widget.onPanelClosed != null && _ac.value == 0.0) widget.onPanelClosed();
|
||||
if(widget.onPanelClosed != null && _ac!.value == 0.0) widget.onPanelClosed!();
|
||||
});
|
||||
|
||||
// prevent the panel content from being scrolled only if the widget is
|
||||
// draggable and panel scrolling is enabled
|
||||
_sc = new ScrollController();
|
||||
_sc.addListener((){
|
||||
if(widget.isDraggable && !_scrollingEnabled)
|
||||
_sc.jumpTo(0);
|
||||
_sc!.addListener((){
|
||||
if(widget.isDraggable! && !_scrollingEnabled)
|
||||
_sc!.jumpTo(0);
|
||||
});
|
||||
|
||||
widget.controller?._addState(this);
|
||||
@@ -254,11 +254,11 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
//make the back widget take up the entire back side
|
||||
widget.body != null ? AnimatedBuilder(
|
||||
animation: _ac,
|
||||
animation: _ac!,
|
||||
builder: (context, child){
|
||||
return Positioned(
|
||||
top: widget.parallaxEnabled ? _getParallax() : 0.0,
|
||||
child: child,
|
||||
top: widget.parallaxEnabled! ? _getParallax() : 0.0,
|
||||
child: child!,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
@@ -278,7 +278,7 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
} : null,
|
||||
onTap: widget.backdropTapClosesPanel ? () => _close() : null,
|
||||
child: AnimatedBuilder(
|
||||
animation: _ac,
|
||||
animation: _ac!,
|
||||
builder: (context, _) {
|
||||
return Container(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
@@ -287,7 +287,7 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
//set color to null so that touch events pass through
|
||||
//to the body when the panel is closed, otherwise,
|
||||
//if a color exists, then touch events won't go through
|
||||
color: _ac.value == 0.0 ? null : widget.backdropColor.withOpacity(widget.backdropOpacity * _ac.value),
|
||||
color: _ac!.value == 0.0 ? null : widget.backdropColor.withOpacity(widget.backdropOpacity * _ac!.value),
|
||||
);
|
||||
}
|
||||
),
|
||||
@@ -296,10 +296,10 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
//the actual sliding part
|
||||
!_isPanelVisible ? Container() : _gestureHandler(
|
||||
child: AnimatedBuilder(
|
||||
animation: _ac,
|
||||
animation: _ac!,
|
||||
builder: (context, child) {
|
||||
return Container(
|
||||
height: _ac.value * (widget.maxHeight - widget.minHeight) + widget.minHeight,
|
||||
height: _ac!.value * (widget.maxHeight - widget.minHeight) + widget.minHeight,
|
||||
margin: widget.margin,
|
||||
padding: widget.padding,
|
||||
decoration: widget.renderPanelSheet ? BoxDecoration(
|
||||
@@ -320,13 +320,13 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
top: widget.slideDirection == SlideDirection.UP ? 0.0 : null,
|
||||
bottom: widget.slideDirection == SlideDirection.DOWN ? 0.0 : null,
|
||||
width: MediaQuery.of(context).size.width -
|
||||
(widget.margin != null ? widget.margin.horizontal : 0) -
|
||||
(widget.padding != null ? widget.padding.horizontal : 0),
|
||||
(widget.margin != null ? widget.margin!.horizontal : 0) -
|
||||
(widget.padding != null ? widget.padding!.horizontal : 0),
|
||||
child: Container(
|
||||
height: widget.maxHeight,
|
||||
child: widget.panel != null
|
||||
? widget.panel
|
||||
: widget.panelBuilder(_sc),
|
||||
: widget.panelBuilder!(_sc!),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -334,14 +334,14 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
widget.header != null ? Positioned(
|
||||
top: widget.slideDirection == SlideDirection.UP ? 0.0 : null,
|
||||
bottom: widget.slideDirection == SlideDirection.DOWN ? 0.0 : null,
|
||||
child: widget.header,
|
||||
child: widget.header!,
|
||||
) : Container(),
|
||||
|
||||
// footer
|
||||
widget.footer != null ? Positioned(
|
||||
top: widget.slideDirection == SlideDirection.UP ? null : 0.0,
|
||||
bottom: widget.slideDirection == SlideDirection.DOWN ? null : 0.0,
|
||||
child: widget.footer
|
||||
child: widget.footer!
|
||||
) : Container(),
|
||||
|
||||
// collapsed panel
|
||||
@@ -349,12 +349,12 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
top: widget.slideDirection == SlideDirection.UP ? 0.0 : null,
|
||||
bottom: widget.slideDirection == SlideDirection.DOWN ? 0.0 : null,
|
||||
width: MediaQuery.of(context).size.width -
|
||||
(widget.margin != null ? widget.margin.horizontal : 0) -
|
||||
(widget.padding != null ? widget.padding.horizontal : 0),
|
||||
(widget.margin != null ? widget.margin!.horizontal : 0) -
|
||||
(widget.padding != null ? widget.padding!.horizontal : 0),
|
||||
child: Container(
|
||||
height: widget.minHeight,
|
||||
child: widget.collapsed == null ? Container() : FadeTransition(
|
||||
opacity: Tween(begin: 1.0, end: 0.0).animate(_ac),
|
||||
opacity: Tween(begin: 1.0, end: 0.0).animate(_ac!),
|
||||
|
||||
// if the panel is open ignore pointers (touch events) on the collapsed
|
||||
// child so that way touch events go through to whatever is underneath
|
||||
@@ -375,22 +375,22 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
@override
|
||||
void dispose(){
|
||||
_ac.dispose();
|
||||
_ac?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
double _getParallax(){
|
||||
if(widget.slideDirection == SlideDirection.UP)
|
||||
return -_ac.value * (widget.maxHeight - widget.minHeight) * widget.parallaxOffset;
|
||||
return -_ac!.value * (widget.maxHeight - widget.minHeight) * widget.parallaxOffset;
|
||||
else
|
||||
return _ac.value * (widget.maxHeight - widget.minHeight) * widget.parallaxOffset;
|
||||
return _ac!.value * (widget.maxHeight - widget.minHeight) * widget.parallaxOffset;
|
||||
}
|
||||
|
||||
// returns a gesture detector if panel is used
|
||||
// and a listener if panelBuilder is used.
|
||||
// this is because the listener is designed only for use with linking the scrolling of
|
||||
// panels and using it for panels that don't want to linked scrolling yields odd results
|
||||
Widget _gestureHandler({Widget child}){
|
||||
Widget _gestureHandler({required Widget child}){
|
||||
if (!widget.isDraggable) return child;
|
||||
|
||||
if (widget.panel != null){
|
||||
@@ -418,15 +418,15 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
// only slide the panel if scrolling is not enabled
|
||||
if(!_scrollingEnabled){
|
||||
if(widget.slideDirection == SlideDirection.UP)
|
||||
_ac.value -= dy / (widget.maxHeight - widget.minHeight);
|
||||
_ac!.value -= dy / (widget.maxHeight - widget.minHeight);
|
||||
else
|
||||
_ac.value += dy / (widget.maxHeight - widget.minHeight);
|
||||
_ac!.value += dy / (widget.maxHeight - widget.minHeight);
|
||||
}
|
||||
|
||||
// if the panel is open and the user hasn't scrolled, we need to determine
|
||||
// whether to enable scrolling if the user swipes up, or disable closing and
|
||||
// begin to close the panel if the user swipes down
|
||||
if(_isPanelOpen && _sc.hasClients && _sc.offset <= 0){
|
||||
if(_isPanelOpen && _sc!.hasClients && _sc!.offset <= 0){
|
||||
setState(() {
|
||||
if(dy < 0){
|
||||
_scrollingEnabled = true;
|
||||
@@ -443,7 +443,7 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
double kSnap = 8;
|
||||
|
||||
//let the current animation finish before starting a new one
|
||||
if(_ac.isAnimating) return;
|
||||
if(_ac!.isAnimating) return;
|
||||
|
||||
// if scrolling is allowed and the panel is open, we don't want to close
|
||||
// the panel if they swipe up on the scrollable
|
||||
@@ -458,9 +458,9 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
|
||||
// get minimum distances to figure out where the panel is at
|
||||
double d2Close = _ac.value;
|
||||
double d2Open = 1 - _ac.value;
|
||||
double d2Snap = ((widget.snapPoint ?? 3) -_ac.value).abs(); // large value if null results in not every being the min
|
||||
double d2Close = _ac!.value;
|
||||
double d2Open = 1 - _ac!.value;
|
||||
double d2Snap = ((widget.snapPoint ?? 3) -_ac!.value).abs(); // large value if null results in not every being the min
|
||||
double minDistance = min(d2Close, min(d2Snap, d2Open));
|
||||
|
||||
// check if velocity is sufficient for a fling
|
||||
@@ -469,18 +469,18 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
// snapPoint exists
|
||||
if(widget.panelSnapping && widget.snapPoint != null){
|
||||
if(v.pixelsPerSecond.dy.abs() >= kSnap*minFlingVelocity || minDistance == d2Snap)
|
||||
_ac.fling(velocity: visualVelocity);
|
||||
_ac!.fling(velocity: visualVelocity);
|
||||
else
|
||||
_flingPanelToPosition(widget.snapPoint, visualVelocity);
|
||||
_flingPanelToPosition(widget.snapPoint!, visualVelocity);
|
||||
|
||||
// no snap point exists
|
||||
}else if(widget.panelSnapping){
|
||||
_ac.fling(velocity: visualVelocity);
|
||||
_ac!.fling(velocity: visualVelocity);
|
||||
|
||||
// panel snapping disabled
|
||||
}else{
|
||||
_ac.animateTo(
|
||||
_ac.value + visualVelocity * 0.16,
|
||||
_ac!.animateTo(
|
||||
_ac!.value + visualVelocity * 0.16,
|
||||
duration: Duration(milliseconds: 410),
|
||||
curve: Curves.decelerate,
|
||||
);
|
||||
@@ -495,7 +495,7 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
if(minDistance == d2Close){
|
||||
_close();
|
||||
}else if(minDistance == d2Snap){
|
||||
_flingPanelToPosition(widget.snapPoint, visualVelocity);
|
||||
_flingPanelToPosition(widget.snapPoint!, visualVelocity);
|
||||
}else{
|
||||
_open();
|
||||
}
|
||||
@@ -510,12 +510,12 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
stiffness: 500.0,
|
||||
ratio: 1.0,
|
||||
),
|
||||
_ac.value,
|
||||
_ac!.value,
|
||||
targetPos,
|
||||
velocity
|
||||
);
|
||||
|
||||
_ac.animateWith(simulation);
|
||||
_ac!.animateWith(simulation);
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
@@ -524,17 +524,17 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
//close the panel
|
||||
Future<void> _close(){
|
||||
return _ac.fling(velocity: -1.0);
|
||||
return _ac!.fling(velocity: -1.0);
|
||||
}
|
||||
|
||||
//open the panel
|
||||
Future<void> _open(){
|
||||
return _ac.fling(velocity: 1.0);
|
||||
return _ac!.fling(velocity: 1.0);
|
||||
}
|
||||
|
||||
//hide the panel (completely offscreen)
|
||||
Future<void> _hide(){
|
||||
return _ac.fling(velocity: -1.0).then((x){
|
||||
return _ac!.fling(velocity: -1.0).then((x){
|
||||
setState(() {
|
||||
_isPanelVisible = false;
|
||||
});
|
||||
@@ -543,7 +543,7 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
//show the panel (in collapsed mode)
|
||||
Future<void> _show(){
|
||||
return _ac.fling(velocity: -1.0).then((x){
|
||||
return _ac!.fling(velocity: -1.0).then((x){
|
||||
setState(() {
|
||||
_isPanelVisible = true;
|
||||
});
|
||||
@@ -552,41 +552,41 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
//animate the panel position to value - must
|
||||
//be between 0.0 and 1.0
|
||||
Future<void> _animatePanelToPosition(double value, {Duration duration, Curve curve = Curves.linear}){
|
||||
Future<void> _animatePanelToPosition(double value, {required Duration duration, Curve curve = Curves.linear}){
|
||||
assert(0.0 <= value && value <= 1.0);
|
||||
return _ac.animateTo(value, duration: duration, curve: curve);
|
||||
return _ac!.animateTo(value, duration: duration, curve: curve);
|
||||
}
|
||||
|
||||
//animate the panel position to the snap point
|
||||
//REQUIRES that widget.snapPoint != null
|
||||
Future<void> _animatePanelToSnapPoint({Duration duration, Curve curve = Curves.linear}){
|
||||
Future<void> _animatePanelToSnapPoint({required Duration duration, Curve curve = Curves.linear}){
|
||||
assert(widget.snapPoint != null);
|
||||
return _ac.animateTo(widget.snapPoint, duration: duration, curve: curve);
|
||||
return _ac!.animateTo(widget.snapPoint!, duration: duration, curve: curve);
|
||||
}
|
||||
|
||||
//set the panel position to value - must
|
||||
//be between 0.0 and 1.0
|
||||
set _panelPosition(double value){
|
||||
assert(0.0 <= value && value <= 1.0);
|
||||
_ac.value = value;
|
||||
_ac!.value = value;
|
||||
}
|
||||
|
||||
//get the current panel position
|
||||
//returns the % offset from collapsed state
|
||||
//as a decimal between 0.0 and 1.0
|
||||
double get _panelPosition => _ac.value;
|
||||
double get _panelPosition => _ac!.value;
|
||||
|
||||
//returns whether or not
|
||||
//the panel is still animating
|
||||
bool get _isPanelAnimating => _ac.isAnimating;
|
||||
bool get _isPanelAnimating => _ac!.isAnimating;
|
||||
|
||||
//returns whether or not the
|
||||
//panel is open
|
||||
bool get _isPanelOpen => _ac.value == 1.0;
|
||||
bool get _isPanelOpen => _ac!.value == 1.0;
|
||||
|
||||
//returns whether or not the
|
||||
//panel is closed
|
||||
bool get _isPanelClosed => _ac.value == 0.0;
|
||||
bool get _isPanelClosed => _ac!.value == 0.0;
|
||||
|
||||
//returns whether or not the
|
||||
//panel is shown/hidden
|
||||
@@ -602,7 +602,7 @@ class _SlidingUpPanelState extends State<SlidingUpPanel> with SingleTickerProvid
|
||||
|
||||
|
||||
class PanelController{
|
||||
_SlidingUpPanelState _panelState;
|
||||
_SlidingUpPanelState? _panelState;
|
||||
|
||||
void _addState(_SlidingUpPanelState panelState){
|
||||
this._panelState = panelState;
|
||||
@@ -616,27 +616,27 @@ class PanelController{
|
||||
/// Closes the sliding panel to its collapsed state (i.e. to the minHeight)
|
||||
Future<void> close(){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._close();
|
||||
return _panelState!._close();
|
||||
}
|
||||
|
||||
/// Opens the sliding panel fully
|
||||
/// (i.e. to the maxHeight)
|
||||
Future<void> open(){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._open();
|
||||
return _panelState!._open();
|
||||
}
|
||||
|
||||
/// Hides the sliding panel (i.e. is invisible)
|
||||
Future<void> hide(){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._hide();
|
||||
return _panelState!._hide();
|
||||
}
|
||||
|
||||
/// Shows the sliding panel in its collapsed state
|
||||
/// (i.e. "un-hide" the sliding panel)
|
||||
Future<void> show(){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._show();
|
||||
return _panelState!._show();
|
||||
}
|
||||
|
||||
/// Animates the panel position to the value.
|
||||
@@ -644,20 +644,20 @@ class PanelController{
|
||||
/// where 0.0 is fully collapsed and 1.0 is completely open.
|
||||
/// (optional) duration specifies the time for the animation to complete
|
||||
/// (optional) curve specifies the easing behavior of the animation.
|
||||
Future<void> animatePanelToPosition(double value, {Duration duration, Curve curve = Curves.linear}){
|
||||
Future<void> animatePanelToPosition(double value, {required Duration duration, Curve curve = Curves.linear}){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
assert(0.0 <= value && value <= 1.0);
|
||||
return _panelState._animatePanelToPosition(value, duration: duration, curve: curve);
|
||||
return _panelState!._animatePanelToPosition(value, duration: duration, curve: curve);
|
||||
}
|
||||
|
||||
/// Animates the panel position to the snap point
|
||||
/// Requires that the SlidingUpPanel snapPoint property is not null
|
||||
/// (optional) duration specifies the time for the animation to complete
|
||||
/// (optional) curve specifies the easing behavior of the animation.
|
||||
Future<void> animatePanelToSnapPoint({Duration duration, Curve curve = Curves.linear}){
|
||||
Future<void> animatePanelToSnapPoint({required Duration duration, Curve curve = Curves.linear}){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
assert(_panelState.widget.snapPoint != null, "SlidingUpPanel snapPoint property must not be null");
|
||||
return _panelState._animatePanelToSnapPoint(duration: duration, curve: curve);
|
||||
assert(_panelState!.widget.snapPoint != null, "SlidingUpPanel snapPoint property must not be null");
|
||||
return _panelState!._animatePanelToSnapPoint(duration: duration, curve: curve);
|
||||
}
|
||||
|
||||
/// Sets the panel position (without animation).
|
||||
@@ -666,7 +666,7 @@ class PanelController{
|
||||
set panelPosition(double value){
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
assert(0.0 <= value && value <= 1.0);
|
||||
_panelState._panelPosition = value;
|
||||
_panelState!._panelPosition = value;
|
||||
}
|
||||
|
||||
/// Gets the current panel position.
|
||||
@@ -677,35 +677,35 @@ class PanelController{
|
||||
/// 1.0 is full open.
|
||||
double get panelPosition{
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._panelPosition;
|
||||
return _panelState!._panelPosition;
|
||||
}
|
||||
|
||||
/// Returns whether or not the panel is
|
||||
/// currently animating.
|
||||
bool get isPanelAnimating{
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._isPanelAnimating;
|
||||
return _panelState!._isPanelAnimating;
|
||||
}
|
||||
|
||||
/// Returns whether or not the
|
||||
/// panel is open.
|
||||
bool get isPanelOpen{
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._isPanelOpen;
|
||||
return _panelState!._isPanelOpen;
|
||||
}
|
||||
|
||||
/// Returns whether or not the
|
||||
/// panel is closed.
|
||||
bool get isPanelClosed{
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._isPanelClosed;
|
||||
return _panelState!._isPanelClosed;
|
||||
}
|
||||
|
||||
/// Returns whether or not the
|
||||
/// panel is shown/hidden.
|
||||
bool get isPanelShown{
|
||||
assert(isAttached, "PanelController must be attached to a SlidingUpPanel");
|
||||
return _panelState._isPanelShown;
|
||||
return _panelState!._isPanelShown;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,11 +16,10 @@ import '../../utils/utils.dart';
|
||||
|
||||
|
||||
class StripePay extends StatefulWidget {
|
||||
final Key key;
|
||||
final Order order;
|
||||
final PaymentPlatform paymentPlatform;
|
||||
final StripePaymentMethod stripePaymentMethod;
|
||||
const StripePay(this.order, this.paymentPlatform, {this.key, this.stripePaymentMethod});
|
||||
final StripePaymentMethod? stripePaymentMethod;
|
||||
const StripePay(this.order, this.paymentPlatform, {Key? key, this.stripePaymentMethod}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -33,7 +32,7 @@ class StripePayState extends State<StripePay> {
|
||||
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
|
||||
|
||||
bool isSubmitting;
|
||||
bool isSubmitting = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -71,9 +70,9 @@ class StripePayState extends State<StripePay> {
|
||||
}
|
||||
|
||||
_paymentWithPaymentMethod(BuildContext context) async {
|
||||
Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod.customerId,
|
||||
widget.stripePaymentMethod.paymentMethodId,
|
||||
widget.stripePaymentMethod.paymentMethodType, (response){
|
||||
Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod?.customerId,
|
||||
widget.stripePaymentMethod!.paymentMethodId,
|
||||
widget.stripePaymentMethod!.paymentMethodType, (response){
|
||||
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
StripePayment.confirmPaymentIntent(
|
||||
@@ -84,8 +83,8 @@ class StripePayState extends State<StripePay> {
|
||||
).then((paymentIntentResult) {
|
||||
if (paymentIntentResult.status == Constants.STRIPE_STATUS_SUCCEDED) {
|
||||
Utils.stripeChargedSuccess(widget.order,
|
||||
widget.stripePaymentMethod.paymentMethodId,
|
||||
paymentIntentResult.paymentIntentId,
|
||||
widget.stripePaymentMethod!.paymentMethodId,
|
||||
paymentIntentResult.paymentIntentId!,
|
||||
(response) {
|
||||
eventBus.fire(OnOrderUpdated());
|
||||
Routes.router.navigateTo(context, '/orderdetail/${widget
|
||||
@@ -107,7 +106,7 @@ class StripePayState extends State<StripePay> {
|
||||
StripePayment.paymentRequestWithCardForm(
|
||||
CardFormPaymentRequest()
|
||||
).then((paymentMethod) {
|
||||
Utils.stripePaymentIntent(widget.order, null, paymentMethod.id, paymentMethod.type, (response){
|
||||
Utils.stripePaymentIntent(widget.order, null, paymentMethod.id!, paymentMethod.type!, (response){
|
||||
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
StripePayment.confirmPaymentIntent(
|
||||
@@ -118,8 +117,8 @@ class StripePayState extends State<StripePay> {
|
||||
).then((paymentIntentResult) {
|
||||
if (paymentIntentResult.status == Constants.STRIPE_STATUS_SUCCEDED) {
|
||||
Utils.stripeChargedSuccess(widget.order,
|
||||
paymentMethod.id,
|
||||
paymentIntentResult.paymentIntentId,
|
||||
paymentMethod.id!,
|
||||
paymentIntentResult.paymentIntentId!,
|
||||
(response) {
|
||||
eventBus.fire(OnOrderUpdated());
|
||||
Routes.router.navigateTo(context, '/orderdetail/${widget
|
||||
@@ -133,12 +132,12 @@ class StripePayState extends State<StripePay> {
|
||||
}).catchError(showErrorDialog);
|
||||
}
|
||||
}, (showErrorDialog),
|
||||
cardBrand: paymentMethod.card.brand,
|
||||
cardCountry: paymentMethod.card.country,
|
||||
cardExpMonth: paymentMethod.card.expMonth,
|
||||
cardExpYear: paymentMethod.card.expYear,
|
||||
cardFunding: paymentMethod.card.funding,
|
||||
cardLast4: paymentMethod.card.last4,
|
||||
cardBrand: paymentMethod.card!.brand,
|
||||
cardCountry: paymentMethod.card!.country,
|
||||
cardExpMonth: paymentMethod.card!.expMonth,
|
||||
cardExpYear: paymentMethod.card!.expYear,
|
||||
cardFunding: paymentMethod.card!.funding,
|
||||
cardLast4: paymentMethod.card!.last4,
|
||||
);
|
||||
}).catchError(showErrorDialog);
|
||||
isSubmitting = true;
|
||||
|
||||
@@ -10,26 +10,26 @@ import '../../routes.dart';
|
||||
|
||||
class TextLink extends StatelessWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final Color color;
|
||||
final Color hoverColor;
|
||||
final double paddingHorizontal;
|
||||
final double paddingVertical;
|
||||
final FontWeight fontWeight;
|
||||
final bool selected;
|
||||
final bool isLink;
|
||||
final bool replace;
|
||||
final bool clearStack;
|
||||
final bool maintainState;
|
||||
final bool rootNavigator;
|
||||
final TransitionType transition;
|
||||
final bool closeDrawer;
|
||||
final bool isEmail;
|
||||
final bool isPhone;
|
||||
final double fontSize;
|
||||
final bool isAddress;
|
||||
final TextOverflow overflow;
|
||||
final int maxLines;
|
||||
final String? url;
|
||||
final Color? color;
|
||||
final Color? hoverColor;
|
||||
final double? paddingHorizontal;
|
||||
final double? paddingVertical;
|
||||
final FontWeight? fontWeight;
|
||||
final bool? selected;
|
||||
final bool? isLink;
|
||||
final bool? replace;
|
||||
final bool? clearStack;
|
||||
final bool? maintainState;
|
||||
final bool? rootNavigator;
|
||||
final TransitionType? transition;
|
||||
final bool? closeDrawer;
|
||||
final bool? isEmail;
|
||||
final bool? isPhone;
|
||||
final double? fontSize;
|
||||
final bool? isAddress;
|
||||
final TextOverflow? overflow;
|
||||
final int? maxLines;
|
||||
|
||||
TextLink(this.title, this.url, {
|
||||
this.color,
|
||||
@@ -38,19 +38,19 @@ class TextLink extends StatelessWidget {
|
||||
this.paddingVertical,
|
||||
this.fontWeight,
|
||||
this.selected,
|
||||
bool isLink,
|
||||
bool replace,
|
||||
bool clearStack,
|
||||
bool maintainState,
|
||||
bool rootNavigator,
|
||||
bool? isLink,
|
||||
bool? replace,
|
||||
bool? clearStack,
|
||||
bool? maintainState,
|
||||
bool? rootNavigator,
|
||||
this.transition,
|
||||
bool closeDrawer,
|
||||
bool isEmail,
|
||||
bool isPhone,
|
||||
double fontSize,
|
||||
bool isAddress,
|
||||
TextOverflow overflow,
|
||||
int maxLines,
|
||||
bool? closeDrawer,
|
||||
bool? isEmail,
|
||||
bool? isPhone,
|
||||
double? fontSize,
|
||||
bool? isAddress,
|
||||
TextOverflow? overflow,
|
||||
int? maxLines,
|
||||
}) :
|
||||
isLink = isLink ?? false,
|
||||
replace = replace ?? false,
|
||||
@@ -101,7 +101,7 @@ class TextLink extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: (selected != null && selected) ? Border(
|
||||
border: (selected != null && selected!) ? Border(
|
||||
bottom: BorderSide(
|
||||
color: color ?? Colors.blue,
|
||||
width: 3.0,
|
||||
@@ -110,27 +110,27 @@ class TextLink extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
if (selected == null || !selected) {
|
||||
if (isEmail) {
|
||||
Utils.openEmail(url);
|
||||
} else if (isPhone) {
|
||||
Utils.callPhone(url);
|
||||
} else if (isAddress) {
|
||||
await launch('https://maps.google.com/?q=${url}');
|
||||
} else if (!isLink) {
|
||||
if (closeDrawer) {
|
||||
if (selected == null || !selected!) {
|
||||
if (isEmail!) {
|
||||
Utils.openEmail(url!);
|
||||
} else if (isPhone!) {
|
||||
Utils.callPhone(url!);
|
||||
} else if (isAddress!) {
|
||||
await launchUrl(Uri.parse('https://maps.google.com/?q=${url}'));
|
||||
} else if (!isLink!) {
|
||||
if (closeDrawer!) {
|
||||
Routes.router.pop(context);
|
||||
}
|
||||
Routes.router.navigateTo(
|
||||
context, url,
|
||||
replace: replace,
|
||||
clearStack: clearStack,
|
||||
maintainState: maintainState,
|
||||
rootNavigator: rootNavigator,
|
||||
context, url!,
|
||||
replace: replace!,
|
||||
clearStack: clearStack!,
|
||||
maintainState: maintainState!,
|
||||
rootNavigator: rootNavigator!,
|
||||
);
|
||||
} else {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
if (await canLaunchUrl(Uri.parse(url!))) {
|
||||
await launchUrl(Uri.parse(url!));
|
||||
} else {
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import '../../utils/utils.dart';
|
||||
class CreateOnlineStore1 extends StatefulWidget {
|
||||
final int businessId;
|
||||
|
||||
const CreateOnlineStore1(this.businessId, {Key key}) : super(key: key);
|
||||
const CreateOnlineStore1(this.businessId, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -30,12 +30,12 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
bool canSubmit = false;
|
||||
|
||||
List<dynamic> stores = [];
|
||||
Map<String, dynamic> service;
|
||||
Map<String, dynamic>? service;
|
||||
dynamic selectedStore;
|
||||
|
||||
Group group;
|
||||
Group? group;
|
||||
|
||||
String selectedDomain;
|
||||
String? selectedDomain;
|
||||
List<dynamic> domainResult = [];
|
||||
|
||||
@override
|
||||
@@ -136,7 +136,7 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
),
|
||||
),
|
||||
);
|
||||
Map<String, dynamic> existing_web_svc;
|
||||
Map<String, dynamic>? existing_web_svc;
|
||||
if (selectedStore != null && (selectedStore['services'] as List).length > 0) {
|
||||
for (Map<String, dynamic>svc in (selectedStore['services'] as List)) {
|
||||
if (svc['code'] == Constants.WEB_MINISTORE_SERVICE) {
|
||||
@@ -187,8 +187,8 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
BuyService(group.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: existing_web_svc['domain'],
|
||||
BuyService(group!.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: existing_web_svc!['domain'],
|
||||
sid: existing_web_svc['store']['id'],
|
||||
),
|
||||
));
|
||||
@@ -230,8 +230,8 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).domains_separated_comma;
|
||||
}
|
||||
return null;
|
||||
@@ -269,7 +269,7 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
service['description'],
|
||||
service!['description'],
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -277,7 +277,7 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
service['options'][0]['name'],
|
||||
service!['options'][0]['name'],
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -285,7 +285,7 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'\$${service['options'][0]['price']}',
|
||||
'\$${service!['options'][0]['price']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -304,7 +304,7 @@ class CreateOnlineStore1State extends State<CreateOnlineStore1> {
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) =>
|
||||
BuyService(group.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
BuyService(group!.id, Constants.WEB_MINISTORE_SERVICE,
|
||||
domain: selectedDomain,
|
||||
sid: selectedStore['id'],
|
||||
),
|
||||
|
||||
@@ -19,10 +19,9 @@ import '../../widgets/general/attribute/radio_options.dart';
|
||||
class MobileAttributeSelection extends StatefulWidget {
|
||||
final Product product;
|
||||
final Business business;
|
||||
final Key key;
|
||||
final GlobalKey startKey;
|
||||
final GlobalKey? startKey;
|
||||
|
||||
const MobileAttributeSelection({@required this.product, @required this.business, this.key, this.startKey})
|
||||
const MobileAttributeSelection({required this.product, required this.business, Key? key, this.startKey})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
@@ -33,18 +32,18 @@ class MobileAttributeSelection extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
Product product;
|
||||
int index;
|
||||
TextButton previousButton;
|
||||
TextButton nextButton;
|
||||
bool previousButtonEnable;
|
||||
bool nextButtonEnable;
|
||||
Product? product;
|
||||
int? index;
|
||||
TextButton? previousButton;
|
||||
TextButton? nextButton;
|
||||
bool previousButtonEnable = false;
|
||||
bool nextButtonEnable = false;
|
||||
|
||||
String productDesc;
|
||||
double productPrice;
|
||||
String? productDesc;
|
||||
double? productPrice;
|
||||
|
||||
String nextText;
|
||||
String finishText;
|
||||
String? nextText;
|
||||
String? finishText;
|
||||
|
||||
Map<String, dynamic> selections = new Map();
|
||||
|
||||
@@ -80,8 +79,8 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
child: new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
previousButton,
|
||||
nextButton
|
||||
previousButton!,
|
||||
nextButton!
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -96,8 +95,8 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
product = widget.product;
|
||||
previousButtonEnable = false;
|
||||
nextButtonEnable = false;
|
||||
productDesc = product.description;
|
||||
productPrice = product.price;
|
||||
productDesc = product!.description;
|
||||
productPrice = product!.price;
|
||||
});
|
||||
|
||||
eventBus.on<OnAttributeSelectionsChanged>().listen((event) {
|
||||
@@ -118,31 +117,31 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
extendDescription.add(key + ': ' + opt.join(', '));
|
||||
});
|
||||
|
||||
ProductAttribute pa = product.productAttributes[index];
|
||||
ProductAttribute pa = product!.productAttributes![index!];
|
||||
if (pa.required && Utils.selectionsNotEmptyAt(selections, pa.name)) {
|
||||
setState(() {
|
||||
nextButtonEnable = true;
|
||||
productDesc = product.description + ', ' + extendDescription.join('; ');
|
||||
productPrice = product.price + extendPrice;
|
||||
productDesc = (product!.description ?? '') + ', ' + extendDescription.join('; ');
|
||||
productPrice = product!.price! + extendPrice;
|
||||
});
|
||||
} else if (!pa.required){
|
||||
setState(() {
|
||||
nextButtonEnable = true;
|
||||
productDesc = product.description + ', ' + extendDescription.join('; ');
|
||||
productPrice = product.price + extendPrice;
|
||||
productDesc = (product!.description ?? '') + ', ' + extendDescription.join('; ');
|
||||
productPrice = product!.price! + extendPrice;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
nextButtonEnable = false;
|
||||
productDesc = product.description + ', ' + extendDescription.join('; ');
|
||||
productPrice = product.price + extendPrice;
|
||||
productDesc = (product!.description ?? '') + ', ' + extendDescription.join('; ');
|
||||
productPrice = product!.price! + extendPrice;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool _checkCanGoNext() {
|
||||
ProductAttribute pa = product.productAttributes[index];
|
||||
ProductAttribute pa = product!.productAttributes![index!];
|
||||
if (pa.required && Utils.selectionsNotEmptyAt(selections, pa.name)) {
|
||||
return true;
|
||||
} else if (!pa.required){
|
||||
@@ -167,7 +166,7 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
nextButton = TextButton(
|
||||
onPressed: nextButtonEnable ? _goNext : null,
|
||||
child: new Text(
|
||||
product.productAttributes.length > index + 1 ? nextText : finishText
|
||||
'${product!.productAttributes!.length > index! + 1 ? nextText : finishText}'
|
||||
),
|
||||
);
|
||||
|
||||
@@ -180,7 +179,7 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
padding: new EdgeInsets.all(10.0),
|
||||
width: 70.0,
|
||||
height: 70.0,
|
||||
child: Util.showImage(product.imagePath,
|
||||
child: Util.showImage(product!.imagePath ?? '',
|
||||
width: 70.0,
|
||||
height: 70.0,
|
||||
fit: BoxFit.fill,
|
||||
@@ -194,7 +193,7 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
new Container(
|
||||
padding: new EdgeInsets.all(10.0).copyWith(left: 0.0).copyWith(bottom: 0.0),
|
||||
child: new Text(
|
||||
product.name,
|
||||
product!.name ?? '',
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
@@ -205,7 +204,7 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
new Container(
|
||||
padding: new EdgeInsets.only(right: 10.0),
|
||||
child: new Text(
|
||||
productDesc,
|
||||
productDesc ?? '',
|
||||
style: new TextStyle(
|
||||
fontSize: 9.0,
|
||||
color: new Color(0xFFCDCDCD)
|
||||
@@ -223,7 +222,7 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
width: 70.0,
|
||||
child:
|
||||
new Text(
|
||||
productPrice.toStringAsFixed(2),
|
||||
productPrice!.toStringAsFixed(2),
|
||||
textAlign: TextAlign.right,
|
||||
style: new TextStyle(
|
||||
fontSize: 18.0,
|
||||
@@ -239,14 +238,14 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
Widget _getOptionsView() {
|
||||
Widget optionsView;
|
||||
|
||||
ProductAttribute productAttribute = product.productAttributes[index];
|
||||
ProductAttribute productAttribute = product!.productAttributes![index!];
|
||||
if (productAttribute.byQuantity) {
|
||||
optionsView = new QtyOptions(product: product, index: index, selections: selections);
|
||||
optionsView = new QtyOptions(product: product!, index: index!, selections: selections);
|
||||
} else {
|
||||
if (productAttribute.singleSelection) {
|
||||
optionsView = new RadioOptions(product: product, index: index, selections: selections);
|
||||
optionsView = new RadioOptions(product: product!, index: index!, selections: selections);
|
||||
} else {
|
||||
optionsView = new CheckOptions(product: product, index: index, selections: selections);
|
||||
optionsView = new CheckOptions(product: product!, index: index!, selections: selections);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,27 +253,27 @@ class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
||||
}
|
||||
|
||||
void _goNext() {
|
||||
if (index + 1 < product.productAttributes.length) {
|
||||
if (index! + 1 < product!.productAttributes!.length) {
|
||||
setState(() {
|
||||
index = index + 1;
|
||||
previousButtonEnable = index >= 1;
|
||||
index = index! + 1;
|
||||
previousButtonEnable = index! >= 1;
|
||||
nextButtonEnable = _checkCanGoNext();
|
||||
});
|
||||
} else if (product.productAttributes.length == index + 1) {
|
||||
eventBus.fire(new OnProductWillAddToCart(product, selections, productPrice, productDesc, widget.business, buttonKey: widget.startKey));
|
||||
} else if (product!.productAttributes!.length == index! + 1) {
|
||||
eventBus.fire(new OnProductWillAddToCart(product!, selections, productPrice!, productDesc ?? '', widget.business, buttonKey: widget.startKey));
|
||||
Navigator.pop(context);
|
||||
}
|
||||
eventBus.fire(new OnAttributePageChanged(index));
|
||||
eventBus.fire(new OnAttributePageChanged(index!));
|
||||
}
|
||||
|
||||
void _goPrevious() {
|
||||
if (index - 1 >= 0) {
|
||||
if (index! - 1 >= 0) {
|
||||
setState(() {
|
||||
index = index - 1;
|
||||
previousButtonEnable = index > 0;
|
||||
index = index! - 1;
|
||||
previousButtonEnable = index! > 0;
|
||||
nextButtonEnable = _checkCanGoNext();
|
||||
});
|
||||
eventBus.fire(new OnAttributePageChanged(index));
|
||||
eventBus.fire(new OnAttributePageChanged(index!));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import '../../widgets/mobile/MobileBottomNav.dart';
|
||||
|
||||
class MobileBlog extends StatefulWidget {
|
||||
final int businessId;
|
||||
const MobileBlog({Key key, this.businessId}) : super(key: key);
|
||||
const MobileBlog({Key? key, required this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -28,7 +28,7 @@ class MobileBlog extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileBlogState extends State<MobileBlog> {
|
||||
List<Blog> blogs;
|
||||
List<Blog>? blogs;
|
||||
|
||||
int _page = 1;
|
||||
int _pageCount = 1;
|
||||
@@ -41,7 +41,7 @@ class MobileBlogState extends State<MobileBlog> {
|
||||
void _onRefresh() {
|
||||
_page = 1;
|
||||
if (blogs != null) {
|
||||
blogs.clear();
|
||||
blogs?.clear();
|
||||
} else {
|
||||
blogs = [];
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class MobileBlogState extends State<MobileBlog> {
|
||||
enablePullUp: true,
|
||||
header: WaterDropHeader(),
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode){
|
||||
builder: (BuildContext context, LoadStatus? mode){
|
||||
Widget footer;
|
||||
if(mode == LoadStatus.idle) {
|
||||
footer = Text(S.of(context).pull_up_to_load_more);
|
||||
@@ -123,9 +123,9 @@ class MobileBlogState extends State<MobileBlog> {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: blogs.length <= 1 ? 1 : blogs.length,
|
||||
itemCount: blogs!.length <= 1 ? 1 : blogs!.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
if (blogs.length <= 0) {
|
||||
if (blogs!.length <= 0) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Center(
|
||||
@@ -133,7 +133,7 @@ class MobileBlogState extends State<MobileBlog> {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Blog blog = blogs[i];
|
||||
Blog blog = blogs![i];
|
||||
|
||||
Widget w = Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
|
||||
@@ -243,7 +243,7 @@ class MobileBlogState extends State<MobileBlog> {
|
||||
if (blogs == null) {
|
||||
blogs = [];
|
||||
}
|
||||
blogs.addAll((value['blogs'] as List).map((e) => Blog.fromJson(e)).toList());
|
||||
blogs!.addAll((value['blogs'] as List).map((e) => Blog.fromJson(e)).toList());
|
||||
});
|
||||
}
|
||||
}).catchError((error) {
|
||||
|
||||
@@ -9,9 +9,9 @@ import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class MobileBuyService extends StatefulWidget {
|
||||
final Map<String, dynamic> data;
|
||||
final Map<String, dynamic>? data;
|
||||
|
||||
const MobileBuyService(this.data, {Key key})
|
||||
const MobileBuyService(this.data, {Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
@@ -20,7 +20,7 @@ class MobileBuyService extends StatefulWidget {
|
||||
|
||||
class MobileBuyServiceState extends State<MobileBuyService> {
|
||||
List<KeyValue> plans = [];
|
||||
KeyValue selectedPlan;
|
||||
KeyValue? selectedPlan;
|
||||
double price = 0.0;
|
||||
double tax = 0.0;
|
||||
double paymentAmount = 0.0;
|
||||
@@ -45,37 +45,37 @@ class MobileBuyServiceState extends State<MobileBuyService> {
|
||||
);
|
||||
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).service_descritpion, widget.data['service_selections']['description'], valueSize: 16),
|
||||
Utils.buildLine(S.of(context).service_descritpion, widget.data!['service_selections']['description'], valueSize: 16),
|
||||
);
|
||||
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).your_group, widget.data['group']['name'], valueSize: 16),
|
||||
Utils.buildLine(S.of(context).your_group, widget.data!['group']['name'], valueSize: 16),
|
||||
);
|
||||
|
||||
if (widget.data['store']['id'] != null) {
|
||||
if (widget.data!['store']['id'] != null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).store, widget.data['store']['name'], valueSize: 16),
|
||||
Utils.buildLine(S.of(context).store, widget.data!['store']['name'], valueSize: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.data['domain'] != null) {
|
||||
if (widget.data!['domain'] != null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).domain_name, widget.data['domain'], valueSize: 16),
|
||||
Utils.buildLine(S.of(context).domain_name, widget.data!['domain'], valueSize: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.data['exists_service'] == null) {
|
||||
if (widget.data!['exists_service'] == null) {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).current_plan, 'N/A', valueSize: 16),
|
||||
);
|
||||
} else {
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).current_plan, widget.data['exists_service']['description'], valueSize: 16),
|
||||
Utils.buildLine(S.of(context).current_plan, widget.data!['exists_service']['description'], valueSize: 16),
|
||||
);
|
||||
col1.children.add(
|
||||
Utils.buildLine(S.of(context).expiration_date,
|
||||
Utils.utcDatetimeStringToLocalDatetimeString(context,
|
||||
widget.data['exists_service']['expiration_date']),
|
||||
widget.data!['exists_service']['expiration_date']),
|
||||
valueSize: 16
|
||||
),
|
||||
);
|
||||
@@ -97,8 +97,8 @@ class MobileBuyServiceState extends State<MobileBuyService> {
|
||||
print('newValue $newValue');
|
||||
setState(() {
|
||||
selectedPlan = newValue;
|
||||
price = selectedPlan.value['price'];
|
||||
tax = selectedPlan.value['price'] * selectedPlan.value['tax'];
|
||||
price = selectedPlan!.value['price'];
|
||||
tax = selectedPlan!.value['price'] * selectedPlan!.value['tax'];
|
||||
paymentAmount = price + tax;
|
||||
});
|
||||
},
|
||||
@@ -155,11 +155,11 @@ class MobileBuyServiceState extends State<MobileBuyService> {
|
||||
|
||||
void _submit() {
|
||||
if (store.state.user == null) {
|
||||
Utils.requireLogin(context, returnUrl: '/buy-service/${widget.data['group']['id']}/${widget.data['service_selections']['code']}');
|
||||
Utils.requireLogin(context, returnUrl: '/buy-service/${widget.data!['group']['id']}/${widget.data!['service_selections']['code']}');
|
||||
return;
|
||||
}
|
||||
Map<String, dynamic> newData = widget.data;
|
||||
newData['selected_plan'] = selectedPlan.value;
|
||||
Map<String, dynamic>? newData = widget.data;
|
||||
newData?['selected_plan'] = selectedPlan!.value;
|
||||
HttpUtil.httpPost('v1/create-service-buy-renewal-invoice',
|
||||
(response) {
|
||||
Routes.router.navigateTo(context, '/paynow/${response.data['order_id']}', replace: true);
|
||||
@@ -173,7 +173,7 @@ class MobileBuyServiceState extends State<MobileBuyService> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
List o = (widget.data['service_selections']['options'] as List);
|
||||
List o = (widget.data!['service_selections']['options'] as List);
|
||||
for (int i = 0; i < o.length; i++) {
|
||||
Map<String, dynamic> o1 = o[i];
|
||||
plans.add(new KeyValue(o1['name'], o1));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
import 'package:countdown/countdown.dart';
|
||||
import '../../vendor/countdown/countdown.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
@@ -15,7 +15,7 @@ import '../../utils/utils.dart';
|
||||
class MobileChangeMobileOrEmail extends StatefulWidget {
|
||||
final bool isMobile;
|
||||
|
||||
const MobileChangeMobileOrEmail(this.isMobile, {Key key}) : super(key: key);
|
||||
const MobileChangeMobileOrEmail(this.isMobile, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -31,9 +31,9 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
bool usernameEnable = true;
|
||||
final codeController = TextEditingController();
|
||||
|
||||
bool enableGetCode;
|
||||
String getCodeText;
|
||||
bool canRegister;
|
||||
bool enableGetCode = false;
|
||||
String? getCodeText;
|
||||
bool canRegister = false;
|
||||
|
||||
var countDownListener;
|
||||
|
||||
@@ -93,8 +93,8 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
if (widget.isMobile) {
|
||||
return S
|
||||
.of(context)
|
||||
@@ -105,10 +105,10 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
.email_is_required;
|
||||
}
|
||||
}
|
||||
if (widget.isMobile && value.trim() == store.state.user.mobile) {
|
||||
if (widget.isMobile && value.trim() == store.state.user?.mobile) {
|
||||
return S.of(context).the_mobile_number_is_same_as_current;
|
||||
}
|
||||
if (!widget.isMobile && value.trim() == store.state.user.email) {
|
||||
if (!widget.isMobile && value.trim() == store.state.user?.email) {
|
||||
return S.of(context).the_email_is_same_as_current;
|
||||
}
|
||||
return null;
|
||||
@@ -175,7 +175,7 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
child: Text(
|
||||
getCodeText,
|
||||
'$getCodeText',
|
||||
style: TextStyle(
|
||||
color: enableGetCode ? Colors.black87 : Colors.black26,
|
||||
fontSize: 14.0
|
||||
@@ -190,8 +190,8 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).verification_code_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -223,7 +223,7 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
alignment: Alignment.centerRight,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).submit_to_change,
|
||||
@@ -256,8 +256,8 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
}
|
||||
|
||||
void register() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
HttpUtil.httpPost('v1/users', (response) {
|
||||
Utils.showMessageDialog(context, Exception(S.of(context).update_success), title: S.of(context).success, onOk: () {
|
||||
Navigator.of(context).pop();
|
||||
@@ -269,7 +269,7 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
},
|
||||
isFormData: true,
|
||||
body: {
|
||||
'id': store.state.user.id,
|
||||
'id': store.state.user?.id,
|
||||
'mobile': usernameController.text.trim(),
|
||||
'code': codeController.text.trim(),
|
||||
},
|
||||
@@ -281,8 +281,8 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
|
||||
void getCodeTapped() {
|
||||
if (usernameController.text.isNotEmpty &&
|
||||
((widget.isMobile && usernameController.text.trim() != store.state.user.mobile) ||
|
||||
(!widget.isMobile && usernameController.text.trim() != store.state.user.email))) {
|
||||
((widget.isMobile && usernameController.text.trim() != store.state.user?.mobile) ||
|
||||
(!widget.isMobile && usernameController.text.trim() != store.state.user?.email))) {
|
||||
HttpUtil.httpPost('v1/users', (response) {
|
||||
Fluttertoast.showToast(
|
||||
msg: S.of(context).verification_code_sent,
|
||||
@@ -303,7 +303,7 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
'action': 'change_mobile_email_send_code'
|
||||
},
|
||||
body: {
|
||||
'id': store.state.user.id,
|
||||
'id': store.state.user?.id,
|
||||
'mobile': usernameController.text,
|
||||
},
|
||||
isFormData: true,
|
||||
@@ -321,9 +321,9 @@ class MobileChangeMobileOrEmailState extends State<MobileChangeMobileOrEmail> {
|
||||
errorMsg = S.of(context).mobile_is_required;
|
||||
} else if (!widget.isMobile && usernameController.text.trim().isEmpty) {
|
||||
errorMsg = S.of(context).email_is_required;
|
||||
} else if (widget.isMobile && usernameController.text.trim() == store.state.user.mobile) {
|
||||
} else if (widget.isMobile && usernameController.text.trim() == store.state.user?.mobile) {
|
||||
errorMsg = S.of(context).the_mobile_number_is_same_as_current;
|
||||
} else if (!widget.isMobile && usernameController.text.trim() == store.state.user.email) {
|
||||
} else if (!widget.isMobile && usernameController.text.trim() == store.state.user?.email) {
|
||||
errorMsg = S.of(context).the_email_is_same_as_current;
|
||||
}
|
||||
Fluttertoast.showToast(
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../utils/utils.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
|
||||
class MobileChangePassword extends StatefulWidget {
|
||||
const MobileChangePassword({Key key}) : super(key: key);
|
||||
const MobileChangePassword({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -22,10 +22,10 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
final passwordController = TextEditingController();
|
||||
final passwordAgainController = TextEditingController();
|
||||
|
||||
bool passwordVisible;
|
||||
bool passwordAgainVisible;
|
||||
bool passwordVisible = false;
|
||||
bool passwordAgainVisible = false;
|
||||
|
||||
bool canReset;
|
||||
bool canReset = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -87,8 +87,8 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).current_password_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -141,8 +141,8 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).password_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -195,8 +195,8 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).password_is_required;
|
||||
}
|
||||
if (value.trim() != passwordController.text.trim()) {
|
||||
@@ -232,7 +232,7 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
alignment: Alignment.centerRight,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).submit,
|
||||
@@ -249,8 +249,8 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
}
|
||||
|
||||
void resetPassword() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
HttpUtil.httpPost('v1/users', (response) {
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -276,7 +276,7 @@ class MobileChangePasswordState extends State<MobileChangePassword> {
|
||||
},
|
||||
isFormData: true,
|
||||
body: {
|
||||
'id': store.state.user.id,
|
||||
'id': store.state.user?.id,
|
||||
'old_password': oldPasswordController.text.trim(),
|
||||
'password': passwordController.text.trim(),
|
||||
}
|
||||
|
||||
@@ -32,10 +32,9 @@ import '../../utils/utils.dart';
|
||||
import '../../widgets/general/sliding_up_panel.dart';
|
||||
|
||||
class MobileCheckout extends StatefulWidget {
|
||||
final Key key;
|
||||
final int businessId;
|
||||
|
||||
const MobileCheckout(this.businessId, {this.key,}) : super(key: key);
|
||||
const MobileCheckout(this.businessId, {Key? key,}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -45,17 +44,17 @@ class MobileCheckout extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
||||
CartInfo cartInfo;
|
||||
Address shipAddress;
|
||||
bool canSubmit;
|
||||
List<ErrorMessage> errorMessages;
|
||||
List<BookingTime> bookingTimeList;
|
||||
List<BookingDateTime> bookingDateTimeList;
|
||||
List<PaymentPlatform> paymentPlatforms;
|
||||
TextValue durationInTraffic;
|
||||
int selectedCoupon;
|
||||
CartInfo? cartInfo;
|
||||
Address? shipAddress;
|
||||
bool canSubmit = false;
|
||||
List<ErrorMessage>? errorMessages;
|
||||
List<BookingTime>? bookingTimeList;
|
||||
List<BookingDateTime>? bookingDateTimeList;
|
||||
List<PaymentPlatform>? paymentPlatforms;
|
||||
TextValue? durationInTraffic;
|
||||
int? selectedCoupon;
|
||||
double couponDiscountAmount = 0;
|
||||
List<Coupon> coupons;
|
||||
List<Coupon>? coupons;
|
||||
|
||||
int peopleCount = 2;
|
||||
|
||||
@@ -63,25 +62,25 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
String orderRemark = '';
|
||||
|
||||
int deliveryMethodIndex = 0;
|
||||
String deliveryMethod;
|
||||
String? deliveryMethod;
|
||||
List<ShippingRate> shippingRates = [];
|
||||
ShippingRate selectedShippingRate;
|
||||
ShippingRate? selectedShippingRate;
|
||||
|
||||
List<String> shippingMethodLabels = [];
|
||||
List<IconData> shippingMethodIcons = [];
|
||||
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
int bookingDateIndex;
|
||||
int bookingTimeIndex;
|
||||
int paymentPlatformIndex;
|
||||
int? bookingDateIndex;
|
||||
int? bookingTimeIndex;
|
||||
int? paymentPlatformIndex;
|
||||
|
||||
GlobalKey slidingUpPanelKey = GlobalKey();
|
||||
SlidingUpPanel slidingUpPanel;
|
||||
SlidingUpPanel? slidingUpPanel;
|
||||
PanelController panelController = PanelController();
|
||||
Widget panel;
|
||||
Widget? panel;
|
||||
|
||||
double subtotal;
|
||||
double? subtotal;
|
||||
|
||||
TextEditingController newCouponController = TextEditingController();
|
||||
|
||||
@@ -102,7 +101,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
);
|
||||
}
|
||||
|
||||
if (cartInfo.businessInfo.deliveryPickup == false && cartInfo.businessInfo.deliveryCanadaPost == false && cartInfo.businessInfo.deliveryStoreDelivery == false) {
|
||||
if (cartInfo!.businessInfo?.deliveryPickup == false && cartInfo!.businessInfo?.deliveryCanadaPost == false && cartInfo!.businessInfo?.deliveryStoreDelivery == false) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
child: Center(
|
||||
@@ -114,7 +113,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).ok,
|
||||
@@ -134,10 +133,10 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
}
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
if(errorMessages.length > 0) {
|
||||
if(errorMessages != null && errorMessages!.length > 0) {
|
||||
print('error: ${errorMessages.toString()}');
|
||||
// _scaffoldKey.currentState.showSnackBar(errorSnackBar(errorMessages));
|
||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages));
|
||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages!));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -169,7 +168,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
centerTitle: true,
|
||||
),
|
||||
body: WillPopScope(
|
||||
child: slidingUpPanel,
|
||||
child: slidingUpPanel!,
|
||||
onWillPop: () async {
|
||||
if (panelController != null && panelController.isPanelOpen) {
|
||||
panelController.close();
|
||||
@@ -197,13 +196,13 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'\$${(cartInfo.totalPrice - couponDiscountAmount).toStringAsFixed(2)}',
|
||||
'\$${(cartInfo!.totalPrice! - couponDiscountAmount).toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
cartInfo.businessInfo.isPublic ? SizedBox.shrink() : Container(
|
||||
cartInfo!.businessInfo!.isPublic ? SizedBox.shrink() : Container(
|
||||
padding: EdgeInsets.only(top: 2.0, bottom: 2.0, left: 5.0, right: 5.0),
|
||||
width: 100.0,
|
||||
color: Colors.red,
|
||||
@@ -267,7 +266,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
itemCount: 6,
|
||||
addAutomaticKeepAlives: true,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
var deliveryTimeInSeconds = cartInfo.businessInfo.shippingTime * 60 + (durationInTraffic != null ? durationInTraffic.value : 0);
|
||||
var deliveryTimeInSeconds = cartInfo!.businessInfo!.shippingTime * 60 + (durationInTraffic != null ? durationInTraffic!.value : 0);
|
||||
print('aaa: $deliveryTimeInSeconds');
|
||||
DateTime now = DateTime.now();
|
||||
var formatter = DateFormat('H:mm');
|
||||
@@ -281,7 +280,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).table_token(store.state.tableNumber),
|
||||
S.of(context).table_token(store.state.tableNumber!),
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -308,7 +307,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
onChanged: (newValue) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
peopleCount = newValue;
|
||||
peopleCount = newValue!;
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -333,7 +332,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
icons: shippingMethodIcons,
|
||||
onToggle: (index) {
|
||||
selectedShippingRate = null;
|
||||
deliveryMethod = getShippingMethod(index);
|
||||
deliveryMethod = getShippingMethod(index!);
|
||||
check();
|
||||
},
|
||||
initialLabelIndex: deliveryMethodIndex,
|
||||
@@ -341,7 +340,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
);
|
||||
switch (position) {
|
||||
case 0:
|
||||
if (cartInfo.businessInfo.deliveryPickup) {
|
||||
if (cartInfo!.businessInfo!.deliveryPickup) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 16.0, bottom: 16.0, left: 16.0, right: 16.0),
|
||||
@@ -355,8 +354,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: store.state.deviceId != null && store.state.deviceId.isNotEmpty ? (
|
||||
store.state.tableNumber != null && store.state.tableNumber.isNotEmpty ?
|
||||
child: store.state.deviceId != null && store.state.deviceId!.isNotEmpty ? (
|
||||
store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty ?
|
||||
peopleCountSelection :
|
||||
SizedBox.shrink()
|
||||
) : Center(child: toggleSwitch,),
|
||||
@@ -369,8 +368,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (store.state.deviceId != null && store.state.deviceId.isNotEmpty ||
|
||||
store.state.tableNumber != null && store.state.tableNumber.isNotEmpty) {
|
||||
if (store.state.deviceId != null && store.state.deviceId!.isNotEmpty ||
|
||||
store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
if (deliveryMethod == 'pickup') {
|
||||
@@ -389,7 +388,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 10.0),
|
||||
child: Text(
|
||||
cartInfo.businessInfo.name,
|
||||
cartInfo!.businessInfo!.name,
|
||||
style: TextStyle(
|
||||
fontSize: 17.0,
|
||||
),
|
||||
@@ -398,7 +397,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 5.0),
|
||||
child: Text(
|
||||
cartInfo.businessInfo.address.addressLine1,
|
||||
'${cartInfo!.businessInfo?.address.addressLine1}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: Colors.black45,
|
||||
@@ -406,9 +405,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: cartInfo.businessInfo.address.addressLine2 != null
|
||||
&& cartInfo.businessInfo.address.addressLine2.length > 0 ?
|
||||
Text(cartInfo.businessInfo.address.addressLine2,
|
||||
child: cartInfo!.businessInfo?.address.addressLine2 != null
|
||||
&& cartInfo!.businessInfo!.address.addressLine2!.length > 0 ?
|
||||
Text('${cartInfo!.businessInfo!.address.addressLine2}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: Colors.black45,
|
||||
@@ -417,7 +416,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
'${cartInfo.businessInfo.address.city}, ${cartInfo.businessInfo.address.state}, ${cartInfo.businessInfo.address.zip}',
|
||||
'${cartInfo!.businessInfo?.address.city}, ${cartInfo!.businessInfo?.address.state}, ${cartInfo!.businessInfo?.address.zip}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: Colors.black45,
|
||||
@@ -427,7 +426,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 5.0),
|
||||
child: Text(
|
||||
'Tel: ${cartInfo.businessInfo.phone}',
|
||||
'Tel: ${cartInfo!.businessInfo?.phone}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.black54,
|
||||
@@ -469,7 +468,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
shipAddress != null ? shipAddress.fullAddress : S.of(context).enter_delivery_address,
|
||||
shipAddress != null ? shipAddress!.fullAddress! : S.of(context).enter_delivery_address,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0
|
||||
),
|
||||
@@ -480,7 +479,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 6.0),
|
||||
child: Text(
|
||||
shipAddress != null ? shipAddress.contactName + ' ' + shipAddress.phone : '',
|
||||
shipAddress != null ? shipAddress!.contactName! + ' ' + shipAddress!.phone! : '',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: Colors.black38,
|
||||
@@ -504,13 +503,13 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Routes.router.navigateTo(context, '/my-addresses/${cartInfo.businessInfo.id}', replace: true);
|
||||
Routes.router.navigateTo(context, '/my-addresses/${cartInfo!.businessInfo?.id}', replace: true);
|
||||
},
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
if (deliveryMethod == 'pickup' || store.state.deviceId != null && store.state.deviceId.isNotEmpty ||
|
||||
store.state.tableNumber != null && store.state.tableNumber.isNotEmpty) {
|
||||
if (deliveryMethod == 'pickup' || store.state.deviceId != null && store.state.deviceId!.isNotEmpty ||
|
||||
store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
if (deliveryMethod == 'canada-post') {
|
||||
@@ -553,7 +552,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
selectedShippingRate != null ?
|
||||
'${selectedShippingRate.name} \$${selectedShippingRate.price.toStringAsFixed(2)}' :
|
||||
'${selectedShippingRate?.name} \$${selectedShippingRate?.price.toStringAsFixed(2)}' :
|
||||
S.of(context).please_select,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
@@ -583,7 +582,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
},
|
||||
);
|
||||
}
|
||||
if (!cartInfo.businessInfo.instanceDelivery) {
|
||||
if (!cartInfo!.businessInfo!.instanceDelivery) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 0.0, bottom: 16.0),
|
||||
child: Text(S.of(context).no_instance_delivery_desc),
|
||||
@@ -613,7 +612,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
bookingTimeList.length > 0 || bookingDateTimeList.length > 0 ? S.of(context).delivery_now : S.of(context).delivery_unavailable,
|
||||
bookingTimeList!.length > 0 || bookingDateTimeList!.length > 0 ? S.of(context).delivery_now : S.of(context).delivery_unavailable,
|
||||
style: TextStyle(
|
||||
fontSize: 17.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -627,9 +626,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
bookingTimeList.length > 0 ? '${Utils.timestampToString(context, bookingTimeList[bookingTimeIndex].unixTime)}'
|
||||
: ((bookingTimeList.length == 0 && bookingDateTimeList.length == 0) ? ''
|
||||
: bookingDateTimeList[bookingDateIndex].viewDate + ' ' + (bookingDateTimeList[bookingDateIndex].bookTimes.length > 0 ? bookingDateTimeList[bookingDateIndex].bookTimes[bookingTimeIndex].viewTime : '')),
|
||||
bookingTimeList!.length > 0 ? '${Utils.timestampToString(context, bookingTimeList![bookingTimeIndex!].unixTime)}'
|
||||
: ((bookingTimeList!.length == 0 && bookingDateTimeList!.length == 0) ? ''
|
||||
: bookingDateTimeList![bookingDateIndex!].viewDate + ' ' + (bookingDateTimeList![bookingDateIndex!].bookTimes.length > 0 ? bookingDateTimeList![bookingDateIndex!].bookTimes[bookingTimeIndex!].viewTime : '')),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
@@ -681,7 +680,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
paymentPlatforms.length == 0 ? S.of(context).pay_on_deliery : PaymentPlatform.getPaymentPlatformName(context, paymentPlatforms[paymentPlatformIndex].code),
|
||||
paymentPlatforms!.length == 0 ? S.of(context).pay_on_deliery : PaymentPlatform.getPaymentPlatformName(context, paymentPlatforms![paymentPlatformIndex!].code!),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
@@ -712,7 +711,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(bottom: 10.0),
|
||||
child: Text(
|
||||
cartInfo.businessInfo.name,
|
||||
'${cartInfo!.businessInfo?.name}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
@@ -731,9 +730,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
|
||||
subtotal = 0.0;
|
||||
|
||||
for (var i = 0; i < cartInfo.productList.length; i++) {
|
||||
subtotal += cartInfo.productList[i].totalPrice;
|
||||
column.children.add(lineItem(cartInfo.productList[i]));
|
||||
for (var i = 0; i < cartInfo!.productList!.length; i++) {
|
||||
subtotal = subtotal! + cartInfo!.productList![i].totalPrice!;
|
||||
column.children.add(lineItem(cartInfo!.productList![i]));
|
||||
}
|
||||
column.children.add(GestureDetector(
|
||||
child: Container(
|
||||
@@ -815,7 +814,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
width: 100.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${(subtotal - couponDiscountAmount).toStringAsFixed(2)}',
|
||||
'${(subtotal! - couponDiscountAmount).toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -826,8 +825,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
));
|
||||
|
||||
if (cartInfo.extraFeeList.length > 0) {
|
||||
for (var i = 0; i < cartInfo.extraFeeList.length; i++) {
|
||||
if (cartInfo!.extraFeeList!.length > 0) {
|
||||
for (var i = 0; i < cartInfo!.extraFeeList!.length; i++) {
|
||||
column.children.add(Container(
|
||||
padding: EdgeInsets.only(bottom: 16.0),
|
||||
alignment: Alignment.centerRight,
|
||||
@@ -838,7 +837,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
S.of(context).extra_fee_token(cartInfo.extraFeeList[i].name, cartInfo.extraFeeList[i].rate),
|
||||
S.of(context).extra_fee_token(cartInfo!.extraFeeList![i].name, cartInfo!.extraFeeList![i].rate),
|
||||
style: TextStyle(
|
||||
color: Colors.grey,
|
||||
),
|
||||
@@ -848,7 +847,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
width: 100.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${cartInfo.extraFeeList[i].price.toStringAsFixed(2)}'
|
||||
'${cartInfo!.extraFeeList![i].price.toStringAsFixed(2)}'
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -876,7 +875,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
width: 100.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${(cartInfo.totalPrice - couponDiscountAmount).toStringAsFixed(2)}',
|
||||
'${(cartInfo!.totalPrice! - couponDiscountAmount).toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 19.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -974,7 +973,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.all(5.0),
|
||||
child: Util.showImage('${cartLineItem.product.imagePath}',
|
||||
child: Util.showImage('${cartLineItem.product?.imagePath}',
|
||||
width: 40.0,
|
||||
height: 40.0,
|
||||
fit: BoxFit.fill,
|
||||
@@ -988,14 +987,14 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
Utils.knownName(context, cartLineItem.name),
|
||||
Utils.knownName(context, cartLineItem.name!),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
cartLineItem.description,
|
||||
'${cartLineItem.description}',
|
||||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: Colors.black38,
|
||||
@@ -1011,14 +1010,14 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
alignment: Alignment.centerRight,
|
||||
margin: EdgeInsets.only(right: 10.0),
|
||||
child: Text(
|
||||
'x${cartLineItem.quantity.round()}',
|
||||
'x${cartLineItem.quantity!.round()}',
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 60.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${cartLineItem.totalPrice.toStringAsFixed(2)}',
|
||||
'${cartLineItem.totalPrice!.toStringAsFixed(2)}',
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1050,7 +1049,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
if (cartInfo != null) {
|
||||
Utils.showLoadingDialog(context);
|
||||
}
|
||||
CartInfo ci = Utils.getCartInfoByBusinessId(store.state.cartInfos, widget.businessId);
|
||||
CartInfo? ci = Utils.getCartInfoByBusinessId(store.state.cartInfos, widget.businessId);
|
||||
HttpUtil.httpPost('v1/orders/check', (response) {
|
||||
if (cartInfo != null) {
|
||||
Navigator.of(context).pop();
|
||||
@@ -1074,7 +1073,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
shippingRates = (response.data['shipping_rates'] as List).map((e) => ShippingRate.fromJson(e)).toList();
|
||||
selectedShippingRate = (response.data['selected_shipping_rate'] as String).length > 0 ? ShippingRate.fromJson(json.decode(response.data['selected_shipping_rate'])) : null;
|
||||
int i = 0;
|
||||
if (cartInfo.businessInfo.deliveryStoreDelivery) {
|
||||
if (cartInfo!.businessInfo!.deliveryStoreDelivery) {
|
||||
shippingMethodLabels.add(S.of(context).delivery);
|
||||
shippingMethodIcons.add(Icons.directions_car);
|
||||
if (deliveryMethod == 'store-delivery') {
|
||||
@@ -1082,7 +1081,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (cartInfo.businessInfo.deliveryCanadaPost) {
|
||||
if (cartInfo!.businessInfo!.deliveryCanadaPost) {
|
||||
shippingMethodLabels.add(S.of(context).canada_post);
|
||||
shippingMethodIcons.add(Icons.local_shipping);
|
||||
if (deliveryMethod == 'canada-post') {
|
||||
@@ -1090,7 +1089,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (cartInfo.businessInfo.deliveryPickup) {
|
||||
if (cartInfo!.businessInfo!.deliveryPickup) {
|
||||
shippingMethodLabels.add(S.of(context).pickup);
|
||||
shippingMethodIcons.add(Icons.store);
|
||||
if (deliveryMethod == 'pickup') {
|
||||
@@ -1103,8 +1102,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
},
|
||||
businessId: widget.businessId,
|
||||
body: {
|
||||
'product_list': ci.productList.toString(),
|
||||
'extra_data': ci.extraData,
|
||||
'product_list': ci?.productList.toString(),
|
||||
'extra_data': ci?.extraData,
|
||||
'business_id': widget.businessId,
|
||||
'pay_method': getPaymentMethod(),
|
||||
'delivery': deliveryMethod,
|
||||
@@ -1128,8 +1127,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
|
||||
int getPaymentMethod() {
|
||||
int method = 0;
|
||||
if (paymentPlatforms.length > 0 && paymentPlatformIndex < paymentPlatforms.length) {
|
||||
PaymentPlatform paymentPlatform = paymentPlatforms[paymentPlatformIndex];
|
||||
if (paymentPlatforms!.length > 0 && paymentPlatformIndex! < paymentPlatforms!.length) {
|
||||
PaymentPlatform paymentPlatform = paymentPlatforms![paymentPlatformIndex!];
|
||||
if (paymentPlatform.method == Constants.PAYMENT_METHOD_PAY_ON_DELIVERY) {
|
||||
return 1;
|
||||
}
|
||||
@@ -1138,10 +1137,10 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
}
|
||||
|
||||
void afterBuild(Duration time) {
|
||||
if(errorMessages.length > 0) {
|
||||
if(errorMessages != null && errorMessages!.length > 0) {
|
||||
print('error: ${errorMessages.toString()}');
|
||||
// _scaffoldKey.currentState.showSnackBar(errorSnackBar(errorMessages));
|
||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages));
|
||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages!));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1176,7 +1175,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
|
||||
Widget getBookingTimeWidget() {
|
||||
Widget widget;
|
||||
if (bookingTimeList.length > 0) {
|
||||
if (bookingTimeList!.length > 0) {
|
||||
widget = Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -1208,9 +1207,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: bookingTimeList.length,
|
||||
itemCount: bookingTimeList!.length,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
BookingTime bookingTime = bookingTimeList[position];
|
||||
BookingTime bookingTime = bookingTimeList![position];
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 10.0, top: 10.0),
|
||||
@@ -1241,7 +1240,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
)
|
||||
],
|
||||
);
|
||||
} else if (bookingDateTimeList.length > 0) {
|
||||
} else if (bookingDateTimeList!.length > 0) {
|
||||
widget = Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -1281,9 +1280,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
color: new Color(0xFFF5F5F5),
|
||||
child: SizedBox.expand(
|
||||
child: ListView.builder(
|
||||
itemCount: bookingDateTimeList.length,
|
||||
itemCount: bookingDateTimeList!.length,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
BookingDateTime bookingDateTime = bookingDateTimeList[position];
|
||||
BookingDateTime bookingDateTime = bookingDateTimeList![position];
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
color: bookingDateIndex == position ? Colors.white : Colors.transparent,
|
||||
@@ -1310,9 +1309,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Expanded(
|
||||
child: SizedBox.expand(
|
||||
child: ListView.builder(
|
||||
itemCount: bookingDateTimeList[bookingDateIndex].bookTimes.length,
|
||||
itemCount: bookingDateTimeList![bookingDateIndex!].bookTimes.length,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
BookingDateTime bookingDateTime = bookingDateTimeList[bookingDateIndex];
|
||||
BookingDateTime bookingDateTime = bookingDateTimeList![bookingDateIndex!];
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 12.0, right: 12.0, top: 12.0, bottom: 12.0),
|
||||
@@ -1425,7 +1424,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
],
|
||||
);
|
||||
|
||||
if (paymentPlatforms.length == 0) {
|
||||
if (paymentPlatforms!.length == 0) {
|
||||
widget.children.add(Center(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
@@ -1438,20 +1437,20 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
widget.children.add(
|
||||
Expanded(
|
||||
child:ListView.builder(
|
||||
itemCount: paymentPlatforms.length,
|
||||
itemCount: paymentPlatforms!.length,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
PaymentPlatform paymentPlatform = paymentPlatforms[position];
|
||||
PaymentPlatform paymentPlatform = paymentPlatforms![position];
|
||||
if (paymentPlatform.code == Constants.PAYMENT_METHOD_CODE_SQUARE &&
|
||||
(paymentPlatform.squareAppId == null || paymentPlatform.squareAppId.isEmpty) &&
|
||||
(paymentPlatform.squareAccessToken == null || paymentPlatform.squareAccessToken.isEmpty) &&
|
||||
(paymentPlatform.squareLocationId == null || paymentPlatform.squareLocationId.isEmpty)
|
||||
(paymentPlatform.squareAppId == null || paymentPlatform.squareAppId!.isEmpty) &&
|
||||
(paymentPlatform.squareAccessToken == null || paymentPlatform.squareAccessToken!.isEmpty) &&
|
||||
(paymentPlatform.squareLocationId == null || paymentPlatform.squareLocationId!.isEmpty)
|
||||
) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
if (paymentPlatform.code == Constants.PAYMENT_METHOD_CODE_CHASE &&
|
||||
(paymentPlatform.xLogin == null || paymentPlatform.xLogin.isEmpty) &&
|
||||
(paymentPlatform.transactionKey == null || paymentPlatform.transactionKey.isEmpty) &&
|
||||
(paymentPlatform.responseKey == null || paymentPlatform.responseKey.isEmpty)
|
||||
(paymentPlatform.xLogin == null || paymentPlatform.xLogin!.isEmpty) &&
|
||||
(paymentPlatform.transactionKey == null || paymentPlatform.transactionKey!.isEmpty) &&
|
||||
(paymentPlatform.responseKey == null || paymentPlatform.responseKey!.isEmpty)
|
||||
) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
@@ -1494,7 +1493,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Util.showImage(paymentPlatform.icon,
|
||||
child: Util.showImage(paymentPlatform.icon ?? '',
|
||||
errorWidget: (context, url, error) => Icon(Icons.broken_image, size: 50.0, color: Colors.transparent,),
|
||||
fit: BoxFit.cover,
|
||||
width: 50.0,
|
||||
@@ -1504,7 +1503,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 10.0),
|
||||
child: Text(
|
||||
PaymentPlatform.getPaymentPlatformName(context, paymentPlatform.code),
|
||||
PaymentPlatform.getPaymentPlatformName(context, paymentPlatform.code ?? ''),
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -1541,7 +1540,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
|
||||
String getSelectedCouponName() {
|
||||
if (selectedCoupon == null) {
|
||||
if (coupons.length > 0) {
|
||||
if (coupons!.length > 0) {
|
||||
return S
|
||||
.of(context)
|
||||
.please_select;
|
||||
@@ -1553,10 +1552,10 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
} else if (selectedCoupon == 0) {
|
||||
return S.of(context).dont_use;
|
||||
} else {
|
||||
for (var i = 0; i < coupons.length; i++) {
|
||||
if (selectedCoupon == coupons[i].id) {
|
||||
if (coupons[i].isPercentage) {
|
||||
return S.of(context).percentage_discount_token2(couponDiscountAmount.toStringAsFixed(2), coupons[i].valueAmount);
|
||||
for (var i = 0; i < coupons!.length; i++) {
|
||||
if (selectedCoupon == coupons![i].id) {
|
||||
if (coupons![i].isPercentage) {
|
||||
return S.of(context).percentage_discount_token2(couponDiscountAmount.toStringAsFixed(2), coupons![i].valueAmount);
|
||||
} else {
|
||||
return S.of(context).discount_amount_token(couponDiscountAmount.toStringAsFixed(2));
|
||||
}
|
||||
@@ -1632,7 +1631,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
labelText: S.of(context).enter_coupon_code,
|
||||
),
|
||||
validator: (String value) {
|
||||
validator: (String? value) {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
@@ -1663,7 +1662,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
);
|
||||
|
||||
if (paymentPlatforms.length == 0) {
|
||||
if (paymentPlatforms!.length == 0) {
|
||||
widget.children.add(Center(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
@@ -1675,13 +1674,13 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
} else {
|
||||
widget.children.add(Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: coupons.length + 1,
|
||||
itemCount: coupons!.length + 1,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
if (position == 0) {
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
decoration: selectedCoupon == 0 ? BoxDecoration(
|
||||
color: subtotal > cartInfo.businessInfo.minPrice ? Colors
|
||||
color: subtotal! > cartInfo!.businessInfo!.minPrice ? Colors
|
||||
.transparent : Colors.black38,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
@@ -1702,7 +1701,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
),
|
||||
) : BoxDecoration(
|
||||
color: subtotal > cartInfo.businessInfo.minPrice ? Colors
|
||||
color: subtotal! > cartInfo!.businessInfo!.minPrice ? Colors
|
||||
.transparent : Colors.black38,
|
||||
),
|
||||
child: Row(
|
||||
@@ -1739,11 +1738,11 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
},
|
||||
);
|
||||
} else {
|
||||
Coupon coupon = coupons[position - 1];
|
||||
Coupon coupon = coupons![position - 1];
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
decoration: selectedCoupon == coupon.id ? BoxDecoration(
|
||||
color: subtotal > cartInfo.businessInfo.minPrice ? Colors
|
||||
color: subtotal! > cartInfo!.businessInfo!.minPrice ? Colors
|
||||
.transparent : Colors.black38,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
@@ -1764,7 +1763,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
),
|
||||
) : BoxDecoration(
|
||||
color: subtotal > coupon.minAmount ? Colors
|
||||
color: subtotal! > coupon.minAmount ? Colors
|
||||
.transparent : Colors.black26,
|
||||
),
|
||||
child: Row(
|
||||
@@ -1885,12 +1884,12 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (subtotal > coupon.minAmount &&
|
||||
if (subtotal! > coupon.minAmount &&
|
||||
mounted) {
|
||||
setState(() {
|
||||
selectedCoupon = coupon.id;
|
||||
if (coupon.isPercentage) {
|
||||
couponDiscountAmount = subtotal * coupon.valueAmount / 100.0;
|
||||
couponDiscountAmount = subtotal! * coupon.valueAmount / 100.0;
|
||||
} else {
|
||||
couponDiscountAmount = coupon.valueAmount;
|
||||
}
|
||||
@@ -1917,7 +1916,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [],
|
||||
);
|
||||
if (cartInfo.businessInfo.quickInputs.length > 0) {
|
||||
if (cartInfo!.businessInfo!.quickInputs.length > 0) {
|
||||
Wrap w = Wrap(
|
||||
children: [],
|
||||
);
|
||||
@@ -1931,8 +1930,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
),
|
||||
),
|
||||
));
|
||||
for (int i = 0; i < cartInfo.businessInfo.quickInputs.length; i++) {
|
||||
String qi = cartInfo.businessInfo.quickInputs[i].value;
|
||||
for (int i = 0; i < cartInfo!.businessInfo!.quickInputs.length; i++) {
|
||||
String qi = cartInfo!.businessInfo!.quickInputs[i].value;
|
||||
w.children.add(TextButton(
|
||||
child: Text(
|
||||
qi,
|
||||
@@ -2183,7 +2182,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
confirmOrder() {
|
||||
if (!canSubmit) {
|
||||
// _scaffoldKey.currentState.showSnackBar(errorSnackBar(errorMessages));
|
||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages));
|
||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages!));
|
||||
} else {
|
||||
Utils.showSubmitDialog(context);
|
||||
HttpUtil.httpPost('v1/orders', (response) {
|
||||
@@ -2191,19 +2190,19 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
|
||||
store.dispatch(UpdateCartInfo(Utils.removeCartInfoFromCartInfoList(store.state.cartInfos, cartInfo)));
|
||||
eventBus.fire(OnCartInfoUpdated());
|
||||
Order order = Order.fromJson(response.data);
|
||||
PaymentPlatform paymentPlatform = paymentPlatforms[paymentPlatformIndex];
|
||||
PaymentPlatform paymentPlatform = paymentPlatforms![paymentPlatformIndex!];
|
||||
Routes.router.navigateTo(context, '/paynow/${order.id}', replace: true);
|
||||
},
|
||||
businessId: widget.businessId,
|
||||
body: {
|
||||
'cart_id': cartInfo.id,
|
||||
'cart_id': cartInfo?.id,
|
||||
'remark': orderRemark,
|
||||
'booked_at': bookingTimeList.length > 0
|
||||
? bookingTimeList[bookingTimeIndex].unixTime
|
||||
'booked_at': bookingTimeList!.length > 0
|
||||
? bookingTimeList![bookingTimeIndex!].unixTime
|
||||
: (
|
||||
(bookingTimeList.length == 0 && bookingDateTimeList.length == 0) ?
|
||||
(bookingTimeList!.length == 0 && bookingDateTimeList!.length == 0) ?
|
||||
0 :
|
||||
bookingDateTimeList[bookingDateIndex].bookTimes[bookingTimeIndex]
|
||||
bookingDateTimeList![bookingDateIndex!].bookTimes[bookingTimeIndex!]
|
||||
.unixTime
|
||||
),
|
||||
'delivery': deliveryMethod,
|
||||
|
||||
@@ -15,7 +15,7 @@ import '../../widgets/general/text_link.dart';
|
||||
class MobileContactUs extends StatefulWidget {
|
||||
final Business business;
|
||||
|
||||
const MobileContactUs(this.business, {Key key}) : super(key: key);
|
||||
const MobileContactUs(this.business, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -29,7 +29,7 @@ class MobileContactUsState extends State<MobileContactUs> {
|
||||
String mapUrl = 'https://goo.gl/maps/M365MF5AW35n9ij67';
|
||||
|
||||
Completer<GoogleMapController> _controller = Completer();
|
||||
LatLng _lastMapPosition;
|
||||
LatLng? _lastMapPosition;
|
||||
final Set<Marker> _markers = {};
|
||||
final Set<Polyline> _polyLine = {};
|
||||
|
||||
@@ -243,7 +243,7 @@ class MobileContactUsState extends State<MobileContactUs> {
|
||||
),
|
||||
)
|
||||
);
|
||||
if (widget.business.address.addressLine2 != null && widget.business.address.addressLine2.isNotEmpty) {
|
||||
if (widget.business.address.addressLine2 != null && widget.business.address.addressLine2!.isNotEmpty) {
|
||||
col.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 16, right: 16, top: 4, bottom: 4),
|
||||
@@ -273,8 +273,8 @@ class MobileContactUsState extends State<MobileContactUs> {
|
||||
_markers.clear();
|
||||
_markers.add(Marker(
|
||||
markerId: MarkerId('shop_position'),
|
||||
position: LatLng(double.parse(widget.business.address.lat),
|
||||
double.parse(widget.business.address.lng)),
|
||||
position: LatLng(double.parse(widget.business.address.lat ?? ''),
|
||||
double.parse(widget.business.address.lng ?? '')),
|
||||
infoWindow: InfoWindow(
|
||||
title: S
|
||||
.of(context)
|
||||
@@ -290,8 +290,8 @@ class MobileContactUsState extends State<MobileContactUs> {
|
||||
onMapCreated: _onMapCreated,
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: LatLng(
|
||||
double.parse(widget.business.address.lat),
|
||||
double.parse(widget.business.address.lng)),
|
||||
double.parse(widget.business.address.lat ?? ''),
|
||||
double.parse(widget.business.address.lng ?? '')),
|
||||
zoom: 14.0,
|
||||
),
|
||||
onCameraMove: _onCameraMove,
|
||||
|
||||
@@ -14,8 +14,7 @@ import '../../utils/utils.dart';
|
||||
|
||||
class MobileCoupons extends StatefulWidget {
|
||||
final int contactId;
|
||||
final Key key;
|
||||
const MobileCoupons(this.contactId, {this.key});
|
||||
const MobileCoupons(this.contactId, {Key? key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -24,7 +23,7 @@ class MobileCoupons extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileCouponsState extends State<MobileCoupons> {
|
||||
List<Coupon> coupons;
|
||||
List<Coupon>? coupons;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -54,10 +53,10 @@ class MobileCouponsState extends State<MobileCoupons> {
|
||||
),
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: coupons.length > 0 ? coupons.length : 1,
|
||||
itemCount: coupons!.length > 0 ? coupons!.length : 1,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
if (coupons.length > 0) {
|
||||
Coupon coupon = coupons[position];
|
||||
if (coupons!.length > 0) {
|
||||
Coupon coupon = coupons![position];
|
||||
return Container(
|
||||
color: Colors.black12,
|
||||
child: couponWidget(coupon),
|
||||
@@ -97,7 +96,7 @@ class MobileCouponsState extends State<MobileCoupons> {
|
||||
Container(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
child: coupon.store != null ?
|
||||
Util.showImage('${coupon.store.picUrl}',
|
||||
Util.showImage('${coupon.store?.picUrl}',
|
||||
fit: BoxFit.fill,
|
||||
width: 40.0,
|
||||
) :
|
||||
@@ -114,7 +113,7 @@ class MobileCouponsState extends State<MobileCoupons> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
coupon.store != null ? coupon.store.name : S.of(context).general_coupon,
|
||||
coupon.store != null ? coupon.store!.name : S.of(context).general_coupon,
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -248,7 +247,7 @@ class MobileCouponsState extends State<MobileCoupons> {
|
||||
Container(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
@@ -261,7 +260,7 @@ class MobileCouponsState extends State<MobileCoupons> {
|
||||
),
|
||||
onPressed: () {
|
||||
if (coupon.store != null) {
|
||||
Routes.router.navigateTo(context, '/shop/${coupon.store.id}/na/na/na');
|
||||
Routes.router.navigateTo(context, '/shop/${coupon.store?.id}/na/na/na');
|
||||
} else {
|
||||
Routes.router.navigateTo(context, '/businesses');
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dar
|
||||
class MobileDownloadApps extends StatefulWidget {
|
||||
final Map<String, dynamic> data;
|
||||
|
||||
MobileDownloadApps(this.data, {Key key}) : super(key: key);
|
||||
MobileDownloadApps(this.data, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
|
||||
@@ -13,15 +13,15 @@ import 'package:flutter_wisetronic/store/store.dart';
|
||||
import 'package:flutter_wisetronic/utils/http_util.dart';
|
||||
import 'package:flutter_wisetronic/utils/utils.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:gender_selection/gender_selection.dart';
|
||||
import 'package:gender_picker/gender_picker.dart';
|
||||
import 'package:gender_picker/source/enums.dart';
|
||||
|
||||
import '../../routes.dart';
|
||||
|
||||
class MobileEditAddress extends StatefulWidget {
|
||||
final Key key;
|
||||
final Address address;
|
||||
final int businessId;
|
||||
const MobileEditAddress(this.address, {this.key, int businessId}) :
|
||||
final Address? address;
|
||||
final int? businessId;
|
||||
const MobileEditAddress(this.address, {Key? key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
@@ -43,12 +43,12 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
final emailController = TextEditingController();
|
||||
final faxController = TextEditingController();
|
||||
|
||||
String country;
|
||||
Gender _selectedGender;
|
||||
String? country;
|
||||
Gender? _selectedGender;
|
||||
|
||||
String _selectedProvince;
|
||||
String? _selectedProvince;
|
||||
|
||||
bool showLoading;
|
||||
bool showLoading = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -109,8 +109,8 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
.of(context)
|
||||
.contact_name,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -121,27 +121,25 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
},
|
||||
),
|
||||
),
|
||||
GenderSelection(
|
||||
maleText: S
|
||||
.of(context)
|
||||
.mr,
|
||||
femaleText: S
|
||||
.of(context)
|
||||
.ms,
|
||||
selectedGenderIconBackgroundColor: Colors.indigo,
|
||||
checkIconAlignment: Alignment.bottomRight,
|
||||
selectedGenderCheckIcon: Icons.check,
|
||||
onChanged: (Gender gender) {
|
||||
GenderPickerWithImage(
|
||||
onChanged: (Gender? gender) {
|
||||
_selectedGender = gender;
|
||||
},
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 400),
|
||||
isCircular: true,
|
||||
isSelectedGenderIconCircular: true,
|
||||
opacityOfGradient: 0.6,
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
size: 50,
|
||||
maleText: S.of(context).mr,
|
||||
femaleText: S.of(context).ms,
|
||||
selectedGender: _selectedGender,
|
||||
showOtherGender: false,
|
||||
verticalAlignedText: false,
|
||||
selectedGenderTextStyle: TextStyle(
|
||||
color: Color(0xFF8b32a8), fontWeight: FontWeight.bold),
|
||||
unSelectedGenderTextStyle: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.normal),
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 200),
|
||||
isCircular: true,
|
||||
opacityOfGradient: 0.5,
|
||||
padding: const EdgeInsets.all(3),
|
||||
size: 50,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
@@ -164,8 +162,8 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
.of(context)
|
||||
.mobile_phone_number,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -196,8 +194,8 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
.of(context)
|
||||
.street_line_1,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -250,8 +248,8 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
.of(context)
|
||||
.city,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -320,8 +318,8 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
.of(context)
|
||||
.postal_code,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value
|
||||
validator: (String? value) {
|
||||
if (value == null || value
|
||||
.trim()
|
||||
.isEmpty) {
|
||||
return S
|
||||
@@ -365,8 +363,8 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
.of(context)
|
||||
.email,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
validator: (String? value) {
|
||||
if (value != null && value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
return S
|
||||
.of(context)
|
||||
.email_is_not_valid;
|
||||
@@ -472,43 +470,43 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
super.initState();
|
||||
setState(() {
|
||||
showLoading = false;
|
||||
_selectedProvince = widget.address.state;
|
||||
cityController.text = widget.address.city;
|
||||
postalCodeController.text = widget.address.zip;
|
||||
streetLine1Controller.text = widget.address.addressLine1;
|
||||
streetLine2Controller.text = widget.address.addressLine2;
|
||||
_selectedGender = widget.address.gender == 1 ? Gender.Male : Gender.Female;
|
||||
country = widget.address.country;
|
||||
contactNameController.text = widget.address.contactName;
|
||||
phoneController.text = widget.address.phone;
|
||||
emailController.text = widget.address.email;
|
||||
faxController.text = widget.address.fax;
|
||||
_selectedProvince = widget.address?.state;
|
||||
cityController.text = widget.address?.city ?? '';
|
||||
postalCodeController.text = widget.address?.zip ?? '';
|
||||
streetLine1Controller.text = widget.address?.addressLine1 ?? '';
|
||||
streetLine2Controller.text = widget.address?.addressLine2 ?? '';
|
||||
_selectedGender = widget.address?.gender == 1 ? Gender.Male : Gender.Female;
|
||||
country = widget.address?.country;
|
||||
contactNameController.text = widget.address?.contactName ?? '';
|
||||
phoneController.text = widget.address?.phone ?? '';
|
||||
emailController.text = widget.address?.email ?? '';
|
||||
faxController.text = widget.address?.fax ?? '';
|
||||
});
|
||||
}
|
||||
|
||||
void _saveEditAddress() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
showLoading = true;
|
||||
});
|
||||
}
|
||||
HttpUtil.httpPatch('v1/addresses/${widget.address.id}', (response) {
|
||||
HttpUtil.httpPatch('v1/addresses/${widget.address?.id}', (response) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
showLoading = false;
|
||||
});
|
||||
}
|
||||
eventBus.fire(OnAddressesUpdated());
|
||||
if (widget.businessId > 0) {
|
||||
if (widget.businessId != null && widget.businessId! > 0) {
|
||||
Routes.router.navigateTo(context, '/checkout/${widget.businessId}', replace: true);
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
body: {
|
||||
'id': widget.address.id,
|
||||
'id': widget.address?.id,
|
||||
'name': contactNameController.text.trim(),
|
||||
'address_line1': streetLine1Controller.text.trim(),
|
||||
'address_line2': streetLine2Controller.text.trim(),
|
||||
@@ -538,7 +536,7 @@ class MobileEditAddressState extends State<MobileEditAddress> {
|
||||
showLoading = true;
|
||||
});
|
||||
}
|
||||
HttpUtil.httpDelete('v1/addresses/${widget.address.id}', (response) {
|
||||
HttpUtil.httpDelete('v1/addresses/${widget.address?.id}', (response) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
showLoading = false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import 'package:countdown/countdown.dart';
|
||||
import '../../vendor/countdown/countdown.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
@@ -12,7 +12,7 @@ import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class MobileForgotPassword extends StatefulWidget {
|
||||
const MobileForgotPassword({Key key}) : super(key: key);
|
||||
const MobileForgotPassword({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -28,9 +28,9 @@ class MobileForgotPasswordState extends State<MobileForgotPassword> {
|
||||
bool usernameEnable = true;
|
||||
final codeController = TextEditingController();
|
||||
|
||||
bool enableGetCode;
|
||||
String getCodeText;
|
||||
bool canRegister;
|
||||
bool enableGetCode = false;
|
||||
String? getCodeText;
|
||||
bool canRegister = false;
|
||||
|
||||
var countDownListener;
|
||||
|
||||
@@ -90,8 +90,8 @@ class MobileForgotPasswordState extends State<MobileForgotPassword> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).mobile_or_email_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -158,7 +158,7 @@ class MobileForgotPasswordState extends State<MobileForgotPassword> {
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
child: Text(
|
||||
getCodeText,
|
||||
'${getCodeText}',
|
||||
style: TextStyle(
|
||||
color: enableGetCode ? Colors.black87 : Colors.black26,
|
||||
fontSize: 12.0
|
||||
@@ -173,8 +173,8 @@ class MobileForgotPasswordState extends State<MobileForgotPassword> {
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).verification_code_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -206,7 +206,7 @@ class MobileForgotPasswordState extends State<MobileForgotPassword> {
|
||||
alignment: Alignment.centerRight,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).verify,
|
||||
@@ -239,8 +239,8 @@ class MobileForgotPasswordState extends State<MobileForgotPassword> {
|
||||
}
|
||||
|
||||
void register() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
HttpUtil.httpPost('v1/users', (response) {
|
||||
Routes.router.navigateTo(context, '/reset-password/${usernameController.text.trim()}/${codeController.text.trim()}', replace: true);
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@ import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dar
|
||||
|
||||
class MobileiGoShowLearnMore extends StatefulWidget {
|
||||
final Map<String, dynamic> data;
|
||||
const MobileiGoShowLearnMore(this.data, {Key key}) : super(key: key);
|
||||
const MobileiGoShowLearnMore(this.data, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
|
||||
@@ -7,7 +7,7 @@ import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dar
|
||||
class MobileIndexCarousel extends StatefulWidget {
|
||||
final List<Gallery> galleries;
|
||||
|
||||
const MobileIndexCarousel(this.galleries, {Key key}) : super(key: key);
|
||||
const MobileIndexCarousel(this.galleries, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
|
||||
@@ -3,9 +3,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
|
||||
class MobileIndexMainContent1 extends StatefulWidget {
|
||||
final String message;
|
||||
final String? message;
|
||||
|
||||
const MobileIndexMainContent1(this.message, {Key key}) : super(key: key);
|
||||
const MobileIndexMainContent1(this.message, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -22,7 +22,7 @@ class MobileIndexMainContent1State extends State<MobileIndexMainContent1> {
|
||||
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
|
||||
child: Container(
|
||||
child: Text(
|
||||
widget.message,
|
||||
widget.message ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
||||
@@ -5,9 +5,9 @@ import '../../widgets/general/text_link.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileIndexMainContent2 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
final Map<String, dynamic>? content;
|
||||
|
||||
const MobileIndexMainContent2(this.content, {Key key}) : super(key: key);
|
||||
const MobileIndexMainContent2(this.content, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -33,7 +33,7 @@ class MobileIndexMainContent2State extends State<MobileIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['minipos']}',
|
||||
'${widget.content?['minipos']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -44,7 +44,7 @@ class MobileIndexMainContent2State extends State<MobileIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['point_of_sale_system_solution']}',
|
||||
'${widget.content?['point_of_sale_system_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
@@ -58,7 +58,7 @@ class MobileIndexMainContent2State extends State<MobileIndexMainContent2> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'https:${widget.content['minipos_image']['image']}',
|
||||
'https:${widget.content?['minipos_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
@@ -71,7 +71,7 @@ class MobileIndexMainContent2State extends State<MobileIndexMainContent2> {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['minipos_features'] as List).length; i++) {
|
||||
for (int i = 0; i < (widget.content?['minipos_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -88,7 +88,7 @@ class MobileIndexMainContent2State extends State<MobileIndexMainContent2> {
|
||||
width: MediaQuery.of(context).size.width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['minipos_features'] as List)[i]}',
|
||||
'${(widget.content?['minipos_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
|
||||
@@ -5,9 +5,9 @@ import '../../widgets/general/text_link.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileIndexMainContent3 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
final Map<String, dynamic>? content;
|
||||
|
||||
const MobileIndexMainContent3(this.content, {Key key}) : super(key: key);
|
||||
const MobileIndexMainContent3(this.content, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -33,7 +33,7 @@ class MobileIndexMainContent3State extends State<MobileIndexMainContent3> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow']}',
|
||||
'${widget.content?['igoshow']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -44,7 +44,7 @@ class MobileIndexMainContent3State extends State<MobileIndexMainContent3> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow_solution']}',
|
||||
'${widget.content?['igoshow_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
@@ -58,7 +58,7 @@ class MobileIndexMainContent3State extends State<MobileIndexMainContent3> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'https:${widget.content['igoshow_image']['image']}',
|
||||
'https:${widget.content?['igoshow_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
@@ -74,7 +74,7 @@ class MobileIndexMainContent3State extends State<MobileIndexMainContent3> {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['igoshow_features'] as List).length; i++) {
|
||||
for (int i = 0; i < (widget.content?['igoshow_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -91,7 +91,7 @@ class MobileIndexMainContent3State extends State<MobileIndexMainContent3> {
|
||||
width: MediaQuery.of(context).size.width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['igoshow_features'] as List)[i]}',
|
||||
'${(widget.content?['igoshow_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
|
||||
@@ -11,9 +11,8 @@ import '../../store/actions.dart';
|
||||
import '../../store/store.dart';
|
||||
|
||||
class MobileLogin extends StatefulWidget {
|
||||
final Key key;
|
||||
|
||||
const MobileLogin({this.key}) : super(key: key);
|
||||
const MobileLogin({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -26,9 +25,9 @@ class MobileLoginState extends State<MobileLogin> {
|
||||
|
||||
final usernameController = TextEditingController();
|
||||
final passwordController = TextEditingController();
|
||||
bool passwordVisible;
|
||||
bool passwordVisible = false;
|
||||
|
||||
bool onSubmitting;
|
||||
bool onSubmitting = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -103,8 +102,8 @@ class MobileLoginState extends State<MobileLogin> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).this_field_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -143,8 +142,8 @@ class MobileLoginState extends State<MobileLogin> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
obscureText: passwordVisible,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).password_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -196,7 +195,7 @@ class MobileLoginState extends State<MobileLogin> {
|
||||
padding: EdgeInsets.only(top: 20.0, left: 16.0, right: 16.0, bottom: 20.0),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).login,
|
||||
@@ -226,8 +225,8 @@ class MobileLoginState extends State<MobileLogin> {
|
||||
}
|
||||
|
||||
void signIn() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
onSubmitting = true;
|
||||
@@ -239,19 +238,15 @@ class MobileLoginState extends State<MobileLogin> {
|
||||
print('response $response');
|
||||
User user = User.fromJson(response.data['user']);
|
||||
store.dispatch(UpdateCurrentUser(user));
|
||||
Utils.getBox().then((box) {
|
||||
box.put(Constants.KEY_USER_ID, response.data['user_id']);
|
||||
box.put(Constants.KEY_ACCESS_TOKEN, response.data['access_token']);
|
||||
if (store.state.redirectRoute != null) {
|
||||
Routes.router.navigateTo(context, store.state.redirectRoute, replace: true);
|
||||
store.dispatch(UpdateRedirectRoute(null));
|
||||
} else {
|
||||
Routes.router.navigateTo(
|
||||
context, '/me', replace: true, clearStack: false);
|
||||
}
|
||||
}).catchError((error) {
|
||||
Utils.showMessageDialog(context, error);
|
||||
});
|
||||
Utils.prefs?.setString(Constants.KEY_USER_ID, response.data['user_id']);
|
||||
Utils.prefs?.setString(Constants.KEY_ACCESS_TOKEN, response.data['access_token']);
|
||||
if (store.state.redirectRoute != null) {
|
||||
Routes.router.navigateTo(context, store.state.redirectRoute!, replace: true);
|
||||
store.dispatch(UpdateRedirectRoute(null));
|
||||
} else {
|
||||
Routes.router.navigateTo(
|
||||
context, '/me', replace: true, clearStack: false);
|
||||
}
|
||||
},
|
||||
queryParameters: {
|
||||
'client_id': '${Utils.getPlatformName()}',
|
||||
|
||||
@@ -20,14 +20,13 @@ import '../../utils/util_web.dart'
|
||||
if (dart.library.io) '../../utils/util_io.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
MediaQueryData mediaQuery;
|
||||
double statusBarHeight;
|
||||
double screenHeight;
|
||||
MediaQueryData? mediaQuery;
|
||||
double? statusBarHeight;
|
||||
double? screenHeight;
|
||||
|
||||
class MobileMe extends StatefulWidget {
|
||||
final Key key;
|
||||
|
||||
const MobileMe({this.key}) : super(key: key);
|
||||
const MobileMe({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -36,18 +35,18 @@ class MobileMe extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileMeState extends State<MobileMe> {
|
||||
int userId;
|
||||
String accessToken;
|
||||
int? userId;
|
||||
String? accessToken;
|
||||
|
||||
bool isLoading;
|
||||
User _user;
|
||||
bool isLoading = false;
|
||||
User? _user;
|
||||
|
||||
ShopScrollCoordinator _shopCoordinator;
|
||||
ShopScrollController _pageScrollController;
|
||||
ShopScrollCoordinator? _shopCoordinator;
|
||||
ShopScrollController? _pageScrollController;
|
||||
final double _sliverAppBarInitHeight = 165.0;
|
||||
final double _appBarHeight = 85.0;
|
||||
|
||||
ShopScrollController _listScrollController1;
|
||||
ShopScrollController? _listScrollController1;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -65,16 +64,16 @@ class MobileMeState extends State<MobileMe> {
|
||||
}
|
||||
|
||||
mediaQuery ??= MediaQuery.of(context);
|
||||
screenHeight ??= mediaQuery.size.height;
|
||||
statusBarHeight ??= mediaQuery.padding.top;
|
||||
screenHeight ??= mediaQuery!.size.height;
|
||||
statusBarHeight ??= mediaQuery!.padding.top;
|
||||
|
||||
_pageScrollController ??=
|
||||
_shopCoordinator.pageScrollController(_sliverAppBarInitHeight * -1.0);
|
||||
_shopCoordinator.pinnedHeaderSliverHeightBuilder ??= () {
|
||||
return statusBarHeight + kToolbarHeight + _appBarHeight;
|
||||
_shopCoordinator!.pageScrollController(_sliverAppBarInitHeight * -1.0);
|
||||
_shopCoordinator!.pinnedHeaderSliverHeightBuilder ??= () {
|
||||
return statusBarHeight! + kToolbarHeight + _appBarHeight;
|
||||
};
|
||||
|
||||
_listScrollController1 = _shopCoordinator.newChildScrollController();
|
||||
_listScrollController1 = _shopCoordinator?.newChildScrollController();
|
||||
|
||||
Widget userInfo = GestureDetector(
|
||||
child: Container(
|
||||
@@ -88,9 +87,9 @@ class MobileMeState extends State<MobileMe> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 5.0),
|
||||
child: _user != null && _user.avatarUrl.isNotEmpty
|
||||
child: _user != null && _user!.avatarUrl.isNotEmpty
|
||||
? Util.showImage(
|
||||
'https:${_user.avatarUrl}',
|
||||
'https:${_user!.avatarUrl}',
|
||||
width: 60,
|
||||
height: 60,
|
||||
fit: BoxFit.fill,
|
||||
@@ -116,7 +115,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
Container(
|
||||
child: Text(
|
||||
_user != null
|
||||
? _user.nickname
|
||||
? _user!.nickname
|
||||
: S.of(context).please_login,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
@@ -142,7 +141,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
Container(
|
||||
child: Text(
|
||||
_user != null
|
||||
? Utils.safePhoneNumber(_user.mobile)
|
||||
? Utils.safePhoneNumber(_user!.mobile)
|
||||
: '',
|
||||
style: TextStyle(
|
||||
color:
|
||||
@@ -180,7 +179,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
);
|
||||
|
||||
Listener listener = Listener(
|
||||
onPointerUp: _shopCoordinator.onPointerUp,
|
||||
onPointerUp: _shopCoordinator?.onPointerUp,
|
||||
child: CustomScrollView(
|
||||
controller: _pageScrollController,
|
||||
physics: ClampingScrollPhysics(),
|
||||
@@ -219,7 +218,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
Container(
|
||||
child: Text(
|
||||
_user != null
|
||||
? '${_user.wallet.toStringAsFixed(2)}'
|
||||
? '${_user!.wallet.toStringAsFixed(2)}'
|
||||
: '0.00',
|
||||
style: TextStyle(
|
||||
fontSize: 24.0,
|
||||
@@ -262,7 +261,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
_user != null ? '${_user.coupon}' : '0',
|
||||
_user != null ? '${_user!.coupon}' : '0',
|
||||
style: TextStyle(
|
||||
fontSize: 24.0,
|
||||
color: Colors.orangeAccent,
|
||||
@@ -296,7 +295,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
onTap: () {
|
||||
if (_user != null) {
|
||||
Routes.router
|
||||
.navigateTo(context, '/coupons/${_user.id}');
|
||||
.navigateTo(context, '/coupons/${_user!.id}');
|
||||
} else {
|
||||
_pleaseLoginToast();
|
||||
}
|
||||
@@ -312,7 +311,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
_user != null ? '${_user.points}' : '0',
|
||||
_user != null ? '${_user!.points}' : '0',
|
||||
style: TextStyle(
|
||||
fontSize: 24.0,
|
||||
color: Colors.lightGreen,
|
||||
@@ -350,7 +349,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
controller: _listScrollController1,
|
||||
itemCount: 7,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
Widget item;
|
||||
Widget? item;
|
||||
switch (i) {
|
||||
case 0:
|
||||
item = GestureDetector(
|
||||
@@ -671,7 +670,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
),
|
||||
onTap: () {
|
||||
if (_user != null) {
|
||||
if (_user.email == null || _user.email.isEmpty) {
|
||||
if (_user!.email == null || _user!.email.isEmpty) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
@@ -687,7 +686,7 @@ class MobileMeState extends State<MobileMe> {
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
@@ -816,9 +815,9 @@ class MobileMeState extends State<MobileMe> {
|
||||
|
||||
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
||||
_SliverAppBarDelegate({
|
||||
@required this.minHeight,
|
||||
@required this.maxHeight,
|
||||
@required this.child,
|
||||
required this.minHeight,
|
||||
required this.maxHeight,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final double minHeight;
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dar
|
||||
|
||||
class MobileMiniPosLearnMore extends StatefulWidget {
|
||||
final Map<String, dynamic> data;
|
||||
const MobileMiniPosLearnMore(this.data, {Key key}) : super(key: key);
|
||||
const MobileMiniPosLearnMore(this.data, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
|
||||
@@ -17,7 +17,7 @@ import '../../routes.dart';
|
||||
|
||||
class MobileMyAddresses extends StatefulWidget {
|
||||
final int businessId;
|
||||
const MobileMyAddresses({Key key, this.businessId}) : super(key: key);
|
||||
const MobileMyAddresses({Key? key, required this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -27,7 +27,7 @@ class MobileMyAddresses extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileMyAddressesState extends State<MobileMyAddresses> {
|
||||
List<Address> addresses;
|
||||
List<Address>? addresses;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -70,9 +70,9 @@ class MobileMyAddressesState extends State<MobileMyAddresses> {
|
||||
],
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: addresses.length <= 1 ? 1 : addresses.length,
|
||||
itemCount: addresses!.length <= 1 ? 1 : addresses!.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
if (addresses.length <= 0) {
|
||||
if (addresses!.length <= 0) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Center(
|
||||
@@ -80,7 +80,7 @@ class MobileMyAddressesState extends State<MobileMyAddresses> {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Address address = addresses[i];
|
||||
Address address = addresses![i];
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
|
||||
@@ -102,7 +102,7 @@ class MobileMyAddressesState extends State<MobileMyAddresses> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
address.addressLine1,
|
||||
'${address.addressLine1}',
|
||||
style: TextStyle(
|
||||
fontSize: 19.0,
|
||||
),
|
||||
@@ -110,7 +110,7 @@ class MobileMyAddressesState extends State<MobileMyAddresses> {
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
address.addressLine2,
|
||||
'${address.addressLine2}',
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Colors.grey,
|
||||
@@ -120,7 +120,7 @@ class MobileMyAddressesState extends State<MobileMyAddresses> {
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 10.0),
|
||||
child: Text(
|
||||
'${address.contactName} ${Utils.safePhoneNumber(address.phone)}',
|
||||
'${address.contactName} ${Utils.safePhoneNumber(address.phone ?? '')}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.black87,
|
||||
|
||||
@@ -13,8 +13,7 @@ import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class MobileMyCards extends StatefulWidget {
|
||||
final Key key;
|
||||
const MobileMyCards({this.key});
|
||||
const MobileMyCards({Key? key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -24,9 +23,9 @@ class MobileMyCards extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MyCardsState extends State<MobileMyCards> {
|
||||
User _user;
|
||||
User? _user;
|
||||
|
||||
bool isSubmitting;
|
||||
bool isSubmitting = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -44,9 +43,9 @@ class MyCardsState extends State<MobileMyCards> {
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: _user.stripePaymentMethods.length,
|
||||
itemCount: _user!.stripePaymentMethods.length,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
StripePaymentMethod paymentMethod = _user.stripePaymentMethods[position];
|
||||
StripePaymentMethod paymentMethod = _user!.stripePaymentMethods[position];
|
||||
return cardWidget(paymentMethod);
|
||||
}
|
||||
),
|
||||
@@ -116,7 +115,7 @@ class MyCardsState extends State<MobileMyCards> {
|
||||
TextButton(
|
||||
child: Text(S.of(context).cancel),
|
||||
style: TextButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
foregroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
@@ -18,7 +18,7 @@ import '../../widgets/mobile/MobileBottomNav.dart';
|
||||
|
||||
class MobileMySupport extends StatefulWidget {
|
||||
final int businessId;
|
||||
const MobileMySupport({Key key, this.businessId}) : super(key: key);
|
||||
const MobileMySupport({Key? key, required this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -28,7 +28,7 @@ class MobileMySupport extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileMySupportState extends State<MobileMySupport> {
|
||||
List<Ticket> tickets;
|
||||
List<Ticket>? tickets;
|
||||
|
||||
int _page = 1;
|
||||
int _pageCount = 1;
|
||||
@@ -41,7 +41,7 @@ class MobileMySupportState extends State<MobileMySupport> {
|
||||
void _onRefresh() {
|
||||
_page = 1;
|
||||
if (tickets != null) {
|
||||
tickets.clear();
|
||||
tickets?.clear();
|
||||
} else {
|
||||
tickets = [];
|
||||
}
|
||||
@@ -101,7 +101,7 @@ class MobileMySupportState extends State<MobileMySupport> {
|
||||
enablePullUp: true,
|
||||
header: WaterDropHeader(),
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode){
|
||||
builder: (BuildContext context, LoadStatus? mode){
|
||||
Widget footer;
|
||||
if(mode == LoadStatus.idle) {
|
||||
footer = Text(S.of(context).pull_up_to_load_more);
|
||||
@@ -143,9 +143,9 @@ class MobileMySupportState extends State<MobileMySupport> {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: tickets.length <= 1 ? 1 : tickets.length,
|
||||
itemCount: tickets!.length <= 1 ? 1 : tickets!.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
if (tickets.length <= 0) {
|
||||
if (tickets!.length <= 0) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Center(
|
||||
@@ -153,7 +153,7 @@ class MobileMySupportState extends State<MobileMySupport> {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Ticket ticket = tickets[i];
|
||||
Ticket ticket = tickets![i];
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
@@ -273,7 +273,7 @@ class MobileMySupportState extends State<MobileMySupport> {
|
||||
if (tickets == null) {
|
||||
tickets = [];
|
||||
}
|
||||
tickets.addAll((value['tickets'] as List).map((e) => Ticket.fromJson(e)).toList());
|
||||
tickets!.addAll((value['tickets'] as List).map((e) => Ticket.fromJson(e)).toList());
|
||||
});
|
||||
}
|
||||
}).catchError((error) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import '../../widgets/mobile/mobile_navigation_drawer_header.dart';
|
||||
import '../../constants.dart';
|
||||
|
||||
class MobileNavigationDrawer extends StatefulWidget {
|
||||
const MobileNavigationDrawer({Key key}) : super(key: key);
|
||||
const MobileNavigationDrawer({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -23,11 +23,11 @@ class MobileNavigationDrawer extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileNavigationDrawerState extends State<MobileNavigationDrawer> {
|
||||
User _user;
|
||||
User? _user;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String currentRoute = ModalRoute.of(context).settings.name;
|
||||
String? currentRoute = ModalRoute.of(context)?.settings.name;
|
||||
|
||||
return Container(
|
||||
width: 200.0,
|
||||
|
||||
@@ -10,11 +10,11 @@ import '../../widgets/general/navigationbar_logo.dart';
|
||||
import '../../routes.dart';
|
||||
|
||||
class MobileNavigationBar extends StatefulWidget {
|
||||
final String title;
|
||||
final bool back;
|
||||
final bool toHome;
|
||||
final bool showMe;
|
||||
const MobileNavigationBar({Key key, this.title, this.back, this.toHome, this.showMe}) : super(key: key);
|
||||
final String? title;
|
||||
final bool? back;
|
||||
final bool? toHome;
|
||||
final bool? showMe;
|
||||
const MobileNavigationBar({Key? key, this.title, this.back, this.toHome, this.showMe}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -24,19 +24,19 @@ class MobileNavigationBar extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileNavigationBarState extends State<MobileNavigationBar> {
|
||||
User _user;
|
||||
User? _user;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
leading: widget.back ?
|
||||
leading: widget.back != null && widget.back! ?
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
if (widget.toHome) {
|
||||
if (widget.toHome != null && widget.toHome!) {
|
||||
Routes.router.navigateTo(context, '/', clearStack: true);
|
||||
} else {
|
||||
Routes.router.pop(context);
|
||||
@@ -53,7 +53,7 @@ class MobileNavigationBarState extends State<MobileNavigationBar> {
|
||||
},
|
||||
),
|
||||
title: Container(
|
||||
child: widget.title.isNotEmpty ?
|
||||
child: widget.title != null && widget.title!.isNotEmpty ?
|
||||
Container(
|
||||
child: Text(
|
||||
'${widget.title}',
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
import 'package:email_validator/email_validator.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gender_selection/gender_selection.dart';
|
||||
import 'package:gender_picker/gender_picker.dart';
|
||||
import 'package:gender_picker/source/enums.dart';
|
||||
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../models/located_address.dart';
|
||||
@@ -11,10 +12,9 @@ import '../../store/store.dart';
|
||||
import '../../utils/http_util.dart';
|
||||
|
||||
class MobileNewAddress extends StatefulWidget {
|
||||
final Key key;
|
||||
final LocatedAddress locatedAddress;
|
||||
final int businessId;
|
||||
const MobileNewAddress({this.key, this.locatedAddress, this.businessId}) : super(key: key);
|
||||
final LocatedAddress? locatedAddress;
|
||||
final int? businessId;
|
||||
const MobileNewAddress({Key? key, this.locatedAddress, this.businessId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -36,9 +36,9 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
final faxController = TextEditingController();
|
||||
|
||||
String country = 'CA';
|
||||
Gender _selectedGender;
|
||||
Gender? _selectedGender;
|
||||
|
||||
String _selectedProvince;
|
||||
String? _selectedProvince;
|
||||
|
||||
List<String> provinces = <String>[
|
||||
'Ontario',
|
||||
@@ -96,31 +96,33 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).contact_name,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).contact_name_is_required;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
GenderSelection(
|
||||
maleText: S.of(context).mr,
|
||||
femaleText: S.of(context).ms,
|
||||
selectedGenderIconBackgroundColor: Colors.indigo,
|
||||
checkIconAlignment: Alignment.bottomRight,
|
||||
selectedGenderCheckIcon: Icons.check,
|
||||
onChanged: (Gender gender) {
|
||||
GenderPickerWithImage(
|
||||
onChanged: (Gender? gender) {
|
||||
_selectedGender = gender;
|
||||
},
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 400),
|
||||
isCircular: true,
|
||||
isSelectedGenderIconCircular: true,
|
||||
opacityOfGradient: 0.6,
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
size: 50,
|
||||
maleText: S.of(context).mr,
|
||||
femaleText: S.of(context).ms,
|
||||
selectedGender: _selectedGender,
|
||||
showOtherGender: false,
|
||||
verticalAlignedText: false,
|
||||
selectedGenderTextStyle: TextStyle(
|
||||
color: Color(0xFF8b32a8), fontWeight: FontWeight.bold),
|
||||
unSelectedGenderTextStyle: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.normal),
|
||||
equallyAligned: true,
|
||||
animationDuration: Duration(milliseconds: 200),
|
||||
isCircular: true,
|
||||
opacityOfGradient: 0.5,
|
||||
padding: const EdgeInsets.all(3),
|
||||
size: 50,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 0.0),
|
||||
@@ -140,8 +142,8 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).mobile_phone_number,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).mobile_phone_number_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -165,8 +167,8 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).street_line_1,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).street_line_1_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -209,8 +211,8 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).city,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).city_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -255,8 +257,8 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).postal_code,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).postal_code_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -290,8 +292,8 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
),
|
||||
labelText: S.of(context).email,
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
validator: (String? value) {
|
||||
if (value != null && value.isNotEmpty && !EmailValidator.validate(value)) {
|
||||
return S.of(context).email_is_not_valid;
|
||||
}
|
||||
return null;
|
||||
@@ -348,15 +350,15 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
super.initState();
|
||||
setState(() {
|
||||
if (widget.locatedAddress != null) {
|
||||
if (provinces.contains(widget.locatedAddress.province)) {
|
||||
_selectedProvince = widget.locatedAddress.province;
|
||||
if (provinces.contains(widget.locatedAddress!.province)) {
|
||||
_selectedProvince = widget.locatedAddress!.province;
|
||||
}
|
||||
cityController.text = widget.locatedAddress.city;
|
||||
postalCodeController.text = widget.locatedAddress.postalCode;
|
||||
streetLine1Controller.text = (widget.locatedAddress.streetNumber != null
|
||||
&& widget.locatedAddress.streetNumber.isNotEmpty
|
||||
? widget.locatedAddress.streetNumber + ' ' : '')
|
||||
+ widget.locatedAddress.streetName;
|
||||
cityController.text = widget.locatedAddress!.city;
|
||||
postalCodeController.text = widget.locatedAddress!.postalCode;
|
||||
streetLine1Controller.text = (widget.locatedAddress!.streetNumber != null
|
||||
&& widget.locatedAddress!.streetNumber.isNotEmpty
|
||||
? widget.locatedAddress!.streetNumber + ' ' : '')
|
||||
+ widget.locatedAddress!.streetName;
|
||||
} else {
|
||||
_selectedProvince = 'Ontario';
|
||||
}
|
||||
@@ -366,11 +368,11 @@ class MobileNewAddressState extends State<MobileNewAddress> {
|
||||
}
|
||||
|
||||
void _saveNewAddress() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
|
||||
HttpUtil.httpPost('v1/addresses', (response) {
|
||||
if (widget.businessId > 0) {
|
||||
if (widget.businessId! > 0) {
|
||||
Routes.router.navigateTo(context, '/checkout/${widget.businessId}', replace: true);
|
||||
} else {
|
||||
Routes.router.navigateTo(context, '/my-addresses/${widget.businessId}', replace: true);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:smooth_star_rating/smooth_star_rating.dart';
|
||||
import 'package:smooth_star_rating_nsafe/smooth_star_rating.dart';
|
||||
|
||||
import '../../events/eventbus.dart';
|
||||
import '../../events/events.dart';
|
||||
@@ -19,9 +19,8 @@ import '../../utils/utils.dart';
|
||||
|
||||
|
||||
class MobileNewComment extends StatefulWidget {
|
||||
final Key key;
|
||||
final int orderId;
|
||||
const MobileNewComment(this.orderId, {this.key});
|
||||
const MobileNewComment(this.orderId, {Key? key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -31,13 +30,13 @@ class MobileNewComment extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileNewCommentState extends State<MobileNewComment> {
|
||||
Comment comment;
|
||||
Comment? comment;
|
||||
|
||||
bool _showProgress;
|
||||
bool _showProgress = false;
|
||||
|
||||
double _progress;
|
||||
double? _progress;
|
||||
|
||||
double rating;
|
||||
double? rating;
|
||||
|
||||
bool isSubmitting = false;
|
||||
|
||||
@@ -112,13 +111,8 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
padding: EdgeInsets.only(left: 20.0, right: 20.0, top: 16.0, bottom: 16.0),
|
||||
child: SmoothStarRating(
|
||||
allowHalfRating: false,
|
||||
onRated: (v) {
|
||||
setState(() {
|
||||
rating = v;
|
||||
});
|
||||
},
|
||||
starCount: 5,
|
||||
rating: rating,
|
||||
rating: rating!,
|
||||
size: 40.0,
|
||||
filledIconData: Icons.star,
|
||||
color: Colors.green,
|
||||
@@ -167,13 +161,13 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
children: <Widget>[],
|
||||
);
|
||||
|
||||
if (comment != null && comment.images.length > 0) {
|
||||
for (ProductImage image in comment.images) {
|
||||
if (comment != null && comment!.images.length > 0) {
|
||||
for (ProductImage image in comment!.images) {
|
||||
row.children.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 10.0),
|
||||
child: Badge(
|
||||
position: BadgePosition.topEnd(top: -10.0, end: -6.0),
|
||||
child: badges.Badge(
|
||||
position: badges.BadgePosition.topEnd(top: -10.0, end: -6.0),
|
||||
badgeContent: Container(
|
||||
child: Text(
|
||||
'-',
|
||||
@@ -210,7 +204,7 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
foregroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
@@ -239,7 +233,7 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
size: 60.0,
|
||||
color: comment == null || comment.images.length < 3 ? Colors.lightBlue : Colors.black12,
|
||||
color: comment == null || comment!.images.length < 3 ? Colors.lightBlue : Colors.black12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white70,
|
||||
@@ -264,13 +258,13 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (comment == null || comment.images.length < 3) {
|
||||
if (comment == null || comment!.images.length < 3) {
|
||||
showDialog(
|
||||
context: mainContext,
|
||||
barrierDismissible: true,
|
||||
builder: (BuildContext context) {
|
||||
return Util().getPicture(mainContext, store.state.user,
|
||||
commentId: comment != null ? comment.id : 0,
|
||||
return Util().getPicture(mainContext, store.state.user!,
|
||||
commentId: comment != null ? comment!.id : 0,
|
||||
orderId: widget.orderId);
|
||||
}
|
||||
);
|
||||
@@ -290,7 +284,7 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
visible: _showProgress,
|
||||
child: LinearPercentIndicator(
|
||||
lineHeight: 10.0,
|
||||
percent: _progress,
|
||||
percent: _progress!,
|
||||
backgroundColor: Colors.transparent,
|
||||
progressColor: Colors.blue,
|
||||
linearStrokeCap: LinearStrokeCap.butt,
|
||||
@@ -329,7 +323,7 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
}
|
||||
},
|
||||
queryParameters: {
|
||||
'comment_id': comment != null ? comment.id : 0,
|
||||
'comment_id': comment != null ? comment!.id : 0,
|
||||
},
|
||||
).catchError((error) {
|
||||
Utils.showMessageDialog(context, error);
|
||||
@@ -356,9 +350,9 @@ class MobileNewCommentState extends State<MobileNewComment> {
|
||||
isFormData: true,
|
||||
body: {
|
||||
'order_id': widget.orderId,
|
||||
'comment_id': comment != null ? comment.id : 0,
|
||||
'comment_id': comment != null ? comment!.id : 0,
|
||||
'content': commentController.text,
|
||||
'rating': rating.round(),
|
||||
'rating': rating!.round(),
|
||||
},
|
||||
).catchError((error) {
|
||||
if (isSubmitting) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
@@ -17,10 +17,9 @@ import '../../store/store.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileNewTicket extends StatefulWidget {
|
||||
final Key key;
|
||||
final int businessId;
|
||||
|
||||
const MobileNewTicket({this.key, int businessId}) :
|
||||
const MobileNewTicket({Key? key, required int businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
@@ -110,8 +109,8 @@ class MobileNewTicketState extends State<MobileNewTicket> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).this_field_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -162,7 +161,7 @@ class MobileNewTicketState extends State<MobileNewTicket> {
|
||||
padding: EdgeInsets.only(top: 20.0, left: 16.0, right: 16.0, bottom: 20.0),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).submit,
|
||||
@@ -221,8 +220,8 @@ class MobileNewTicketState extends State<MobileNewTicket> {
|
||||
}
|
||||
|
||||
void _submit() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
setState(() {
|
||||
onSubmitting = true;
|
||||
});
|
||||
@@ -331,14 +330,13 @@ class MobileNewTicketState extends State<MobileNewTicket> {
|
||||
galleryImagesFlag[imageId]['path'] = path;
|
||||
});
|
||||
});
|
||||
return null;
|
||||
}
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
row.children.add(Badge(
|
||||
position: BadgePosition.topEnd(top: -10.0, end: 10.0),
|
||||
row.children.add(badges.Badge(
|
||||
position: badges.BadgePosition.topEnd(top: -10.0, end: 10.0),
|
||||
badgeContent: Container(
|
||||
child: GestureDetector(
|
||||
child: Icon(
|
||||
@@ -374,7 +372,7 @@ class MobileNewTicketState extends State<MobileNewTicket> {
|
||||
ElevatedButton(
|
||||
child: Text(S.of(context).yes_i_am_sure),
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import 'package:countdown/countdown.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
import '../../vendor/countdown/countdown.dart';
|
||||
import '../../constants.dart';
|
||||
import '../../generated/l10n.dart';
|
||||
import '../../routes.dart';
|
||||
@@ -11,7 +11,7 @@ import '../../utils/http_util.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class MobileNewUser extends StatefulWidget {
|
||||
const MobileNewUser({Key key}) : super(key: key);
|
||||
const MobileNewUser({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -28,9 +28,9 @@ class MobileNewUserState extends State<MobileNewUser> {
|
||||
bool usernameEnable = true;
|
||||
final codeController = TextEditingController();
|
||||
|
||||
bool enableGetCode;
|
||||
String getCodeText;
|
||||
bool canRegister;
|
||||
bool enableGetCode = false;
|
||||
String? getCodeText;
|
||||
bool canRegister = false;
|
||||
|
||||
var countDownListener;
|
||||
|
||||
@@ -87,8 +87,8 @@ class MobileNewUserState extends State<MobileNewUser> {
|
||||
fontSize: 18.0
|
||||
),
|
||||
autofocus: true,
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).mobile_or_email_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -155,7 +155,7 @@ class MobileNewUserState extends State<MobileNewUser> {
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
child: Text(
|
||||
getCodeText,
|
||||
'${getCodeText}',
|
||||
style: TextStyle(
|
||||
color: enableGetCode ? Colors.black87 : Colors.black26,
|
||||
fontSize: 14.0
|
||||
@@ -170,8 +170,8 @@ class MobileNewUserState extends State<MobileNewUser> {
|
||||
style: TextStyle(
|
||||
fontSize: 18.0
|
||||
),
|
||||
validator: (String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
validator: (String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return S.of(context).verification_code_is_required;
|
||||
}
|
||||
return null;
|
||||
@@ -203,7 +203,7 @@ class MobileNewUserState extends State<MobileNewUser> {
|
||||
alignment: Alignment.centerRight,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).register,
|
||||
@@ -236,8 +236,8 @@ class MobileNewUserState extends State<MobileNewUser> {
|
||||
}
|
||||
|
||||
void register() {
|
||||
final FormState form = _formKey.currentState;
|
||||
if (form.validate()) {
|
||||
final FormState? form = _formKey.currentState;
|
||||
if (form != null && form.validate()) {
|
||||
HttpUtil.httpPost('v1/users', (response) {
|
||||
Routes.router.navigateTo(context, '/set-password/${usernameController.text.trim()}/${codeController.text.trim()}', replace: true);
|
||||
},
|
||||
|
||||
@@ -24,10 +24,9 @@ import '../../routes.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileOrderDetail extends StatefulWidget {
|
||||
final Key key;
|
||||
final int orderId;
|
||||
final bool fromOrders;
|
||||
const MobileOrderDetail(this.orderId, {this.key, this.fromOrders});
|
||||
const MobileOrderDetail(this.orderId, {Key? key, required this.fromOrders});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -37,18 +36,18 @@ class MobileOrderDetail extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
Order order;
|
||||
Order? order;
|
||||
|
||||
LatLng _lastMapPosition;
|
||||
LatLng customerLatLng;
|
||||
LatLng deliveryLatLng;
|
||||
LatLng storeLatLng;
|
||||
LatLng? _lastMapPosition;
|
||||
LatLng? customerLatLng;
|
||||
LatLng? deliveryLatLng;
|
||||
LatLng? storeLatLng;
|
||||
final Set<Marker> _markers = {};
|
||||
final Set<Polyline> _polyLine = {};
|
||||
|
||||
BitmapDescriptor homeIcon;
|
||||
BitmapDescriptor deliveryIcon;
|
||||
BitmapDescriptor shopIcon;
|
||||
BitmapDescriptor? homeIcon;
|
||||
BitmapDescriptor? deliveryIcon;
|
||||
BitmapDescriptor? shopIcon;
|
||||
|
||||
Completer<GoogleMapController> _controller = Completer();
|
||||
|
||||
@@ -91,15 +90,16 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
title: Text(S.of(context).order_detail),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
body: WillPopScope(
|
||||
onWillPop: () async {
|
||||
if (widget.fromOrders != null && widget.fromOrders) {
|
||||
return true;
|
||||
body: PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (didPop) return;
|
||||
if (widget.fromOrders) {
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
Routes.router.navigateTo(
|
||||
context, '/orders', replace: true, clearStack: true);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
child: ListView.builder(
|
||||
itemCount: 4,
|
||||
@@ -123,7 +123,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(top: 0.0, bottom: 16.0),
|
||||
child: Text(
|
||||
order.cartInfo.businessInfo.name,
|
||||
'${order?.cartInfo?.businessInfo?.name}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
@@ -142,7 +142,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Routes.router.navigateTo(context, '/shop/${order.businessId}/na/na/na');
|
||||
Routes.router.navigateTo(context, '/shop/${order?.businessId}/na/na/na');
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -154,7 +154,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
Icons.phone,
|
||||
),
|
||||
onTap: () {
|
||||
Utils.launchURL('tel:${order.businessInfo.phone}');
|
||||
Utils.launchURL('tel:${order?.businessInfo?.phone}');
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -163,15 +163,15 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
);
|
||||
|
||||
if (!kIsWeb) {
|
||||
if (order.shippingMethod == 'store-delivery' && order.status != Constants.STATUS_COMPLETE && order.status != Constants.STATUS_CANCELLED) {
|
||||
if (order!.shippingMethod == 'store-delivery' && order!.status != Constants.STATUS_COMPLETE && order!.status != Constants.STATUS_CANCELLED) {
|
||||
col.children.add(Container(
|
||||
height: 200.0,
|
||||
child: GoogleMap(
|
||||
onMapCreated: _onMapCreated,
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: LatLng(
|
||||
double.parse(order.shippingAddress.lat),
|
||||
double.parse(order.shippingAddress.lng)),
|
||||
double.parse(order?.shippingAddress?.lat ?? ''),
|
||||
double.parse(order?.shippingAddress?.lng ?? '')),
|
||||
zoom: 11.0,
|
||||
),
|
||||
onCameraMove: _onCameraMove,
|
||||
@@ -182,14 +182,14 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
].toSet(),
|
||||
),
|
||||
));
|
||||
if (order.deliveryDistance != null && order.deliveryDistance.distance != null) {
|
||||
if (order!.deliveryDistance != null && order!.deliveryDistance?.distance != null) {
|
||||
col.children.add(Container(
|
||||
padding: EdgeInsets.only(top: 6.0, bottom: 6.0),
|
||||
margin: EdgeInsets.only(bottom: 6.0),
|
||||
child: Text(
|
||||
S.of(context).delivery_distance_token(
|
||||
order.deliveryDistance.distance.text,
|
||||
order.deliveryDistance.duration.text
|
||||
order!.deliveryDistance!.distance?.text ?? '',
|
||||
order!.deliveryDistance!.duration?.text ?? ''
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
@@ -205,7 +205,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
}
|
||||
}
|
||||
|
||||
for (CartLineItem lineItem in order.cartInfo.productList) {
|
||||
for (CartLineItem lineItem in order!.cartInfo!.productList!) {
|
||||
|
||||
col.children.add(Container(
|
||||
padding: EdgeInsets.only(top: 16.0, bottom: 0.0),
|
||||
@@ -213,7 +213,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Util.showImage('${lineItem.product.imagePath}',
|
||||
Util.showImage('${lineItem.product!.imagePath}',
|
||||
width: 40.0,
|
||||
height: 40.0,
|
||||
fit: BoxFit.fill,
|
||||
@@ -251,7 +251,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
width: 30.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'x${lineItem.quantity.round()}',
|
||||
'x${lineItem.quantity!.round()}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
),
|
||||
@@ -304,7 +304,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
width: 100.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${order.getSubtotal().toStringAsFixed(2)}',
|
||||
'${order!.getSubtotal().toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
@@ -313,8 +313,8 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
],
|
||||
),
|
||||
);
|
||||
for (var i = 0; i < order.cartInfo.extraFeeList.length; i++) {
|
||||
ExtraFee extraFee = order.cartInfo.extraFeeList[i];
|
||||
for (var i = 0; i < order!.cartInfo!.extraFeeList!.length; i++) {
|
||||
ExtraFee extraFee = order!.cartInfo!.extraFeeList![i];
|
||||
col.children.add(
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@@ -371,7 +371,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
width: 100.0,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${order.totalPrice.toStringAsFixed(2)}',
|
||||
'${order!.totalPrice.toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -424,7 +424,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
),
|
||||
),
|
||||
);
|
||||
if (order.shippingMethod != 'pickup') {
|
||||
if (order!.shippingMethod != 'pickup') {
|
||||
col.children.add(Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@@ -443,7 +443,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Text(
|
||||
'${order.address}, ${order.consignee}, ${order.phone}',
|
||||
'${order!.address}, ${order!.consignee}, ${order!.phone}',
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -481,7 +481,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${order.cartInfo.businessInfo.fullAddress}',
|
||||
'${order!.cartInfo!.businessInfo?.fullAddress}',
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -520,7 +520,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${Utils.timestampToString(context, order.bookedAt, withTime: true)}',
|
||||
'${Utils.timestampToString(context, order!.bookedAt, withTime: true)}',
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -558,7 +558,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
order.shippingMethod == 'pickup' ? S.of(context).pickup : S.of(context).store_delivery,
|
||||
order!.shippingMethod == 'pickup' ? S.of(context).pickup : S.of(context).store_delivery,
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -648,7 +648,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'${order.orderNum}',
|
||||
'${order!.orderNum}',
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -670,7 +670,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
S.of(context).copy,
|
||||
),
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: '${order.orderNum}'));
|
||||
Clipboard.setData(ClipboardData(text: '${order!.orderNum}'));
|
||||
Fluttertoast.showToast(
|
||||
msg: S.of(context).order_number_copied_to_clipboard,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
@@ -715,7 +715,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
order.payMethod == 0 ? S.of(context).online_payment : S.of(context).pay_on_deliery,
|
||||
order!.payMethod == 0 ? S.of(context).online_payment : S.of(context).pay_on_deliery,
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -756,15 +756,15 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
order.paymentStatus == Constants.PAYMENT_STATUS_PAID ? S.of(context).paid : S.of(context).unpaid,
|
||||
order!.paymentStatus == Constants.PAYMENT_STATUS_PAID ? S.of(context).paid : S.of(context).unpaid,
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: order.paymentStatus != Constants.PAYMENT_STATUS_PAID && order.status != Constants.STATUS_CANCELLED ? EdgeInsets.only(left: 10.0, right: 10.0) : EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
child: order.paymentStatus != Constants.PAYMENT_STATUS_PAID && order.status != Constants.STATUS_CANCELLED ? Text('') : SizedBox.shrink(),
|
||||
decoration: order.paymentStatus != Constants.PAYMENT_STATUS_PAID && order.status != Constants.STATUS_CANCELLED ? BoxDecoration(
|
||||
margin: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID && order!.status != Constants.STATUS_CANCELLED ? EdgeInsets.only(left: 10.0, right: 10.0) : EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
child: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID && order!.status != Constants.STATUS_CANCELLED ? Text('') : SizedBox.shrink(),
|
||||
decoration: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID && order!.status != Constants.STATUS_CANCELLED ? BoxDecoration(
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
width: 0.5,
|
||||
@@ -774,16 +774,16 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
) : null,
|
||||
),
|
||||
GestureDetector(
|
||||
child: order.paymentStatus != Constants.PAYMENT_STATUS_PAID
|
||||
&& order.status != Constants.STATUS_CANCELLED
|
||||
&& order.status != Constants.STATUS_COMPLETE ? Text(
|
||||
child: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID
|
||||
&& order!.status != Constants.STATUS_CANCELLED
|
||||
&& order!.status != Constants.STATUS_COMPLETE ? Text(
|
||||
S.of(context).pay_now,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
) : SizedBox.shrink(),
|
||||
onTap: () {
|
||||
Routes.router.navigateTo(context, '/paynow/${order.id}');
|
||||
Routes.router.navigateTo(context, '/paynow/${order!.id}');
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -821,7 +821,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
Utils.timestampToString(context, order.createdAt, withTime: true),
|
||||
Utils.timestampToString(context, order!.createdAt, withTime: true),
|
||||
style: TextStyle(
|
||||
color: Colors.black38,
|
||||
),
|
||||
@@ -877,7 +877,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
),
|
||||
),
|
||||
Text(
|
||||
Utils.getOrderStatus(context, order.status),
|
||||
Utils.getOrderStatus(context, order!.status),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
@@ -899,7 +899,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
),
|
||||
),);
|
||||
|
||||
for (Fulfillment fulfillment in order.fulfillments) {
|
||||
for (Fulfillment fulfillment in order!.fulfillments) {
|
||||
col.children.add(Container(
|
||||
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
width: double.infinity,
|
||||
@@ -983,7 +983,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(right: 10.0),
|
||||
child: order.status == Constants.STATUS_PENDING && order.paymentStatus == Constants.PAYMENT_STATUS_UNPAID ?
|
||||
child: order!.status == Constants.STATUS_PENDING && order!.paymentStatus == Constants.PAYMENT_STATUS_UNPAID ?
|
||||
TextButton(
|
||||
child: Text(
|
||||
S.of(context).cancel_order,
|
||||
@@ -994,34 +994,34 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
Container(
|
||||
child: order.status == Constants.STATUS_COMPLETE && !order.hasComment ? ElevatedButton(
|
||||
child: order!.status == Constants.STATUS_COMPLETE && !order!.hasComment ? ElevatedButton(
|
||||
child: Text(
|
||||
S.of(context).comment,
|
||||
),
|
||||
onPressed: () {
|
||||
Routes.router.navigateTo(context, '/new-comment/${order.id}');
|
||||
Routes.router.navigateTo(context, '/new-comment/${order!.id}');
|
||||
},
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
child: order.paymentStatus != Constants.PAYMENT_STATUS_PAID
|
||||
&& order.status != Constants.STATUS_CANCELLED
|
||||
&& order.status != Constants.STATUS_COMPLETE ?
|
||||
child: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID
|
||||
&& order!.status != Constants.STATUS_CANCELLED
|
||||
&& order!.status != Constants.STATUS_COMPLETE ?
|
||||
TextButton(
|
||||
child: Text(
|
||||
S.of(context).pay_now,
|
||||
),
|
||||
onPressed: () {
|
||||
Routes.router.navigateTo(context, '/paynow/${order.id}');
|
||||
Routes.router.navigateTo(context, '/paynow/${order!.id}');
|
||||
},
|
||||
) : TextButton(
|
||||
child: Text(
|
||||
S.of(context).order_again,
|
||||
),
|
||||
onPressed: () {
|
||||
Utils.orderAgain(context, order.cartInfo);
|
||||
Utils.orderAgain(context, order!.cartInfo!);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -1059,13 +1059,13 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
order = Order.fromJson(data);
|
||||
|
||||
if (!kIsWeb) {
|
||||
if (order.shippingMethod == 'store-delivery' && order.status != Constants.STATUS_COMPLETE && order.status != Constants.STATUS_CANCELLED) {
|
||||
storeLatLng = LatLng(double.parse(order.businessInfo.address.lat),
|
||||
double.parse(order.businessInfo.address.lng));
|
||||
customerLatLng = LatLng(double.parse(order.shippingAddress.lat),
|
||||
double.parse(order.shippingAddress.lng));
|
||||
if (order!.shippingMethod == 'store-delivery' && order!.status != Constants.STATUS_COMPLETE && order!.status != Constants.STATUS_CANCELLED) {
|
||||
storeLatLng = LatLng(double.parse(order!.businessInfo?.address.lat ?? '0'),
|
||||
double.parse(order!.businessInfo?.address.lng ?? '0'));
|
||||
customerLatLng = LatLng(double.parse(order!.shippingAddress?.lat ?? '0'),
|
||||
double.parse(order!.shippingAddress?.lng ?? '0'));
|
||||
deliveryLatLng =
|
||||
LatLng(order.shipperPosition.lat, order.shipperPosition.lng);
|
||||
LatLng(order!.shipperPosition.lat, order!.shipperPosition.lng);
|
||||
|
||||
_polyLine.clear();
|
||||
_polyLine.add(
|
||||
@@ -1078,8 +1078,8 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
],
|
||||
width: 3,
|
||||
points: [
|
||||
order.shipperPosition.lat != 0.0 ? deliveryLatLng : storeLatLng,
|
||||
customerLatLng,
|
||||
order!.shipperPosition.lat != 0.0 ? deliveryLatLng! : storeLatLng!,
|
||||
customerLatLng!,
|
||||
]
|
||||
)
|
||||
);
|
||||
@@ -1087,38 +1087,38 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
_markers.clear();
|
||||
_markers.add(Marker(
|
||||
markerId: MarkerId('shop_position'),
|
||||
position: storeLatLng,
|
||||
position: storeLatLng!,
|
||||
infoWindow: InfoWindow(
|
||||
title: S
|
||||
.of(context)
|
||||
.store,
|
||||
snippet: '',
|
||||
),
|
||||
icon: shopIcon,
|
||||
icon: shopIcon!,
|
||||
));
|
||||
_markers.add(Marker(
|
||||
markerId: MarkerId('customer_position'),
|
||||
position: customerLatLng,
|
||||
position: customerLatLng!,
|
||||
infoWindow: InfoWindow(
|
||||
title: S
|
||||
.of(context)
|
||||
.customer,
|
||||
snippet: order.shippingAddress.addressLine1,
|
||||
snippet: order!.shippingAddress!.addressLine1,
|
||||
),
|
||||
icon: homeIcon,
|
||||
icon: homeIcon!,
|
||||
));
|
||||
if (order.shipperPosition.lat != 0.0 &&
|
||||
order.shipperPosition.lng != 0.0) {
|
||||
if (order!.shipperPosition.lat != 0.0 &&
|
||||
order!.shipperPosition.lng != 0.0) {
|
||||
_markers.add(Marker(
|
||||
markerId: MarkerId('shipper_position'),
|
||||
position: deliveryLatLng,
|
||||
position: deliveryLatLng!,
|
||||
infoWindow: InfoWindow(
|
||||
title: S
|
||||
.of(context)
|
||||
.delivery_guy,
|
||||
snippet: '',
|
||||
),
|
||||
icon: deliveryIcon,
|
||||
icon: deliveryIcon!,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1145,7 +1145,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
|
||||
S.of(context).no,
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
foregroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
@@ -18,8 +18,7 @@ import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'MobileBottomNav.dart';
|
||||
|
||||
class MobileOrders extends StatefulWidget {
|
||||
final Key key;
|
||||
const MobileOrders({this.key});
|
||||
const MobileOrders({Key? key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -31,7 +30,7 @@ class MobileOrders extends StatefulWidget {
|
||||
class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderStateMixin {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
List<Order> orders = [];
|
||||
List<Order>? orders = [];
|
||||
|
||||
int _page = 1;
|
||||
int _pageCount = 1;
|
||||
@@ -44,7 +43,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
void _onRefresh() {
|
||||
_page = 1;
|
||||
if (orders != null) {
|
||||
orders.clear();
|
||||
orders?.clear();
|
||||
} else {
|
||||
orders = [];
|
||||
}
|
||||
@@ -79,7 +78,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
enablePullUp: true,
|
||||
header: WaterDropHeader(),
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode){
|
||||
builder: (BuildContext context, LoadStatus? mode){
|
||||
Widget footer;
|
||||
if(mode == LoadStatus.idle) {
|
||||
footer = Text(S.of(context).pull_up_to_load_more);
|
||||
@@ -127,11 +126,11 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
Widget _buildBody() {
|
||||
|
||||
return ListView.builder(
|
||||
itemCount: orders != null && orders.length > 0 ? orders.length : 1,
|
||||
itemCount: orders != null && orders!.length > 0 ? orders!.length : 1,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
Order order;
|
||||
if (orders != null && orders.length > 0) {
|
||||
order = orders[position];
|
||||
Order? order;
|
||||
if (orders != null && orders!.length > 0) {
|
||||
order = orders![position];
|
||||
}
|
||||
if (order == null) {
|
||||
return Container(
|
||||
@@ -152,7 +151,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
row.children.add(Expanded(
|
||||
child: Container(
|
||||
child: Text(
|
||||
order.cartInfo.productList[0].name,
|
||||
'${order.cartInfo?.productList?[0].name}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
),
|
||||
@@ -161,10 +160,10 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
),
|
||||
));
|
||||
if (order.cartInfo.productList.length > 1) {
|
||||
if (order.cartInfo!.productList!.length > 1) {
|
||||
row.children.add(Container(
|
||||
child: Text(
|
||||
S.of(context).and_more_item_token(Utils.getProductLineInOrder(order.cartInfo)),
|
||||
S.of(context).and_more_item_token(Utils.getProductLineInOrder(order.cartInfo!)),
|
||||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: Colors.black26,
|
||||
@@ -193,7 +192,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) => OrderDetail(order.id, fromOrders: true,),
|
||||
builder: (BuildContext context) => OrderDetail(order!.id, fromOrders: true,),
|
||||
));
|
||||
},
|
||||
),
|
||||
@@ -208,7 +207,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
S.of(context).comment,
|
||||
),
|
||||
onPressed: () {
|
||||
Routes.router.navigateTo(context, '/new-comment/${order.id}');
|
||||
Routes.router.navigateTo(context, '/new-comment/${order!.id}');
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -234,10 +233,10 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.redAccent,
|
||||
backgroundColor: Colors.redAccent,
|
||||
),
|
||||
onPressed: () {
|
||||
Routes.router.navigateTo(context, '/paynow/${order.id}');
|
||||
Routes.router.navigateTo(context, '/paynow/${order!.id}');
|
||||
},
|
||||
));
|
||||
} else {
|
||||
@@ -249,10 +248,10 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Utils.orderAgain(context, order.cartInfo);
|
||||
Utils.orderAgain(context, order!.cartInfo!);
|
||||
},
|
||||
));
|
||||
}
|
||||
@@ -266,10 +265,10 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).primaryColor,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Utils.orderAgain(context, order.cartInfo);
|
||||
Utils.orderAgain(context, order!.cartInfo!);
|
||||
},
|
||||
));
|
||||
}
|
||||
@@ -291,7 +290,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Util.showImage('${order.cartInfo.businessInfo.picUrl}',
|
||||
child: Util.showImage('${order.cartInfo!.businessInfo?.picUrl}',
|
||||
width: 32.0,
|
||||
height: 32.0,
|
||||
fit: BoxFit.fill,
|
||||
@@ -307,7 +306,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Text(
|
||||
'${order.cartInfo.businessInfo.name}',
|
||||
'${order.cartInfo!.businessInfo?.name}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
),
|
||||
@@ -329,7 +328,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) => OrderDetail(order.id, fromOrders: true,),
|
||||
builder: (BuildContext context) => OrderDetail(order!.id, fromOrders: true,),
|
||||
));
|
||||
},
|
||||
),
|
||||
@@ -375,7 +374,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) => OrderDetail(order.id, fromOrders: true,),
|
||||
builder: (BuildContext context) => OrderDetail(order!.id, fromOrders: true,),
|
||||
));
|
||||
},
|
||||
),
|
||||
@@ -438,7 +437,7 @@ class MobileOrdersState extends State<MobileOrders> with SingleTickerProviderSta
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
orders.addAll((data['items'] as List).map((e) => Order.fromJson(e)).toList());
|
||||
orders!.addAll((data['items'] as List).map((e) => Order.fromJson(e)).toList());
|
||||
});
|
||||
}
|
||||
}).catchError((error) {
|
||||
|
||||
@@ -20,9 +20,8 @@ import '../../utils/utils.dart';
|
||||
import '../../widgets/general/payment_verification_code_dialog.dart';
|
||||
|
||||
class MobilePayNow extends StatefulWidget {
|
||||
final Key key;
|
||||
final int orderId;
|
||||
const MobilePayNow(this.orderId, {this.key});
|
||||
const MobilePayNow(this.orderId, {Key? key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -32,11 +31,11 @@ class MobilePayNow extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MobilePayNowState extends State<MobilePayNow> {
|
||||
Order order;
|
||||
List<PaymentPlatform> paymentPlatforms;
|
||||
User _user;
|
||||
Order? order;
|
||||
List<PaymentPlatform>? paymentPlatforms;
|
||||
User? _user;
|
||||
|
||||
bool nativePay;
|
||||
bool nativePay = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -56,7 +55,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
BuildContext mainContext = context;
|
||||
|
||||
ListView listView = ListView.builder(
|
||||
itemCount: nativePay ? paymentPlatforms.length + 3 : paymentPlatforms.length + 2,
|
||||
itemCount: nativePay ? paymentPlatforms!.length + 3 : paymentPlatforms!.length + 2,
|
||||
itemBuilder: (BuildContext context, int position) {
|
||||
if (position == 0) {
|
||||
return Column(
|
||||
@@ -77,7 +76,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'\$${order.totalPrice.toStringAsFixed(2)}',
|
||||
'\$${order!.totalPrice.toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 24.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -94,7 +93,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
)
|
||||
),
|
||||
),
|
||||
store.state.deviceId != null && store.state.deviceId.isNotEmpty || store.state.tableNumber != null && store.state.tableNumber.isNotEmpty ?
|
||||
store.state.deviceId != null && store.state.deviceId!.isNotEmpty || store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty ?
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0, left: 16.0, right: 16.0),
|
||||
@@ -157,8 +156,8 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
}
|
||||
PaymentPlatform paymentPlatform;
|
||||
if (position == 1) {
|
||||
if (_user.stripePaymentMethods.length > 0) {
|
||||
paymentPlatform = paymentPlatforms[position - 1];
|
||||
if (_user!.stripePaymentMethods.length > 0) {
|
||||
paymentPlatform = paymentPlatforms![position - 1];
|
||||
Column column = Column(
|
||||
children: <Widget>[],
|
||||
);
|
||||
@@ -180,7 +179,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
),
|
||||
),
|
||||
);
|
||||
for (StripePaymentMethod stripePaymentMethod in _user.stripePaymentMethods) {
|
||||
for (StripePaymentMethod stripePaymentMethod in _user!.stripePaymentMethods) {
|
||||
column.children.add(
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
@@ -249,8 +248,8 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
showDialog(
|
||||
context: mainContext,
|
||||
builder: (BuildContext context) {
|
||||
return PaymentVerificationCodeDialog(_user, () {
|
||||
Util.goPayment(context, order, paymentPlatform,
|
||||
return PaymentVerificationCodeDialog(_user!, () {
|
||||
Util.goPayment(context, order!, paymentPlatform,
|
||||
stripePaymentMethod: stripePaymentMethod);
|
||||
}, () {
|
||||
|
||||
@@ -281,10 +280,10 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
}
|
||||
}
|
||||
if (position == 2 && nativePay) {
|
||||
paymentPlatform = paymentPlatforms[position - 2];
|
||||
return Util().getNativePay(mainContext, order, paymentPlatform);
|
||||
paymentPlatform = paymentPlatforms![position - 2];
|
||||
return Util().getNativePay(mainContext, order!, paymentPlatform);
|
||||
}
|
||||
paymentPlatform = nativePay ? paymentPlatforms[position - 3] : paymentPlatforms[position - 2];
|
||||
paymentPlatform = nativePay ? paymentPlatforms![position - 3] : paymentPlatforms![position - 2];
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0, bottom: 16.0),
|
||||
@@ -293,7 +292,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(right: 10.0),
|
||||
child: Util.showImage(paymentPlatform.icon,
|
||||
child: Util.showImage(paymentPlatform.icon ?? '',
|
||||
errorWidget: (context, url, error) => Icon(Icons.broken_image, size: 50.0, color: Colors.transparent,),
|
||||
fit: BoxFit.cover,
|
||||
width: 50.0,
|
||||
@@ -302,7 +301,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
S.of(context).pay_with_token(PaymentPlatform.getPaymentPlatformName(context, paymentPlatform.code)),
|
||||
S.of(context).pay_with_token(PaymentPlatform.getPaymentPlatformName(context, paymentPlatform.code ?? '')),
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -325,7 +324,7 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Util.goPayment(context, order, paymentPlatform);
|
||||
Util.goPayment(context, order!, paymentPlatform);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -354,10 +353,10 @@ class MobilePayNowState extends State<MobilePayNow> {
|
||||
).then((data) {
|
||||
paymentPlatforms = (data['payment_platforms'] as List).map((e) =>
|
||||
PaymentPlatform.fromJson(e)).toList();
|
||||
PaymentPlatform pp = paymentPlatforms[0];
|
||||
PaymentPlatform pp = paymentPlatforms![0];
|
||||
if (Constants.ENABLE_NATIVE_PAY && pp.publishableKey != null
|
||||
&& pp.publishableKey.isNotEmpty && pp.merchantId != null
|
||||
&& pp.merchantId.isNotEmpty) {
|
||||
&& pp.publishableKey!.isNotEmpty && pp.merchantId != null
|
||||
&& pp.merchantId!.isNotEmpty) {
|
||||
nativePay = true;
|
||||
} else {
|
||||
nativePay = false;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stripe_sdk/stripe_sdk.dart';
|
||||
import 'package:stripe_sdk/stripe_sdk_ui.dart';
|
||||
import '../../vendor/stripe_sdk/lib/stripe_sdk_ui.dart';
|
||||
import '../../utils/mini_stripe_api.dart';
|
||||
|
||||
import '../../constants.dart';
|
||||
import '../../events/eventbus.dart';
|
||||
@@ -18,11 +18,10 @@ import '../../utils/utils.dart';
|
||||
|
||||
|
||||
class MobileStripePayWeb extends StatefulWidget {
|
||||
final Key key;
|
||||
final Order order;
|
||||
final PaymentPlatform paymentPlatform;
|
||||
final StripePaymentMethod stripePaymentMethod;
|
||||
const MobileStripePayWeb(this.order, this.paymentPlatform, {this.key, this.stripePaymentMethod});
|
||||
final StripePaymentMethod? stripePaymentMethod;
|
||||
const MobileStripePayWeb(this.order, this.paymentPlatform, {Key? key, this.stripePaymentMethod});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -37,9 +36,9 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
final formKey = GlobalKey<FormState>();
|
||||
final card = StripeCard();
|
||||
|
||||
CardForm form;
|
||||
CardForm? form;
|
||||
|
||||
bool isSubmitting;
|
||||
bool isSubmitting = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -55,7 +54,7 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
if (widget.stripePaymentMethod == null) {
|
||||
form = CardForm(card: card, formKey: formKey, displayPostalCode: false,);
|
||||
body = ListView(
|
||||
children: <Widget>[form,],
|
||||
children: <Widget>[form!,],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,8 +79,8 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
IconButton(
|
||||
icon: Icon(Icons.check),
|
||||
onPressed: widget.stripePaymentMethod == null ? () {
|
||||
if (formKey.currentState.validate()) {
|
||||
formKey.currentState.save();
|
||||
if (formKey.currentState != null && formKey.currentState!.validate()) {
|
||||
formKey.currentState!.save();
|
||||
_paymentRequestWithCard(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -102,7 +101,7 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
isSubmitting = false;
|
||||
StripeApi.init(widget.paymentPlatform.publishableKey);
|
||||
MiniStripeApi.init(widget.paymentPlatform.publishableKey!);
|
||||
}
|
||||
|
||||
SnackBar messageSnackBar(BuildContext context, String message) {
|
||||
@@ -131,12 +130,12 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
}
|
||||
|
||||
_paymentWithPaymentMethod(BuildContext context) async {
|
||||
Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod.customerId,
|
||||
widget.stripePaymentMethod.paymentMethodId,
|
||||
widget.stripePaymentMethod.paymentMethodType, (response) async {
|
||||
Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod?.customerId,
|
||||
widget.stripePaymentMethod!.paymentMethodId,
|
||||
widget.stripePaymentMethod!.paymentMethodType, (response) async {
|
||||
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
await StripeApi.instance.confirmPaymentIntent(
|
||||
await MiniStripeApi.instance.confirmPaymentIntent(
|
||||
response.data[Constants.STRIPE_CLIENT_SECRET],
|
||||
data: {
|
||||
'payment_method': response.data['payment_method'],
|
||||
@@ -144,7 +143,7 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
).then((result2) {
|
||||
if (result2['status'] == Constants.STRIPE_STATUS_SUCCEDED) {
|
||||
Utils.stripeChargedSuccess(widget.order,
|
||||
widget.stripePaymentMethod.paymentMethodId,
|
||||
widget.stripePaymentMethod!.paymentMethodId,
|
||||
result2['id'], (response) {
|
||||
if (isSubmitting) {
|
||||
Navigator.of(context).pop();
|
||||
@@ -169,11 +168,11 @@ class MobileStripePayWebState extends State<MobileStripePayWeb> {
|
||||
_paymentRequestWithCard(BuildContext context) async {
|
||||
isSubmitting = true;
|
||||
Utils.showSubmitDialog(context);
|
||||
await StripeApi.instance.createPaymentMethodFromCard(card)
|
||||
await MiniStripeApi.instance.createPaymentMethodFromCard(card)
|
||||
.then((result) {
|
||||
Utils.stripePaymentIntent(widget.order, null, result['id'], result['type'], (response) async {
|
||||
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
|
||||
await StripeApi.instance.confirmPaymentIntent(
|
||||
await MiniStripeApi.instance.confirmPaymentIntent(
|
||||
response.data[Constants.STRIPE_CLIENT_SECRET],
|
||||
data: {
|
||||
'payment_method': response.data['payment_method'],
|
||||
|
||||
Reference in New Issue
Block a user