diff --git a/dialer/lib/presentation/features/contacts/contact_page.dart b/dialer/lib/presentation/features/contacts/contact_page.dart index 00b227e..ad9b2b9 100644 --- a/dialer/lib/presentation/features/contacts/contact_page.dart +++ b/dialer/lib/presentation/features/contacts/contact_page.dart @@ -38,24 +38,28 @@ class _ContactPageState extends State { void _toggleFavorite(Contact contact) async { try { if (await FlutterContacts.requestPermission()) { + // Avoid full contact fetch by using minimal properties Contact? fullContact = await FlutterContacts.getContact(contact.id, withProperties: true, - withAccounts: true, - withPhoto: true, - withThumbnail: true); + withAccounts: false, // Don't need accounts for favorite toggle + withPhoto: false, // Don't need photo for favorite toggle + withThumbnail: false // Don't need thumbnail for favorite toggle + ); if (fullContact != null) { fullContact.isStarred = !fullContact.isStarred; await FlutterContacts.updateContact(fullContact); + await _refreshContacts(); } - await _refreshContacts(); } else { debugPrint("Could not fetch contact details"); } } catch (e) { debugPrint("Error updating favorite status: $e"); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to update favorite status'))); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Failed to update favorite status'))); + } } } diff --git a/dialer/lib/presentation/features/contacts/contact_state.dart b/dialer/lib/presentation/features/contacts/contact_state.dart index f555d66..2cf192d 100644 --- a/dialer/lib/presentation/features/contacts/contact_state.dart +++ b/dialer/lib/presentation/features/contacts/contact_state.dart @@ -101,6 +101,10 @@ class _ContactStateState extends State { void _processContactsInitial(List contacts) { if (!mounted) return; + // Optimize by doing a single pass through contacts instead of multiple iterations + final filteredContacts = contacts.where((contact) => contact.phones.isNotEmpty).toList() + ..sort((a, b) => a.displayName.compareTo(b.displayName)); + _selfContact = contacts.firstWhere( (contact) => contact.displayName.toLowerCase() == "user", orElse: () => Contact(), @@ -109,12 +113,9 @@ class _ContactStateState extends State { if (_selfContact!.phones.isEmpty) { _selfContact = null; } - - contacts = contacts.where((contact) => contact.phones.isNotEmpty).toList(); - contacts.sort((a, b) => a.displayName.compareTo(b.displayName)); - - _allContacts = contacts; - _favoriteContacts = contacts.where((contact) => contact.isStarred).toList(); + + _allContacts = filteredContacts; + _favoriteContacts = filteredContacts.where((contact) => contact.isStarred).toList(); _loading = false; // Force a rebuild after initialization is complete @@ -128,6 +129,10 @@ class _ContactStateState extends State { void _processContacts(List contacts) { if (!mounted) return; + // Same optimization as above + final filteredContacts = contacts.where((contact) => contact.phones.isNotEmpty).toList() + ..sort((a, b) => a.displayName.compareTo(b.displayName)); + _selfContact = contacts.firstWhere( (contact) => contact.displayName.toLowerCase() == "user", orElse: () => Contact(), @@ -137,12 +142,9 @@ class _ContactStateState extends State { _selfContact = null; } - contacts = contacts.where((contact) => contact.phones.isNotEmpty).toList(); - contacts.sort((a, b) => a.displayName.compareTo(b.displayName)); - setState(() { - _allContacts = contacts; - _favoriteContacts = contacts.where((contact) => contact.isStarred).toList(); + _allContacts = filteredContacts; + _favoriteContacts = filteredContacts.where((contact) => contact.isStarred).toList(); }); } diff --git a/dialer/lib/presentation/features/home/home_page.dart b/dialer/lib/presentation/features/home/home_page.dart index f19fa01..fb43fc6 100644 --- a/dialer/lib/presentation/features/home/home_page.dart +++ b/dialer/lib/presentation/features/home/home_page.dart @@ -62,16 +62,24 @@ class _MyHomePageState extends State } void _onSearchChanged(String query) { - setState(() { - if (query.isEmpty) { + if (query.isEmpty) { + setState(() { _contactSuggestions = List.from(_allContacts); // Reset suggestions - } else { - _contactSuggestions = _allContacts.where((contact) { - return contact.displayName - .toLowerCase() - .contains(query.toLowerCase()); - }).toList(); - } + }); + return; + } + + // Convert query to lowercase once for efficiency + final lowerQuery = query.toLowerCase(); + + // Use where with efficient filter + final filtered = _allContacts.where((contact) { + final name = contact.displayName.toLowerCase(); + return name.contains(lowerQuery); + }).toList(); + + setState(() { + _contactSuggestions = filtered; }); }