This commit is contained in:
2026-07-12 04:33:48 +08:00
parent f8a90ad305
commit e7ce0f7bae
151 changed files with 2765 additions and 2947 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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,

View File

@@ -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,
),

View File

@@ -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() {

View File

@@ -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,

View File

@@ -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);

View File

@@ -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'],

View File

@@ -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());
}

View File

@@ -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(

View File

@@ -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]) {

View File

@@ -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);

View File

@@ -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]) {

View File

@@ -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]) {

View File

@@ -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() {

View File

@@ -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});
}

View File

@@ -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,

View File

@@ -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!,
);
}
}

View File

@@ -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
),

View File

@@ -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),
);
}

View File

@@ -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),
);
}

View File

@@ -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),
);
}

View File

@@ -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),
);
}

View File

@@ -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,),
);
}

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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),
),
),
),

View File

@@ -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;
}
}

View File

@@ -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(

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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';
}

View File

@@ -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'],
),

View File

@@ -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!));
}
}

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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(

View File

@@ -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(),
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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');
}

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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);
},

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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,

View File

@@ -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,
),

View File

@@ -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,
),

View File

@@ -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()}',

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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,

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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}',

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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);
},

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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'],