|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
|
import '../../../core/constants/app_contants.dart';
|
|
|
|
|
import '../../../core/constants/translation_keys.dart';
|
|
|
|
|
import '../../../core/dialogs/custom_loading.dart';
|
|
|
|
|
import '../../../custom_widgets/Fields/input_field.dart';
|
|
|
|
|
import '../../../custom_widgets/custom_toasty.dart';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ContactsScreenController extends GetxController {
|
|
|
|
|
static TextEditingController phoneController = TextEditingController();
|
|
|
|
|
Contact? selectedContact;
|
|
|
|
|
|
|
|
|
|
List<Contact> contactsList = [];
|
|
|
|
|
RxList<Contact> filteredContacts = <Contact>[].obs;
|
|
|
|
|
|
|
|
|
|
late InputField searchContacts;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void onInit() {
|
|
|
|
|
super.onInit();
|
|
|
|
|
_loadContacts();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
onReady() {
|
|
|
|
|
super.onReady();
|
|
|
|
|
searchContacts.controller?.addListener(() {
|
|
|
|
|
if (searchContacts.getCustomText().isEmpty) {
|
|
|
|
|
filteredContacts.assignAll(contactsList);
|
|
|
|
|
} else {
|
|
|
|
|
filteredContacts.value = contactsList.where((element) => element.name.first == searchContacts.getCustomText() || element.name.last == searchContacts.getCustomText()).toList();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> _loadContacts() async {
|
|
|
|
|
/// Check if the app has permission to access contacts
|
|
|
|
|
var status = await Permission.contacts.status;
|
|
|
|
|
showLoader();
|
|
|
|
|
if (status.isGranted) {
|
|
|
|
|
/// Permission is granted, load contacts
|
|
|
|
|
try {
|
|
|
|
|
contactsList = await FlutterContacts.getContacts(withProperties: true, withAccounts: true, withPhoto: true, sorted: true, withThumbnail: true);
|
|
|
|
|
filteredContacts.assignAll(contactsList);
|
|
|
|
|
hideLoader();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
print('Error loading contacts: $e');
|
|
|
|
|
hideLoader();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/// Permission is not granted, request permission
|
|
|
|
|
await _requestPermissions();
|
|
|
|
|
hideLoader();
|
|
|
|
|
}
|
|
|
|
|
hideLoader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> _requestPermissions() async {
|
|
|
|
|
/// Request contacts permission
|
|
|
|
|
var status = await Permission.contacts.request();
|
|
|
|
|
if (!status.isGranted) {
|
|
|
|
|
Toasty.error(TranslationKeys.makeTranslation(TranslationKeys.textPermissionDenied));
|
|
|
|
|
} else {
|
|
|
|
|
/// Permission granted, load contacts
|
|
|
|
|
await _loadContacts();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Function to filter contacts based on search query
|
|
|
|
|
void filterContacts(String searchText) {
|
|
|
|
|
if (searchText.isEmpty) {
|
|
|
|
|
filteredContacts.assignAll(contactsList);
|
|
|
|
|
} else {
|
|
|
|
|
searchText = searchText.toLowerCase();
|
|
|
|
|
filteredContacts.assignAll(contactsList.where((contact) {
|
|
|
|
|
// Check if either name or phone number matches the search text
|
|
|
|
|
bool matchesName = contact.name.first.toLowerCase().contains(searchText) ||
|
|
|
|
|
(contact.name.last != null && contact.name.last!.toLowerCase().contains(searchText));
|
|
|
|
|
|
|
|
|
|
bool matchesPhoneNumber = false;
|
|
|
|
|
for (var number in contact.phones) {
|
|
|
|
|
if (number.number.toLowerCase().contains(searchText)) {
|
|
|
|
|
matchesPhoneNumber = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return matchesName || matchesPhoneNumber;
|
|
|
|
|
}).toList());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// Phone number pattern
|
|
|
|
|
String flattenPhoneNumber(String phoneStr) {
|
|
|
|
|
return phoneStr.replaceAllMapped(RegExp(r'^(\+)|\D'), (Match m) {
|
|
|
|
|
return m[0] == "+" ? "+" : "";
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleContactSelection(Contact selectedContact) {
|
|
|
|
|
Get.back(result: {AppConstants.SELECTED_CONTACT: selectedContact});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|