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.
392 lines
12 KiB
Dart
392 lines
12 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: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/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(
|
|
context: cxt,
|
|
builder: (cxt) => ConfirmDialog(
|
|
message: errorMessage,
|
|
onTap: () {
|
|
Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route<dynamic> route) => false);
|
|
},
|
|
),
|
|
);
|
|
} 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').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').format(DateFormat('dd-MMM-yyyy').parseLoose(date));
|
|
} else {
|
|
return DateFormat('dd-MM-yyyy').format(DateFormat('yyyy-MM-dd').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) {
|
|
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);
|
|
}).catchError((err) {
|
|
print(err);
|
|
});
|
|
}
|
|
}
|