import 'package:flutter/widgets.dart'; import 'package:fancy_password_field/fancy_password_field.dart'; import 'package:pweb/widgets/password/hint/error.dart'; import 'package:pweb/widgets/password/hint/short.dart'; import 'package:pweb/widgets/password/password.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; class PasswordVeirificationRule extends ValidationRule { final String ruleName; final TextEditingController externalPasswordController; PasswordVeirificationRule({ required this.ruleName, required this.externalPasswordController, }); @override String get name => ruleName; @override bool get showName => true; @override bool validate(String value) => value == externalPasswordController.text; } class VerifyPasswordField extends StatefulWidget { final ValueChanged? onValid; final TextEditingController controller; final TextEditingController externalPasswordController; const VerifyPasswordField({ super.key, this.onValid, required this.controller, required this.externalPasswordController, }); @override State createState() => _VerifyPasswordFieldState(); } class _VerifyPasswordFieldState extends State { bool _isCurrentlyValid = false; @override void initState() { super.initState(); widget.controller.addListener(_validatePassword); widget.externalPasswordController.addListener(_validatePassword); } void _validatePassword() { final isValid = widget.controller.text == widget.externalPasswordController.text; // Only call onValid if the validity state has changed to prevent infinite loops if (isValid != _isCurrentlyValid) { setState(() { _isCurrentlyValid = isValid; }); widget.onValid?.call(isValid); } } @override Widget build(BuildContext context) { final rule = PasswordVeirificationRule( ruleName: AppLocalizations.of(context)!.passwordsDoNotMatch, externalPasswordController: widget.externalPasswordController, ); return defaulRulesPasswordField( context, controller: widget.controller, key: widget.key, labelText: AppLocalizations.of(context)!.confirmPassword, additionalRules: { rule }, validationRuleBuilder: (rules, value) => rule.validate(value) ? shortValidation(context, rules, value) : PasswordValidationErrorLabel(labelText: AppLocalizations.of(context)!.passwordsDoNotMatch), onValid: widget.onValid, ); } @override void dispose() { widget.controller.removeListener(_validatePassword); widget.externalPasswordController.removeListener(_validatePassword); super.dispose(); } }