From 6bed3f5ad9ccbdfa60ba685f8e5c1608d63d3f65 Mon Sep 17 00:00:00 2001 From: Florian Griffon Date: Wed, 11 Dec 2024 21:54:20 +0100 Subject: [PATCH] feat: WIP contact-modal --- .../widgets/alphabet_scroll_page.dart | 180 +++++++++++++++++- 1 file changed, 175 insertions(+), 5 deletions(-) diff --git a/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart b/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart index 7453181..e0b8b76 100644 --- a/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart +++ b/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart @@ -5,11 +5,14 @@ import '../contact_state.dart'; import '../../../widgets/color_darkener.dart'; import 'add_contact_button.dart'; import 'contact_modal.dart'; +import 'contact_modal.dart'; import 'share_own_qr.dart'; class AlphabetScrollPage extends StatefulWidget { final double scrollOffset; + const AlphabetScrollPage( + {super.key, required this.contacts, required this.scrollOffset}); const AlphabetScrollPage({super.key, required this.scrollOffset}); @override @@ -18,10 +21,14 @@ class AlphabetScrollPage extends StatefulWidget { class _AlphabetScrollPageState extends State { late ScrollController _scrollController; + List _contacts = []; // Local copy of contacts for updating @override void initState() { super.initState(); + _scrollController = + ScrollController(initialScrollOffset: widget.scrollOffset); + _contacts = widget.contacts; // Initialize with the provided contacts _scrollController = ScrollController(initialScrollOffset: widget.scrollOffset); _scrollController.addListener(_onScroll); @@ -69,6 +76,142 @@ class _AlphabetScrollPageState extends State { } } + Future _refreshContacts() async { + if (await FlutterContacts.requestPermission()) { + final updatedContacts = await FlutterContacts.getContacts( + withProperties: true, withThumbnail: true); + setState(() { + _contacts = updatedContacts; + }); + } + } + + // void _toggleFavorite(Contact contact) async { + // print(contact.id); + + // if (await FlutterContacts.requestPermission()) { + // try { + // // Fetch all contacts (this can be slow if there are many contacts) + // List allContacts = await FlutterContacts.getContacts( + // withProperties: true, + // withThumbnail: true, + // withAccounts: true, + // withPhoto: true + // ); + + // // Find the specific contact by matching contact.id + // // Use `orElse` to return a nullable Contact? or throw an exception if not found + // Contact? contactToUpdate = allContacts.firstWhere( + // (c) => c.id == contact.id, + // orElse: () => throw Exception( + // "Contact not found"), // Throw an exception if not found + // ); + + // if (contactToUpdate != null) { + // print("Contact fetched: ${contactToUpdate.displayName}"); + // print("Current isStarred status: ${contactToUpdate.isStarred}"); + + // // Toggle the favorite status + // contactToUpdate.isStarred = !contactToUpdate.isStarred; + // print("Updated isStarred status: ${contactToUpdate.isStarred}"); + + // // Update the contact + // await FlutterContacts.updateContact(contactToUpdate); + // print("Contact updated successfully"); + + // // Refresh the UI by updating the state + // setState(() { + // contact.isStarred = contactToUpdate.isStarred; + // }); + // } + // } catch (e) { + // print("Error updating favorite status: $e"); + // } + // } + // } + + // void _toggleFavorite(Contact contact) async { + // print(contact.id); + + // try { + // // Fetch the contact with details + // final contactWithDetails = await FlutterContacts.getContact(contact.id, + // withProperties: true, withThumbnail: true, withAccounts: true); + + // if (contactWithDetails != null) { + // print("Contact fetched: ${contactWithDetails.displayName}"); + // print("Current isStarred status: ${contactWithDetails.isStarred}"); + + // // Toggle the favorite status + // contactWithDetails.isStarred = !contactWithDetails.isStarred; + // print("Updated isStarred status: ${contactWithDetails.isStarred}"); + + // // Update the contact + // await FlutterContacts.updateContact(contactWithDetails); + // print("Contact updated successfully"); + + // // Reset the contact state (optional) + // setState(() { + // contact.isStarred = contactWithDetails.isStarred; + // }); + + // // Re-fetch the contact to ensure UI reflects changes + // final updatedContact = await FlutterContacts.getContact(contact.id, + // withProperties: true, withThumbnail: true, withAccounts: true); + + // if (updatedContact != null) { + // print("Re-fetched updated contact: ${updatedContact.displayName}"); + // print("Re-fetched isStarred status: ${updatedContact.isStarred}"); + // } else { + // print("Re-fetching contact failed."); + // } + // } else { + // print("Contact details are not available"); + // } + // } catch (e) { + // print("Error updating favorite status: $e"); + // } + // } + + void _toggleFavorite(Contact contact) async { + print(contact.id); + + try { + if (contact != null) { + print("Contact fetched: ${contact.displayName}"); + print("Current isStarred status: ${contact.isStarred}"); + + // Toggle the favorite status + contact.isStarred = !contact.isStarred; + print("Updated isStarred status: ${contact.isStarred}"); + + // Update the contact + await FlutterContacts.updateContact(contact); + print("Contact updated successfully"); + + // Reset the contact state (optional) + setState(() { + contact.isStarred = contact.isStarred; + }); + + // Re-fetch the contact to ensure UI reflects changes + final updatedContact = await FlutterContacts.getContact(contact.id, + withProperties: true, withThumbnail: true, withAccounts: true); + + if (updatedContact != null) { + print("Re-fetched updated contact: ${updatedContact.displayName}"); + print("Re-fetched isStarred status: ${updatedContact.isStarred}"); + } else { + print("Re-fetching contact failed."); + } + } else { + print("Contact details are not available"); + } + } catch (e) { + print("Error updating favorite status: $e"); + } + } + @override Widget build(BuildContext context) { final contactState = ContactState.of(context); @@ -76,7 +219,7 @@ class _AlphabetScrollPageState extends State { final selfContact = contactState.selfContact; Map> alphabetizedContacts = {}; - for (var contact in contacts) { + for (var contact in _contacts) { String firstLetter = contact.displayName.isNotEmpty ? contact.displayName[0].toUpperCase() : '#'; @@ -91,16 +234,21 @@ class _AlphabetScrollPageState extends State { return Scaffold( backgroundColor: Colors.black, body: Column( + children: [ + // Top buttons row children: [ // Top buttons row Container( color: Colors.black, - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AddContactButton(), - QRCodeButton(contacts: contacts, selfContact: selfContact), + QRCodeButton( + contacts: _contacts, + selfContact: ContactState.of(context).selfContact), ], ), ), @@ -117,6 +265,8 @@ class _AlphabetScrollPageState extends State { children: [ // Alphabet Letter Header Padding( + padding: const EdgeInsets.symmetric( + vertical: 8.0, horizontal: 16.0), padding: const EdgeInsets.symmetric( vertical: 8.0, horizontal: 16.0), child: Text( @@ -129,19 +279,24 @@ class _AlphabetScrollPageState extends State { ), ), // Contact Entries - ...contactsForLetter.map((contact) { + ...contacts.map((contact) { String phoneNumber = contact.phones.isNotEmpty ? contact.phones.first.number : 'No phone number'; Color avatarColor = generateColorFromName(contact.displayName); return ListTile( + leading: (contact.thumbnail != null && + contact.thumbnail!.isNotEmpty) leading: (contact.thumbnail != null && contact.thumbnail!.isNotEmpty) ? CircleAvatar( backgroundImage: MemoryImage(contact.thumbnail!), ) + backgroundImage: + MemoryImage(contact.thumbnail!), + ) : CircleAvatar( backgroundColor: avatarColor, child: Text( @@ -154,6 +309,19 @@ class _AlphabetScrollPageState extends State { ), title: Text(contact.displayName, style: TextStyle(color: Colors.white)), + subtitle: Text(phoneNumber, + style: TextStyle(color: Colors.white70)), + backgroundColor: avatarColor, + child: Text( + contact.displayName.isNotEmpty + ? contact.displayName[0].toUpperCase() + : '?', + style: TextStyle( + color: darken(avatarColor, 0.4)), + ), + ), + title: Text(contact.displayName, + style: TextStyle(color: Colors.white)), subtitle: Text(phoneNumber, style: TextStyle(color: Colors.white70)), onTap: () { @@ -165,7 +333,9 @@ class _AlphabetScrollPageState extends State { return ContactModal( contact: contact, onEdit: () async { - if (await FlutterContacts.requestPermission()) { + // Trigger edit logic and refresh contacts + if (await FlutterContacts + .requestPermission()) { final updatedContact = await FlutterContacts.openExternalEdit( contact.id);