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/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/widgets/button/show_fill_button.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 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 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 openNumberViaWhatsApp({required String phoneNumber}) async { final url = 'https://wa.me/$phoneNumber?text='; await launchUrlString(url, mode: LaunchMode.externalApplication); } static Future 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 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 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 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; } } 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 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 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}) { 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 '
'; } // 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 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 shareAppInvitation() async { ShareResult result = await Share.share(GlobalConsts.getAppInvitationLink(), subject: 'Join Mowater'); return result; } }