refactor: optimize contact fetching and processing for improved performance
All checks were successful
/ mirror (push) Successful in 4s
/ build-stealth (push) Successful in 9m52s
/ build (push) Successful in 9m56s

This commit is contained in:
AlexisDanlos 2025-04-04 14:38:32 +02:00
parent 9e04185da1
commit 8cb206a640
3 changed files with 40 additions and 26 deletions

View File

@ -38,24 +38,28 @@ class _ContactPageState extends State<ContactPage> {
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')));
}
}
}

View File

@ -101,6 +101,10 @@ class _ContactStateState extends State<ContactState> {
void _processContactsInitial(List<Contact> 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<ContactState> {
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<ContactState> {
void _processContacts(List<Contact> 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<ContactState> {
_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();
});
}

View File

@ -62,16 +62,24 @@ class _MyHomePageState extends State<MyHomePage>
}
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;
});
}