Sync update: 2026-05-18 16:14:25
This commit is contained in:
85
whatsapp_app/lib/services/contacts_service.dart
Normal file
85
whatsapp_app/lib/services/contacts_service.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class ContactInfo {
|
||||
final String name;
|
||||
final String? avatarPath;
|
||||
ContactInfo({required this.name, this.avatarPath});
|
||||
}
|
||||
|
||||
class ContactsService extends GetxService {
|
||||
final RxMap<String, ContactInfo> _contactsMap = <String, ContactInfo>{}.obs;
|
||||
final RxBool permissionGranted = false.obs;
|
||||
|
||||
Future<ContactsService> init() async {
|
||||
await fetchContacts();
|
||||
return this;
|
||||
}
|
||||
|
||||
Future<void> fetchContacts() async {
|
||||
try {
|
||||
// Check and request permission
|
||||
bool permission = await FlutterContacts.requestPermission(readonly: true);
|
||||
permissionGranted.value = permission;
|
||||
|
||||
if (permission) {
|
||||
// Fetch contacts with photos and phone numbers
|
||||
final contacts = await FlutterContacts.getContacts(withProperties: true, withPhoto: true);
|
||||
|
||||
final Map<String, ContactInfo> tempMap = {};
|
||||
for (var contact in contacts) {
|
||||
final fullName = contact.displayName;
|
||||
if (fullName.isEmpty) continue;
|
||||
|
||||
for (var phone in contact.phones) {
|
||||
final normalized = normalizePhoneNumber(phone.number);
|
||||
if (normalized.isNotEmpty) {
|
||||
tempMap[normalized] = ContactInfo(
|
||||
name: fullName,
|
||||
avatarPath: null, // Custom local avatar path can be handled if needed
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
_contactsMap.assignAll(tempMap);
|
||||
print('[CONTACTS] Successfully loaded ${_contactsMap.length} normalized phone contacts');
|
||||
}
|
||||
} catch (e) {
|
||||
print('[CONTACTS ERROR] Failed to fetch system contacts: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Normalizes numbers to match them easily (e.g., removes spaces, dashes, brackets, and leading zeros)
|
||||
String normalizePhoneNumber(String number) {
|
||||
String clean = number.replaceAll(RegExp(r'[\s\-\(\)\+]'), '');
|
||||
// If it starts with local country prefix or leading 0, we can do substring matches
|
||||
if (clean.startsWith('00')) {
|
||||
clean = clean.substring(2);
|
||||
}
|
||||
return clean;
|
||||
}
|
||||
|
||||
String getContactName(String rawNumber, String fallback) {
|
||||
if (!permissionGranted.value || _contactsMap.isEmpty) return fallback;
|
||||
|
||||
final clean = normalizePhoneNumber(rawNumber);
|
||||
if (clean.isEmpty) return fallback;
|
||||
|
||||
// Direct match
|
||||
if (_contactsMap.containsKey(clean)) {
|
||||
return _contactsMap[clean]!.name;
|
||||
}
|
||||
|
||||
// Partial match for varying country codes (match last 9 digits of the phone number)
|
||||
if (clean.length >= 9) {
|
||||
final suffix = clean.substring(clean.length - 9);
|
||||
for (var key in _contactsMap.keys) {
|
||||
if (key.endsWith(suffix)) {
|
||||
return _contactsMap[key]!.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user