import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:url_launcher/url_launcher.dart'; import '../contacts/contact_state.dart'; import '../../../domain/services/obfuscate_service.dart'; import '../../common/widgets/obfuscated_avatar.dart'; import '../../../core/utils/color_utils.dart'; import '../../../domain/services/call_service.dart'; import '../../../domain/services/block_service.dart'; import 'widgets/contact_modal.dart'; import 'widgets/alphabet_scroll_page.dart'; class ContactPage extends StatefulWidget { const ContactPage({super.key}); @override _ContactPageState createState() => _ContactPageState(); } class _ContactPageState extends State { final ObfuscateService _obfuscateService = ObfuscateService(); final CallService _callService = CallService(); int? _expandedIndex; Future _refreshContacts() async { final contactState = ContactState.of(context); try { await contactState.fetchContacts(); } catch (e) { debugPrint('Error refreshing contacts: $e'); if (mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('Failed to refresh contacts'))); } } } void _toggleFavorite(Contact contact) async { try { if (await FlutterContacts.requestPermission()) { Contact? fullContact = await FlutterContacts.getContact(contact.id, withProperties: true, withAccounts: true, withPhoto: true, withThumbnail: true); if (fullContact != null) { fullContact.isStarred = !fullContact.isStarred; await FlutterContacts.updateContact(fullContact); } 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'))); } } @override Widget build(BuildContext context) { final contactState = ContactState.of(context); if (contactState.loading) { return const Center(child: CircularProgressIndicator()); } final contacts = contactState.contacts; if (contacts.isEmpty) { return const Center( child: Text( 'No contacts found.\nAdd contacts to get started.', style: TextStyle(color: Colors.white60), textAlign: TextAlign.center, ), ); } return Scaffold( backgroundColor: Colors.black, body: AlphabetScrollPage( scrollOffset: contactState.scrollOffset, contacts: contacts, ), ); } Widget _getCallIcon(Contact contact) { if (!contact.phones.isNotEmpty) return const SizedBox.shrink(); return Icon( contact.isStarred ? Icons.star : Icons.star_border, color: contact.isStarred ? Colors.amber : Colors.grey, ); } Future _launchSms(Contact contact) async { if (!contact.phones.isNotEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('No phone number available')), ); return; } final Uri smsUri = Uri( scheme: 'sms', path: contact.phones.first.number, ); if (await canLaunchUrl(smsUri)) { await launchUrl(smsUri); } else { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Could not launch SMS')), ); } } void _editContact(Contact contact) async { if (await FlutterContacts.requestPermission()) { final updatedContact = await FlutterContacts.openExternalEdit(contact.id); if (updatedContact != null) { await _refreshContacts(); setState(() => _expandedIndex = null); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('${contact.displayName} updated successfully!')), ); } } } void _toggleBlock(Contact contact, bool isBlocked) async { if (!contact.phones.isNotEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('No phone number to block')), ); return; } final phoneNumber = contact.phones.first.number; if (isBlocked) { await BlockService().unblockNumber(phoneNumber); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('$phoneNumber unblocked')), ); } else { await BlockService().blockNumber(phoneNumber); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('$phoneNumber blocked')), ); } setState(() {}); } void _showContactModal(Contact contact) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => ContactModal( contact: contact, onEdit: () async { 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!')), ); } } }, onToggleFavorite: () => _toggleFavorite(contact), isFavorite: contact.isStarred, ), ); } Widget _buildActionButton({ required IconData icon, required String label, required VoidCallback onPressed, }) { return InkWell( onTap: onPressed, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, color: Colors.white), const SizedBox(height: 4), Text( label, style: const TextStyle( color: Colors.white, fontSize: 12, ), ), ], ), ), ); } }