import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_nurses/classes/enums.dart'; import 'package:hmg_nurses/classes/utils.dart'; import 'package:hmg_nurses/config/routes.dart'; import 'package:hmg_nurses/main.dart'; import 'package:hmg_nurses/model/base/generic_response_model.dart'; import 'package:hmg_nurses/model/login/imei_details_model.dart'; import 'package:hmg_nurses/model/login/member_login_model.dart'; import 'package:hmg_nurses/model/login/project_info_model.dart'; import 'package:hmg_nurses/provider/base_vm.dart'; import 'package:hmg_nurses/services/api_repo/login_api_repo.dart'; import 'package:hmg_nurses/widgets/dialogs/otp_dialog.dart'; import 'package:injector/injector.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; class LoginProviderModel extends BaseViewModel { //UI variables late LocalAuthentication auth; late bool isFaceBioAvailable, isFingerBioAvailable; late List _availableBiometrics; //API's variables late List assignedBranches; final ILoginApiRepo _loginApiRepo = Injector.appInstance.get(); LoginProviderModel() { setOnlyState(ViewState.hide); checkBiosAvailblity(); } checkBiosAvailblity() async { auth = LocalAuthentication(); await _getAvailableBiometrics(); isFaceBioAvailable = checkBiometricIsAvailable(BiometricType.face); isFingerBioAvailable = checkBiometricIsAvailable(BiometricType.fingerprint); } /// check specific biometric if it available or not bool checkBiometricIsAvailable(BiometricType biometricType) { bool isAvailable = false; for (int i = 0; i < _availableBiometrics.length; i++) { if (biometricType == _availableBiometrics[i]) { isAvailable = true; break; } } return isAvailable; } /// get all available biometric on the device for local Auth service Future _getAvailableBiometrics() async { try { _availableBiometrics = await auth.getAvailableBiometrics(); print(_availableBiometrics); } on PlatformException catch (e) { // AppToast.showErrorToast(message: e.message); print("_getAvailableBiometrics"); print(e); } } Future loginWithFaceIDAndBiometrics() async { IOSAuthMessages iosStrings = const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); bool authenticated = false; try { authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, biometricOnly: true, iOSAuthStrings: iosStrings); } on PlatformException catch (e) { print(e); Utils.hideLoading(); Utils.showToast("Please enable your Touch or Face ID"); } return authenticated; } int getLoginMethodId(AuthMethodTypes authMethodTypes) { switch (authMethodTypes) { case AuthMethodTypes.sms: return 1; case AuthMethodTypes.whatsApp: return 2; case AuthMethodTypes.fingerPrint: return 3; case AuthMethodTypes.faceID: return 4; default: return 1; } } //API Calls checkLastSession() async { try { Utils.showLoading(); List deviceInfo = await _loginApiRepo.getDeviceInfoByIMEI(); Utils.showToast(deviceInfo.length.toString()); Utils.hideLoading(); } catch (e) { Utils.hideLoading(); } } getAssignedBranches(String userId) async { setState(ViewState.busy); assignedBranches = await _loginApiRepo.getProjectInfo(userId); print(assignedBranches.length); setState(ViewState.idle); } performLogin(String userID, String password, int branchId) async { try { Utils.showLoading(); MemberLoginModel memberLogin = await _loginApiRepo.memberLogin(userID, password, branchId); // Utils.showToast(deviceInfo.length.toString()); appState.setMemberBeforeLogin = memberLogin; appState.projectID = branchId; appState.logInTokenID = memberLogin.logInTokenId; Utils.hideLoading(); Navigator.pushNamed(navigatorKey.currentContext!, AppRoutes.loginMethodsPage, arguments: LoginType.FROM_LOGIN); } catch (e) { Utils.hideLoading(); Utils.handleException(e, navigatorKey.currentContext!, (msg) { Utils.confirmDialog(navigatorKey.currentContext!, msg); }); } } Future sendActivationCode(MemberLoginModel memberLoginModel, int facilityID, int sendOtpType,bool isFromSilentLogin) async { try { Utils.showLoading(); GenericResponseModel memberLogin = await _loginApiRepo.sendActivationCode(memberLoginModel, facilityID, sendOtpType); // Utils.showToast(deviceInfo.length.toString()); Utils.hideLoading(); // Navigator.pushNamed(navigatorKey.currentContext!, AppRoutes.loginMethodsPage, arguments: LoginType.FROM_LOGIN); startSMSService(sendOtpType,isFromSilentLogin); return memberLogin; } catch (e) { Utils.hideLoading(); Utils.handleException(e, navigatorKey.currentContext!, (msg) { Utils.confirmDialog(navigatorKey.currentContext!, msg); }); } } Future checkActivationCode(String activationCode, int sendOtpType, bool isFromSilentLogin) async { try { Utils.showLoading(); GenericResponseModel memberLogin = await _loginApiRepo.checkActivationCode(activationCode, sendOtpType, isFromSilentLogin); // Utils.showToast(deviceInfo.length.toString()); _loginApiRepo.getDoctorProfile(); Utils.hideLoading(); return memberLogin; } catch (e) { Utils.hideLoading(); Utils.handleException(e, navigatorKey.currentContext!, (msg) { Utils.confirmDialog(navigatorKey.currentContext!, msg); }); } return null; } startSMSService(int sendOtpType, bool isFromSilentLogin) { OtpDialog( type: sendOtpType, mobileNo: appState.memberBeforeLogin!.mobileNumber, onSuccess: (String otpCode, TextEditingController pinPut) { Navigator.pop(navigatorKey.currentContext!); Utils.showLoading(); checkActivationCode(otpCode, sendOtpType, isFromSilentLogin); Utils.hideLoading(); }, onFailure: () => Navigator.pop(navigatorKey.currentContext!), onResendCode: () {}, ).displayDialog(navigatorKey.currentContext!); } }