feat: WIP contact-modal
This commit is contained in:
parent
21b6b0a29a
commit
6bed3f5ad9
@ -5,11 +5,14 @@ import '../contact_state.dart';
|
|||||||
import '../../../widgets/color_darkener.dart';
|
import '../../../widgets/color_darkener.dart';
|
||||||
import 'add_contact_button.dart';
|
import 'add_contact_button.dart';
|
||||||
import 'contact_modal.dart';
|
import 'contact_modal.dart';
|
||||||
|
import 'contact_modal.dart';
|
||||||
import 'share_own_qr.dart';
|
import 'share_own_qr.dart';
|
||||||
|
|
||||||
class AlphabetScrollPage extends StatefulWidget {
|
class AlphabetScrollPage extends StatefulWidget {
|
||||||
final double scrollOffset;
|
final double scrollOffset;
|
||||||
|
|
||||||
|
const AlphabetScrollPage(
|
||||||
|
{super.key, required this.contacts, required this.scrollOffset});
|
||||||
const AlphabetScrollPage({super.key, required this.scrollOffset});
|
const AlphabetScrollPage({super.key, required this.scrollOffset});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -18,10 +21,14 @@ class AlphabetScrollPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
||||||
late ScrollController _scrollController;
|
late ScrollController _scrollController;
|
||||||
|
List<Contact> _contacts = []; // Local copy of contacts for updating
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_scrollController =
|
||||||
|
ScrollController(initialScrollOffset: widget.scrollOffset);
|
||||||
|
_contacts = widget.contacts; // Initialize with the provided contacts
|
||||||
_scrollController =
|
_scrollController =
|
||||||
ScrollController(initialScrollOffset: widget.scrollOffset);
|
ScrollController(initialScrollOffset: widget.scrollOffset);
|
||||||
_scrollController.addListener(_onScroll);
|
_scrollController.addListener(_onScroll);
|
||||||
@ -69,6 +76,142 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _refreshContacts() async {
|
||||||
|
if (await FlutterContacts.requestPermission()) {
|
||||||
|
final updatedContacts = await FlutterContacts.getContacts(
|
||||||
|
withProperties: true, withThumbnail: true);
|
||||||
|
setState(() {
|
||||||
|
_contacts = updatedContacts;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void _toggleFavorite(Contact contact) async {
|
||||||
|
// print(contact.id);
|
||||||
|
|
||||||
|
// if (await FlutterContacts.requestPermission()) {
|
||||||
|
// try {
|
||||||
|
// // Fetch all contacts (this can be slow if there are many contacts)
|
||||||
|
// List<Contact> allContacts = await FlutterContacts.getContacts(
|
||||||
|
// withProperties: true,
|
||||||
|
// withThumbnail: true,
|
||||||
|
// withAccounts: true,
|
||||||
|
// withPhoto: true
|
||||||
|
// );
|
||||||
|
|
||||||
|
// // Find the specific contact by matching contact.id
|
||||||
|
// // Use `orElse` to return a nullable Contact? or throw an exception if not found
|
||||||
|
// Contact? contactToUpdate = allContacts.firstWhere(
|
||||||
|
// (c) => c.id == contact.id,
|
||||||
|
// orElse: () => throw Exception(
|
||||||
|
// "Contact not found"), // Throw an exception if not found
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if (contactToUpdate != null) {
|
||||||
|
// print("Contact fetched: ${contactToUpdate.displayName}");
|
||||||
|
// print("Current isStarred status: ${contactToUpdate.isStarred}");
|
||||||
|
|
||||||
|
// // Toggle the favorite status
|
||||||
|
// contactToUpdate.isStarred = !contactToUpdate.isStarred;
|
||||||
|
// print("Updated isStarred status: ${contactToUpdate.isStarred}");
|
||||||
|
|
||||||
|
// // Update the contact
|
||||||
|
// await FlutterContacts.updateContact(contactToUpdate);
|
||||||
|
// print("Contact updated successfully");
|
||||||
|
|
||||||
|
// // Refresh the UI by updating the state
|
||||||
|
// setState(() {
|
||||||
|
// contact.isStarred = contactToUpdate.isStarred;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Error updating favorite status: $e");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void _toggleFavorite(Contact contact) async {
|
||||||
|
// print(contact.id);
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// // Fetch the contact with details
|
||||||
|
// final contactWithDetails = await FlutterContacts.getContact(contact.id,
|
||||||
|
// withProperties: true, withThumbnail: true, withAccounts: true);
|
||||||
|
|
||||||
|
// if (contactWithDetails != null) {
|
||||||
|
// print("Contact fetched: ${contactWithDetails.displayName}");
|
||||||
|
// print("Current isStarred status: ${contactWithDetails.isStarred}");
|
||||||
|
|
||||||
|
// // Toggle the favorite status
|
||||||
|
// contactWithDetails.isStarred = !contactWithDetails.isStarred;
|
||||||
|
// print("Updated isStarred status: ${contactWithDetails.isStarred}");
|
||||||
|
|
||||||
|
// // Update the contact
|
||||||
|
// await FlutterContacts.updateContact(contactWithDetails);
|
||||||
|
// print("Contact updated successfully");
|
||||||
|
|
||||||
|
// // Reset the contact state (optional)
|
||||||
|
// setState(() {
|
||||||
|
// contact.isStarred = contactWithDetails.isStarred;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Re-fetch the contact to ensure UI reflects changes
|
||||||
|
// final updatedContact = await FlutterContacts.getContact(contact.id,
|
||||||
|
// withProperties: true, withThumbnail: true, withAccounts: true);
|
||||||
|
|
||||||
|
// if (updatedContact != null) {
|
||||||
|
// print("Re-fetched updated contact: ${updatedContact.displayName}");
|
||||||
|
// print("Re-fetched isStarred status: ${updatedContact.isStarred}");
|
||||||
|
// } else {
|
||||||
|
// print("Re-fetching contact failed.");
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// print("Contact details are not available");
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Error updating favorite status: $e");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
void _toggleFavorite(Contact contact) async {
|
||||||
|
print(contact.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (contact != null) {
|
||||||
|
print("Contact fetched: ${contact.displayName}");
|
||||||
|
print("Current isStarred status: ${contact.isStarred}");
|
||||||
|
|
||||||
|
// Toggle the favorite status
|
||||||
|
contact.isStarred = !contact.isStarred;
|
||||||
|
print("Updated isStarred status: ${contact.isStarred}");
|
||||||
|
|
||||||
|
// Update the contact
|
||||||
|
await FlutterContacts.updateContact(contact);
|
||||||
|
print("Contact updated successfully");
|
||||||
|
|
||||||
|
// Reset the contact state (optional)
|
||||||
|
setState(() {
|
||||||
|
contact.isStarred = contact.isStarred;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Re-fetch the contact to ensure UI reflects changes
|
||||||
|
final updatedContact = await FlutterContacts.getContact(contact.id,
|
||||||
|
withProperties: true, withThumbnail: true, withAccounts: true);
|
||||||
|
|
||||||
|
if (updatedContact != null) {
|
||||||
|
print("Re-fetched updated contact: ${updatedContact.displayName}");
|
||||||
|
print("Re-fetched isStarred status: ${updatedContact.isStarred}");
|
||||||
|
} else {
|
||||||
|
print("Re-fetching contact failed.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("Contact details are not available");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("Error updating favorite status: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final contactState = ContactState.of(context);
|
final contactState = ContactState.of(context);
|
||||||
@ -76,7 +219,7 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
final selfContact = contactState.selfContact;
|
final selfContact = contactState.selfContact;
|
||||||
|
|
||||||
Map<String, List<Contact>> alphabetizedContacts = {};
|
Map<String, List<Contact>> alphabetizedContacts = {};
|
||||||
for (var contact in contacts) {
|
for (var contact in _contacts) {
|
||||||
String firstLetter = contact.displayName.isNotEmpty
|
String firstLetter = contact.displayName.isNotEmpty
|
||||||
? contact.displayName[0].toUpperCase()
|
? contact.displayName[0].toUpperCase()
|
||||||
: '#';
|
: '#';
|
||||||
@ -91,16 +234,21 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
body: Column(
|
body: Column(
|
||||||
|
children: [
|
||||||
|
// Top buttons row
|
||||||
children: [
|
children: [
|
||||||
// Top buttons row
|
// Top buttons row
|
||||||
Container(
|
Container(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
AddContactButton(),
|
AddContactButton(),
|
||||||
QRCodeButton(contacts: contacts, selfContact: selfContact),
|
QRCodeButton(
|
||||||
|
contacts: _contacts,
|
||||||
|
selfContact: ContactState.of(context).selfContact),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -117,6 +265,8 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
children: [
|
children: [
|
||||||
// Alphabet Letter Header
|
// Alphabet Letter Header
|
||||||
Padding(
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8.0, horizontal: 16.0),
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 8.0, horizontal: 16.0),
|
vertical: 8.0, horizontal: 16.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -129,19 +279,24 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Contact Entries
|
// Contact Entries
|
||||||
...contactsForLetter.map((contact) {
|
...contacts.map((contact) {
|
||||||
String phoneNumber = contact.phones.isNotEmpty
|
String phoneNumber = contact.phones.isNotEmpty
|
||||||
? contact.phones.first.number
|
? contact.phones.first.number
|
||||||
: 'No phone number';
|
: 'No phone number';
|
||||||
Color avatarColor =
|
Color avatarColor =
|
||||||
generateColorFromName(contact.displayName);
|
generateColorFromName(contact.displayName);
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
leading: (contact.thumbnail != null &&
|
||||||
|
contact.thumbnail!.isNotEmpty)
|
||||||
leading: (contact.thumbnail != null &&
|
leading: (contact.thumbnail != null &&
|
||||||
contact.thumbnail!.isNotEmpty)
|
contact.thumbnail!.isNotEmpty)
|
||||||
? CircleAvatar(
|
? CircleAvatar(
|
||||||
backgroundImage:
|
backgroundImage:
|
||||||
MemoryImage(contact.thumbnail!),
|
MemoryImage(contact.thumbnail!),
|
||||||
)
|
)
|
||||||
|
backgroundImage:
|
||||||
|
MemoryImage(contact.thumbnail!),
|
||||||
|
)
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
backgroundColor: avatarColor,
|
backgroundColor: avatarColor,
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -154,6 +309,19 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
),
|
),
|
||||||
title: Text(contact.displayName,
|
title: Text(contact.displayName,
|
||||||
style: TextStyle(color: Colors.white)),
|
style: TextStyle(color: Colors.white)),
|
||||||
|
subtitle: Text(phoneNumber,
|
||||||
|
style: TextStyle(color: Colors.white70)),
|
||||||
|
backgroundColor: avatarColor,
|
||||||
|
child: Text(
|
||||||
|
contact.displayName.isNotEmpty
|
||||||
|
? contact.displayName[0].toUpperCase()
|
||||||
|
: '?',
|
||||||
|
style: TextStyle(
|
||||||
|
color: darken(avatarColor, 0.4)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
title: Text(contact.displayName,
|
||||||
|
style: TextStyle(color: Colors.white)),
|
||||||
subtitle: Text(phoneNumber,
|
subtitle: Text(phoneNumber,
|
||||||
style: TextStyle(color: Colors.white70)),
|
style: TextStyle(color: Colors.white70)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -165,7 +333,9 @@ class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|||||||
return ContactModal(
|
return ContactModal(
|
||||||
contact: contact,
|
contact: contact,
|
||||||
onEdit: () async {
|
onEdit: () async {
|
||||||
if (await FlutterContacts.requestPermission()) {
|
// Trigger edit logic and refresh contacts
|
||||||
|
if (await FlutterContacts
|
||||||
|
.requestPermission()) {
|
||||||
final updatedContact =
|
final updatedContact =
|
||||||
await FlutterContacts.openExternalEdit(
|
await FlutterContacts.openExternalEdit(
|
||||||
contact.id);
|
contact.id);
|
||||||
|
Loading…
Reference in New Issue
Block a user