import 'package:dialer/services/obfuscate_service.dart'; import 'package:flutter/material.dart'; import 'package:dialer/features/contacts/contact_page.dart'; import 'package:dialer/features/favorites/favorites_page.dart'; import 'package:dialer/features/history/history_page.dart'; import 'package:dialer/features/composition/composition.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:dialer/features/settings/settings.dart'; import '../../services/contact_service.dart'; import 'package:dialer/features/voicemail/voicemail_page.dart'; import '../contacts/widgets/contact_modal.dart'; class _MyHomePageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; List _allContacts = []; List _contactSuggestions = []; final ContactService _contactService = ContactService(); final ObfuscateService _obfuscateService = ObfuscateService(); final TextEditingController _searchController = TextEditingController(); @override void initState() { super.initState(); // Set the TabController length to 4 _tabController = TabController(length: 4, vsync: this, initialIndex: 1); _tabController.addListener(_handleTabIndex); _fetchContacts(); } void _fetchContacts() async { _allContacts = await _contactService.fetchContacts(); setState(() {}); } void _clearSearch() { _searchController.clear(); _onSearchChanged(''); } void _onSearchChanged(String query) { setState(() { if (query.isEmpty) { _contactSuggestions = List.from(_allContacts); // Reset suggestions } else { _contactSuggestions = _allContacts.where((contact) { return contact.displayName .toLowerCase() .contains(query.toLowerCase()); }).toList(); } }); } @override void dispose() { _searchController.dispose(); _tabController.removeListener(_handleTabIndex); _tabController.dispose(); super.dispose(); } void _handleTabIndex() { setState(() {}); } 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); setState(() { // Updating the contact list after toggling the favorite _fetchContacts(); }); } } else { print("Could not fetch contact details"); } } catch (e) { print("Error updating favorite status: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to update contact favorite status')), ); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Column( children: [ // Persistent Search Bar Padding( padding: const EdgeInsets.only( top: 24.0, bottom: 10.0, left: 16.0, right: 16.0, ), child: Row( children: [ Expanded( child: Container( decoration: BoxDecoration( color: const Color.fromARGB(255, 30, 30, 30), borderRadius: BorderRadius.circular(12.0), border: Border.all(color: Colors.grey.shade800, width: 1), ), child: SearchAnchor( builder: (BuildContext context, SearchController controller) { return GestureDetector( onTap: () { controller.openView(); // Open the search view }, child: Container( decoration: BoxDecoration( color: const Color.fromARGB(255, 30, 30, 30), borderRadius: BorderRadius.circular(12.0), border: Border.all( color: Colors.grey.shade800, width: 1), ), padding: const EdgeInsets.symmetric( vertical: 12.0, horizontal: 16.0), child: Row( children: [ const Icon(Icons.search, color: Colors.grey, size: 24.0), const SizedBox(width: 8.0), Text( _searchController.text.isEmpty ? 'Search contacts' : _searchController.text, style: const TextStyle( color: Colors.grey, fontSize: 16.0), ), const Spacer(), if (_searchController.text.isNotEmpty) GestureDetector( onTap: _clearSearch, child: const Icon( Icons.clear, color: Colors.grey, size: 24.0, ), ), ], ), ), ); }, viewOnChanged: (query) { _onSearchChanged(query); // Update immediately }, suggestionsBuilder: (BuildContext context, SearchController controller) { return _contactSuggestions.map((contact) { return ListTile( key: ValueKey(contact.id), title: Text(_obfuscateService.obfuscateData(contact.displayName), style: const TextStyle(color: Colors.white)), onTap: () { // Clear the search text input controller.text = ''; // Close the search view controller.closeView(contact.displayName); // Show the ContactModal when a contact is tapped showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) { return ContactModal( contact: contact, onEdit: () async { if (await FlutterContacts .requestPermission()) { final updatedContact = await FlutterContacts .openExternalEdit(contact.id); if (updatedContact != null) { _fetchContacts(); 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, ); }, ); }, ); }).toList(); }, ), ), ), // 3-dot menu PopupMenuButton( icon: const Icon(Icons.more_vert, color: Colors.white), itemBuilder: (BuildContext context) => [ const PopupMenuItem( value: 'settings', child: Text('Settings'), ), ], onSelected: (String value) { if (value == 'settings') { Navigator.push( context, MaterialPageRoute( builder: (context) => const SettingsPage()), ); } }, ), ], ), ), // Main content with TabBarView Expanded( child: Stack( children: [ TabBarView( controller: _tabController, children: const [ FavoritesPage(), HistoryPage(), ContactPage(), VoicemailPage(), ], ), Positioned( right: 20, bottom: 20, child: FloatingActionButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const CompositionPage(), ), ); }, backgroundColor: Colors.blue, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(45), ), child: const Icon(Icons.dialpad, color: Colors.white), ), ), ], ), ), ], ), bottomNavigationBar: Container( color: Colors.black, child: TabBar( controller: _tabController, tabs: [ Tab( icon: Icon(_tabController.index == 0 ? Icons.star : Icons.star_border)), Tab( icon: Icon(_tabController.index == 1 ? Icons.access_time_filled : Icons.access_time_outlined)), Tab( icon: Icon(_tabController.index == 2 ? Icons.contacts : Icons.contacts_outlined)), Tab( icon: Icon(_tabController.index == 3 ? Icons.voicemail : Icons.voicemail_outlined), ), ], labelColor: Colors.white, unselectedLabelColor: const Color.fromARGB(255, 158, 158, 158), indicatorSize: TabBarIndicatorSize.label, indicatorColor: Colors.white, ), ), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override _MyHomePageState createState() => _MyHomePageState(); }