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.
906 lines
31 KiB
Dart
906 lines
31 KiB
Dart
import 'dart:async';
|
|
import 'dart:developer';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:google_api_availability/google_api_availability.dart';
|
|
import 'package:huawei_location/huawei_location.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:nfc_manager/nfc_manager.dart';
|
|
import 'package:nfc_manager/platform_tags.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:test_sa/controllers/providers/api/user_provider.dart';
|
|
import 'package:test_sa/extensions/context_extension.dart';
|
|
import 'package:test_sa/extensions/int_extensions.dart';
|
|
import 'package:test_sa/extensions/text_extensions.dart';
|
|
import 'package:test_sa/extensions/widget_extensions.dart';
|
|
import 'package:test_sa/main.dart';
|
|
import 'package:test_sa/new_views/app_style/app_color.dart';
|
|
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
|
|
import 'package:test_sa/new_views/pages/land_page/nfc/nfc_reader_sheet.dart';
|
|
import 'package:test_sa/new_views/swipe_module/dialoge/confirm_dialog.dart';
|
|
import 'package:test_sa/new_views/swipe_module/dialoge/qr_scanner_dialog.dart';
|
|
import 'package:test_sa/new_views/swipe_module/enums/swipe_type.dart';
|
|
import 'package:test_sa/new_views/swipe_module/models/swipe_model.dart';
|
|
import 'package:test_sa/new_views/swipe_module/swipe_success_view.dart';
|
|
import 'package:test_sa/new_views/swipe_module/utils/location_utils.dart';
|
|
|
|
class SwipeGeneralUtils {
|
|
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 void markFakeAttendance(dynamic sourceName, String lat, String long, @required BuildContext context) async {
|
|
showLoading(context);
|
|
try {
|
|
hideLoading(navigatorKey.currentState.overlay.context);
|
|
confirmDialog(navigatorKey.currentState.overlay.context, "Fake Location)");
|
|
} catch (ex) {
|
|
log('$ex');
|
|
hideLoading(context);
|
|
//handleException(ex, context, 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, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
|
|
|
showDialog(
|
|
context: context,
|
|
barrierColor: Colors.black.withOpacity(0.5),
|
|
useRootNavigator: false,
|
|
builder: (BuildContext context) => const AppLazyLoading(),
|
|
).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 void showErrorDialog({String message, @required BuildContext context}) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => ConfirmDialog(
|
|
message: message,
|
|
title: 'Error',
|
|
onTap: () => Navigator.pop(context),
|
|
),
|
|
);
|
|
}
|
|
|
|
static void showMDialog(context, {Widget child, Color backgroundColor, bool isDismissable = true, bool isBusniessCard = false}) async {
|
|
return showDialog(
|
|
context: context,
|
|
barrierDismissible: isDismissable,
|
|
builder: (context) {
|
|
return Dialog(
|
|
shape: isBusniessCard
|
|
? const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.all(
|
|
Radius.circular(15.0),
|
|
),
|
|
)
|
|
: null,
|
|
backgroundColor: backgroundColor,
|
|
child: child,
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
static Widget attendanceTypeCard(String title, String icon, bool isEnabled, VoidCallback onPress, BuildContext context) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: isEnabled ? Colors.white : AppColor.white40,
|
|
borderRadius: BorderRadius.circular(18),
|
|
border: Border.all(color: AppColor.white40, width: 2),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
icon.toSvgAsset(color: isEnabled ? null : Colors.grey.withOpacity(0.5)),
|
|
title.heading5(context).custom(color: isEnabled ? AppColor.neutral50 : Colors.grey.withOpacity(0.5)),
|
|
],
|
|
),
|
|
).onPress(
|
|
() {
|
|
if (!isEnabled) return;
|
|
onPress();
|
|
},
|
|
);
|
|
// return Container(
|
|
// decoration: BoxDecoration(
|
|
// borderRadius: BorderRadius.circular(15),
|
|
// color: isEnabled ? null : Colors.grey.withOpacity(.5),
|
|
// gradient: isEnabled
|
|
// ? const LinearGradient(
|
|
// transform: GradientRotation(.64),
|
|
// begin: Alignment.topRight,
|
|
// end: Alignment.bottomLeft,
|
|
// colors: [
|
|
// //ToDo set Colors according to design provided by designer...
|
|
// Colors.blue,
|
|
// Colors.green,
|
|
// // AppColor.gradiantEndColor,
|
|
// // MyColors.gradiantStartColor,
|
|
// ],
|
|
// )
|
|
// : null,
|
|
// ),
|
|
// clipBehavior: Clip.antiAlias,
|
|
// padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14),
|
|
// child: Column(
|
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
// children: [
|
|
// // SvgPicture.asset(image, color: Colors.white, alignment: Alignment.topLeft).expanded,
|
|
// Icon(iconData, color: isEnabled ? AppColor.black35 : Colors.grey),
|
|
// title.heading6(context),
|
|
// // title.toText17(isBold: true, color: Colors.white),
|
|
// ],
|
|
// ),
|
|
// ).onPress(
|
|
// () {
|
|
// log('isEnabled is ${!isEnabled}');
|
|
// if (!isEnabled) return;
|
|
// onPress();
|
|
// },
|
|
// );
|
|
}
|
|
|
|
//huawei permission part....
|
|
static void getHuaweiCurrentLocation({SwipeTypeEnum attendanceType, BuildContext context}) async {
|
|
try {
|
|
showLoading(context);
|
|
FusedLocationProviderClient locationService = FusedLocationProviderClient()..initFusedLocationService();
|
|
LocationRequest locationRequest = LocationRequest();
|
|
locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
|
|
locationRequest.interval = 500;
|
|
List<LocationRequest> locationRequestList = <LocationRequest>[locationRequest];
|
|
LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList);
|
|
|
|
StreamSubscription<Location> _streamSubscription;
|
|
int requestCode = (await (locationService.requestLocationUpdates(locationRequest)));
|
|
|
|
_streamSubscription = locationService.onLocationData.listen(
|
|
(Location location) async {
|
|
hideLoading(context);
|
|
await locationService.removeLocationUpdates(requestCode);
|
|
handleSwipeOperation(swipeType: attendanceType, context: context);
|
|
requestCode = 0;
|
|
},
|
|
);
|
|
|
|
// locationService.checkLocationSettings(locationSettingsRequest).then((settings) async {
|
|
// await locationService.getLastLocation().then((value) {
|
|
// if (value.latitude == null || value.longitude == null) {
|
|
// showDialog(
|
|
// context: context,
|
|
// builder: (BuildContext cxt) => ConfirmDialog(
|
|
// message: "Unable to get your location, Please check your location settings & try again.",
|
|
// onTap: () {
|
|
// Navigator.pop(context);
|
|
// },
|
|
// ),
|
|
// );
|
|
// } else {
|
|
// if (attendanceType == "QR") {
|
|
// performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
|
|
// }
|
|
// if (attendanceType == "WIFI") {
|
|
// performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
|
|
// }
|
|
// if (attendanceType == "NFC") {
|
|
// performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
|
|
// }
|
|
// }
|
|
// }).catchError((error) {
|
|
// log("HUAWEI LOCATION getLastLocation ERROR!!!!!");
|
|
// log(error);
|
|
// });
|
|
// }).catchError((error) {
|
|
// log("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
|
|
// log(error);
|
|
// if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
|
|
// // Location service not enabled.
|
|
// }
|
|
// });
|
|
} catch (error) {
|
|
log("HUAWEI LOCATION ERROR!!!!!");
|
|
log('$error');
|
|
hideLoading(context);
|
|
// handleException(error, context, null);
|
|
}
|
|
}
|
|
|
|
static Future<bool> requestPermissions() async {
|
|
var result = await [
|
|
Permission.location,
|
|
].request();
|
|
return (result[Permission.location] == PermissionStatus.granted || result[Permission.locationAlways] == PermissionStatus.granted);
|
|
}
|
|
|
|
static void checkHuaweiLocationPermission({SwipeTypeEnum attendanceType, BuildContext context}) async {
|
|
// Permission_Handler permissionHandler = PermissionHandler();
|
|
LocationUtilities.isEnabled((bool isEnabled) async {
|
|
if (isEnabled) {
|
|
LocationUtilities.havePermission((bool permission) async {
|
|
if (permission) {
|
|
getHuaweiCurrentLocation(attendanceType: attendanceType, context: context);
|
|
} else {
|
|
bool has = await requestPermissions();
|
|
if (has) {
|
|
getHuaweiCurrentLocation(attendanceType: attendanceType, context: context);
|
|
} else {
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext cxt) => ConfirmDialog(
|
|
message: "You need to give location permission to mark attendance",
|
|
onTap: () {
|
|
Navigator.pop(context);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext cxt) => ConfirmDialog(
|
|
message: "You need to enable location services to mark attendance",
|
|
onTap: () async {
|
|
Navigator.pop(context);
|
|
await Geolocator.openLocationSettings();
|
|
},
|
|
),
|
|
);
|
|
}
|
|
});
|
|
|
|
// if (await permissionHandler.hasLocationPermission()) {
|
|
// getHuaweiCurrentLocation(attendanceType);
|
|
// } else {
|
|
// bool has = await requestPermissions();
|
|
// if (has) {
|
|
// getHuaweiCurrentLocation(attendanceType);
|
|
// } else {
|
|
// showDialog(
|
|
// context: context,
|
|
// builder: (BuildContext cxt) => ConfirmDialog(
|
|
// message: "You need to give location permission to mark attendance",
|
|
// onTap: () {
|
|
// Navigator.pop(context);
|
|
// },
|
|
// ),
|
|
// );
|
|
// }
|
|
// }
|
|
}
|
|
|
|
// general methods......
|
|
|
|
static void handleSwipeOperation({@required SwipeTypeEnum swipeType, double lat, double lang, BuildContext context}) {
|
|
switch (swipeType) {
|
|
case SwipeTypeEnum.NFC:
|
|
handleNfcAttendance(latitude: lat, longitude: lang, context: context);
|
|
return;
|
|
case SwipeTypeEnum.QR:
|
|
performQrCodeAttendance(latitude: lat, longitude: lang, context: context);
|
|
return;
|
|
case SwipeTypeEnum.Wifi:
|
|
//TODO need to implement.
|
|
return;
|
|
}
|
|
}
|
|
|
|
static String formatTimeOnly(DateTime dateTime) {
|
|
return DateFormat.Hms().format(dateTime);
|
|
}
|
|
|
|
static Future<void> performQrCodeAttendance({double latitude, double longitude, BuildContext context}) async {
|
|
UserProvider userProvider = Provider.of<UserProvider>(context, listen: false);
|
|
var qrCodeValue = await Navigator.of(context).push(
|
|
MaterialPageRoute(
|
|
builder: (BuildContext context) => QrScannerDialog(),
|
|
),
|
|
);
|
|
if (qrCodeValue != null) {
|
|
showLoading(context);
|
|
try {
|
|
//test model..
|
|
final swipeModel = Swipe(
|
|
swipeTypeValue: SwipeTypeEnum.QR.getIntFromSwipeTypeEnum(),
|
|
value: '456',
|
|
latitude: 24.70865415364271,
|
|
longitude: 46.66600861881879,
|
|
);
|
|
// final swipeModel = Swipe(
|
|
// swipeTypeValue: SwipeTypeEnum.QR.getIntFromSwipeTypeEnum(),
|
|
// value: qrCodeValue,
|
|
// latitude: latitude,
|
|
// longitude: longitude,
|
|
// );
|
|
log('model i got to scan qr is ${swipeModel.toJson()}');
|
|
final swipeResponse = await userProvider.makeSwipe(model: swipeModel);
|
|
log('response of swipe is ${swipeResponse.toJson()}');
|
|
|
|
if (swipeResponse.isSuccess) {
|
|
hideLoading(context);
|
|
showSuccessDialog(context: context);
|
|
} else {
|
|
hideLoading(context);
|
|
showDialog(
|
|
barrierDismissible: true,
|
|
context: context,
|
|
builder: (cxt) => ConfirmDialog(
|
|
message: swipeResponse.message ?? "",
|
|
onTap: () {
|
|
Navigator.pop(context);
|
|
},
|
|
onCloseTap: () {},
|
|
),
|
|
);
|
|
}
|
|
} catch (ex) {
|
|
log('$ex');
|
|
hideLoading(context);
|
|
//this need to confirm where it comes..
|
|
// handleException(ex, context, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Future<void> handleNfcAttendance({double latitude = 0, double longitude = 0, BuildContext context}) async {
|
|
// UserProvider _userProvider = Provider.of<UserProvider>(context,listen:false);
|
|
|
|
if (Platform.isIOS) {
|
|
readNFc(onRead: (String nfcId) async {
|
|
await _processNfcAttendance(nfcId, latitude, longitude, context);
|
|
});
|
|
} else {
|
|
showNfcReader(context, onNcfScan: (String nfcId) async {
|
|
await _processNfcAttendance(nfcId ?? '', latitude, longitude, context);
|
|
});
|
|
}
|
|
}
|
|
|
|
static Future<void> _processNfcAttendance(
|
|
String nfcId,
|
|
double latitude,
|
|
double longitude,
|
|
BuildContext context,
|
|
) async {
|
|
showLoading(context);
|
|
try {
|
|
// final swipeModel = Swipe(
|
|
// swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(),
|
|
// value: nfcId,
|
|
// latitude: latitude,
|
|
// longitude: longitude,
|
|
// );
|
|
UserProvider userProvider = Provider.of<UserProvider>(context, listen: false);
|
|
//Test model...
|
|
|
|
final swipeModel = Swipe(
|
|
swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(),
|
|
value: '123',
|
|
latitude: 24.70865415364271,
|
|
longitude: 46.66600861881879,
|
|
);
|
|
final swipeResponse = await userProvider.makeSwipe(model: swipeModel);
|
|
|
|
if (swipeResponse.isSuccess) {
|
|
hideLoading(context);
|
|
showSuccessDialog(context: context, fromDashBoard: true);
|
|
} else {
|
|
hideLoading(context);
|
|
showErrorDialog(message: swipeResponse.message ?? "Unexpected error occurred", context: context);
|
|
}
|
|
} catch (errSwipeGeneralUtilsor) {
|
|
hideLoading(context);
|
|
// Uncomment below line for error handling if needed
|
|
// handleException(error, context, null);
|
|
}
|
|
}
|
|
|
|
static void handleSwipe({
|
|
SwipeTypeEnum swipeType,
|
|
@required bool isEnable,
|
|
@required BuildContext context,
|
|
}) async {
|
|
if (!(await isGoogleServicesAvailable())) {
|
|
checkHuaweiLocationPermission(attendanceType: swipeType, context: context);
|
|
} else {
|
|
LocationUtilities.isEnabled((bool isEnabled) {
|
|
if (isEnabled) {
|
|
LocationUtilities.havePermission((bool permission) {
|
|
if (permission) {
|
|
showLoading(context);
|
|
LocationUtilities.getCurrentLocation(
|
|
(Position position, bool isMocked) {
|
|
if (isMocked) {
|
|
hideLoading(context);
|
|
markFakeAttendance(swipeType.name, position.latitude.toString() ?? "", position.longitude.toString() ?? "", context);
|
|
} else {
|
|
hideLoading(context);
|
|
handleSwipeOperation(swipeType: swipeType, lat: position.latitude, lang: position.longitude, context: context);
|
|
}
|
|
},
|
|
() {
|
|
hideLoading(context);
|
|
confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
|
|
},
|
|
context,
|
|
);
|
|
} else {
|
|
showInfoDialog(
|
|
message: "You need to give location permission to mark attendance",
|
|
onTap: () async {
|
|
await Geolocator.openAppSettings();
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
showInfoDialog(
|
|
message: "You need to enable location services to mark attendance",
|
|
onTap: () async {
|
|
await Geolocator.openLocationSettings();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
static void showInfoDialog({@required String message, VoidCallback onTap}) {
|
|
showDialog(
|
|
context: navigatorKey.currentState.overlay.context,
|
|
builder: (BuildContext cxt) => ConfirmDialog(
|
|
message: message,
|
|
onTap: () async {
|
|
Navigator.pop(navigatorKey.currentState.overlay.context);
|
|
onTap();
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
static List<Widget> availableAttendanceMethodList({@required BuildContext context, @required UserProvider userProvider, @required bool isNfcSupported}) {
|
|
List<Widget> availableMethods = [];
|
|
if (userProvider.user.enableNFC) {
|
|
availableMethods.add(attendanceTypeCard(SwipeTypeEnum.NFC.name, 'nfc_icon', isNfcSupported, () {
|
|
handleSwipe(swipeType: SwipeTypeEnum.NFC, isEnable: userProvider.user.enableNFC, context: navigatorKey.currentState.overlay.context);
|
|
}, context));
|
|
}
|
|
if (userProvider.user.enableQR) {
|
|
availableMethods.add(attendanceTypeCard(SwipeTypeEnum.QR.name, 'qr', userProvider.user.enableQR, () {
|
|
handleSwipe(swipeType: SwipeTypeEnum.QR, isEnable: userProvider.user.enableQR, context: navigatorKey.currentState.overlay.context);
|
|
}, context));
|
|
}
|
|
if (userProvider.user.enableWifi) {
|
|
availableMethods.add(attendanceTypeCard(SwipeTypeEnum.Wifi.name, 'wifi_icon', userProvider.user.enableWifi, () {
|
|
handleSwipe(swipeType: SwipeTypeEnum.Wifi, isEnable: userProvider.user.enableWifi, context: navigatorKey.currentState.overlay.context);
|
|
}, context));
|
|
}
|
|
return availableMethods;
|
|
}
|
|
|
|
static Future<void> showSwipeTypeBottomSheetSheet({@required BuildContext context, @required bool isNfcSupported}) {
|
|
UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false);
|
|
|
|
return showModalBottomSheet(
|
|
context: context,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.vertical(
|
|
top: Radius.circular(20),
|
|
),
|
|
),
|
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
|
builder: (BuildContext context) => Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
context.translation.markAttendance.heading4(context).custom(color: AppColor.neutral80),
|
|
8.height,
|
|
context.translation.selectMethodToMarkAttendance.bodyText2(context).custom(color: AppColor.white20),
|
|
12.height,
|
|
GridView(
|
|
padding: const EdgeInsets.all(0),
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 12, mainAxisSpacing: 12),
|
|
children: availableAttendanceMethodList(context: context, userProvider: _userProvider, isNfcSupported: isNfcSupported)),
|
|
],
|
|
).paddingAll(16),
|
|
);
|
|
}
|
|
|
|
static void showSuccessDialog({@required BuildContext context, bool fromDashBoard}) {
|
|
Navigator.pushReplacementNamed(context, SwipeSuccessView.routeName);
|
|
// showMDialog(
|
|
// context,
|
|
// backgroundColor: Colors.transparent,
|
|
// isDismissable: true,
|
|
// child: SuccessDialog(fromDashBoard),
|
|
// );
|
|
}
|
|
|
|
static void readNFc({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);
|
|
});
|
|
}
|
|
|
|
//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 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 && GeneralUtils.isBase64(b64)) return GeneralUtils.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;
|
|
// }
|