feat: all getContacts use the contactService | can favorite a contact
All checks were successful
/ mirror (push) Successful in 5s
All checks were successful
/ mirror (push) Successful in 5s
This commit is contained in:
parent
a64b32d114
commit
f3c092d5b8
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
|
import '../../widgets/contact_service.dart';
|
||||||
|
|
||||||
class CompositionPage extends StatefulWidget {
|
class CompositionPage extends StatefulWidget {
|
||||||
const CompositionPage({super.key});
|
const CompositionPage({super.key});
|
||||||
@ -12,6 +13,7 @@ class _CompositionPageState extends State<CompositionPage> {
|
|||||||
String dialedNumber = "";
|
String dialedNumber = "";
|
||||||
List<Contact> _allContacts = [];
|
List<Contact> _allContacts = [];
|
||||||
List<Contact> _filteredContacts = [];
|
List<Contact> _filteredContacts = [];
|
||||||
|
final ContactService _contactService = ContactService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -21,7 +23,7 @@ class _CompositionPageState extends State<CompositionPage> {
|
|||||||
|
|
||||||
Future<void> _fetchContacts() async {
|
Future<void> _fetchContacts() async {
|
||||||
if (await FlutterContacts.requestPermission()) {
|
if (await FlutterContacts.requestPermission()) {
|
||||||
_allContacts = await FlutterContacts.getContacts(withProperties: true);
|
_allContacts = await _contactService.fetchContacts();
|
||||||
_filteredContacts = _allContacts;
|
_filteredContacts = _allContacts;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
import 'contact_service.dart';
|
import '../../widgets/contact_service.dart';
|
||||||
|
|
||||||
class ContactState extends StatefulWidget {
|
class ContactState extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
import '../../../widgets/color_darkener.dart';
|
import '../../../widgets/color_darkener.dart';
|
||||||
import '../contact_state.dart';
|
import '../contact_state.dart';
|
||||||
|
import '../../../widgets/contact_service.dart';
|
||||||
import 'add_contact_button.dart';
|
import 'add_contact_button.dart';
|
||||||
import 'contact_modal.dart';
|
import 'contact_modal.dart';
|
||||||
import 'share_own_qr.dart';
|
import 'share_own_qr.dart';
|
||||||
@ -21,6 +22,7 @@ class AlphabetScrollPage extends StatefulWidget {
|
|||||||
class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
||||||
late ScrollController _scrollController;
|
late ScrollController _scrollController;
|
||||||
List<Contact> _contacts = []; // Local copy of contacts for updating
|
List<Contact> _contacts = []; // Local copy of contacts for updating
|
||||||
|
final ContactService _contactService = ContactService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -37,138 +39,48 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _refreshContacts() async {
|
Future<void> _refreshContacts() async {
|
||||||
if (await FlutterContacts.requestPermission()) {
|
try {
|
||||||
final updatedContacts = await FlutterContacts.getContacts(
|
// Use the fetchContacts method from ContactService
|
||||||
withProperties: true, withThumbnail: true);
|
final updatedContacts = await _contactService.fetchContacts();
|
||||||
setState(() {
|
|
||||||
_contacts = updatedContacts;
|
if (mounted) {
|
||||||
});
|
setState(() {
|
||||||
|
_contacts = updatedContacts;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Error refreshing contacts: $e');
|
||||||
|
// Optionally show a user-friendly error message
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(SnackBar(content: Text('Failed to refresh contacts')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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<Contact> 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 {
|
void _toggleFavorite(Contact contact) async {
|
||||||
print(contact.id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (contact != null) {
|
// Request permission first
|
||||||
print("Contact fetched: ${contact.displayName}");
|
if (await FlutterContacts.requestPermission()) {
|
||||||
print("Current isStarred status: ${contact.isStarred}");
|
// Fetch the full contact details with all available properties
|
||||||
|
Contact? fullContact = await FlutterContacts.getContact(contact.id,
|
||||||
|
withProperties: true,
|
||||||
|
withAccounts: true,
|
||||||
|
withPhoto: true,
|
||||||
|
withThumbnail: true);
|
||||||
|
|
||||||
// Toggle the favorite status
|
if (fullContact != null) {
|
||||||
contact.isStarred = !contact.isStarred;
|
// Update the contact
|
||||||
print("Updated isStarred status: ${contact.isStarred}");
|
fullContact.isStarred = !fullContact.isStarred;
|
||||||
|
await FlutterContacts.updateContact(fullContact);
|
||||||
// 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.");
|
|
||||||
}
|
}
|
||||||
|
await _refreshContacts();
|
||||||
} else {
|
} else {
|
||||||
print("Contact details are not available");
|
print("Could not fetch contact details");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Error updating favorite status: $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')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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<Contact> contacts;
|
||||||
|
// final double scrollOffset;
|
||||||
|
|
||||||
|
// const FavoritePage({
|
||||||
|
// super.key,
|
||||||
|
// required this.contacts,
|
||||||
|
// required this.scrollOffset,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// _FavoritePageState createState() => _FavoritePageState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _FavoritePageState extends State<FavoritePage> {
|
||||||
|
// late ScrollController _scrollController;
|
||||||
|
// List<Contact> _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<void> _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<Contact> 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';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class FavoritePage extends StatefulWidget {
|
class FavoritePage extends StatefulWidget {
|
||||||
|
@ -5,12 +5,15 @@ import 'package:dialer/features/history/history_page.dart';
|
|||||||
import 'package:dialer/features/composition/composition.dart';
|
import 'package:dialer/features/composition/composition.dart';
|
||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
import 'package:dialer/features/settings/settings.dart';
|
import 'package:dialer/features/settings/settings.dart';
|
||||||
|
import '../../widgets/contact_service.dart';
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage>
|
class _MyHomePageState extends State<MyHomePage>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late TabController _tabController;
|
late TabController _tabController;
|
||||||
List<Contact> _allContacts = [];
|
List<Contact> _allContacts = [];
|
||||||
List<Contact> _contactSuggestions = [];
|
List<Contact> _contactSuggestions = [];
|
||||||
|
final ContactService _contactService = ContactService();
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -21,10 +24,8 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _fetchContacts() async {
|
void _fetchContacts() async {
|
||||||
if (await FlutterContacts.requestPermission()) {
|
_allContacts = await _contactService.fetchContacts();
|
||||||
_allContacts = await FlutterContacts.getContacts(withProperties: true);
|
setState(() {});
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSearchChanged(String query) {
|
void _onSearchChanged(String query) {
|
||||||
|
Loading…
Reference in New Issue
Block a user