Skip to content

Commit

Permalink
Merge pull request #444 from natintosh/develop
Browse files Browse the repository at this point in the history
v0.8.0
  • Loading branch information
natintosh authored Sep 9, 2024
2 parents bee1d65 + ad132f8 commit d10eb21
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 83 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [0.7.5]
* Fixed bug in `AsYouTypeFormatter` that could throw a `RangeError` if the user typed non digit characters

## [0.7.4]
* Updated minimum os version on iOS
* Updated dependencies
Expand Down
32 changes: 3 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ A simple and customizable flutter package for inputting phone number in intl / i


### What's new
- Replace libphonenumber_plugin with dlibphonenumber
- Updated libphonenumber and PhoneNumberToCarrierMapper on Android
- Removed dependency on libphonenumber
- Switch from libphonenumber-iOS to PhoneNumberKit on iOS
Expand All @@ -20,7 +21,7 @@ A simple and customizable flutter package for inputting phone number in intl / i


### Features
- Web support.
- Support all Flutter platforms.
- Support for RTL languages
- Selector mode dropdown, bottom sheet and dialog
- As You Type Formatter: formats inputs to its selected international format
Expand All @@ -35,33 +36,6 @@ A simple and customizable flutter package for inputting phone number in intl / i
`controller reference`.text = parsableNumber
```

### Web Support

In your app directory, edit `web/index.html` to add the following

```html

<!DOCTYPE html>
<html>
<head>
...
</head>
<body>

...

<script src="assets/packages/libphonenumber_plugin/js/libphonenumber.js"></script>
<script src="assets/packages/libphonenumber_plugin/js/stringbuffer.js"></script>

...

<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
```

Or checkout `/example` folder from [Github](https://github.com/natintosh/intl_phone_number_input/tree/develop/example).


### Note
``` dart
Expand Down Expand Up @@ -195,7 +169,7 @@ Made with [contributors-img](https://contributors-img.web.app).

# Dependencies

* [libphonenumber](https://pub.dev/packages/libphonenumber)
* [dlibphonenumber](https://pub.dev/packages/dlibphonenumber)
* [equatable](https://pub.dev/packages/equatable)

# Credits
Expand Down
2 changes: 1 addition & 1 deletion lib/src/models/country_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7466,7 +7466,7 @@ class Countries {
"num_code": "826",
"alpha_2_code": "GB",
"alpha_3_code": "GBR",
"en_short_name": "United Kingdom of Great Britain and Northern Ireland",
"en_short_name": "United Kingdom of Great Britain",
"nationality": "British, UK",
"dial_code": "+44",
"nameTranslations": {
Expand Down
86 changes: 48 additions & 38 deletions lib/src/utils/formatter/as_you_type_formatter.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:flutter/services.dart';
import 'package:intl_phone_number_input/src/utils/phone_number/phone_number_util.dart';

Expand Down Expand Up @@ -38,61 +40,69 @@ class AsYouTypeFormatter extends TextInputFormatter {
if (newValueLength > 0 && newValueLength > oldValueLength) {
String newValueText = newValue.text;
String rawText = newValueText.replaceAll(separatorChars, '');
String textToParse = dialCode + rawText;

final _ = newValueText
.substring(
oldValue.selection.start == -1 ? 0 : oldValue.selection.start,
newValue.selection.end == -1 ? 0 : newValue.selection.end)
.replaceAll(separatorChars, '');
int rawCursorPosition = newValue.selection.end;

int digitsBeforeCursor = 0, digitsAfterCursor = 0;

if (rawCursorPosition > 0 && rawCursorPosition <= newValueText.length) {
final rawTextBeforeCursor = newValueText
.substring(0, rawCursorPosition)
.replaceAll(separatorChars, '');
final rawTextAfterCursor = newValueText
.substring(rawCursorPosition)
.replaceAll(separatorChars, '');

digitsBeforeCursor = rawTextBeforeCursor.length;
digitsAfterCursor = rawTextAfterCursor.length;
}

String textToParse = dialCode + rawText;

formatAsYouType(input: textToParse).then(
(String? value) {
String parsedText = parsePhoneNumber(value);

int offset =
newValue.selection.end == -1 ? 0 : newValue.selection.end;

if (separatorChars.hasMatch(parsedText)) {
String valueInInputIndex = parsedText[offset - 1];
int newCursorPosition = 0;

if (offset < parsedText.length) {
int offsetDifference = parsedText.length - offset;
if (digitsBeforeCursor > 0 || digitsAfterCursor > 0) {
for (var i = 0; i < parsedText.length; i++) {
final startCursor = i;

if (offsetDifference < 2) {
if (separatorChars.hasMatch(valueInInputIndex)) {
offset += 1;
if (allowedChars.hasMatch(parsedText[startCursor])) {
if (digitsBeforeCursor > 0) {
digitsBeforeCursor--;
} else {
bool isLastChar;
try {
var _ = newValueText[newValue.selection.end];
isLastChar = false;
} on RangeError {
isLastChar = true;
}
if (isLastChar) {
offset += offsetDifference;
}
newCursorPosition = startCursor + 1;
break;
}
} else {
if (parsedText.length > offset - 1) {
if (separatorChars.hasMatch(valueInInputIndex)) {
offset += 1;
}
}

final endCursor = parsedText.length - 1 - i;

if (allowedChars.hasMatch(parsedText[endCursor])) {
if (digitsAfterCursor > 0) {
digitsAfterCursor--;
} else {
newCursorPosition = endCursor + 1;
break;
}
}
}

this.onInputFormatted(
TextEditingValue(
text: parsedText,
selection: TextSelection.collapsed(offset: offset),
),
);
}

newCursorPosition = min(max(newCursorPosition, 0), parsedText.length);

this.onInputFormatted(
TextEditingValue(
text: parsedText,
selection: TextSelection.collapsed(offset: newCursorPosition),
),
);
},
);
}

return newValue;
}

Expand Down
38 changes: 25 additions & 13 deletions lib/src/utils/phone_number/phone_number_util.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'package:dlibphonenumber/dlibphonenumber.dart' as p;
import 'package:intl_phone_number_input/src/utils/phone_number.dart';
import 'package:libphonenumber_plugin/libphonenumber_plugin.dart' as p;

/// A wrapper class [PhoneNumberUtil] that basically switch between plugin available for `Web` or `Android or IOS` and `Other platforms` when available.
class PhoneNumberUtil {
static p.PhoneNumberUtil phoneUtil = p.PhoneNumberUtil.instance;

/// [isValidNumber] checks if a [phoneNumber] is valid.
/// Accepts [phoneNumber] and [isoCode]
/// Returns [Future<bool>].
Expand All @@ -11,35 +12,41 @@ class PhoneNumberUtil {
if (phoneNumber.length < 2) {
return false;
}
return p.PhoneNumberUtil.isValidPhoneNumber(phoneNumber, isoCode);
final number = phoneUtil.parse(phoneNumber, isoCode.toUpperCase());
return phoneUtil.isValidNumber(number);
}

/// [normalizePhoneNumber] normalizes a string of characters representing a phone number
/// Accepts [phoneNumber] and [isoCode]
/// Returns [Future<String>]
static Future<String?> normalizePhoneNumber(
{required String phoneNumber, required String isoCode}) async {
return p.PhoneNumberUtil.normalizePhoneNumber(phoneNumber, isoCode);
final number = phoneUtil.parse(phoneNumber, isoCode.toUpperCase());
return phoneUtil.format(number, p.PhoneNumberFormat.e164);
}

/// Accepts [phoneNumber] and [isoCode]
/// Returns [Future<RegionInfo>] of all information available about the [phoneNumber]
static Future<RegionInfo> getRegionInfo(
{required String phoneNumber, required String isoCode}) async {
var response = await p.PhoneNumberUtil.getRegionInfo(phoneNumber, isoCode);

final number = phoneUtil.parse(phoneNumber, isoCode.toUpperCase());
final regionCode = phoneUtil.getRegionCodeForNumber(number);
final countryCode = number.countryCode.toString();
final formattedNumber =
phoneUtil.format(number, p.PhoneNumberFormat.national);
return RegionInfo(
regionPrefix: response.regionPrefix,
isoCode: response.isoCode,
formattedPhoneNumber: response.formattedPhoneNumber);
regionPrefix: countryCode,
isoCode: regionCode,
formattedPhoneNumber: formattedNumber,
);
}

/// Accepts [phoneNumber] and [isoCode]
/// Returns [Future<PhoneNumberType>] type of phone number
static Future<PhoneNumberType> getNumberType(
{required String phoneNumber, required String isoCode}) async {
final dynamic type =
await p.PhoneNumberUtil.getNumberType(phoneNumber, isoCode);
final p.PhoneNumberType type = phoneUtil
.getNumberType(phoneUtil.parse(phoneNumber, isoCode.toUpperCase()));

return PhoneNumberTypeUtil.getType(type.index);
}
Expand All @@ -49,7 +56,12 @@ class PhoneNumberUtil {
/// Returns [Future<String>]
static Future<String?> formatAsYouType(
{required String phoneNumber, required String isoCode}) async {
return p.PhoneNumberUtil.formatAsYouType(phoneNumber, isoCode);
final asYouTypeFormatter = phoneUtil.getAsYouTypeFormatter(isoCode);
String? result;
for (int i = 0; i < phoneNumber.length; i++) {
result = asYouTypeFormatter.inputDigit(phoneNumber[i]);
}
return result;
}
}

Expand Down Expand Up @@ -138,7 +150,7 @@ extension phonenumbertypeproperties on PhoneNumberType {
return 6;
case PhoneNumberType.PERSONAL_NUMBER:
return 7;
case PhoneNumberType.PREMIUM_RATE:
case PhoneNumberType.PAGER:
return 8;
case PhoneNumberType.UAN:
return 9;
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: intl_phone_number_input
description: A simple and customizable flutter package for inputting phone number in intl / international format uses Google's libphonenumber.
version: 0.7.4
version: 0.7.5
homepage: https://github.com/natintosh/intl-phone-number-input

environment:
Expand All @@ -10,7 +10,7 @@ dependencies:
flutter:
sdk: flutter

libphonenumber_plugin: ^0.3.3
dlibphonenumber: ^1.1.17
equatable: ^2.0.5
collection: ^1.18.0

Expand Down

0 comments on commit d10eb21

Please sign in to comment.