@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
 
			
		
	
		
		
			
				
					
					import  ' package:flutter/rendering.dart ' ; import  ' package:flutter/rendering.dart ' ;  
			
		
	
		
		
			
				
					
					import  ' package:flutter/services.dart ' ; import  ' package:flutter/services.dart ' ;  
			
		
	
		
		
			
				
					
					import  ' package:hmg_patient_app_new/core/utils/size_utils.dart ' ; import  ' package:hmg_patient_app_new/core/utils/size_utils.dart ' ;  
			
		
	
		
		
			
				
					
					import  ' package:hmg_patient_app_new/extensions/widget_extensions.dart ' ;  
			
		
	
		
		
			
				
					
					import  ' package:hmg_patient_app_new/theme/colors.dart ' ; import  ' package:hmg_patient_app_new/theme/colors.dart ' ;  
			
		
	
		
		
			
				
					
					import  ' package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart ' ; import  ' package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart ' ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -50,12 +51,12 @@ class OTPWidget extends StatefulWidget {
 
			
		
	
		
		
			
				
					
					  final  TextInputType  keyboardType ; 
  final  TextInputType  keyboardType ; 
 
			
		
	
		
		
			
				
					
					  final  EdgeInsets  pinBoxOuterPadding ; 
  final  EdgeInsets  pinBoxOuterPadding ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  OTPWidget ( { 
  const  OTPWidget ( { 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    Key ?  key , 
    Key ?  key , 
 
			
		
	
		
		
			
				
					
					    this . maxLength  =  4 , 
    this . maxLength  =  4 , 
 
			
		
	
		
		
			
				
					
					    this . controller , 
    this . controller , 
 
			
		
	
		
		
			
				
					
					    this . pinBoxWidth  =  70.0 , 
    this . pinBoxWidth  =  70.0 , 
 
			
		
	
		
		
			
				
					
					    this . pinBoxHeight  =  10 0.0, 
    this . pinBoxHeight  =  7 0.0, 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    this . pinTextStyle , 
    this . pinTextStyle , 
 
			
		
	
		
		
			
				
					
					    this . onDone , 
    this . onDone , 
 
			
		
	
		
		
			
				
					
					    this . defaultBorderColor  =  Colors . black , 
    this . defaultBorderColor  =  Colors . black , 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -127,7 +128,9 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
			
		
	
		
		
			
				
					
					    _highlightAnimationController  =  AnimationController ( vsync:  this ) ; 
    _highlightAnimationController  =  AnimationController ( vsync:  this ) ; 
 
			
		
	
		
		
			
				
					
					    _initTextController ( ) ; 
    _initTextController ( ) ; 
 
			
		
	
		
		
			
				
					
					    _calculateStrList ( ) ; 
    _calculateStrList ( ) ; 
 
			
		
	
		
		
			
				
					
					    if  ( widget . controller  ! =  null )  { 
 
			
		
	
		
		
			
				
					
					      widget . controller ! . addListener ( _controllerListener ) ; 
      widget . controller ! . addListener ( _controllerListener ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					    focusNode . addListener ( _focusListener ) ; 
    focusNode . addListener ( _focusListener ) ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -190,7 +193,9 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
			
		
	
		
		
			
				
					
					      focusNode . removeListener ( _focusListener ) ; 
      focusNode . removeListener ( _focusListener ) ; 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					    _highlightAnimationController . dispose ( ) ; 
    _highlightAnimationController . dispose ( ) ; 
 
			
		
	
		
		
			
				
					
					    widget . controller ? . removeListener ( _controllerListener ) ; 
    if  ( widget . controller  ! =  null )  { 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      widget . controller ! . removeListener ( _controllerListener ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    super . dispose ( ) ; 
    super . dispose ( ) ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -231,7 +236,7 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
			
		
	
		
		
			
				
					
					        width:  0.0 , 
        width:  0.0 , 
 
			
		
	
		
		
			
				
					
					      ) , 
      ) , 
 
			
		
	
		
		
			
				
					
					    ) ; 
    ) ; 
 
			
		
	
		
		
			
				
					
					    return  SizedBox ( 
    return  Container ( 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      width:  _width , 
      width:  _width , 
 
			
		
	
		
		
			
				
					
					      height:  widget . pinBoxHeight , 
      height:  widget . pinBoxHeight , 
 
			
		
	
		
		
			
				
					
					      child:  TextField ( 
      child:  TextField ( 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -241,8 +246,6 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
			
		
	
		
		
			
				
					
					        controller:  widget . controller , 
        controller:  widget . controller , 
 
			
		
	
		
		
			
				
					
					        keyboardType:  widget . keyboardType , 
        keyboardType:  widget . keyboardType , 
 
			
		
	
		
		
			
				
					
					        inputFormatters:  widget . keyboardType  = =  TextInputType . number  ?  < TextInputFormatter > [ FilteringTextInputFormatter . digitsOnly ]  :  null , 
        inputFormatters:  widget . keyboardType  = =  TextInputType . number  ?  < TextInputFormatter > [ FilteringTextInputFormatter . digitsOnly ]  :  null , 
 
			
		
	
		
		
			
				
					
					        / /  Enable  SMS  autofill 
 
			
		
	
		
		
			
				
					
					        autofillHints:  const  [ AutofillHints . oneTimeCode ] , 
 
			
		
	
		
		
			
				
					
					        style:  TextStyle ( 
        style:  TextStyle ( 
 
			
		
	
		
		
			
				
					
					          height:  0.1 , 
          height:  0.1 , 
 
			
		
	
		
		
			
				
					
					          color:  Colors . transparent , 
          color:  Colors . transparent , 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -301,33 +304,28 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
			
		
	
		
		
			
				
					
					      return  _buildPinCode ( i ,  context ) ; 
      return  _buildPinCode ( i ,  context ) ; 
 
			
		
	
		
		
			
				
					
					    } ) ; 
    } ) ; 
 
			
		
	
		
		
			
				
					
					    return  Row ( 
    return  Row ( 
 
			
		
	
		
		
			
				
					
					      children:  pinCodes , 
 
			
		
	
		
		
			
				
					
					      mainAxisSize:  MainAxisSize . min , 
      mainAxisSize:  MainAxisSize . min , 
 
			
		
	
		
		
			
				
					
					      mainAxisAlignment:  MainAxisAlignment . spaceBetween , 
      mainAxisAlignment:  MainAxisAlignment . spaceBetween , 
 
			
		
	
		
		
			
				
					
					      children:  pinCodes , 
 
			
		
	
		
		
			
				
					
					    ) ; 
    ) ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  Widget  _buildPinCode ( int  i ,  BuildContext  context )  { 
  Widget  _buildPinCode ( int  i ,  BuildContext  context )  { 
 
			
		
	
		
		
			
				
					
					    Color  borderColor ; 
    Color  pinBoxColor  =  widget . pinBoxColor ; 
 
			
				
				
			
		
	
		
		
			
				
					
					    Color  pinBoxColor ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    / /  Determine  if  OTP  is  complete 
 
			
		
	
		
		
			
				
					
					    bool  isComplete  =  text . length  = =  widget . maxLength ; 
 
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    if  ( widget . hasError )  { 
    if  ( widget . hasError )  { 
 
			
		
	
		
		
			
				
					
					      borderColor  =  widget . errorBorderColor ; 
      pinBoxColor  =  widget . errorBorderColor ; 
 
			
				
				
			
		
	
		
		
			
				
					
					      pinBoxColor  =  widget . pinBoxColor ; 
 
			
		
	
		
		
			
				
					
					    }  else  if  ( isComplete )  { 
 
			
		
	
		
		
			
				
					
					      borderColor  =  Colors . transparent ; 
 
			
		
	
		
		
			
				
					
					      pinBoxColor  =  AppColors . successColor ; 
 
			
		
	
		
		
	
		
		
			
				
					
					    }  else  if  ( i  <  text . length )  { 
    }  else  if  ( i  <  text . length )  { 
 
			
		
	
		
		
			
				
					
					      borderColor  =  Colors . transparent ; 
      pinBoxColor  =  AppColors . blackBgColor ;  / /  Custom  color  for  filled  boxes 
 
			
				
				
			
		
	
		
		
			
				
					
					      pinBoxColor  =  AppColors . blackBgColor ; 
 
			
		
	
		
		
	
		
		
			
				
					
					    }  else  { 
    }  else  { 
 
			
		
	
		
		
			
				
					
					      borderColor  =  Colors . transparent ; 
 
			
		
	
		
		
			
				
					
					      pinBoxColor  =  widget . pinBoxColor ; 
      pinBoxColor  =  widget . pinBoxColor ; 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    / /  Change  color  to  success  when  all  fields  are  complete 
 
			
		
	
		
		
			
				
					
					    if  ( text . length  = =  widget . maxLength )  { 
 
			
		
	
		
		
			
				
					
					      pinBoxColor  =  AppColors . successColor ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    EdgeInsets  insets ; 
    EdgeInsets  insets ; 
 
			
		
	
		
		
			
				
					
					    if  ( i  = =  0 )  { 
    if  ( i  = =  0 )  { 
 
			
		
	
		
		
			
				
					
					      insets  =  EdgeInsets . only ( 
      insets  =  EdgeInsets . only ( 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -346,22 +344,21 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
			
		
	
		
		
			
				
					
					    }  else  { 
    }  else  { 
 
			
		
	
		
		
			
				
					
					      insets  =  widget . pinBoxOuterPadding ; 
      insets  =  widget . pinBoxOuterPadding ; 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					    return  Container ( 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    return  AnimatedContainer ( 
 
			
		
	
		
		
			
				
					
					      duration:  const  Duration ( milliseconds:  200 ) , 
 
			
		
	
		
		
			
				
					
					      curve:  Curves . easeInOut , 
 
			
		
	
		
		
			
				
					
					      key:  ValueKey < String > ( " container $ i " ) , 
      key:  ValueKey < String > ( " container $ i " ) , 
 
			
		
	
		
		
			
				
					
					      alignment:  Alignment . center , 
      alignment:  Alignment . center , 
 
			
		
	
		
		
			
				
					
					      padding:  EdgeInsets . symmetric ( vertical:  4.0 ,  horizontal:  1.0 ) , 
      padding:  EdgeInsets . symmetric ( vertical:  4.0 ,  horizontal:  1.0 ) , 
 
			
		
	
		
		
			
				
					
					      margin:  insets , 
      margin:  insets , 
 
			
		
	
		
		
			
				
					
					      decoration:  BoxDecoration ( 
      child:  _animatedTextBox ( strList [ i ] ,  i ) , 
 
			
				
				
			
		
	
		
		
			
				
					
					        border:  Border . all ( 
      decoration:  RoundedRectangleBorder ( ) . toSmoothCornerDecoration ( 
 
			
				
				
			
		
	
		
		
			
				
					
					          color:  borderColor , 
 
			
		
	
		
		
			
				
					
					          width:  widget . pinBoxBorderWidth , 
 
			
		
	
		
		
			
				
					
					        ) , 
 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        color:  pinBoxColor , 
        color:  pinBoxColor , 
 
			
		
	
		
		
			
				
					
					        borderRadius:  BorderRadius. circular (  widget. pinBoxRadius ) , 
        borderRadius:  widget . pinBoxRadius , 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      ) , 
      ) , 
 
			
		
	
		
		
			
				
					
					      width:  widget . pinBoxWidth , 
      width:  widget . pinBoxWidth , 
 
			
		
	
		
		
			
				
					
					      height:  widget . pinBoxHeight , 
      height:  widget . pinBoxHeight , 
 
			
		
	
		
		
			
				
					
					      child:  _animatedTextBox ( strList [ i ] ,  i ) , 
 
			
		
	
		
		
			
				
					
					    ) ; 
    ) ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -407,10 +404,12 @@ class OTPVerificationScreen extends StatefulWidget {
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					class  _OTPVerificationScreenState  extends  State < OTPVerificationScreen >  { class  _OTPVerificationScreenState  extends  State < OTPVerificationScreen >  {  
			
		
	
		
		
			
				
					
					  final  int  _otpLength  =  4 ; 
  final  int  _otpLength  =  4 ; 
 
			
		
	
		
		
			
				
					
					  late  TextEditingController  _otpController ; 
  late  final  TextEditingController  _otpController ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  Timer ?  _resendTimer ; 
  Timer ?  _resendTimer ; 
 
			
		
	
		
		
			
				
					
					  int  _resendTime  =  60 ; 
  int  _resendTime  =  120 ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  bool  _isOtpComplete  =  false ; 
 
			
		
	
		
		
			
				
					
					  bool  _isVerifying  =  false ;  / /  Flag  to  prevent  multiple  verification  calls 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  @ override 
  @ override 
 
			
		
	
		
		
			
				
					
					  void  initState ( )  { 
  void  initState ( )  { 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -437,29 +436,27 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  void  _onOtpChanged ( String  value )  { 
  void  _onOtpChanged ( String  value )  { 
 
			
		
	
		
		
			
				
					
					    / /  Handle  clipboard  paste  or  programmatic  input 
    setState ( ( )  { 
 
			
				
				
			
		
	
		
		
			
				
					
					    if  ( value . length  >  1 )  { 
      _isOtpComplete  =  value . length  = =  _otpLength ; 
 
			
				
				
			
		
	
		
		
			
				
					
					      String ?  otp  =  _extractOtpFromText ( value ) ; 
    } ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
					      if  ( otp  ! =  null )  { 
 
			
		
	
		
		
			
				
					
					        autoFillOtp ( otp ) ; 
 
			
		
	
		
		
			
				
					
					        return ; 
 
			
		
	
		
		
			
				
					
					      } 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    / /  The  OTPWidget  will  automatically  call  onDone  when  complete 
    if  ( _isOtpComplete  & &  ! _isVerifying )  { 
 
			
				
				
			
		
	
		
		
			
				
					
					    / /  This  method  can  be  used  for  any  additional  logic  on  text  change 
      _isVerifying  =  true ; 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					      _verifyOtp ( value ) ; 
 
			
		
	
		
		
			
				
					
					    }  else  if  ( ! _isOtpComplete )  { 
 
			
		
	
		
		
			
				
					
					      / /  Reset  the  flag  when  OTP  is  incomplete  ( user  is  editing ) 
 
			
		
	
		
		
			
				
					
					      _isVerifying  =  false ; 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  void  _onOtpCompleted ( String  otp )  { 
 
			
		
	
		
		
			
				
					
					    debugPrint ( ' OTP Completed:  $ otp ' ) ; 
 
			
		
	
		
		
			
				
					
					    widget . checkActivationCode ( int . parse ( otp ) ) ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  void  _resendOtp ( )  { 
  void  _resendOtp ( )  { 
 
			
		
	
		
		
			
				
					
					    if  ( _resendTime  = =  0 )  { 
    if  ( _resendTime  = =  0 )  { 
 
			
		
	
		
		
			
				
					
					      setState ( ( )  = >  _resendTime  =  60 ) ; 
      setState ( ( )  { 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					        _resendTime  =  120 ; 
 
			
		
	
		
		
			
				
					
					        _isVerifying  =  false ;  / /  Reset  verification  flag 
 
			
		
	
		
		
			
				
					
					      } ) ; 
 
			
		
	
		
		
			
				
					
					      _startResendTimer ( ) ; 
      _startResendTimer ( ) ; 
 
			
		
	
		
		
			
				
					
					      autoFillOtp ( " 1234 " ) ; 
      / /  autoFillOtp ( " 1234 " ) ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      widget . onResendOTPPressed ( widget . phoneNumber ) ; 
      widget . onResendOTPPressed ( widget . phoneNumber ) ; 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -469,68 +466,6 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
			
		
	
		
		
			
				
					
					    return  phone . length  >  4  ?  ' 05xxxxxx ${ phone . substring ( phone . length  -  2 ) } '  :  phone ; 
    return  phone . length  >  4  ?  ' 05xxxxxx ${ phone . substring ( phone . length  -  2 ) } '  :  phone ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Extract  OTP  from  text  using  multiple  patterns 
 
			
		
	
		
		
			
				
					
					  String ?  _extractOtpFromText ( String  text )  { 
 
			
		
	
		
		
			
				
					
					    / /  Pattern  1 :  Find  4 - 6  consecutive  digits 
 
			
		
	
		
		
			
				
					
					    RegExp  digitPattern  =  RegExp ( r'\b\d{4,6}\b' ) ; 
 
			
		
	
		
		
			
				
					
					    Match ?  match  =  digitPattern . firstMatch ( text ) ; 
 
			
		
	
		
		
			
				
					
					    
 
			
		
	
		
		
			
				
					
					    if  ( match  ! =  null )  { 
 
			
		
	
		
		
			
				
					
					      String  digits  =  match . group ( 0 ) ! ; 
 
			
		
	
		
		
			
				
					
					      if  ( digits . length  > =  _otpLength )  { 
 
			
		
	
		
		
			
				
					
					        return  digits . substring ( 0 ,  _otpLength ) ; 
 
			
		
	
		
		
			
				
					
					      } 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					    
 
			
		
	
		
		
			
				
					
					    / /  Pattern  2 :  Find  digits  separated  by  spaces  or  special  characters 
 
			
		
	
		
		
			
				
					
					    String  cleanedText  =  text . replaceAll ( RegExp ( r'[^\d]' ) ,  ' ' ) ; 
 
			
		
	
		
		
			
				
					
					    if  ( cleanedText . length  > =  _otpLength )  { 
 
			
		
	
		
		
			
				
					
					      return  cleanedText . substring ( 0 ,  _otpLength ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					    
 
			
		
	
		
		
			
				
					
					    return  null ; 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Paste  OTP  from  clipboard 
 
			
		
	
		
		
			
				
					
					  Future < void >  _pasteFromClipboard ( )  async  { 
 
			
		
	
		
		
			
				
					
					    try  { 
 
			
		
	
		
		
			
				
					
					      ClipboardData ?  data  =  await  Clipboard . getData ( Clipboard . kTextPlain ) ; 
 
			
		
	
		
		
			
				
					
					      if  ( data  ! =  null  & &  data . text  ! =  null )  { 
 
			
		
	
		
		
			
				
					
					        String  clipboardText  =  data . text ! ; 
 
			
		
	
		
		
			
				
					
					        String ?  otp  =  _extractOtpFromText ( clipboardText ) ; 
 
			
		
	
		
		
			
				
					
					        
 
			
		
	
		
		
			
				
					
					        if  ( otp  ! =  null )  { 
 
			
		
	
		
		
			
				
					
					          autoFillOtp ( otp ) ; 
 
			
		
	
		
		
			
				
					
					          
 
			
		
	
		
		
			
				
					
					          / /  Show  feedback  to  user 
 
			
		
	
		
		
			
				
					
					          ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
			
		
	
		
		
			
				
					
					            SnackBar ( 
 
			
		
	
		
		
			
				
					
					              content:  Text ( ' OTP pasted:  $ otp ' ) , 
 
			
		
	
		
		
			
				
					
					              duration:  const  Duration ( seconds:  2 ) , 
 
			
		
	
		
		
			
				
					
					              backgroundColor:  AppColors . successColor , 
 
			
		
	
		
		
			
				
					
					            ) , 
 
			
		
	
		
		
			
				
					
					          ) ; 
 
			
		
	
		
		
			
				
					
					        }  else  { 
 
			
		
	
		
		
			
				
					
					          / /  Show  error  if  no  valid  OTP  found 
 
			
		
	
		
		
			
				
					
					          ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
			
		
	
		
		
			
				
					
					            const  SnackBar ( 
 
			
		
	
		
		
			
				
					
					              content:  Text ( ' No valid OTP found in clipboard ' ) , 
 
			
		
	
		
		
			
				
					
					              duration:  Duration ( seconds:  2 ) , 
 
			
		
	
		
		
			
				
					
					            ) , 
 
			
		
	
		
		
			
				
					
					          ) ; 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					      } 
 
			
		
	
		
		
			
				
					
					    }  catch  ( e )  { 
 
			
		
	
		
		
			
				
					
					      debugPrint ( ' Error pasting from clipboard:  $ e ' ) ; 
 
			
		
	
		
		
			
				
					
					      ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
			
		
	
		
		
			
				
					
					        const  SnackBar ( 
 
			
		
	
		
		
			
				
					
					          content:  Text ( ' Failed to paste from clipboard ' ) , 
 
			
		
	
		
		
			
				
					
					          duration:  Duration ( seconds:  2 ) , 
 
			
		
	
		
		
			
				
					
					        ) , 
 
			
		
	
		
		
			
				
					
					      ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  @ override 
  @ override 
 
			
		
	
		
		
			
				
					
					  Widget  build ( BuildContext  context )  { 
  Widget  build ( BuildContext  context )  { 
 
			
		
	
		
		
			
				
					
					    return  Scaffold ( 
    return  Scaffold ( 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -562,33 +497,28 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					              / /  OTP  Input  Fields  using  new  OTP  Widget 
              / /  OTP  Input  Fields  using  new  OTP  Widget 
 
			
		
	
		
		
			
				
					
					              Center ( 
              Center ( 
 
			
		
	
		
		
			
				
					
					                child:  AutofillGroup ( 
 
			
		
	
		
		
			
				
					
					                child:  OTPWidget ( 
                child:  OTPWidget ( 
 
			
		
	
		
		
			
				
					
					                  maxLength:  _otpLength , 
                  maxLength:  _otpLength , 
 
			
		
	
		
		
			
				
					
					                  controller:  _otpController , 
                  controller:  _otpController , 
 
			
		
	
		
		
			
				
					
					                    pinBoxWidth:  75. h , 
                  pinBoxWidth:  70. h , 
 
			
				
				
			
		
	
		
		
			
				
					
					                    pinBoxHeight:  100. h , 
                  pinBoxHeight:  100 , 
 
			
				
				
			
		
	
		
		
			
				
					
					                    autoFocus:  true , 
 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                  pinBoxRadius:  16 , 
                  pinBoxRadius:  16 , 
 
			
		
	
		
		
			
				
					
					                  pinBoxBorderWidth:  0 , 
                  pinBoxBorderWidth:  0 , 
 
			
		
	
		
		
			
				
					
					                  pinBoxOuterPadding:  EdgeInsets . symmetric ( horizontal:  4. h ) , 
                  pinBoxOuterPadding:  EdgeInsets . symmetric ( horizontal:  4. h ) , 
 
			
		
	
		
		
			
				
					
					                  defaultBorderColor:  Colors . transparent , 
                  defaultBorderColor:  Colors . transparent , 
 
			
		
	
		
		
			
				
					
					                  textBorderColor:  Colors . transparent , 
                  textBorderColor:  Colors . transparent , 
 
			
		
	
		
		
			
				
					
					                    errorBorderColor:  AppColors . primaryRedColor , 
 
			
		
	
		
		
			
				
					
					                  pinBoxColor:  AppColors . whiteColor , 
                  pinBoxColor:  AppColors . whiteColor , 
 
			
		
	
		
		
			
				
					
					                  autoFocus:  true , 
 
			
		
	
		
		
			
				
					
					                  onTextChanged:  _onOtpChanged , 
 
			
		
	
		
		
			
				
					
					                  pinTextStyle:  TextStyle ( 
                  pinTextStyle:  TextStyle ( 
 
			
		
	
		
		
			
				
					
					                      fontSize:  50. fSize , 
                    fontSize:  4 fSize , 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                    fontWeight:  FontWeight . bold , 
                    fontWeight:  FontWeight . bold , 
 
			
		
	
		
		
			
				
					
					                    color:  AppColors . whiteColor , 
                    color:  AppColors . whiteColor , 
 
			
		
	
		
		
			
				
					
					                  ) , 
                  ) , 
 
			
		
	
		
		
			
				
					
					                    onTextChanged:  _onOtpChanged , 
 
			
		
	
		
		
			
				
					
					                    onDone:  _onOtpCompleted , 
 
			
		
	
		
		
			
				
					
					                  ) , 
 
			
		
	
		
		
			
				
					
					                ) , 
                ) , 
 
			
		
	
		
		
			
				
					
					              ) , 
              ) , 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					              const  SizedBox ( height:  16 ) , 
              const  SizedBox ( height:  32 ) , 
 
			
				
				
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					              / /  Resend  OTP 
              / /  Resend  OTP 
 
			
		
	
		
		
			
				
					
					              Row ( 
              Row ( 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -596,9 +526,18 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
			
		
	
		
		
			
				
					
					                children:  [ 
                children:  [ 
 
			
		
	
		
		
			
				
					
					                  const  Text ( " Didn't receive it?  " ) , 
                  const  Text ( " Didn't receive it?  " ) , 
 
			
		
	
		
		
			
				
					
					                  if  ( _resendTime  >  0 ) 
                  if  ( _resendTime  >  0 ) 
 
			
		
	
		
		
			
				
					
					                    Text ( 
                    Builder ( 
 
			
				
				
			
		
	
		
		
			
				
					
					                      ' resend in ( ${ _resendTime . toString ( ) . padLeft ( 2 ,  ' 0 ' ) } :00).  ' , 
                      / /  Use  a  Builder  to  easily  calculate  minutes  and  seconds  inline 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                      builder:  ( context )  { 
 
			
		
	
		
		
			
				
					
					                        final  minutes  =  ( _resendTime  ~ /  60 ) 
 
			
		
	
		
		
			
				
					
					                            . toString ( ) 
 
			
		
	
		
		
			
				
					
					                            . padLeft ( 2 ,  ' 0 ' ) ;  / /  Integer  division  for  minutes           final  seconds  =  ( _resendTime  %  60 ) . toString ( ) . padLeft ( 2 ,  ' 0 ' ) ;  / /  Modulo  for  remaining  seconds 
 
			
		
	
		
		
			
				
					
					                        final  seconds  =  ( _resendTime  %  60 ) . toString ( ) . padLeft ( 2 ,  ' 0 ' ) ;  / /  Modulo  for  remaining  seconds  / /  < - - -  HERE  IT  IS 
 
			
		
	
		
		
			
				
					
					                        return  Text ( 
 
			
		
	
		
		
			
				
					
					                          ' resend in ( $ minutes : $ seconds ).  ' , 
 
			
		
	
		
		
			
				
					
					                          style:  const  TextStyle ( color:  Colors . grey ) , 
                          style:  const  TextStyle ( color:  Colors . grey ) , 
 
			
		
	
		
		
			
				
					
					                        ) ; 
 
			
		
	
		
		
			
				
					
					                      } , 
 
			
		
	
		
		
			
				
					
					                    ) 
                    ) 
 
			
		
	
		
		
			
				
					
					                  else 
                  else 
 
			
		
	
		
		
			
				
					
					                    GestureDetector ( 
                    GestureDetector ( 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -620,50 +559,15 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
			
		
	
		
		
			
				
					
					    ) ; 
    ) ; 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  void  _verifyOtp ( String  otp )  { 
 
			
		
	
		
		
			
				
					
					    debugPrint ( ' Verifying OTP:  $ otp ' ) ; 
 
			
		
	
		
		
			
				
					
					    widget . checkActivationCode ( int . parse ( otp ) ) ; 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Auto  fill  OTP  into  text  fields 
  / / /  Auto  fill  OTP  into  text  fields 
 
			
		
	
		
		
			
				
					
					  void  autoFillOtp ( String  otp )  { 
  void  autoFillOtp ( String  otp )  { 
 
			
		
	
		
		
			
				
					
					    if  ( otp . length  ! =  _otpLength )  return ; 
    if  ( otp . length  ! =  _otpLength )  return ; 
 
			
		
	
		
		
			
				
					
					    
    _isVerifying  =  false ; 
 
			
				
				
			
		
	
		
		
			
				
					
					    / /  Clear  any  existing  text  first 
 
			
		
	
		
		
			
				
					
					    _otpController . clear ( ) ; 
 
			
		
	
		
		
			
				
					
					    
 
			
		
	
		
		
			
				
					
					    / /  Add  a  small  delay  to  ensure  the  UI  is  updated 
 
			
		
	
		
		
			
				
					
					    Future . delayed ( const  Duration ( milliseconds:  50 ) ,  ( )  { 
 
			
		
	
		
		
	
		
		
			
				
					
					    _otpController . text  =  otp ; 
    _otpController . text  =  otp ; 
 
			
		
	
		
		
			
				
					
					      / /  Move  cursor  to  the  end 
 
			
		
	
		
		
			
				
					
					      _otpController . selection  =  TextSelection . fromPosition ( 
 
			
		
	
		
		
			
				
					
					        TextPosition ( offset:  otp . length ) , 
 
			
		
	
		
		
			
				
					
					      ) ; 
 
			
		
	
		
		
			
				
					
					    } ) ; 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Clear  OTP  fields 
 
			
		
	
		
		
			
				
					
					  void  clearOtp ( )  { 
 
			
		
	
		
		
			
				
					
					    _otpController . clear ( ) ; 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Get  current  OTP  value 
 
			
		
	
		
		
			
				
					
					  String  getCurrentOtp ( )  { 
 
			
		
	
		
		
			
				
					
					    return  _otpController . text ; 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Check  if  OTP  is  complete 
 
			
		
	
		
		
			
				
					
					  bool  isOtpComplete ( )  { 
 
			
		
	
		
		
			
				
					
					    return  _otpController . text . length  = =  _otpLength ; 
 
			
		
	
		
		
			
				
					
					  } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  / / /  Simulate  SMS  received  with  OTP  ( for  testing  purposes ) 
 
			
		
	
		
		
			
				
					
					  void  simulateSMSReceived ( String  otp )  { 
 
			
		
	
		
		
			
				
					
					    if  ( otp . length  = =  _otpLength  & &  RegExp ( r'^\d+$' ) . hasMatch ( otp ) )  { 
 
			
		
	
		
		
			
				
					
					      autoFillOtp ( otp ) ; 
 
			
		
	
		
		
			
				
					
					      / /  Show  a  brief  indicator  that  SMS  was  detected 
 
			
		
	
		
		
			
				
					
					      ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
			
		
	
		
		
			
				
					
					        SnackBar ( 
 
			
		
	
		
		
			
				
					
					          content:  Text ( ' OTP detected from SMS:  $ otp ' ) , 
 
			
		
	
		
		
			
				
					
					          duration:  const  Duration ( seconds:  2 ) , 
 
			
		
	
		
		
			
				
					
					          backgroundColor:  AppColors . successColor , 
 
			
		
	
		
		
			
				
					
					        ) , 
 
			
		
	
		
		
			
				
					
					      ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					  } 
  } 
 
			
		
	
		
		
			
				
					
					} }