Florian Griffon
fca1eea1c9
All checks were successful
/ mirror (push) Successful in 4s
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>
279 lines
10 KiB
Dart
279 lines
10 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
|
import '../../widgets/contact_service.dart';
|
|
|
|
class CompositionPage extends StatefulWidget {
|
|
const CompositionPage({super.key});
|
|
|
|
@override
|
|
_CompositionPageState createState() => _CompositionPageState();
|
|
}
|
|
|
|
class _CompositionPageState extends State<CompositionPage> {
|
|
String dialedNumber = "";
|
|
List<Contact> _allContacts = [];
|
|
List<Contact> _filteredContacts = [];
|
|
final ContactService _contactService = ContactService();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_fetchContacts();
|
|
}
|
|
|
|
Future<void> _fetchContacts() async {
|
|
_allContacts = await _contactService.fetchContacts();
|
|
_filteredContacts = _allContacts;
|
|
setState(() {});
|
|
}
|
|
|
|
void _filterContacts() {
|
|
setState(() {
|
|
_filteredContacts = _allContacts.where((contact) {
|
|
final phoneMatch = contact.phones.any((phone) =>
|
|
phone.number.replaceAll(RegExp(r'\D'), '').contains(dialedNumber));
|
|
final nameMatch = contact.displayName
|
|
.toLowerCase()
|
|
.contains(dialedNumber.toLowerCase());
|
|
return phoneMatch || nameMatch;
|
|
}).toList();
|
|
});
|
|
}
|
|
|
|
void _onNumberPress(String number) {
|
|
setState(() {
|
|
dialedNumber += number;
|
|
_filterContacts();
|
|
});
|
|
}
|
|
|
|
void _onDeletePress() {
|
|
setState(() {
|
|
if (dialedNumber.isNotEmpty) {
|
|
dialedNumber = dialedNumber.substring(0, dialedNumber.length - 1);
|
|
_filterContacts();
|
|
}
|
|
});
|
|
}
|
|
|
|
void _onClearPress() {
|
|
setState(() {
|
|
dialedNumber = "";
|
|
_filteredContacts = _allContacts;
|
|
});
|
|
}
|
|
|
|
// Placeholder function for adding contact
|
|
void addContact(String number) {
|
|
// This function is empty for now
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
body: Stack(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
// Top half: Display contacts matching dialed number
|
|
Expanded(
|
|
flex: 2,
|
|
child: Container(
|
|
padding: const EdgeInsets.only(
|
|
top: 42.0, left: 16.0, right: 16.0, bottom: 16.0),
|
|
color: Colors.black,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(
|
|
child: ListView(
|
|
children: _filteredContacts.isNotEmpty
|
|
? _filteredContacts.map((contact) {
|
|
return ListTile(
|
|
title: Text(
|
|
contact.displayName,
|
|
style:
|
|
const TextStyle(color: Colors.white),
|
|
),
|
|
subtitle: contact.phones.isNotEmpty
|
|
? Text(
|
|
contact.phones.first.number,
|
|
style: const TextStyle(
|
|
color: Colors.grey),
|
|
)
|
|
: null,
|
|
trailing: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
// Call button
|
|
IconButton(
|
|
icon: Icon(Icons.phone,
|
|
color: Colors.green[300],
|
|
size: 20),
|
|
onPressed: () {
|
|
print(
|
|
'Calling ${contact.displayName}');
|
|
},
|
|
),
|
|
// Text button
|
|
IconButton(
|
|
icon: Icon(Icons.message,
|
|
color: Colors.blue[300],
|
|
size: 20),
|
|
onPressed: () {
|
|
print(
|
|
'Texting ${contact.displayName}');
|
|
},
|
|
),
|
|
],
|
|
),
|
|
onTap: () {
|
|
// Handle contact selection if needed
|
|
},
|
|
);
|
|
}).toList()
|
|
: [
|
|
Center(
|
|
child: Text('No contacts found',
|
|
style:
|
|
TextStyle(color: Colors.white)))
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
// Bottom half: Dialpad and Dialed number display with erase button
|
|
Expanded(
|
|
flex: 2,
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
// Display dialed number with erase button
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.center,
|
|
child: Text(
|
|
dialedNumber,
|
|
style: const TextStyle(
|
|
fontSize: 24, color: Colors.white),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
),
|
|
IconButton(
|
|
onPressed: _onClearPress,
|
|
icon: const Icon(Icons.backspace,
|
|
color: Colors.white),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 10),
|
|
|
|
// Dialpad
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
_buildDialButton('1'),
|
|
_buildDialButton('2'),
|
|
_buildDialButton('3'),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
_buildDialButton('4'),
|
|
_buildDialButton('5'),
|
|
_buildDialButton('6'),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
_buildDialButton('7'),
|
|
_buildDialButton('8'),
|
|
_buildDialButton('9'),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
_buildDialButton('*'),
|
|
_buildDialButton('0'),
|
|
_buildDialButton('#'),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
// Add Contact Button with empty function call
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 20.0),
|
|
child: FloatingActionButton(
|
|
backgroundColor: Colors.blue,
|
|
onPressed: () {
|
|
addContact(dialedNumber);
|
|
},
|
|
child: const Icon(Icons.person_add, color: Colors.white),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
// Top Row with Back Arrow
|
|
Positioned(
|
|
top: 40.0,
|
|
left: 16.0,
|
|
child: IconButton(
|
|
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDialButton(String number) {
|
|
return ElevatedButton(
|
|
onPressed: () => _onNumberPress(number),
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Colors.black,
|
|
shape: const CircleBorder(),
|
|
padding: const EdgeInsets.all(16),
|
|
),
|
|
child: Text(
|
|
number,
|
|
style: const TextStyle(
|
|
fontSize: 24,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|