From b1de8f4b788890a9b6d75170cd4a9c84ec51b2cb Mon Sep 17 00:00:00 2001 From: rfowler5 Date: Wed, 7 Feb 2024 13:19:35 -0500 Subject: [PATCH 1/2] Refactored the input_widget, esp the validator and phone controller listener. Added user-passable selectorButtonBottomPadding. Corrected method types in PhoneNumberUtil. --- .../utils/phone_number/phone_number_util.dart | 11 +++- lib/src/widgets/input_widget.dart | 56 ++++++++----------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/lib/src/utils/phone_number/phone_number_util.dart b/lib/src/utils/phone_number/phone_number_util.dart index ffabe47067..af8afa3ab0 100644 --- a/lib/src/utils/phone_number/phone_number_util.dart +++ b/lib/src/utils/phone_number/phone_number_util.dart @@ -6,17 +6,22 @@ class PhoneNumberUtil { /// [isValidNumber] checks if a [phoneNumber] is valid. /// Accepts [phoneNumber] and [isoCode] /// Returns [Future]. - static Future isValidNumber( + static Future isValidNumber( {required String phoneNumber, required String isoCode}) async { if (phoneNumber.length < 2) { return false; } - return p.PhoneNumberUtil.isValidPhoneNumber(phoneNumber, isoCode); + // The .then is needed to make sure return Future, instead of Future. It appears + // that the libphonenumber_plugin packages should be returning Future anyway, but the error + // of returning Future runs deep into the dependencies. So fix here until those are fixed + // to return false if validation result is null. + return p.PhoneNumberUtil.isValidPhoneNumber(phoneNumber, isoCode) + .then((v) => v ?? false); } /// [normalizePhoneNumber] normalizes a string of characters representing a phone number /// Accepts [phoneNumber] and [isoCode] - /// Returns [Future] + /// Returns [Future] static Future normalizePhoneNumber( {required String phoneNumber, required String isoCode}) async { return p.PhoneNumberUtil.normalizePhoneNumber(phoneNumber, isoCode); diff --git a/lib/src/widgets/input_widget.dart b/lib/src/widgets/input_widget.dart index 94972bad18..ce8b583bbd 100644 --- a/lib/src/widgets/input_widget.dart +++ b/lib/src/widgets/input_widget.dart @@ -55,6 +55,7 @@ class InternationalPhoneNumberInput extends StatefulWidget { final String? hintText; final String? errorMessage; + final double selectorButtonBottomPadding; final double selectorButtonOnErrorPadding; /// Ignored if [setSelectorButtonAsPrefixIcon = true] @@ -102,6 +103,7 @@ class InternationalPhoneNumberInput extends StatefulWidget { this.initialValue, this.hintText = 'Phone number', this.errorMessage = 'Invalid phone number', + this.selectorButtonBottomPadding = 0, this.selectorButtonOnErrorPadding = 24, this.spaceBetweenSelectorAndTextField = 12, this.maxLength = 15, @@ -133,17 +135,18 @@ class InternationalPhoneNumberInput extends StatefulWidget { class _InputWidgetState extends State { TextEditingController? controller; - double selectorButtonBottomPadding = 0; + late double selectorButtonBottomPadding; Country? country; List countries = []; - bool isNotValid = true; + bool isValidPhone = false; @override void initState() { super.initState(); loadCountries(); controller = widget.textFieldController ?? TextEditingController(); + selectorButtonBottomPadding = widget.selectorButtonBottomPadding; initialiseWidget(); } @@ -231,32 +234,21 @@ class _InputWidgetState extends State { getParsedPhoneNumber(parsedPhoneNumberString, this.country?.alpha2Code) .then((phoneNumber) { if (phoneNumber == null) { - String phoneNumber = - '${this.country?.dialCode}$parsedPhoneNumberString'; - - if (widget.onInputChanged != null) { - widget.onInputChanged!(PhoneNumber( - phoneNumber: phoneNumber, - isoCode: this.country?.alpha2Code, - dialCode: this.country?.dialCode)); - } - - if (widget.onInputValidated != null) { - widget.onInputValidated!(false); - } - this.isNotValid = true; + this.isValidPhone = false; } else { - if (widget.onInputChanged != null) { - widget.onInputChanged!(PhoneNumber( - phoneNumber: phoneNumber, - isoCode: this.country?.alpha2Code, - dialCode: this.country?.dialCode)); - } - - if (widget.onInputValidated != null) { - widget.onInputValidated!(true); - } - this.isNotValid = false; + this.isValidPhone = true; + } + + if (widget.onInputChanged != null) { + widget.onInputChanged!(PhoneNumber( + phoneNumber: phoneNumber ?? + '${this.country?.dialCode}$parsedPhoneNumberString', + isoCode: this.country?.alpha2Code, + dialCode: this.country?.dialCode)); + } + + if (widget.onInputValidated != null) { + widget.onInputValidated!(this.isValidPhone); } }); } @@ -318,22 +310,22 @@ class _InputWidgetState extends State { /// /// Also updates [selectorButtonBottomPadding] String? validator(String? value) { - bool isValid = - this.isNotValid && (value!.isNotEmpty || widget.ignoreBlank == false); + bool isValidInput = + this.isValidPhone && (value!.isNotEmpty || widget.ignoreBlank == false); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - if (isValid && widget.errorMessage != null) { + if (!isValidInput && widget.errorMessage != null) { setState(() { this.selectorButtonBottomPadding = widget.selectorButtonOnErrorPadding; }); } else { setState(() { - this.selectorButtonBottomPadding = 0; + this.selectorButtonBottomPadding = widget.selectorButtonBottomPadding; }); } }); - return isValid ? widget.errorMessage : null; + return !isValidInput ? widget.errorMessage : null; } /// Changes Selector Button Country and Validate Change. From cc62c0cb07c782baa6bfc4a5e5b2874e7bca1e3c Mon Sep 17 00:00:00 2001 From: rfowler5 Date: Wed, 7 Feb 2024 15:37:27 -0500 Subject: [PATCH 2/2] More refactoring of input_widget making use of type corrections. --- example/android/build.gradle | 4 ++-- .../gradle/wrapper/gradle-wrapper.properties | 3 +-- lib/src/widgets/input_widget.dart | 16 ++++++---------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/example/android/build.gradle b/example/android/build.gradle index 7130c89673..6f393b659c 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 939efa2951..8049c684f0 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip diff --git a/lib/src/widgets/input_widget.dart b/lib/src/widgets/input_widget.dart index ce8b583bbd..04296d0e6f 100644 --- a/lib/src/widgets/input_widget.dart +++ b/lib/src/widgets/input_widget.dart @@ -183,7 +183,7 @@ class _InputWidgetState extends State { widget.initialValue!.phoneNumber!.isNotEmpty && (await PhoneNumberUtil.isValidNumber( phoneNumber: widget.initialValue!.phoneNumber!, - isoCode: widget.initialValue!.isoCode!))!) { + isoCode: widget.initialValue!.isoCode!))) { String phoneNumber = await PhoneNumber.getParsableNumber(widget.initialValue!); @@ -233,12 +233,6 @@ class _InputWidgetState extends State { getParsedPhoneNumber(parsedPhoneNumberString, this.country?.alpha2Code) .then((phoneNumber) { - if (phoneNumber == null) { - this.isValidPhone = false; - } else { - this.isValidPhone = true; - } - if (widget.onInputChanged != null) { widget.onInputChanged!(PhoneNumber( phoneNumber: phoneNumber ?? @@ -260,14 +254,16 @@ class _InputWidgetState extends State { String phoneNumber, String? isoCode) async { if (phoneNumber.isNotEmpty && isoCode != null) { try { - bool? isValidPhoneNumber = await PhoneNumberUtil.isValidNumber( + this.isValidPhone = await PhoneNumberUtil.isValidNumber( phoneNumber: phoneNumber, isoCode: isoCode); - if (isValidPhoneNumber!) { + if (this.isValidPhone) { return await PhoneNumberUtil.normalizePhoneNumber( phoneNumber: phoneNumber, isoCode: isoCode); } - } on Exception { + // ignore: unused_catch_clause, unused_catch_stack + } on Exception catch (e, s) { + //Keep catch clause for easier debugging in editors that can hover over e and s. return null; } }