You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
802 lines
24 KiB
Dart
802 lines
24 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:mc_common_app/classes/app_state.dart';
|
|
import 'package:mc_common_app/config/routes.dart';
|
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
|
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
|
import 'package:mc_common_app/utils/date_helper.dart';
|
|
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
|
|
import 'package:mc_common_app/utils/navigator.dart';
|
|
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
|
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
|
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
|
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
import 'package:mc_common_app/classes/consts.dart';
|
|
import 'package:mc_common_app/exceptions/api_exception.dart';
|
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
|
import 'package:mc_common_app/theme/colors.dart';
|
|
import 'package:mc_common_app/utils/enums.dart';
|
|
import 'package:mc_common_app/widgets/loading_dialog.dart';
|
|
import 'package:share_plus/share_plus.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
import 'package:url_launcher/url_launcher_string.dart';
|
|
|
|
class Utils {
|
|
static bool _isLoadingVisible = false;
|
|
|
|
static bool get isLoading => _isLoadingVisible;
|
|
|
|
static void showToast(String message) {
|
|
Fluttertoast.showToast(
|
|
msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 2, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0);
|
|
}
|
|
|
|
static Future<void> openNumberViaCaller({required String phoneNumber}) async {
|
|
Uri phoneLaunchUrl = Uri.parse('tel:$phoneNumber');
|
|
|
|
if (await canLaunchUrl(phoneLaunchUrl)) {
|
|
try {
|
|
await launchUrl(phoneLaunchUrl);
|
|
} catch (e) {
|
|
await launchUrl(phoneLaunchUrl);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Future<void> openEmailViaEmailApp({required String emailAddress}) async {
|
|
Uri emailLaunchUrl = Uri.parse('mailto:$emailAddress');
|
|
|
|
if (await canLaunchUrl(emailLaunchUrl)) {
|
|
try {
|
|
await launchUrl(emailLaunchUrl);
|
|
} catch (e) {
|
|
await launchUrl(emailLaunchUrl);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Future<void> openNumberViaWhatsApp({required String phoneNumber}) async {
|
|
final url = 'https://wa.me/$phoneNumber?text=';
|
|
|
|
await launchUrlString(url, mode: LaunchMode.externalApplication);
|
|
}
|
|
|
|
static Future<String> pickDateFromDatePicker(BuildContext context, {DateTime? initial, DateTime? firstDate, DateTime? lastDate}) async {
|
|
DateTime? pickedDate = await showDatePicker(
|
|
context: context,
|
|
initialDate: initial ?? DateTime.now(), //get today's date
|
|
firstDate: firstDate ?? DateTime.now(), //DateTime.now() - not to allow to choose before today.
|
|
lastDate: lastDate ?? DateTime(2101));
|
|
|
|
if (pickedDate == null) {
|
|
return "";
|
|
}
|
|
|
|
String formattedDate = DateHelper.formatAsYearMonthDay(pickedDate); // format date in required form here we use yyyy-MM-dd that means time is removed
|
|
return formattedDate;
|
|
}
|
|
|
|
static Future<String> pickTime(BuildContext context, {TimeOfDay? initialTime}) async {
|
|
TimeOfDay? timeOfDay = await showTimePicker(
|
|
context: context,
|
|
initialTime: initialTime ?? TimeOfDay.now(),
|
|
);
|
|
|
|
if (timeOfDay == null) {
|
|
return "";
|
|
}
|
|
|
|
return ("${timeOfDay.hour.toString().length == 1 ? "0" : ""}${timeOfDay.hour}:${timeOfDay.minute.toString().length == 1 ? "0" : ""}${timeOfDay.minute}").toString();
|
|
}
|
|
|
|
static dynamic getNotNullValue(List<dynamic> list, int index) {
|
|
try {
|
|
return list[index];
|
|
} catch (ex) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static int stringToHex(String colorCode) {
|
|
try {
|
|
return int.parse(colorCode.replaceAll("#", "0xff"));
|
|
} catch (ex) {
|
|
return (0xff000000);
|
|
}
|
|
}
|
|
|
|
static void showLoading(BuildContext context) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
_isLoadingVisible = true;
|
|
showDialog(
|
|
context: context,
|
|
barrierColor: Colors.black.withOpacity(0.5),
|
|
builder: (BuildContext context) => LoadingDialog(),
|
|
).then((value) {
|
|
_isLoadingVisible = false;
|
|
});
|
|
});
|
|
}
|
|
|
|
static void hideLoading(BuildContext context) {
|
|
if (_isLoadingVisible) {
|
|
_isLoadingVisible = false;
|
|
Navigator.of(context).pop();
|
|
}
|
|
_isLoadingVisible = false;
|
|
}
|
|
|
|
static void handleException(dynamic exception, Function(String)? onErrorMessage) {
|
|
String errorMessage;
|
|
if (exception is APIException) {
|
|
if (exception.message == APIException.UNAUTHORIZED) {
|
|
return;
|
|
} else {
|
|
errorMessage = exception.error?.errorMessage ?? exception.message;
|
|
}
|
|
} else {
|
|
errorMessage = APIException.UNKNOWN;
|
|
}
|
|
if (onErrorMessage != null) {
|
|
onErrorMessage(errorMessage);
|
|
} else {
|
|
showToast(errorMessage);
|
|
}
|
|
}
|
|
|
|
static Color getColorFromHex(String hexColor) {
|
|
hexColor = hexColor.toUpperCase().replaceAll('#', '');
|
|
|
|
if (hexColor.length == 6) {
|
|
hexColor = 'FF$hexColor';
|
|
}
|
|
|
|
return Color(int.parse(hexColor, radix: 16));
|
|
}
|
|
|
|
static Widget spacerVertical(double v) {
|
|
return SizedBox(
|
|
height: v,
|
|
width: double.infinity,
|
|
);
|
|
}
|
|
|
|
static String convertFileToBase64(File file) {
|
|
List<int> imageBytes = file.readAsBytesSync();
|
|
return base64Encode(imageBytes);
|
|
}
|
|
|
|
static Future delay(int millis) async {
|
|
return await Future.delayed(Duration(milliseconds: millis));
|
|
}
|
|
|
|
static inkWellCorner({double? r}) {
|
|
return RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(r ?? 4),
|
|
);
|
|
}
|
|
|
|
static Widget spacerHorizontal(double v) {
|
|
return SizedBox(
|
|
height: v,
|
|
width: v,
|
|
);
|
|
}
|
|
|
|
static Widget mDivider(Color color, {double? h}) {
|
|
return Container(
|
|
width: double.infinity,
|
|
height: h ?? 1,
|
|
color: color,
|
|
);
|
|
}
|
|
|
|
static Widget mDivider3({double? h}) {
|
|
return Container(
|
|
width: double.infinity,
|
|
height: h ?? 1,
|
|
color: borderLightColor!.withOpacity(0.7),
|
|
);
|
|
}
|
|
|
|
static Widget mDivider2(Color color, double w) {
|
|
return Container(
|
|
width: w,
|
|
height: 1,
|
|
color: color,
|
|
);
|
|
}
|
|
|
|
static Color getChipColorByAdStatus(AdPostStatus adPostStatus) {
|
|
switch (adPostStatus) {
|
|
case AdPostStatus.pendingForReview:
|
|
return MyColors.adPendingStatusColor;
|
|
|
|
case AdPostStatus.pendingForPayment:
|
|
return MyColors.submittedColor;
|
|
|
|
case AdPostStatus.rejected:
|
|
return MyColors.adCancelledStatusColor;
|
|
|
|
case AdPostStatus.cancelled:
|
|
return MyColors.adCancelledStatusColor;
|
|
|
|
case AdPostStatus.pendingForPost:
|
|
case AdPostStatus.pendingForActive:
|
|
return MyColors.inProgressColor;
|
|
|
|
case AdPostStatus.active:
|
|
return MyColors.greenColor;
|
|
|
|
case AdPostStatus.expired:
|
|
return MyColors.adCancelledStatusColor;
|
|
|
|
case AdPostStatus.sold:
|
|
return MyColors.adSoldStatusColor;
|
|
|
|
case AdPostStatus.reserved:
|
|
return MyColors.primaryColor;
|
|
|
|
case AdPostStatus.deActive:
|
|
return MyColors.textColor;
|
|
|
|
case AdPostStatus.buyingService:
|
|
case AdPostStatus.reserveCancel:
|
|
case AdPostStatus.allAds:
|
|
return MyColors.greenColor;
|
|
}
|
|
}
|
|
|
|
static Color getChipColorByRequestStatus(RequestStatusEnum requestStatus) {
|
|
switch (requestStatus) {
|
|
case RequestStatusEnum.pending:
|
|
return MyColors.pendingColor;
|
|
case RequestStatusEnum.submitted:
|
|
return MyColors.submittedColor;
|
|
case RequestStatusEnum.inProgress:
|
|
return MyColors.inProgressColor;
|
|
case RequestStatusEnum.completed:
|
|
return MyColors.completedColor;
|
|
case RequestStatusEnum.cancelled:
|
|
return MyColors.cancelledColor;
|
|
case RequestStatusEnum.paid:
|
|
return MyColors.paidColor;
|
|
case RequestStatusEnum.expired:
|
|
return MyColors.expiredColor;
|
|
case RequestStatusEnum.shipping:
|
|
return MyColors.shippingColor;
|
|
case RequestStatusEnum.delivery:
|
|
return MyColors.deliveryColor;
|
|
case RequestStatusEnum.selfPickup:
|
|
return MyColors.selfPickupColor;
|
|
}
|
|
}
|
|
|
|
static Color getChipColorByRequestOfferStatusEnum(RequestOfferStatusEnum requestOfferStatusEnum) {
|
|
switch (requestOfferStatusEnum) {
|
|
case RequestOfferStatusEnum.offer:
|
|
return MyColors.pendingColor;
|
|
|
|
case RequestOfferStatusEnum.negotiate:
|
|
return MyColors.submittedColor;
|
|
|
|
case RequestOfferStatusEnum.accepted:
|
|
return MyColors.completedColor;
|
|
case RequestOfferStatusEnum.rejected:
|
|
return MyColors.cancelledColor;
|
|
|
|
case RequestOfferStatusEnum.cancel:
|
|
return MyColors.cancelledColor;
|
|
}
|
|
}
|
|
|
|
static String getNameByRequestOfferStatusEnum(RequestOfferStatusEnum requestOfferStatusEnum) {
|
|
switch (requestOfferStatusEnum) {
|
|
case RequestOfferStatusEnum.offer:
|
|
return "Offer";
|
|
case RequestOfferStatusEnum.negotiate:
|
|
return "Negotiate";
|
|
case RequestOfferStatusEnum.accepted:
|
|
return "Accepted";
|
|
case RequestOfferStatusEnum.rejected:
|
|
return "Rejected";
|
|
case RequestOfferStatusEnum.cancel:
|
|
return "Cancelled";
|
|
}
|
|
}
|
|
|
|
static String getNameByShippingRequestStatusEnum(ShippingRequestStatusEnum shippingRequestStatusEnum) {
|
|
switch (shippingRequestStatusEnum) {
|
|
case ShippingRequestStatusEnum.allRequests:
|
|
return "All Requests";
|
|
|
|
case ShippingRequestStatusEnum.initiated:
|
|
return "Initiated";
|
|
|
|
case ShippingRequestStatusEnum.inTransit:
|
|
return "In Transit";
|
|
|
|
case ShippingRequestStatusEnum.outForDelivery:
|
|
return "Out For Delivery";
|
|
|
|
case ShippingRequestStatusEnum.delivered:
|
|
return "Delivered";
|
|
|
|
case ShippingRequestStatusEnum.pending:
|
|
return "Pending";
|
|
}
|
|
}
|
|
|
|
static String getNameBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
|
|
switch (selfPickupRequestStatusEnum) {
|
|
case SelfPickupRequestStatusEnum.allRequests:
|
|
return "All Requests";
|
|
|
|
case SelfPickupRequestStatusEnum.pending:
|
|
return "Pending";
|
|
|
|
case SelfPickupRequestStatusEnum.preparingToCollect:
|
|
return "Preparing To Collect";
|
|
|
|
case SelfPickupRequestStatusEnum.readyToCollect:
|
|
return "Ready To Collect";
|
|
|
|
case SelfPickupRequestStatusEnum.collected:
|
|
return "Collected";
|
|
}
|
|
}
|
|
|
|
static Color getChipColorByShippingRequestStatusEnum(ShippingRequestStatusEnum shippingRequestStatusEnum) {
|
|
switch (shippingRequestStatusEnum) {
|
|
case ShippingRequestStatusEnum.allRequests:
|
|
return MyColors.submittedColor;
|
|
|
|
case ShippingRequestStatusEnum.initiated:
|
|
return MyColors.submittedColor;
|
|
|
|
case ShippingRequestStatusEnum.inTransit:
|
|
return MyColors.shippingColor;
|
|
|
|
case ShippingRequestStatusEnum.outForDelivery:
|
|
return MyColors.deliveryColor;
|
|
|
|
case ShippingRequestStatusEnum.delivered:
|
|
return MyColors.greenColor;
|
|
|
|
case ShippingRequestStatusEnum.pending:
|
|
return MyColors.pendingColor;
|
|
}
|
|
}
|
|
|
|
static Color getChipColorBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
|
|
switch (selfPickupRequestStatusEnum) {
|
|
case SelfPickupRequestStatusEnum.allRequests:
|
|
return MyColors.submittedColor;
|
|
|
|
case SelfPickupRequestStatusEnum.pending:
|
|
return MyColors.pendingColor;
|
|
|
|
case SelfPickupRequestStatusEnum.preparingToCollect:
|
|
return MyColors.submittedColor;
|
|
|
|
case SelfPickupRequestStatusEnum.readyToCollect:
|
|
return MyColors.shippingColor;
|
|
|
|
case SelfPickupRequestStatusEnum.collected:
|
|
return MyColors.deliveryColor;
|
|
}
|
|
}
|
|
|
|
static Color getChipColorByBranchStatus(BranchStatusEnum branchStatusEnum) {
|
|
switch (branchStatusEnum) {
|
|
case BranchStatusEnum.pending:
|
|
return MyColors.adPendingStatusColor;
|
|
|
|
case BranchStatusEnum.review:
|
|
return MyColors.adPendingStatusColor;
|
|
|
|
case BranchStatusEnum.rejected:
|
|
return MyColors.adCancelledStatusColor;
|
|
|
|
case BranchStatusEnum.deactivated:
|
|
return MyColors.adCancelledStatusColor;
|
|
|
|
case BranchStatusEnum.blocked:
|
|
return MyColors.expiredColor;
|
|
|
|
case BranchStatusEnum.approvedOrActive:
|
|
return MyColors.greenColor;
|
|
}
|
|
}
|
|
|
|
static String getChipStatusTextByBranchStatus(BranchStatusEnum branchStatusEnum) {
|
|
switch (branchStatusEnum) {
|
|
case BranchStatusEnum.pending:
|
|
return "Pending Approval";
|
|
|
|
case BranchStatusEnum.review:
|
|
return "In Review";
|
|
|
|
case BranchStatusEnum.rejected:
|
|
return "Rejected";
|
|
|
|
case BranchStatusEnum.deactivated:
|
|
return "Deactivated";
|
|
|
|
case BranchStatusEnum.blocked:
|
|
return "Blocked";
|
|
|
|
case BranchStatusEnum.approvedOrActive:
|
|
return "Active";
|
|
}
|
|
}
|
|
|
|
static statusContainerChip({
|
|
required String text,
|
|
EdgeInsetsGeometry padding = const EdgeInsets.symmetric(vertical: 3, horizontal: 6),
|
|
Color chipColor = MyColors.greenColor,
|
|
Color textColor = MyColors.white,
|
|
}) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: chipColor,
|
|
),
|
|
padding: padding,
|
|
child: text.toText(fontSize: 10, color: textColor, letterSpacing: -0.50));
|
|
}
|
|
|
|
static InputDecoration txtField(String label) {
|
|
return InputDecoration(
|
|
border: InputBorder.none,
|
|
focusedBorder: InputBorder.none,
|
|
enabledBorder: InputBorder.none,
|
|
errorBorder: InputBorder.none,
|
|
hintText: label,
|
|
hintStyle: const TextStyle(color: Colors.grey),
|
|
disabledBorder: InputBorder.none,
|
|
isDense: false,
|
|
contentPadding: const EdgeInsets.only(left: 15, right: 15),
|
|
);
|
|
}
|
|
|
|
static Widget mFlex(int f) {
|
|
return Flexible(
|
|
flex: f,
|
|
child: const SizedBox(
|
|
width: double.infinity,
|
|
height: double.infinity,
|
|
),
|
|
);
|
|
}
|
|
|
|
static Widget mExp(int f) {
|
|
return Expanded(
|
|
flex: f,
|
|
child: Container(
|
|
width: double.infinity,
|
|
),
|
|
);
|
|
}
|
|
|
|
static String checkFileExt(String path) {
|
|
String ex = p.extension(path);
|
|
var parts = ex.split('.');
|
|
return parts[1]; // '.dart'
|
|
}
|
|
|
|
static spacer() {
|
|
return const SizedBox(
|
|
height: 8,
|
|
);
|
|
}
|
|
|
|
static cardRadius(double radius) {
|
|
return RoundedRectangleBorder(
|
|
side: const BorderSide(color: Colors.transparent, width: 1),
|
|
borderRadius: BorderRadius.circular(radius),
|
|
);
|
|
}
|
|
|
|
static cardRadiusWithoutBorder(double radius) {
|
|
return RoundedRectangleBorder(
|
|
side: const BorderSide(color: Colors.transparent, width: 1),
|
|
borderRadius: BorderRadius.circular(radius),
|
|
);
|
|
}
|
|
|
|
static Image imageFromBase64String(String base64String) {
|
|
return Image.memory(base64Decode(base64String));
|
|
}
|
|
|
|
static Uint8List dataFromBase64String(String base64String) {
|
|
return base64Decode(base64String);
|
|
}
|
|
|
|
static String base64String(Uint8List data) {
|
|
return base64Encode(data);
|
|
}
|
|
|
|
static Widget overLayWidget({double? width, double? height, List<Color>? color}) {
|
|
return Container(
|
|
width: width ?? double.infinity,
|
|
height: height ?? 60,
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: color ??
|
|
[
|
|
Colors.black.withOpacity(0.2),
|
|
Colors.black.withOpacity(0.1),
|
|
Colors.black.withOpacity(0.004),
|
|
],
|
|
begin: Alignment.topCenter,
|
|
end: Alignment.bottomCenter,
|
|
tileMode: TileMode.clamp,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
static Decoration containerRadius(Color color, double r) {
|
|
return BoxDecoration(
|
|
color: color,
|
|
borderRadius: BorderRadius.all(Radius.circular(r)),
|
|
);
|
|
}
|
|
|
|
static Decoration containerRadiusTop({Color? color, double? r}) {
|
|
return BoxDecoration(
|
|
color: color ?? Colors.white,
|
|
borderRadius: BorderRadius.only(topRight: Radius.circular(r ?? 12), topLeft: Radius.circular(r ?? 12)),
|
|
);
|
|
}
|
|
|
|
static Decoration containerRadiusBorder(Color color, double r) {
|
|
return BoxDecoration(
|
|
color: Colors.transparent,
|
|
border: Border.all(color: color, width: 1),
|
|
borderRadius: BorderRadius.all(Radius.circular(r)),
|
|
);
|
|
}
|
|
|
|
static Decoration containerRadiusBottom(Color color, double r) {
|
|
return BoxDecoration(
|
|
color: color,
|
|
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(r), bottomRight: Radius.circular(r)),
|
|
);
|
|
}
|
|
|
|
static ShapeBorder cardRadiusTop(double radius) {
|
|
return RoundedRectangleBorder(
|
|
side: const BorderSide(color: Colors.transparent, width: 0),
|
|
borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)),
|
|
);
|
|
}
|
|
|
|
static Decoration containerColorRadiusBorderWidth(Color background, double radius, Color color, double w) {
|
|
return BoxDecoration(
|
|
color: background,
|
|
border: Border.all(
|
|
width: w, //
|
|
color: color // <--- border width here
|
|
),
|
|
borderRadius: BorderRadius.circular(radius),
|
|
);
|
|
}
|
|
|
|
static ShapeBorder cardRadiusTop2(double radius) {
|
|
return RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)),
|
|
);
|
|
}
|
|
|
|
static ShapeBorder cardRadiusBottom(double radius) {
|
|
return RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(radius), bottomRight: Radius.circular(radius)),
|
|
);
|
|
}
|
|
|
|
static Decoration containerColorRadiusBorder(Color background, double radius, Color color) {
|
|
return BoxDecoration(
|
|
color: background,
|
|
border: Border.all(
|
|
width: 1, //
|
|
color: color // <--- border width here
|
|
),
|
|
borderRadius: BorderRadius.circular(radius),
|
|
);
|
|
}
|
|
|
|
static bool passwordValidateStructure(String value) {
|
|
String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{6,}$';
|
|
RegExp regExp = RegExp(pattern);
|
|
return regExp.hasMatch(value);
|
|
}
|
|
|
|
static bool isEmailValid(String email) {
|
|
String p = r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
|
|
RegExp regExp = RegExp(p);
|
|
return regExp.hasMatch(email);
|
|
}
|
|
|
|
static String getAdsPaymentBrowserForm({required int paymentId, required int adId}) {
|
|
return '<html> <head></head><body><form id="paymentForm" action="${ApiConsts.paymentWebViewUrl}" method="post"><input type="hidden" name="PaymentType" value="$paymentId"><input type="hidden" name="AdsID" value="$adId"></form><script type="text/javascript"> document.getElementById("paymentForm").submit(); </script></body></html>';
|
|
}
|
|
|
|
// BOTTOM SHEETS
|
|
static void showHelpBottomSheet(BuildContext context) {
|
|
return actionConfirmationBottomSheet(
|
|
context: context,
|
|
title: LocaleKeys.help.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
|
|
subtitle: LocaleKeys.customerCarePrompt.tr(),
|
|
isOnlyOneButton: true,
|
|
actionButtonYes: Expanded(
|
|
child: ShowFillButton(
|
|
maxHeight: 55,
|
|
title: LocaleKeys.callNow.tr(),
|
|
fontSize: 18,
|
|
onPressed: () {
|
|
pop(context);
|
|
},
|
|
),
|
|
),
|
|
actionButtonNo: const SizedBox(),
|
|
);
|
|
}
|
|
|
|
static Widget buildStatusContainer(String text, {double marginAll = 8, double fontSize = 14}) {
|
|
if (text.isEmpty) {
|
|
return const SizedBox();
|
|
}
|
|
return Center(
|
|
child: text.toText(color: MyColors.lightTextColor, fontSize: fontSize),
|
|
).toContainer(
|
|
marginAll: marginAll,
|
|
paddingAll: 15,
|
|
borderRadius: 8,
|
|
width: double.infinity,
|
|
backgroundColor: MyColors.grey98Color.withOpacity(0.1),
|
|
);
|
|
}
|
|
|
|
static Future<void> openLocationInMaps({required double latitude, required double longitude}) async {
|
|
final Uri googleMapsUrl = Uri.parse('https://www.google.com/maps/search/?api=1&query=$latitude,$longitude');
|
|
|
|
if (await canLaunchUrl(googleMapsUrl)) {
|
|
try {
|
|
await launchUrl(googleMapsUrl);
|
|
} catch (e) {
|
|
await launchUrl(googleMapsUrl);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Future<ShareResult> shareAppInvitation() async {
|
|
ShareResult result = await Share.share(GlobalConsts.getAppInvitationLink(), subject: 'Join Mowater');
|
|
return result;
|
|
}
|
|
|
|
static Future<void> inviteFriend({required InviteTypeEnum inviteTypeEnum, required String message}) async {
|
|
String url;
|
|
|
|
switch (inviteTypeEnum) {
|
|
case InviteTypeEnum.whatsapp:
|
|
// WhatsApp requires a phone number and message, format like this:
|
|
url = 'https://wa.me/?text=${Uri.encodeComponent(message)}';
|
|
break;
|
|
|
|
case InviteTypeEnum.sms:
|
|
// SMS: 'sms:<phone_number>?body=<message>'
|
|
// You can add a phone number, or keep it empty to allow the user to input one.
|
|
url = 'sms:?body=${Uri.encodeComponent(message)}';
|
|
break;
|
|
|
|
case InviteTypeEnum.email:
|
|
// Email: 'mailto:<email>?subject=<subject>&body=<message>'
|
|
url = 'mailto:?subject=MowaterInvitation&body=${Uri.encodeComponent(message)}';
|
|
break;
|
|
}
|
|
|
|
// Try to launch the URL and catch any exceptions.
|
|
if (await canLaunchUrl(Uri.parse(url))) {
|
|
try {
|
|
await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
|
|
} catch (e) {
|
|
await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
|
|
}
|
|
}
|
|
}
|
|
|
|
static buildProviderContactInfoBottomSheet({required BuildContext context, required String? email, required String? mobileNo}) {
|
|
return showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
enableDrag: true,
|
|
builder: (BuildContext context) {
|
|
return InfoBottomSheet(
|
|
title: LocaleKeys.contactDetails.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
|
|
description: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (mobileNo != null && mobileNo.isNotEmpty) ...[
|
|
CustomSettingOptionsTile(
|
|
leadingWidget: const Icon(
|
|
Icons.call,
|
|
size: 20,
|
|
color: MyColors.greyColor,
|
|
),
|
|
titleText: LocaleKeys.phoneNumber.tr(),
|
|
subTitle: " $mobileNo",
|
|
needBorderBelow: true,
|
|
showTrailingArrow: false,
|
|
subtitleTextColor: MyColors.greyColor,
|
|
onTap: () {
|
|
Utils.openNumberViaCaller(phoneNumber: mobileNo);
|
|
},
|
|
),
|
|
],
|
|
if (email != null && email.isNotEmpty) ...[
|
|
CustomSettingOptionsTile(
|
|
leadingWidget: const Icon(
|
|
Icons.email_outlined,
|
|
size: 20,
|
|
color: MyColors.greyColor,
|
|
),
|
|
titleText: LocaleKeys.emailAddress.tr(),
|
|
subTitle: " $email",
|
|
needBorderBelow: false,
|
|
showTrailingArrow: false,
|
|
subtitleTextColor: MyColors.greyColor,
|
|
onTap: () {
|
|
Utils.openEmailViaEmailApp(emailAddress: email);
|
|
},
|
|
),
|
|
],
|
|
30.height,
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class NoInternetDialog {
|
|
static void show(BuildContext context) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: Text(
|
|
LocaleKeys.connectionProblem.tr(),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
content: Text(
|
|
LocaleKeys.pleaseCheckConnection.tr(),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
actions: [
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
// // if (AppState().currentAppType == AppType.provider) {
|
|
// Navigator.of(context).pop();
|
|
Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.registerSelection, (Route<dynamic> route) => true);
|
|
},
|
|
child: const Text(
|
|
LocaleKeys.ok,
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|