G-EIP-700-TLS-7-1-eip-steph.../dialer/lib/features/home/home_page.dart
Florian Griffon 90ddeb5b19 contact-modal (#10)
Feat: contact-modal et refonte du contact-state pour la page de favori et possibilité de update les contacts. Aussi mis la composition page avec le service de contact, on évite de fetch dans la page directement
Reviewed-on: #10
Co-authored-by: Florian Griffon <florian.griffon@epitech.eu>
Co-committed-by: Florian Griffon <florian.griffon@epitech.eu>
2024-12-17 13:35:25 +01:00

211 lines
7.0 KiB
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 '../../widgets/contact_service.dart';
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
List<Contact> _allContacts = [];
List<Contact> _contactSuggestions = [];
final ContactService _contactService = ContactService();
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this, initialIndex: 1);
_tabController.addListener(_handleTabIndex);
_fetchContacts();
}
void _fetchContacts() async {
_allContacts = await _contactService.fetchContacts();
setState(() {});
}
void _onSearchChanged(String query) {
print("Search query: $query");
setState(() {
if (query.isEmpty) {
_contactSuggestions = List.from(_allContacts);
} else {
_contactSuggestions = _allContacts.where((contact) {
return contact.displayName
.toLowerCase()
.contains(query.toLowerCase());
}).toList();
}
});
}
@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: 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),
),
),
child: SearchAnchor(
builder: (BuildContext context, SearchController controller) {
return SearchBar(
controller: controller,
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
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>(
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: () {
controller.closeView(contact.displayName);
},
);
}).toList();
},
),
),
),
// Main content with TabBarView
Expanded(
child: Stack(
children: [
TabBarView(
controller: _tabController,
children: const [
FavoritePage(),
HistoryPage(),
ContactPage(),
SettingsPage(), // Add your SettingsPage here
],
),
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 // Corrected index
? Icons.settings
: Icons.settings_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();
}