import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:dialer/features/settings/settings.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 '../../widgets/contact_service.dart'; /// This MyHomePage now expects two callbacks. /// - onMakeCall: used to start calls /// - onRequestDialer: used to become default dialer class MyHomePage extends StatefulWidget { final Function(String) onMakeCall; final Function onRequestDialer; const MyHomePage({ Key? key, required this.onMakeCall, required this.onRequestDialer, }) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; List _allContacts = []; List _contactSuggestions = []; final ContactService _contactService = ContactService(); @override void initState() { super.initState(); // We have 3 tabs: Favorites, History, Contacts _tabController = TabController(length: 3, vsync: this, initialIndex: 1); _tabController.addListener(_handleTabIndex); _fetchContacts(); } void _fetchContacts() async { _allContacts = await _contactService.fetchContacts(); setState(() {}); } void _onSearchChanged(String query) { if (query.isEmpty) { _contactSuggestions = List.from(_allContacts); } else { _contactSuggestions = _allContacts.where((contact) { return contact.displayName.toLowerCase().contains(query.toLowerCase()); }).toList(); } setState(() {}); } @override void dispose() { _tabController.removeListener(_handleTabIndex); _tabController.dispose(); super.dispose(); } void _handleTabIndex() { setState(() {}); } @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( top: BorderSide(color: Colors.grey.shade800, width: 1), left: BorderSide(color: Colors.grey.shade800, width: 1), right: BorderSide(color: Colors.grey.shade800, width: 1), bottom: BorderSide(color: Colors.grey.shade800, width: 2), ), ), // Using Flutter 3.10+ SearchAnchor / SearchBar API: child: SearchAnchor( builder: (BuildContext context, SearchController controller) { return SearchBar( controller: controller, padding: MaterialStateProperty.all( const EdgeInsets.only( top: 6.0, bottom: 6.0, left: 16.0, right: 16.0, ), ), onTap: () { controller.openView(); _onSearchChanged(''); }, backgroundColor: MaterialStateProperty.all( const Color.fromARGB(255, 30, 30, 30), ), hintText: 'Search contacts', hintStyle: MaterialStateProperty.all( const TextStyle(color: Colors.grey, fontSize: 16.0), ), leading: const Icon( Icons.search, color: Colors.grey, size: 24.0, ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), ), ); }, viewOnChanged: (query) { _onSearchChanged(query); }, suggestionsBuilder: (BuildContext context, SearchController controller) { return _contactSuggestions.map((contact) { return ListTile( key: ValueKey(contact.id), title: Text( contact.displayName, style: const TextStyle(color: Colors.white), ), onTap: () { // For example, you might call widget.onMakeCall(contact.phoneNumber) controller.closeView(contact.displayName); }, ); }).toList(); }, ), ), ), // 3-dot menu PopupMenuButton( icon: const Icon(Icons.more_vert, color: Colors.white), itemBuilder: (BuildContext context) => [ const PopupMenuItem( value: 'settings', child: Text('Settings'), ), const PopupMenuItem( value: 'becomeDialer', child: Text('Become Default Dialer'), ), ], onSelected: (String value) { if (value == 'settings') { Navigator.push( context, MaterialPageRoute(builder: (context) => const SettingsPage()), ); } else if (value == 'becomeDialer') { // Use the callback passed in from main.dart: widget.onRequestDialer(); } }, ), ], ), ), // Main content with TabBarView Expanded( child: Stack( children: [ TabBarView( controller: _tabController, children: const [ FavoritesPage(), HistoryPage(), ContactPage(), ], ), // Floating action button for manual composition/dialpad Positioned( right: 20, bottom: 20, child: FloatingActionButton( onPressed: () { // Here you could do widget.onMakeCall('123456') or // push to CompositionPage, etc. 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), ), ], labelColor: Colors.white, unselectedLabelColor: const Color.fromARGB(255, 158, 158, 158), indicatorSize: TabBarIndicatorSize.label, indicatorColor: Colors.white, ), ), ); } }