|  |  |  | import 'dart:async'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import 'package:easy_localization/src/public_ext.dart'; | 
					
						
							|  |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | import 'package:flutter_svg/svg.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/classes/colors.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/extensions/int_extensions.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/extensions/string_extensions.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/widgets/button/default_button.dart'; | 
					
						
							|  |  |  | import 'package:mohem_flutter_app/widgets/otp_widget.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | final ValueNotifier<String> otpFieldClear = ValueNotifier<String>(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class OtpDialog { | 
					
						
							|  |  |  |   final int type; | 
					
						
							|  |  |  |   final int? mobileNo; | 
					
						
							|  |  |  |   final Function(String, TextEditingController _pinPutController) onSuccess; | 
					
						
							|  |  |  |   final Function onFailure; | 
					
						
							|  |  |  |   final BuildContext context; | 
					
						
							|  |  |  |   final Function onResendCode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int remainingTime = 120; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Future<Null>? timer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static BuildContext? _context; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static bool? _loading; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   OtpDialog(this.context, this.type, this.mobileNo, this.onSuccess, this.onFailure, {required this.onResendCode}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GlobalKey? verifyAccountForm = GlobalKey<FormState>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final TextEditingController _pinPutController = TextEditingController(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   TextEditingController digit1 = TextEditingController(text: ""); | 
					
						
							|  |  |  |   TextEditingController digit2 = TextEditingController(text: ""); | 
					
						
							|  |  |  |   TextEditingController digit3 = TextEditingController(text: ""); | 
					
						
							|  |  |  |   TextEditingController digit4 = TextEditingController(text: ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Map verifyAccountFormValue = { | 
					
						
							|  |  |  |     'digit1': '', | 
					
						
							|  |  |  |     'digit2': '', | 
					
						
							|  |  |  |     'digit3': '', | 
					
						
							|  |  |  |     'digit4': '', | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   final focusD1 = FocusNode(); | 
					
						
							|  |  |  |   final focusD2 = FocusNode(); | 
					
						
							|  |  |  |   final focusD3 = FocusNode(); | 
					
						
							|  |  |  |   final focusD4 = FocusNode(); | 
					
						
							|  |  |  |   String? errorMsg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ProjectViewModel projectProvider;
 | 
					
						
							|  |  |  |   String displayTime = ''; | 
					
						
							|  |  |  |   String? _code; | 
					
						
							|  |  |  |   dynamic setState; | 
					
						
							|  |  |  |   bool stopTimer = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // static String signature;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void displayDialog(BuildContext context) async { | 
					
						
							|  |  |  |     return showDialog( | 
					
						
							|  |  |  |         context: context, | 
					
						
							|  |  |  |         barrierColor: Colors.black.withOpacity(0.63), | 
					
						
							|  |  |  |         builder: (context) { | 
					
						
							|  |  |  |           // projectProvider = Provider.of(context);
 | 
					
						
							|  |  |  |           return Dialog( | 
					
						
							|  |  |  |             backgroundColor: Colors.white, | 
					
						
							|  |  |  |             surfaceTintColor: Colors.transparent, | 
					
						
							|  |  |  |             shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), | 
					
						
							|  |  |  |             insetPadding: const EdgeInsets.only(left: 21, right: 21), | 
					
						
							|  |  |  |             child: StatefulBuilder(builder: (context, setState) { | 
					
						
							|  |  |  |               if (displayTime == '') { | 
					
						
							|  |  |  |                 startTimer(setState); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               return Container( | 
					
						
							|  |  |  |                 padding: EdgeInsets.all(21), | 
					
						
							|  |  |  |                 child: Column( | 
					
						
							|  |  |  |                   mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |                   crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |                   children: [ | 
					
						
							|  |  |  |                     SvgPicture.asset( | 
					
						
							|  |  |  |                       type == 1 | 
					
						
							|  |  |  |                           ? "assets/images/login/verify_sms.svg" | 
					
						
							|  |  |  |                           : type == 2 | 
					
						
							|  |  |  |                               ? "assets/images/login/verify_whatsapp.svg" | 
					
						
							|  |  |  |                               : type == 3 | 
					
						
							|  |  |  |                                   ? "assets/images/login/verify_face.svg" | 
					
						
							|  |  |  |                                   : 'assets/images/login/verify_thumb.svg', | 
					
						
							|  |  |  |                       height: 50, | 
					
						
							|  |  |  |                       width: 50, | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                     12.height, | 
					
						
							|  |  |  |                     LocaleKeys.otp.tr().toText14(), | 
					
						
							|  |  |  |                     LocaleKeys.verification.tr().toText24(isBold: true), | 
					
						
							|  |  |  |                     6.height, | 
					
						
							|  |  |  |                     (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16(), | 
					
						
							|  |  |  |                     18.height, | 
					
						
							|  |  |  |                     ValueListenableBuilder<String>( | 
					
						
							|  |  |  |                       builder: (BuildContext context, String value, Widget? child) { | 
					
						
							|  |  |  |                         // This builder will only get called when the _counter
 | 
					
						
							|  |  |  |                         // is updated.
 | 
					
						
							|  |  |  |                         return Column( | 
					
						
							|  |  |  |                           crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |                           children: [ | 
					
						
							|  |  |  |                             Directionality( | 
					
						
							|  |  |  |                               textDirection: TextDirection.ltr, | 
					
						
							|  |  |  |                               child: Center( | 
					
						
							|  |  |  |                                 child: OTPWidget( | 
					
						
							|  |  |  |                                   autoFocus: true, | 
					
						
							|  |  |  |                                   controller: _pinPutController, | 
					
						
							|  |  |  |                                   defaultBorderColor: const Color(0xffD8D8D8), | 
					
						
							|  |  |  |                                   maxLength: 4, | 
					
						
							|  |  |  |                                   onTextChanged: (text) {}, | 
					
						
							|  |  |  |                                   pinBoxColor: Colors.white, | 
					
						
							|  |  |  |                                   onDone: (code) => _onOtpCallBack(code, null), | 
					
						
							|  |  |  |                                   textBorderColor: const Color(0xffD8D8D8), | 
					
						
							|  |  |  |                                   pinBoxWidth: 60, | 
					
						
							|  |  |  |                                   pinBoxHeight: 60, | 
					
						
							|  |  |  |                                   pinTextStyle: const TextStyle(fontSize: 24.0, color: MyColors.darkTextColor), | 
					
						
							|  |  |  |                                   pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition, | 
					
						
							|  |  |  |                                   pinTextAnimatedSwitcherDuration: const Duration(milliseconds: 300), | 
					
						
							|  |  |  |                                   pinBoxRadius: 10, | 
					
						
							|  |  |  |                                   keyboardType: TextInputType.number, | 
					
						
							|  |  |  |                                 ), | 
					
						
							|  |  |  |                               ), | 
					
						
							|  |  |  |                             ), | 
					
						
							|  |  |  |                             10.height, | 
					
						
							|  |  |  |                             stopTimer | 
					
						
							|  |  |  |                                 ? Row( | 
					
						
							|  |  |  |                                     children: [ | 
					
						
							|  |  |  |                                       Expanded( | 
					
						
							|  |  |  |                                         child: LocaleKeys.codeExpire.tr().toText16( | 
					
						
							|  |  |  |                                               color: MyColors.redColor, | 
					
						
							|  |  |  |                                             ), | 
					
						
							|  |  |  |                                       ), | 
					
						
							|  |  |  |                                       12.width, | 
					
						
							|  |  |  |                                       Image.asset( | 
					
						
							|  |  |  |                                         "assets/icons/ic_alarm.png", | 
					
						
							|  |  |  |                                         width: 20, | 
					
						
							|  |  |  |                                         height: 20, | 
					
						
							|  |  |  |                                         color: MyColors.redColor, | 
					
						
							|  |  |  |                                       ), | 
					
						
							|  |  |  |                                     ], | 
					
						
							|  |  |  |                                   ) | 
					
						
							|  |  |  |                                 : RichText( | 
					
						
							|  |  |  |                                     text: TextSpan( | 
					
						
							|  |  |  |                                       text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', | 
					
						
							|  |  |  |                                       style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), | 
					
						
							|  |  |  |                                       children: <TextSpan>[ | 
					
						
							|  |  |  |                                         TextSpan( | 
					
						
							|  |  |  |                                           text: displayTime, | 
					
						
							|  |  |  |                                           style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), | 
					
						
							|  |  |  |                                         ), | 
					
						
							|  |  |  |                                       ], | 
					
						
							|  |  |  |                                     ), | 
					
						
							|  |  |  |                                   ), | 
					
						
							|  |  |  |                           ], | 
					
						
							|  |  |  |                         ); | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                       valueListenable: otpFieldClear, | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                     18.height, | 
					
						
							|  |  |  |                     DefaultButton( | 
					
						
							|  |  |  |                       stopTimer ? LocaleKeys.resend.tr() : LocaleKeys.cancel.tr(), | 
					
						
							|  |  |  |                       () async { | 
					
						
							|  |  |  |                         if (stopTimer) { | 
					
						
							|  |  |  |                           hideSMSBox(context); | 
					
						
							|  |  |  |                           onResendCode(); | 
					
						
							|  |  |  |                         } else { | 
					
						
							|  |  |  |                           stopTimer = true; | 
					
						
							|  |  |  |                           // onFailure();
 | 
					
						
							|  |  |  |                           hideSMSBox(context); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                       colors: stopTimer | 
					
						
							|  |  |  |                           ? null | 
					
						
							|  |  |  |                           : [ | 
					
						
							|  |  |  |                               MyColors.pinkDarkColor, | 
					
						
							|  |  |  |                               MyColors.pinkDarkColor, | 
					
						
							|  |  |  |                             ], | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   ], | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |               ); | 
					
						
							|  |  |  |             }), | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   InputDecoration buildInputDecoration(BuildContext context) { | 
					
						
							|  |  |  |     return InputDecoration( | 
					
						
							|  |  |  |       counterText: " ", | 
					
						
							|  |  |  |       enabledBorder: const OutlineInputBorder( | 
					
						
							|  |  |  |         borderRadius: BorderRadius.all(Radius.circular(10)), | 
					
						
							|  |  |  |         borderSide: BorderSide(color: Colors.black), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |       focusedBorder: OutlineInputBorder( | 
					
						
							|  |  |  |         borderRadius: const BorderRadius.all(Radius.circular(10.0)), | 
					
						
							|  |  |  |         borderSide: BorderSide(color: Theme.of(context).primaryColor), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |       errorBorder: OutlineInputBorder( | 
					
						
							|  |  |  |         borderRadius: const BorderRadius.all(Radius.circular(10.0)), | 
					
						
							|  |  |  |         borderSide: BorderSide(color: Colors.red), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |       // focusedErrorBorder: OutlineInputBorder(
 | 
					
						
							|  |  |  |       //   borderRadius: const BorderRadius.all(Radius.circular(10.0)),
 | 
					
						
							|  |  |  |       //   borderSide: BorderSide(color: Colors.red),
 | 
					
						
							|  |  |  |       //   // borderSide: BorderSide(color: Theme.of(context).colorScheme.error),
 | 
					
						
							|  |  |  |       // ),
 | 
					
						
							|  |  |  |       focusedErrorBorder: OutlineInputBorder( | 
					
						
							|  |  |  |         borderRadius: const BorderRadius.all(Radius.circular(10.0)), | 
					
						
							|  |  |  |         borderSide: BorderSide(color: Theme.of(context).colorScheme.error), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // String validateCodeDigit(value) {
 | 
					
						
							|  |  |  |   //   if (value.isEmpty) {
 | 
					
						
							|  |  |  |   //     return ' ';
 | 
					
						
							|  |  |  |   //   } else if (value.length == 3) {
 | 
					
						
							|  |  |  |   //     print(value);
 | 
					
						
							|  |  |  |   //   } else {
 | 
					
						
							|  |  |  |   //     return null;
 | 
					
						
							|  |  |  |   //   }
 | 
					
						
							|  |  |  |   // }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String getSecondsAsDigitalClock(int inputSeconds) { | 
					
						
							|  |  |  |     int secNum = int.parse(inputSeconds.toString()); // don't forget the second param
 | 
					
						
							|  |  |  |     int hours = (secNum / 3600).floor(); | 
					
						
							|  |  |  |     int minutes = ((secNum - hours * 3600) / 60).floor(); | 
					
						
							|  |  |  |     double seconds = secNum - hours * 3600 - minutes * 60; | 
					
						
							|  |  |  |     String minutesString = ""; | 
					
						
							|  |  |  |     String secondsString = ""; | 
					
						
							|  |  |  |     minutesString = minutes < 10 ? "0" + minutes.toString() : minutes.toString(); | 
					
						
							|  |  |  |     secondsString = seconds < 10 ? "0" + seconds.toStringAsFixed(0) : seconds.toStringAsFixed(0); | 
					
						
							|  |  |  |     return minutesString + ":" + secondsString; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void startTimer(setState) { | 
					
						
							|  |  |  |     remainingTime--; | 
					
						
							|  |  |  |     if (stopTimer) return; | 
					
						
							|  |  |  |     setState(() { | 
					
						
							|  |  |  |       displayTime = getSecondsAsDigitalClock(remainingTime); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     timer = Future.delayed(const Duration(seconds: 1), () { | 
					
						
							|  |  |  |       if (remainingTime > 0) { | 
					
						
							|  |  |  |         startTimer(setState); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         setState(() { | 
					
						
							|  |  |  |           stopTimer = true; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void hideSMSBox(context) { | 
					
						
							|  |  |  |     onFailure(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void _onOtpCallBack(String otpCode, bool? isAutofill) { | 
					
						
							|  |  |  |     if (otpCode.length == 4) { | 
					
						
							|  |  |  |       // stopTimer = true;
 | 
					
						
							|  |  |  |       otpFieldClear.value = otpCode; | 
					
						
							|  |  |  |       onSuccess(otpCode, _pinPutController); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // static getSignature() async {
 | 
					
						
							|  |  |  | //   // if (Platform.isAndroid) {
 | 
					
						
							|  |  |  | //   //   return await SmsRetriever.getAppSignature();
 | 
					
						
							|  |  |  | //   // } else {
 | 
					
						
							|  |  |  | //   //   return null;
 | 
					
						
							|  |  |  | //   // }
 | 
					
						
							|  |  |  | // }
 | 
					
						
							|  |  |  | } |