non hmg mark attendance module added.
parent
561881c7f2
commit
ef38c3d2bd
Binary file not shown.
Binary file not shown.
@ -0,0 +1,420 @@
|
||||
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/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';
|
||||
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
|
||||
import 'package:test_sa/views/widgets/dialogs/confirm_dialog.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, 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 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) {
|
||||
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;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@ -0,0 +1,677 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:huawei_location/huawei_location.dart';
|
||||
// import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart';
|
||||
// import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart';
|
||||
import 'package:nfc_manager/nfc_manager.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
// import 'package:platform_device_id/platform_device_id.dart';
|
||||
import 'package:test_sa/dashboard_latest/widgets/app_bar_widget.dart';
|
||||
import 'package:test_sa/extensions/text_extensions.dart';
|
||||
import 'package:test_sa/extensions/widget_extensions.dart';
|
||||
import 'package:test_sa/helper/utils.dart';
|
||||
import 'package:test_sa/nfc/nfc_reader_sheet.dart';
|
||||
// import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
|
||||
// import 'package:mohem_flutter_app/app_state/app_state.dart';
|
||||
// import 'package:mohem_flutter_app/classes/colors.dart';
|
||||
// import 'package:mohem_flutter_app/classes/utils.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/models/generic_response_model.dart';
|
||||
// import 'package:mohem_flutter_app/models/privilege_list_model.dart';
|
||||
// import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
|
||||
// import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart';
|
||||
// import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
|
||||
// import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart';im
|
||||
|
||||
import 'package:test_sa/utilities/Location.dart' as location;
|
||||
import 'package:test_sa/views/widgets/dialogs/confirm_dialog.dart';
|
||||
import 'package:test_sa/views/widgets/dialogs/success_dialog.dart';
|
||||
import 'package:test_sa/views/widgets/qr_scanner_dialog.dart';
|
||||
import 'package:wifi_iot/wifi_iot.dart';
|
||||
|
||||
import '../../app_style/app_color.dart';
|
||||
|
||||
class MarkAttendanceWidget extends StatefulWidget {
|
||||
// DashboardProviderModel model;
|
||||
double topPadding;
|
||||
bool isFromDashboard;
|
||||
|
||||
MarkAttendanceWidget( {Key? key, this.topPadding = 0, this.isFromDashboard = false}) : super(key: key);
|
||||
// todo MarkAttendanceWidget(this.model, {Key? key, this.topPadding = 0, this.isFromDashboard = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MarkAttendanceWidgetState createState() {
|
||||
return _MarkAttendanceWidgetState();
|
||||
}
|
||||
}
|
||||
|
||||
class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
|
||||
bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false;
|
||||
|
||||
int _locationUpdateCbId = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
checkAttendanceAvailability();
|
||||
}
|
||||
|
||||
void checkAttendanceAvailability() async {
|
||||
bool isAvailable = await NfcManager.instance.isAvailable();
|
||||
// setState(() {
|
||||
// AppState().privilegeListModel!.forEach((PrivilegeListModel element) {
|
||||
// if (element.serviceName == "enableNFC") {
|
||||
// if (isAvailable) if (element.previlege ?? false) isNfcEnabled = true;
|
||||
// } else if (element.serviceName == "enableQR") {
|
||||
// if (element.previlege ?? false) isQrEnabled = true;
|
||||
// } else if (element.serviceName == "enableWIFI") {
|
||||
// if (element.previlege ?? false) isWifiEnabled = true;
|
||||
// } else if (element.serviceName!.trim() == "enableLocationNFC") {
|
||||
// if (element.previlege ?? false) isNfcLocationEnabled = true;
|
||||
// } else if (element.serviceName == "enableLocationQR") {
|
||||
// if (element.previlege ?? false) isQrLocationEnabled = true;
|
||||
// } else if (element.serviceName == "enableLocationWIFI") {
|
||||
// if (element.previlege ?? false) isWifiLocationEnabled = true;
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
void checkHuaweiLocationPermission(String attendanceType) async {
|
||||
// Permission_Handler permissionHandler = PermissionHandler();
|
||||
location.Location.isEnabled((bool isEnabled) async {
|
||||
if (isEnabled) {
|
||||
location.Location.havePermission((bool permission) async {
|
||||
if (permission) {
|
||||
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);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
} 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);
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
Future<bool> requestPermissions() async {
|
||||
var result = await [
|
||||
Permission.location,
|
||||
].request();
|
||||
return (result[Permission.location] == PermissionStatus.granted || result[Permission.locationAlways] == PermissionStatus.granted);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
// Stop Session
|
||||
NfcManager.instance.stopSession();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 21, right: 21, bottom: 21, top: widget.topPadding),
|
||||
decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// LocaleKeys.markAttendance.tr().toSectionHeading(),
|
||||
// LocaleKeys.selectMethodOfAttendance.tr().toText11(color: const Color(0xff535353)),
|
||||
GridView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.only(bottom: 0, top: 21),
|
||||
gridDelegate:
|
||||
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8),
|
||||
children: <Widget>[
|
||||
attendanceMethod("NFC", Icons.nfc, isNfcEnabled, () {
|
||||
// if (AppState().getIsHuawei) {
|
||||
if (false) {
|
||||
checkHuaweiLocationPermission("NFC");
|
||||
} else {
|
||||
location.Location.isEnabled((bool isEnabled) {
|
||||
if (isEnabled) {
|
||||
location.Location.havePermission((bool permission) {
|
||||
if (permission) {
|
||||
Utils.showLoading(context);
|
||||
location.Location.getCurrentLocation(
|
||||
(Position position, bool isMocked) {
|
||||
if (isMocked) {
|
||||
Utils.hideLoading(context);
|
||||
markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
|
||||
} else {
|
||||
Utils.hideLoading(context);
|
||||
//todo performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
|
||||
}
|
||||
},
|
||||
() {
|
||||
Utils.hideLoading(context);
|
||||
Utils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
|
||||
},
|
||||
context,
|
||||
);
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext cxt) => ConfirmDialog(
|
||||
message: "You need to give location permission to mark attendance",
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
await Geolocator.openAppSettings();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
} 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 (isWifiEnabled) //todo
|
||||
attendanceMethod("Wifi", Icons.wifi, isWifiEnabled, () {
|
||||
// if (AppState().getIsHuawei) {
|
||||
if (false) {
|
||||
checkHuaweiLocationPermission("WIFI");
|
||||
} else {
|
||||
location.Location.isEnabled((bool isEnabled) {
|
||||
if (isEnabled) {
|
||||
location.Location.havePermission((bool permission) {
|
||||
if (permission) {
|
||||
Utils.showLoading(context);
|
||||
location.Location.getCurrentLocation(
|
||||
(Position position, bool isMocked) {
|
||||
if (isMocked) {
|
||||
Utils.hideLoading(context);
|
||||
markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
|
||||
} else {
|
||||
Utils.hideLoading(context);
|
||||
//todo performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
|
||||
}
|
||||
},
|
||||
() {
|
||||
Utils.hideLoading(context);
|
||||
Utils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
|
||||
},
|
||||
context,
|
||||
);
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext cxt) => ConfirmDialog(
|
||||
message: "You need to give location permission to mark attendance",
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
await Geolocator.openAppSettings();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
} 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 (isQrEnabled) //todo
|
||||
attendanceMethod("QR", Icons.qr_code_2, isQrEnabled, () async {
|
||||
// if (AppState().getIsHuawei) {
|
||||
if (false) {
|
||||
checkHuaweiLocationPermission("QR");
|
||||
} else {
|
||||
location.Location.isEnabled((bool isEnabled) {
|
||||
if (isEnabled) {
|
||||
location.Location.havePermission((bool permission) {
|
||||
if (permission) {
|
||||
Utils.showLoading(context);
|
||||
location.Location.getCurrentLocation(
|
||||
(Position position, bool isMocked) {
|
||||
if (isMocked) {
|
||||
Utils.hideLoading(context);
|
||||
markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
|
||||
} else {
|
||||
Utils.hideLoading(context);
|
||||
//todo performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
|
||||
}
|
||||
},
|
||||
() {
|
||||
Utils.hideLoading(context);
|
||||
Utils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
|
||||
},
|
||||
context,
|
||||
);
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext cxt) => ConfirmDialog(
|
||||
message: "You need to give location permission to mark attendance",
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
await Geolocator.openAppSettings();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
} 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();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void getHuaweiCurrentLocation(String attendanceType) async {
|
||||
try {
|
||||
Utils.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);
|
||||
|
||||
late StreamSubscription<Location> _streamSubscription;
|
||||
int requestCode = (await (locationService.requestLocationUpdates(locationRequest)))!;
|
||||
|
||||
_streamSubscription = locationService.onLocationData!.listen(
|
||||
(Location location) async {
|
||||
Utils.hideLoading(context);
|
||||
await locationService.removeLocationUpdates(requestCode);
|
||||
if (attendanceType == "QR") {
|
||||
// todo performQrCodeAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
|
||||
}
|
||||
if (attendanceType == "WIFI") {
|
||||
// todo performWifiAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
|
||||
}
|
||||
if (attendanceType == "NFC") {
|
||||
//todo performNfcAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
|
||||
}
|
||||
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) {
|
||||
// print("HUAWEI LOCATION getLastLocation ERROR!!!!!");
|
||||
// print(error);
|
||||
// });
|
||||
// }).catchError((error) {
|
||||
// print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
|
||||
// print(error);
|
||||
// if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
|
||||
// // Location service not enabled.
|
||||
// }
|
||||
// });
|
||||
} catch (error) {
|
||||
print("HUAWEI LOCATION ERROR!!!!!");
|
||||
print(error);
|
||||
Utils.hideLoading(context);
|
||||
// Utils.handleException(error, context, null);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Future<void> performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
|
||||
// if (Platform.isIOS) {
|
||||
// Utils.readNFc(onRead: (String nfcId) async {
|
||||
// Utils.showLoading(context);
|
||||
// try {
|
||||
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId, isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
|
||||
// if (g?.messageStatus != 1) {
|
||||
// Utils.hideLoading(context);
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext cxt) => ConfirmDialog(
|
||||
// message: g?.errorEndUserMessage ?? "Unexpected error occurred",
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// bool status = await model.fetchAttendanceTracking(context);
|
||||
// if (Platform.isIOS) await Future.delayed(const Duration(seconds: 3));
|
||||
// Utils.hideLoading(context);
|
||||
// showMDialog(
|
||||
// context,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// isDismissable: true,
|
||||
// child: SuccessDialog(widget.isFromDashboard),
|
||||
// );
|
||||
// }
|
||||
// } catch (ex) {
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.handleException(ex, context, null);
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// showNfcReader(context, onNcfScan: (String? nfcId) async {
|
||||
// Utils.showLoading(context);
|
||||
// try {
|
||||
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
|
||||
// if (g?.messageStatus != 1) {
|
||||
// Utils.hideLoading(context);
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext cxt) => ConfirmDialog(
|
||||
// message: g?.errorEndUserMessage ?? "Unexpected error occurred",
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// bool status = await model.fetchAttendanceTracking(context);
|
||||
// Utils.hideLoading(context);
|
||||
// showMDialog(
|
||||
// context,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// isDismissable: false,
|
||||
// child: SuccessDialog(widget.isFromDashboard),
|
||||
// );
|
||||
// }
|
||||
// } catch (ex) {
|
||||
// print(ex);
|
||||
// Utils.hideLoading(context);
|
||||
// // Utils.handleException(ex, context, (String msg) {
|
||||
// // Utils.confirmDialog(context, msg);
|
||||
// // });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
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,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
//
|
||||
// Future<bool> checkSession() async {
|
||||
// try {
|
||||
// Utils.showLoading(context);
|
||||
// await DashboardApiClient().getOpenMissingSwipes();
|
||||
// Utils.hideLoading(context);
|
||||
// return true;
|
||||
// } catch (ex) {
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.handleException(ex, context, null);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Future<void> performWifiAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
|
||||
// if (Platform.isAndroid) {
|
||||
// if (!(await checkSession())) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// Utils.showLoading(context);
|
||||
// bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "",
|
||||
// password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false);
|
||||
//
|
||||
// if (Platform.isIOS) {
|
||||
// if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) {
|
||||
// isConnected = true;
|
||||
// } else {
|
||||
// isConnected = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (isConnected && AppState().isAuthenticated) {
|
||||
// await WiFiForIoTPlugin.forceWifiUsage(true);
|
||||
// await Future.delayed(const Duration(seconds: 6));
|
||||
// try {
|
||||
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 3, nfcValue: "", isGpsRequired: isWifiLocationEnabled, lat: lat, long: lng);
|
||||
// bool status = await model.fetchAttendanceTracking(context);
|
||||
// Utils.hideLoading(context);
|
||||
// await closeWifiRequest();
|
||||
// if (g?.messageStatus == 2) {
|
||||
// showDialog(
|
||||
// barrierDismissible: true,
|
||||
// context: context,
|
||||
// builder: (cxt) => ConfirmDialog(
|
||||
// message: g?.errorEndUserMessage ?? "",
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// },
|
||||
// onCloseTap: () {},
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// showMDialog(
|
||||
// context,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// isDismissable: false,
|
||||
// child: SuccessDialog(widget.isFromDashboard),
|
||||
// );
|
||||
// }
|
||||
// } catch (ex) {
|
||||
// await closeWifiRequest();
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.handleException(ex, context, null);
|
||||
// }
|
||||
// } else {
|
||||
// if (AppState().isAuthenticated) {
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.confirmDialog(context, "LocaleKeys.comeNearHMGWifi.tr()");
|
||||
// } else {
|
||||
// await closeWifiRequest();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<bool> closeWifiRequest() async {
|
||||
if (Platform.isAndroid) {
|
||||
await WiFiForIoTPlugin.forceWifiUsage(false);
|
||||
}
|
||||
return await WiFiForIoTPlugin.disconnect();
|
||||
}
|
||||
|
||||
// Future<void> performQrCodeAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
|
||||
// var qrCodeValue = await Navigator.of(context).push(
|
||||
// MaterialPageRoute(
|
||||
// builder: (BuildContext context) => QrScannerDialog(),
|
||||
// ),
|
||||
// );
|
||||
// if (qrCodeValue != null) {
|
||||
// Utils.showLoading(context);
|
||||
// try {
|
||||
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 1, isGpsRequired: isQrLocationEnabled, lat: lat, long: lng, QRValue: qrCodeValue);
|
||||
// bool status = await model.fetchAttendanceTracking(context);
|
||||
// Utils.hideLoading(context);
|
||||
// if (g?.messageStatus == 2) {
|
||||
// showDialog(
|
||||
// barrierDismissible: true,
|
||||
// context: context,
|
||||
// builder: (cxt) => ConfirmDialog(
|
||||
// message: g?.errorEndUserMessage ?? "",
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// },
|
||||
// onCloseTap: () {},
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// showMDialog(
|
||||
// context,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// isDismissable: true,
|
||||
// child: SuccessDialog(widget.isFromDashboard),
|
||||
// );
|
||||
// }
|
||||
// } catch (ex) {
|
||||
// print(ex);
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.handleException(ex, context, null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void markFakeAttendance(String sourceName, String lat, String long) async {
|
||||
Utils.showLoading(context);
|
||||
try {
|
||||
// await DashboardApiClient().markFakeLocation(sourceName: sourceName, lat: lat, long: long);
|
||||
Utils.hideLoading(context);
|
||||
Utils.confirmDialog(context, "LocaleKeys.fakeLocation.tr()");
|
||||
} catch (ex) {
|
||||
print(ex);
|
||||
Utils.hideLoading(context);
|
||||
//Utils.handleException(ex, context, null);
|
||||
}
|
||||
}
|
||||
|
||||
Widget attendanceMethod(String title, IconData iconData, bool isEnabled, VoidCallback onPress) => 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: [
|
||||
//MyColors.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(
|
||||
() {
|
||||
if (!isEnabled) return;
|
||||
onPress();
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,199 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:nfc_manager/nfc_manager.dart';
|
||||
import 'package:nfc_manager/platform_tags.dart';
|
||||
|
||||
void showNfcReader(BuildContext context, {required Function(String? nfcId) onNcfScan}) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
enableDrag: false,
|
||||
isDismissible: false,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
builder: (context) {
|
||||
return NfcLayout(
|
||||
onNcfScan: onNcfScan,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class NfcLayout extends StatefulWidget {
|
||||
Function(String? nfcId) onNcfScan;
|
||||
|
||||
NfcLayout({required this.onNcfScan});
|
||||
|
||||
@override
|
||||
_NfcLayoutState createState() => _NfcLayoutState();
|
||||
}
|
||||
|
||||
class _NfcLayoutState extends State<NfcLayout> {
|
||||
bool _reading = false;
|
||||
Widget? mainWidget;
|
||||
String? nfcId;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
|
||||
var 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('');
|
||||
nfcId = identifier;
|
||||
|
||||
setState(() {
|
||||
_reading = true;
|
||||
mainWidget = doneNfc();
|
||||
});
|
||||
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
NfcManager.instance.stopSession();
|
||||
Navigator.pop(context);
|
||||
// if (Platform.isAndroid) {
|
||||
// Navigator.pop(context);
|
||||
// } else {
|
||||
// Navigator.pop(context);
|
||||
// Navigator.pop(context);
|
||||
// }
|
||||
widget.onNcfScan(nfcId);
|
||||
});
|
||||
}).catchError((err) {
|
||||
print(err);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
(mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc();
|
||||
return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget);
|
||||
}
|
||||
|
||||
Widget scanNfc() {
|
||||
return Container(
|
||||
key: ValueKey(1),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"Ready To Scan",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Image.asset(
|
||||
"assets/icons/nfc/ic_nfc.png",
|
||||
height: MediaQuery.of(context).size.width / 3,
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"Approach an NFC Tag",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
ButtonTheme(
|
||||
minWidth: MediaQuery.of(context).size.width / 1.2,
|
||||
height: 45.0,
|
||||
buttonColor: Colors.grey[300],
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
NfcManager.instance.stopSession();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
// elevation: 0,
|
||||
child: Text("CANCEL"),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget doneNfc() {
|
||||
return Container(
|
||||
key: ValueKey(2),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"Successfully Scanned",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Image.asset(
|
||||
"assets/icons/nfc/ic_done.png",
|
||||
height: MediaQuery.of(context).size.width / 3,
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"Approach an NFC Tag",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
ButtonTheme(
|
||||
minWidth: MediaQuery.of(context).size.width / 1.2,
|
||||
height: 45.0,
|
||||
buttonColor: Colors.grey[300],
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: TextButton(
|
||||
// onPressed: () {
|
||||
// _stream?.cancel();
|
||||
// widget.onNcfScan(nfcId);
|
||||
// Navigator.pop(context);
|
||||
// },
|
||||
onPressed: null,
|
||||
// elevation: 0,
|
||||
child: Text("DONE"),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
import 'package:flutter/material.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/new_views/common_widgets/app_filled_button.dart';
|
||||
|
||||
class ConfirmDialog extends StatelessWidget {
|
||||
final String? title;
|
||||
final String message;
|
||||
final String? okTitle;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onCloseTap;
|
||||
|
||||
const ConfirmDialog({Key? key, this.title, required this.message, this.okTitle, this.onTap, this.onCloseTap}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
backgroundColor: Colors.white,
|
||||
shape: const RoundedRectangleBorder(),
|
||||
insetPadding: const EdgeInsets.only(left: 21, right: 21),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
title ?? "Confirm",
|
||||
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black87, height: 35 / 24, letterSpacing: -0.96),
|
||||
).paddingOnly(top: 16),
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(Icons.close),
|
||||
color: Colors.black87,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () => onCloseTap ?? Navigator.pop(context),
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
)
|
||||
],
|
||||
),
|
||||
message.bodyText(context),
|
||||
28.height,
|
||||
AppFilledButton(
|
||||
label: okTitle ?? "OK",
|
||||
onPressed: onTap ?? () => Navigator.pop(context),
|
||||
textColor: Colors.white,
|
||||
//color: Ap.green,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:lottie/lottie.dart';
|
||||
|
||||
class SuccessDialog extends StatefulWidget {
|
||||
bool isFromDashboard;
|
||||
|
||||
SuccessDialog(this.isFromDashboard);
|
||||
|
||||
@override
|
||||
State<SuccessDialog> createState() => _SuccessDialogState();
|
||||
}
|
||||
|
||||
class _SuccessDialogState extends State<SuccessDialog> with TickerProviderStateMixin {
|
||||
late AnimationController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_controller = AnimationController(vsync: this);
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future<void> playSuccessSound() async {
|
||||
AudioPlayer player = AudioPlayer();
|
||||
String audioAsset = "";
|
||||
if (Platform.isAndroid) {
|
||||
audioAsset = "assets/audio/success_tone_android.mp3";
|
||||
} else {
|
||||
audioAsset = "assets/audio/success_tone_ios.caf";
|
||||
}
|
||||
await player.setAsset(audioAsset);
|
||||
await player.load();
|
||||
player.play();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double size = MediaQuery.of(context).size.width / 1.8;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: size,
|
||||
height: size,
|
||||
child: Card(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(25.0),
|
||||
),
|
||||
child: Lottie.asset(
|
||||
'assets/lottie/lt_success.json',
|
||||
repeat: false,
|
||||
reverse: false,
|
||||
controller: _controller,
|
||||
frameRate: FrameRate(60.0),
|
||||
onLoaded: (LottieComposition v) async {
|
||||
await playSuccessSound();
|
||||
_controller
|
||||
..duration = v.duration
|
||||
..forward().whenComplete(() async {
|
||||
Navigator.pop(context);
|
||||
if (widget.isFromDashboard) Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
|
||||
|
||||
class QrScannerDialog extends StatefulWidget {
|
||||
@override
|
||||
State<QrScannerDialog> createState() => _QrScannerDialogState();
|
||||
}
|
||||
|
||||
class _QrScannerDialogState extends State<QrScannerDialog> {
|
||||
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
||||
Barcode? result;
|
||||
QRViewController? controller;
|
||||
bool isPicked = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: QRView(
|
||||
key: qrKey,
|
||||
onQRViewCreated: _onQRViewCreated,
|
||||
),
|
||||
),
|
||||
// Expanded(
|
||||
// flex: 1,
|
||||
// child: Center(
|
||||
// child: (result != null)
|
||||
// ? Text(
|
||||
// 'Barcode Type: ${result!.format} Data: ${result!.code}')
|
||||
// : Text('Scan a code'),
|
||||
// ),
|
||||
// ),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: AppFilledButton(
|
||||
label: "LocaleKeys.cancel.tr()",
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onQRViewCreated(QRViewController controller) {
|
||||
this.controller = controller;
|
||||
|
||||
controller.scannedDataStream.listen((scanData) {
|
||||
setState(() {
|
||||
result = scanData;
|
||||
if (!isPicked) {
|
||||
isPicked = true;
|
||||
Navigator.pop(context, result!.code);
|
||||
}
|
||||
});
|
||||
});
|
||||
controller.pauseCamera();
|
||||
controller.resumeCamera();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue