import 'package:countdown/countdown.dart'; import 'package:flutter/material.dart'; import 'package:pinput/pin_put/pin_put.dart'; import '../../generated/l10n.dart'; import '../../models/user.dart'; import '../../utils/http_util.dart'; import '../../utils/utils.dart'; typedef OnCodeVerified(); typedef OnCancel(); class PaymentVerificationCodeDialog extends StatefulWidget { final Key key; final User user; final OnCodeVerified onCodeVerified; final OnCancel onCancel; const PaymentVerificationCodeDialog(this.user, this.onCodeVerified, this.onCancel, {this.key}); @override State createState() { return PaymentVerificationCodeDialogState(); } } class PaymentVerificationCodeDialogState extends State { CountDown cd = CountDown(Duration(seconds: 90)); var countDownListener; bool enableGetCode = false; String getCodeText = ''; String paymentCodeEncrypt = ''; String verifyMethod; String verifyName; final TextEditingController _pinPutController = TextEditingController(); final FocusNode _pinPutFocusNode = FocusNode(); BoxDecoration get _pinPutDecoration { return BoxDecoration( border: Border.all(color: Colors.deepPurpleAccent), borderRadius: BorderRadius.circular(15), ); } @override Widget build(BuildContext context) { return AlertDialog( title: Text(S.of(context).payment_verification), content: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.start, children: [ Container( padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 0.0, right: 0.0), child: Text( (verifyMethod != null) ? S.of(context).payment_verification_sent( (verifyName == 'sms') ? S.of(context).mobile : S.of(context).email, Utils.safePhoneNumber(verifyName) ) : '', ), ), Container( padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 0.0, right: 0.0), child: TextButton( child: Text(getCodeText), onPressed: enableGetCode ? () { getPaymentCode(); } : null, ), ), Center( child: Container( padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 0.0, right: 0.0), child: PinPut( fieldsCount: 4, focusNode: _pinPutFocusNode, controller: _pinPutController, onSubmit: (String pin) { String codeString = generateSignature(pin, key: widget.user.id.toString()); FocusScope.of(context).unfocus(); if (paymentCodeEncrypt == codeString) { Navigator.of(context).pop(); if (widget.onCodeVerified != null) { widget.onCodeVerified(); } } else { showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: Text(S.of(context).error), content: Text(S.of(context).wrong_payment_verification_code), actions: [ TextButton( child: Text(S.of(context).ok), onPressed: () { _pinPutController.clear(); _pinPutFocusNode.requestFocus(); Navigator.of(context).pop(); }, ), ], ); }, ); } }, submittedFieldDecoration: _pinPutDecoration.copyWith( borderRadius: BorderRadius.circular(20)), selectedFieldDecoration: _pinPutDecoration, followingFieldDecoration: _pinPutDecoration.copyWith( borderRadius: BorderRadius.circular(5), border: Border.all( color: Colors.deepPurpleAccent.withOpacity(.5), ), ), ), ), ), ], ), actions: [ TextButton( child: Text(S.of(context).close), onPressed: () { Navigator.of(context).pop(); if (widget.onCancel != null) { widget.onCancel(); } }, ) ], ); } @override void initState() { super.initState(); getPaymentCode(); } void getPaymentCode() { HttpUtil.httpGet('v1/get-payment-verification-code', queryParameters: { 'key': widget.user.id, 'method': 'mobile', // or 'mobile' 'is_user': false, }, ).then((data) { paymentCodeEncrypt = data['payment_code_encrypt']; verifyMethod = data['verify_method']; verifyName = data['verify_name']; print('data: $data'); startCountDown(); }).catchError((error) { Utils.showMessageDialog(context, error); }); } void startCountDown() { countDownListener = CountDown(Duration(seconds: 90)).stream.listen(null); countDownListener.onData((Duration d) { if (mounted) { setState(() { enableGetCode = false; getCodeText = S.of(context).get_code_token(d.inSeconds); }); } }); countDownListener.onDone(() { if (mounted) { setState(() { enableGetCode = true; getCodeText = S.of(context).get_code_again; }); } }); } }