From 7a851cd963a3f9ace8633f0f7752cca5485326e8 Mon Sep 17 00:00:00 2001 From: Mohammed Mohsin Date: Thu, 26 Mar 2026 19:56:47 +0530 Subject: [PATCH 1/6] Replace intl_phone_field with intl_country_data for accurate phone validation The intl_phone_field package had incorrect min/max phone number lengths for several countries (e.g. Finland required exactly 12 digits instead of 7-14), causing valid phone numbers to be rejected. Switched to intl_country_data which only provides country data without unused UI components. --- app/ios/Podfile.lock | 16 +++++------ .../xcshareddata/xcschemes/prod.xcscheme | 2 +- app/pubspec.lock | 28 +++++++++---------- app/pubspec.yaml | 2 +- backend/routers/apps.py | 16 ++++++++--- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock index b79e2889e0d..4f7aa07d0b6 100644 --- a/app/ios/Podfile.lock +++ b/app/ios/Podfile.lock @@ -250,9 +250,9 @@ PODS: - PromisesSwift (2.4.0): - PromisesObjC (= 2.4.0) - RecaptchaInterop (101.0.0) - - SDWebImage (5.21.5): - - SDWebImage/Core (= 5.21.5) - - SDWebImage/Core (5.21.5) + - SDWebImage (5.21.7): + - SDWebImage/Core (= 5.21.7) + - SDWebImage/Core (5.21.7) - share_plus (0.0.1): - Flutter - shared_preferences_foundation (0.0.1): @@ -264,9 +264,9 @@ PODS: - Flutter - FlutterMacOS - SwiftCBOR (0.4.4) - - SwiftProtobuf (1.33.3) + - SwiftProtobuf (1.36.1) - SwiftyGif (5.4.5) - - TwilioVoice (6.13.5) + - TwilioVoice (6.13.6) - url_launcher_ios (0.0.1): - Flutter - video_player_avfoundation (0.0.1): @@ -530,15 +530,15 @@ SPEC CHECKSUMS: PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba - SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838 + SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 SwiftCBOR: ce5354ec8b660da2d6fc754462881119dbe1f963 - SwiftProtobuf: e1b437c8e31a4c5577b643249a0bb62ed4f02153 + SwiftProtobuf: 9e106a71456f4d3f6a3b0c8fd87ef0be085efc38 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 - TwilioVoice: 237d012c91fc149943589628703dfd6c7cb2eb31 + TwilioVoice: 04e059fd28d95423b971e823b1c1c1d6737e4e1b url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d diff --git a/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme b/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme index 719bba213cd..b9d52b31fb5 100644 --- a/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme +++ b/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme @@ -43,7 +43,7 @@ Date: Thu, 26 Mar 2026 19:57:32 +0530 Subject: [PATCH 2/6] Update phone_setup_number_page to use intl_country_data API --- .../phone_calls/phone_setup_number_page.dart | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/app/lib/pages/phone_calls/phone_setup_number_page.dart b/app/lib/pages/phone_calls/phone_setup_number_page.dart index d9489b19896..c800f20719f 100644 --- a/app/lib/pages/phone_calls/phone_setup_number_page.dart +++ b/app/lib/pages/phone_calls/phone_setup_number_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:intl_phone_field/countries.dart'; +import 'package:intl_country_data/intl_country_data.dart'; import 'package:provider/provider.dart'; import 'package:omi/pages/phone_calls/phone_setup_verify_page.dart'; @@ -17,7 +17,7 @@ class PhoneSetupNumberPage extends StatefulWidget { class _PhoneSetupNumberPageState extends State { final TextEditingController _phoneController = TextEditingController(); final FocusNode _phoneFocus = FocusNode(); - Country _selectedCountry = countries.firstWhere((c) => c.code == 'US'); + IntlCountryData _selectedCountry = IntlCountryData.fromCountryCodeAlpha2('US'); bool _isLoading = false; String? _errorMessage; @@ -38,12 +38,12 @@ class _PhoneSetupNumberPageState extends State { bool get _isValid { var digits = _phoneController.text.replaceAll(RegExp(r'\D'), ''); - return digits.length >= _selectedCountry.minLength && digits.length <= _selectedCountry.maxLength; + return digits.length >= _selectedCountry.telephoneMinLength && digits.length <= _selectedCountry.telephoneMaxLength; } String get _fullNumber { var digits = _phoneController.text.replaceAll(RegExp(r'\D'), ''); - return '+${_selectedCountry.fullCountryCode}$digits'; + return '+${_selectedCountry.telephoneCode}$digits'; } void _showCountryPicker() { @@ -146,7 +146,7 @@ class _PhoneSetupNumberPageState extends State { Text(_selectedCountry.flag, style: const TextStyle(fontSize: 22)), const SizedBox(width: 6), Text( - '+${_selectedCountry.fullCountryCode}', + '+${_selectedCountry.telephoneCode}', style: const TextStyle(color: Colors.white, fontSize: 16), ), const SizedBox(width: 4), @@ -225,8 +225,8 @@ class _PhoneSetupNumberPageState extends State { } class _CountryPickerSheet extends StatefulWidget { - final Country selected; - final ValueChanged onSelect; + final IntlCountryData selected; + final ValueChanged onSelect; const _CountryPickerSheet({required this.selected, required this.onSelect}); @@ -236,13 +236,15 @@ class _CountryPickerSheet extends StatefulWidget { class _CountryPickerSheetState extends State<_CountryPickerSheet> { final TextEditingController _searchController = TextEditingController(); - List _filtered = countries; + List _filtered = IntlCountryData.all(); void _filter(String query) { var q = query.toLowerCase(); setState(() { - _filtered = countries.where((c) { - return c.name.toLowerCase().contains(q) || c.dialCode.contains(q) || c.code.toLowerCase().contains(q); + _filtered = IntlCountryData.all().where((c) { + return c.name.toLowerCase().contains(q) || + c.telephoneCode.contains(q) || + c.codeAlpha2.toLowerCase().contains(q); }).toList(); }); } @@ -293,7 +295,7 @@ class _CountryPickerSheetState extends State<_CountryPickerSheet> { itemCount: _filtered.length, itemBuilder: (_, i) { var c = _filtered[i]; - var isSelected = c.code == widget.selected.code; + var isSelected = c.codeAlpha2 == widget.selected.codeAlpha2; return GestureDetector( onTap: () => widget.onSelect(c), child: Container( @@ -314,7 +316,7 @@ class _CountryPickerSheetState extends State<_CountryPickerSheet> { overflow: TextOverflow.ellipsis, ), ), - Text('+${c.fullCountryCode}', style: TextStyle(fontSize: 14, color: Colors.grey[500])), + Text('+${c.telephoneCode}', style: TextStyle(fontSize: 14, color: Colors.grey[500])), ], ), ), From cca0d1f96b5ba6a099e1dbf1df3f85215d9a53a4 Mon Sep 17 00:00:00 2001 From: Mohammed Mohsin Date: Thu, 26 Mar 2026 19:58:19 +0530 Subject: [PATCH 3/6] Update phone_calls_page to use intl_country_data API --- app/lib/pages/phone_calls/phone_calls_page.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/pages/phone_calls/phone_calls_page.dart b/app/lib/pages/phone_calls/phone_calls_page.dart index a0c79e13dac..31c48faa65a 100644 --- a/app/lib/pages/phone_calls/phone_calls_page.dart +++ b/app/lib/pages/phone_calls/phone_calls_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:intl_phone_field/countries.dart'; +import 'package:intl_country_data/intl_country_data.dart'; import 'package:provider/provider.dart'; import 'package:omi/pages/phone_calls/active_call_page.dart'; @@ -402,7 +402,7 @@ class _PhoneCallsPageState extends State with SingleTickerProvid for (var len = 3; len >= 1; len--) { if (digits.length <= len) continue; var candidate = digits.substring(0, len); - if (countries.any((c) => c.fullCountryCode == candidate)) { + if (IntlCountryData.all().any((c) => c.telephoneCode == candidate)) { return '+$candidate'; } } From d94634e993459472da5d1d5690f9103c671d4e3f Mon Sep 17 00:00:00 2001 From: Mohammed Mohsin Date: Thu, 26 Mar 2026 20:03:22 +0530 Subject: [PATCH 4/6] Revert unrelated changes to apps.py and prod.xcscheme These were accidentally included from pre-existing staged changes. --- .../xcshareddata/xcschemes/prod.xcscheme | 2 +- backend/routers/apps.py | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme b/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme index b9d52b31fb5..719bba213cd 100644 --- a/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme +++ b/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme @@ -43,7 +43,7 @@ Date: Thu, 26 Mar 2026 20:07:13 +0530 Subject: [PATCH 5/6] Cache IntlCountryData.all() in _extractCountryCode loop --- app/lib/pages/phone_calls/phone_calls_page.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/lib/pages/phone_calls/phone_calls_page.dart b/app/lib/pages/phone_calls/phone_calls_page.dart index 31c48faa65a..af0b32ee4c4 100644 --- a/app/lib/pages/phone_calls/phone_calls_page.dart +++ b/app/lib/pages/phone_calls/phone_calls_page.dart @@ -398,11 +398,12 @@ class _PhoneCallsPageState extends State with SingleTickerProvid String? _extractCountryCode(String e164Number) { if (!e164Number.startsWith('+')) return null; var digits = e164Number.substring(1); // strip '+' + var allCountries = IntlCountryData.all(); // Try longest match first (country codes are 1-3 digits) for (var len = 3; len >= 1; len--) { if (digits.length <= len) continue; var candidate = digits.substring(0, len); - if (IntlCountryData.all().any((c) => c.telephoneCode == candidate)) { + if (allCountries.any((c) => c.telephoneCode == candidate)) { return '+$candidate'; } } From a14f13de88160d2c699e1259871c294e58e7112c Mon Sep 17 00:00:00 2001 From: Mohammed Mohsin Date: Thu, 26 Mar 2026 20:07:23 +0530 Subject: [PATCH 6/6] Cache country list in CountryPickerSheet to avoid per-keystroke allocation --- app/lib/pages/phone_calls/phone_setup_number_page.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/lib/pages/phone_calls/phone_setup_number_page.dart b/app/lib/pages/phone_calls/phone_setup_number_page.dart index c800f20719f..4e30f32717f 100644 --- a/app/lib/pages/phone_calls/phone_setup_number_page.dart +++ b/app/lib/pages/phone_calls/phone_setup_number_page.dart @@ -236,12 +236,13 @@ class _CountryPickerSheet extends StatefulWidget { class _CountryPickerSheetState extends State<_CountryPickerSheet> { final TextEditingController _searchController = TextEditingController(); + final List _allCountries = IntlCountryData.all(); List _filtered = IntlCountryData.all(); void _filter(String query) { var q = query.toLowerCase(); setState(() { - _filtered = IntlCountryData.all().where((c) { + _filtered = _allCountries.where((c) { return c.name.toLowerCase().contains(q) || c.telephoneCode.contains(q) || c.codeAlpha2.toLowerCase().contains(q);