feat: contactModal in searchBar
All checks were successful
/ mirror (push) Successful in 4s

This commit is contained in:
Florian Griffon 2025-01-16 17:12:03 +01:00
parent 4401cba5b5
commit d925717fc2

View File

@ -6,6 +6,7 @@ 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';
import '../contacts/widgets/contact_modal.dart'; // Import the ContactModal widget
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
@ -13,6 +14,7 @@ class _MyHomePageState extends State<MyHomePage>
List<Contact> _allContacts = [];
List<Contact> _contactSuggestions = [];
final ContactService _contactService = ContactService();
final SearchController _searchController = SearchController();
@override
void initState() {
@ -30,7 +32,7 @@ class _MyHomePageState extends State<MyHomePage>
void _onSearchChanged(String query) {
setState(() {
if (query.isEmpty) {
_contactSuggestions = List.from(_allContacts);
_contactSuggestions = List.from(_allContacts); // Reset suggestions
} else {
_contactSuggestions = _allContacts.where((contact) {
return contact.displayName
@ -41,10 +43,14 @@ class _MyHomePageState extends State<MyHomePage>
});
}
void _clearSearch() {
_searchController.text = '';
_onSearchChanged('');
}
@override
void dispose() {
_tabController.removeListener(_handleTabIndex);
_tabController.dispose();
_searchController.dispose();
super.dispose();
}
@ -52,6 +58,35 @@ class _MyHomePageState extends State<MyHomePage>
setState(() {});
}
// New method to handle toggling favorites
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(
@ -69,61 +104,118 @@ class _MyHomePageState extends State<MyHomePage>
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(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Icon(Icons.search,
color: Colors.grey, size: 24.0),
SizedBox(width: 8.0),
Text(
'Search contacts',
style: TextStyle(
color: Colors.grey, fontSize: 16.0),
),
],
),
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(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,
);
},
);
},
);
},
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();
},
)),
}).toList();
},
),
),
),
PopupMenuButton<String>(
icon: const Icon(Icons.more_vert, color: Colors.white),
@ -146,7 +238,6 @@ class _MyHomePageState extends State<MyHomePage>
],
),
),
// Main content with TabBarView
Expanded(
child: Stack(
children: [