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.
		
		
		
		
		
			
		
			
				
	
	
		
			403 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			403 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Dart
		
	
| import 'dart:convert';
 | |
| import 'dart:io';
 | |
| import 'dart:typed_data';
 | |
| 
 | |
| import 'package:easy_localization/easy_localization.dart';
 | |
| import 'package:flutter/cupertino.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| import 'package:flutter_svg/flutter_svg.dart';
 | |
| import 'package:fluttertoast/fluttertoast.dart';
 | |
| import 'package:google_api_availability/google_api_availability.dart';
 | |
| import 'package:mohem_flutter_app/app_state/app_state.dart';
 | |
| import 'package:mohem_flutter_app/classes/colors.dart';
 | |
| import 'package:mohem_flutter_app/config/routes.dart';
 | |
| import 'package:mohem_flutter_app/exceptions/api_exception.dart';
 | |
| import 'package:mohem_flutter_app/extensions/int_extensions.dart';
 | |
| import 'package:mohem_flutter_app/extensions/string_extensions.dart';
 | |
| import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
 | |
| import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
 | |
| import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
 | |
| import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
 | |
| import 'package:mohem_flutter_app/widgets/loading_dialog.dart';
 | |
| import 'package:nfc_manager/nfc_manager.dart';
 | |
| import 'package:nfc_manager/platform_tags.dart';
 | |
| import 'package:shared_preferences/shared_preferences.dart';
 | |
| 
 | |
| // ignore_for_file: avoid_annotating_with_dynamic
 | |
| 
 | |
| class Utils {
 | |
|   static bool _isLoadingVisible = false;
 | |
| 
 | |
|   static bool get isLoading => _isLoadingVisible;
 | |
| 
 | |
|   static void showToast(String message, {bool longDuration = true}) {
 | |
|     Fluttertoast.showToast(
 | |
|       msg: message,
 | |
|       toastLength: longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT,
 | |
|       gravity: ToastGravity.BOTTOM,
 | |
|       timeInSecForIosWeb: 1,
 | |
|       backgroundColor: Colors.black54,
 | |
|       textColor: Colors.white,
 | |
|       fontSize: 13.0,
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   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 Future delay(int millis) async {
 | |
|     return await Future.delayed(Duration(milliseconds: millis));
 | |
|   }
 | |
| 
 | |
|   static void showLoading(BuildContext context) {
 | |
|     WidgetsBinding.instance.addPostFrameCallback((_) {
 | |
|       _isLoadingVisible = true;
 | |
|       showDialog(context: context, barrierColor: Colors.black.withOpacity(0.5), useRootNavigator: false, builder: (BuildContext context) => LoadingDialog()).then((value) {
 | |
|         _isLoadingVisible = false;
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   static void hideLoading(BuildContext context) {
 | |
|     if (_isLoadingVisible) {
 | |
|       _isLoadingVisible = false;
 | |
|       Navigator.of(context).pop();
 | |
|     }
 | |
|     _isLoadingVisible = false;
 | |
|   }
 | |
| 
 | |
|   static Future<String> getStringFromPrefs(String key) async {
 | |
|     SharedPreferences prefs = await SharedPreferences.getInstance();
 | |
|     return prefs.getString(key) ?? "";
 | |
|   }
 | |
| 
 | |
|   static Future<bool> removeStringFromPrefs(String key) async {
 | |
|     SharedPreferences prefs = await SharedPreferences.getInstance();
 | |
|     return prefs.remove(key);
 | |
|   }
 | |
| 
 | |
|   static Future<bool> saveStringFromPrefs(String key, String value) async {
 | |
|     SharedPreferences prefs = await SharedPreferences.getInstance();
 | |
|     return await prefs.setString(key, value);
 | |
|   }
 | |
| 
 | |
|   static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) {
 | |
|     String errorMessage;
 | |
|     if (exception.error.errorType != null && exception.error.errorType == 4) {
 | |
|       Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.appUpdateScreen, (_) => false, arguments: exception.error?.errorMessage);
 | |
|     } else {
 | |
|       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 {
 | |
|         if (!AppState().isAuthenticated) {
 | |
|           showDialog(
 | |
|             barrierDismissible: false,
 | |
|             context: cxt,
 | |
|             builder:
 | |
|                 (cxt) => ConfirmDialog(
 | |
|                   message: errorMessage,
 | |
|                   onTap: () {
 | |
|                     Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route<dynamic> route) => false);
 | |
|                   },
 | |
|                   onCloseTap: () {},
 | |
|                 ),
 | |
|           );
 | |
|         } else {
 | |
|           if (cxt != null) {
 | |
|             confirmDialog(cxt, errorMessage);
 | |
|           } else {
 | |
|             showToast(errorMessage);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   static Future showErrorDialog({required BuildContext context, required VoidCallback onOkTapped, required String message}) async {
 | |
|     return showDialog(context: context, builder: (BuildContext context) => ConfirmDialog(message: message, onTap: onOkTapped));
 | |
|   }
 | |
| 
 | |
|   static void confirmDialog(cxt, String message, {VoidCallback? onTap}) {
 | |
|     showDialog(context: cxt, builder: (BuildContext cxt) => ConfirmDialog(message: message, onTap: onTap));
 | |
|   }
 | |
| 
 | |
|   static Widget getNoDataWidget(BuildContext context) {
 | |
|     return Column(
 | |
|       mainAxisAlignment: MainAxisAlignment.center,
 | |
|       crossAxisAlignment: CrossAxisAlignment.center,
 | |
|       children: [SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0), LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15)],
 | |
|     ).center;
 | |
|   }
 | |
| 
 | |
|   static Widget getNoChatWidget(BuildContext context) {
 | |
|     return Column(
 | |
|       mainAxisAlignment: MainAxisAlignment.center,
 | |
|       crossAxisAlignment: CrossAxisAlignment.center,
 | |
|       children: [SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0), LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15)],
 | |
|     ).center;
 | |
|   }
 | |
| 
 | |
|   static Uint8List getPostBytes(img) {
 | |
|     try {
 | |
|       var b64 = img.replaceFirst('data:image/png;base64,', '');
 | |
|       if (img != null && Utils.isBase64(b64)) return Utils.dataFromBase64String(b64);
 | |
|     } catch (e) {}
 | |
|     return Uint8List.fromList([]);
 | |
|   }
 | |
| 
 | |
|   static String getBase64FromJpeg(img) {
 | |
|     try {
 | |
|       var b64 = img.replaceFirst('data:image/jpeg;base64,', '');
 | |
|       return b64;
 | |
|     } catch (e) {}
 | |
|     return "";
 | |
|   }
 | |
| 
 | |
|   static bool isBase64(String str) {
 | |
|     RegExp _base64 = RegExp(r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$');
 | |
|     return _base64.hasMatch(str);
 | |
|   }
 | |
| 
 | |
|   static Uint8List dataFromBase64String(String base64String) {
 | |
|     return base64Decode(base64String);
 | |
|   }
 | |
| 
 | |
|   static Widget tableColumnTitle(String? text, {bool showDivider = true, bool alignCenter = false}) {
 | |
|     text ??= "";
 | |
|     return Column(
 | |
|       crossAxisAlignment: CrossAxisAlignment.start,
 | |
|       mainAxisSize: MainAxisSize.min,
 | |
|       children: [6.height, alignCenter ? text.toText12().center : text.toText12(), 5.height, if (showDivider) const Divider(height: 1, color: Color(0xff2E303A), thickness: 1)],
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   static Decoration containerRadius(Color background, double radius) {
 | |
|     return BoxDecoration(
 | |
|       color: background,
 | |
|       border: Border.all(
 | |
|         width: 1, //
 | |
|         color: background, //                  <--- border width here
 | |
|       ),
 | |
|       borderRadius: BorderRadius.circular(radius),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   static Widget mHeight(double h) {
 | |
|     return Container(height: h);
 | |
|   }
 | |
| 
 | |
|   static Widget mDivider(Color color) {
 | |
|     return Divider(
 | |
|       // width: double.infinity,
 | |
|       height: 1,
 | |
|       color: color,
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   static Widget tableColumnValue(String text, {bool isCapitable = true, bool alignCenter = false}) {
 | |
|     return Column(
 | |
|       crossAxisAlignment: CrossAxisAlignment.start,
 | |
|       mainAxisSize: MainAxisSize.min,
 | |
|       children: [
 | |
|         12.height,
 | |
|         if (alignCenter)
 | |
|           (isCapitable ? text.toLowerCase().capitalizeFirstofEach : text).toText12(color: MyColors.normalTextColor).center
 | |
|         else
 | |
|           (isCapitable ? text.toLowerCase().capitalizeFirstofEach : text).toText12(color: MyColors.normalTextColor),
 | |
|         12.height,
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   /// EIT Forms date formats
 | |
| 
 | |
|   static String getMonthNamedFormat(DateTime date) {
 | |
|     /// it will return like "29-Sep-2022"
 | |
|     return DateFormat('dd-MMM-yyyy', "en_US").format(date);
 | |
|   }
 | |
| 
 | |
|   static String reverseFormatDate(String date) {
 | |
|     String formattedDate;
 | |
|     if (date.isNotEmpty) {
 | |
|       formattedDate = date.replaceAll('/', '-');
 | |
|       formattedDate = formattedDate.replaceAll(' 00:00:00', '');
 | |
|     } else {
 | |
|       formattedDate = date;
 | |
|     }
 | |
|     return formattedDate;
 | |
|   }
 | |
| 
 | |
|   static String formatStandardDate(String date) {
 | |
|     String formattedDate;
 | |
|     if (date.isNotEmpty) {
 | |
|       formattedDate = date.replaceAll('-', '/');
 | |
|     } else {
 | |
|       formattedDate = date;
 | |
|     }
 | |
|     return formattedDate;
 | |
|   }
 | |
| 
 | |
|   static String reverseFormatStandardDate(String date) {
 | |
|     String formattedDate;
 | |
|     if (date.isNotEmpty) {
 | |
|       formattedDate = date.replaceAll('/', '-');
 | |
|     } else {
 | |
|       formattedDate = date;
 | |
|     }
 | |
|     return formattedDate;
 | |
|   }
 | |
| 
 | |
|   static String formatDate(String date) {
 | |
|     String formattedDate;
 | |
| 
 | |
|     if (date.isNotEmpty) {
 | |
|       date = date.substring(0, 10);
 | |
|       formattedDate = date.replaceAll('-', '/');
 | |
|       formattedDate = formattedDate + ' 00:00:00';
 | |
|     } else {
 | |
|       formattedDate = date;
 | |
|     }
 | |
|     return formattedDate;
 | |
|   }
 | |
| 
 | |
|   static String formatDateNew(String date) {
 | |
|     String formattedDate;
 | |
|     if (date.isNotEmpty) {
 | |
|       formattedDate = date.split('T')[0];
 | |
|       if (!formattedDate.contains("00:00:00")) {
 | |
|         formattedDate = formattedDate + ' 00:00:00';
 | |
|       }
 | |
|     } else {
 | |
|       formattedDate = date;
 | |
|     }
 | |
|     return formattedDate;
 | |
|   }
 | |
| 
 | |
|   static String formatDateDefault(String date) {
 | |
|     if (date.isNotEmpty) {
 | |
|       if (date.toLowerCase().contains("t")) {
 | |
|         date = date.toLowerCase().split("t")[0];
 | |
|         if (!date.contains("00:00:00")) {
 | |
|           date = date + ' 00:00:00';
 | |
|         }
 | |
|         return date;
 | |
|       } else {
 | |
|         if (date.toLowerCase().split("-")[1].length == 3) {
 | |
|           return DateFormat('dd-MM-yyyy', "en_US").format(DateFormat('dd-MMM-yyyy', "en_US").parseLoose(date));
 | |
|         } else {
 | |
|           return DateFormat('dd-MM-yyyy', "en_US").format(DateFormat('yyyy-MM-dd', "en_US").parseLoose(date));
 | |
|         }
 | |
|         // return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MM-yyyy').parseLoose(date));
 | |
|       }
 | |
|     } else {
 | |
|       return date;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   static Future<DateTime> selectDate(BuildContext context, DateTime selectedDate) async {
 | |
|     if (!Platform.isIOS) {
 | |
|       await showCupertinoModalPopup(
 | |
|         context: context,
 | |
|         builder:
 | |
|             (BuildContext cxt) => Container(
 | |
|               height: 250,
 | |
|               color: Colors.white,
 | |
|               child: CupertinoDatePicker(
 | |
|                 backgroundColor: Colors.white,
 | |
|                 mode: CupertinoDatePickerMode.date,
 | |
|                 onDateTimeChanged: (DateTime value) {
 | |
|                   if (value != null && value != selectedDate) {
 | |
|                     selectedDate = value;
 | |
|                   }
 | |
|                 },
 | |
|                 initialDateTime: selectedDate,
 | |
|               ),
 | |
|             ),
 | |
|       );
 | |
|     } else {
 | |
|       DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101));
 | |
|       if (picked != null && picked != selectedDate) {
 | |
|         selectedDate = picked;
 | |
|       }
 | |
|     }
 | |
|     return selectedDate;
 | |
|   }
 | |
| 
 | |
|   static void readNFc({required Function(String) onRead}) {
 | |
|     NfcManager.instance
 | |
|         .startSession(
 | |
|           onDiscovered: (NfcTag tag) async {
 | |
|             MifareUltralight f;
 | |
|             if (Platform.isAndroid) {
 | |
|               print(tag);
 | |
|               f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
 | |
|             } else {
 | |
|               f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
 | |
|             }
 | |
|             String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join('');
 | |
|             NfcManager.instance.stopSession();
 | |
|             onRead(identifier);
 | |
|           },
 | |
|           pollingOptions: {NfcPollingOption.iso14443},
 | |
|         )
 | |
|         .catchError((err) {
 | |
|           print(err);
 | |
|         });
 | |
|   }
 | |
| 
 | |
|   //HUAWEI DECISION MAKING
 | |
|   static Future<bool> isGoogleServicesAvailable() async {
 | |
|     GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
 | |
|     String status = availability.toString().split('.').last;
 | |
|     if (status == "success") {
 | |
|       return true;
 | |
|     }
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   static bool isDate(String input, String format) {
 | |
|     try {
 | |
|       DateTime d = DateFormat(format).parseStrict(input);
 | |
|       //print(d);
 | |
|       return true;
 | |
|     } catch (e) {
 | |
|       //print(e);
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   static Future<void> performLogout(BuildContext? context, ChatProviderModel? chatData) async {
 | |
|     AppState().isAuthenticated = false;
 | |
|     AppState().isLogged = false;
 | |
|     AppState().setPostParamsInitConfig();
 | |
|     if (chatData != null) {
 | |
|       chatData.disposeData();
 | |
|     }
 | |
|     // SharedPreferences prefs = await SharedPreferences.getInstance();
 | |
|     // await prefs.clear();
 | |
|     Navigator.pushNamedAndRemoveUntil(context!, AppRoutes.login, (Route<dynamic> route) => false, arguments: null);
 | |
|   }
 | |
| }
 |