Files
mywhatsapp/whatsapp_app/lib/services/contacts_service.dart
2026-05-18 16:14:25 +03:00

86 lines
2.7 KiB
Dart

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;
}
}