From 7638c23c4078c5f6d8ba8b216bb3957c6e6cb840 Mon Sep 17 00:00:00 2001 From: Florian Griffon Date: Thu, 12 Dec 2024 17:47:49 +0100 Subject: [PATCH] feat: all getContacts use the contactService | can favorite a contact --- .../lib/features/composition/composition.dart | 10 +- .../widgets/alphabet_scroll_page.dart | 162 ++-------------- .../features/favorites/favorites_page.dart | 180 ++++++++++++++++++ 3 files changed, 206 insertions(+), 146 deletions(-) diff --git a/dialer/lib/features/composition/composition.dart b/dialer/lib/features/composition/composition.dart index b224f05..b2dfb7d 100644 --- a/dialer/lib/features/composition/composition.dart +++ b/dialer/lib/features/composition/composition.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import '../../widgets/contact_service.dart'; +import '../../widgets/contact_service.dart'; class CompositionPage extends StatefulWidget { const CompositionPage({super.key}); @@ -14,6 +15,7 @@ class _CompositionPageState extends State { List _allContacts = []; List _filteredContacts = []; final ContactService _contactService = ContactService(); + final ContactService _contactService = ContactService(); @override void initState() { @@ -22,9 +24,11 @@ class _CompositionPageState extends State { } Future _fetchContacts() async { - _allContacts = await _contactService.fetchContacts(); - _filteredContacts = _allContacts; - setState(() {}); + if (await FlutterContacts.requestPermission()) { + _allContacts = await _contactService.fetchContacts(); + _filteredContacts = _allContacts; + setState(() {}); + } } void _filterContacts() { diff --git a/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart b/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart index e0b8b76..f5ddc0a 100644 --- a/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart +++ b/dialer/lib/features/contacts/widgets/alphabet_scroll_page.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import '../contact_state.dart'; import '../../../widgets/color_darkener.dart'; +import '../contact_state.dart'; +import '../../../widgets/contact_service.dart'; import 'add_contact_button.dart'; import 'contact_modal.dart'; import 'contact_modal.dart'; @@ -22,6 +24,7 @@ class AlphabetScrollPage extends StatefulWidget { class _AlphabetScrollPageState extends State { late ScrollController _scrollController; List _contacts = []; // Local copy of contacts for updating + final ContactService _contactService = ContactService(); @override void initState() { @@ -40,20 +43,28 @@ class _AlphabetScrollPageState extends State { } Future _refreshContacts() async { - final contactState = ContactState.of(context); try { - await contactState.fetchContacts(); + // Use the fetchContacts method from ContactService + final updatedContacts = await _contactService.fetchContacts(); + + if (mounted) { + setState(() { + _contacts = updatedContacts; + }); + } } catch (e) { print('Error refreshing contacts: $e'); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to refresh contacts')), - ); + // Optionally show a user-friendly error message + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text('Failed to refresh contacts'))); } } void _toggleFavorite(Contact contact) async { try { + // Request permission first if (await FlutterContacts.requestPermission()) { + // Fetch the full contact details with all available properties Contact? fullContact = await FlutterContacts.getContact(contact.id, withProperties: true, withAccounts: true, @@ -61,6 +72,7 @@ class _AlphabetScrollPageState extends State { withThumbnail: true); if (fullContact != null) { + // Update the contact fullContact.isStarred = !fullContact.isStarred; await FlutterContacts.updateContact(fullContact); } @@ -70,145 +82,9 @@ class _AlphabetScrollPageState extends State { } } catch (e) { print("Error updating favorite status: $e"); + // Optional: Show a user-friendly error message ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to update contact favorite status')), - ); - } - } - - 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"); + SnackBar(content: Text('Failed to update contact favorite status'))); } } diff --git a/dialer/lib/features/favorites/favorites_page.dart b/dialer/lib/features/favorites/favorites_page.dart index 48227c5..4cfda5f 100644 --- a/dialer/lib/features/favorites/favorites_page.dart +++ b/dialer/lib/features/favorites/favorites_page.dart @@ -1,3 +1,183 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_contacts/flutter_contacts.dart'; +// import '../../../widgets/color_darkener.dart'; +// import '../contacts/contact_state.dart'; +// import '../contacts/widgets/add_contact_button.dart'; +// import '../contacts/widgets/contact_modal.dart'; +// import '../contacts/widgets/share_own_qr.dart'; +// import 'package:dialer/widgets/username_color_generator.dart'; + +// class FavoritePage extends StatefulWidget { +// final List contacts; +// final double scrollOffset; + +// const FavoritePage({ +// super.key, +// required this.contacts, +// required this.scrollOffset, +// }); + +// @override +// _FavoritePageState createState() => _FavoritePageState(); +// } + +// class _FavoritePageState extends State { +// late ScrollController _scrollController; +// List _favoriteContacts = []; // Local list of favorite contacts + +// @override +// void initState() { +// super.initState(); +// _favoriteContacts = widget.contacts.where((contact) => contact.isStarred).toList(); // Filter only favorites +// _scrollController = ScrollController(initialScrollOffset: widget.scrollOffset); +// _scrollController.addListener(_onScroll); +// } + +// void _onScroll() { +// final contactState = ContactState.of(context); +// contactState.setScrollOffset(_scrollController.offset); +// } + +// Future _refreshContacts() async { +// if (await FlutterContacts.requestPermission()) { +// final updatedContacts = await FlutterContacts.getContacts( +// withProperties: true, +// withThumbnail: true, +// ); +// setState(() { +// _favoriteContacts = updatedContacts.where((contact) => contact.isStarred).toList(); +// }); +// } +// } + +// void _toggleFavorite(Contact contact) async { +// 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, +// ); + +// // Find the specific contact by matching contact.id +// Contact? contactToUpdate = allContacts.firstWhere( +// (c) => c.id == contact.id, +// orElse: () => throw Exception("Contact not found"), +// ); + +// if (contactToUpdate != null) { +// contactToUpdate.isStarred = !contactToUpdate.isStarred; + +// // Update the contact +// await FlutterContacts.updateContact(contactToUpdate); + +// // Refresh the favorite contacts list +// setState(() { +// _favoriteContacts = allContacts.where((c) => c.isStarred).toList(); +// }); +// } +// } catch (e) { +// print("Error updating favorite status: $e"); +// } +// } +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// backgroundColor: Colors.black, +// appBar: AppBar( +// title: const Text('Favorites'), +// backgroundColor: Colors.black, +// actions: [ +// IconButton( +// icon: const Icon(Icons.refresh), +// onPressed: _refreshContacts, +// ), +// ], +// ), +// body: _favoriteContacts.isEmpty +// ? Center( +// child: Text( +// 'No favorite contacts yet!', +// style: TextStyle(color: Colors.white), +// ), +// ) +// : ListView.builder( +// controller: _scrollController, +// itemCount: _favoriteContacts.length, +// itemBuilder: (context, index) { +// Contact contact = _favoriteContacts[index]; +// 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) +// ? CircleAvatar( +// backgroundImage: MemoryImage(contact.thumbnail!), +// ) +// : CircleAvatar( +// 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: () { +// showModalBottomSheet( +// context: context, +// isScrollControlled: true, +// backgroundColor: Colors.transparent, +// builder: (context) { +// return ContactModal( +// contact: contact, +// onEdit: () async { +// // Trigger edit logic and refresh contacts +// if (await FlutterContacts.requestPermission()) { +// final updatedContact = +// await FlutterContacts.openExternalEdit(contact.id); +// if (updatedContact != null) { +// await _refreshContacts(); +// Navigator.of(context).pop(); +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar(content: Text('${contact.displayName} updated successfully!')), +// ); +// } else { +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar(content: Text('Edit canceled or failed.')), +// ); +// } +// } +// }, +// onToggleFavorite: () { +// _toggleFavorite(contact); +// }, +// isFavorite: contact.isStarred, +// ); +// }, +// ); +// }, +// ); +// }, +// ), +// ); +// } + +// @override +// void dispose() { +// _scrollController.dispose(); +// super.dispose(); +// } +// } + + import 'package:flutter/material.dart'; class FavoritePage extends StatefulWidget {