import 'package:clean/base/base_controller.dart'; import 'package:clean/data/repositories/user_repository.dart'; import 'package:clean/handler/event_handler.dart'; import 'package:clean/module/contact/contact_state.dart'; import 'package:clean/module/store/store_view.dart'; import 'package:flutter/Material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_contacts/contact.dart'; import 'package:get/get.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import '../../../data/consts/event_report_id.dart'; import '../../../dialog/loading_dialog.dart'; import '../../../utils/toast_util.dart'; class ContactInCompleteController extends BaseController { // 存储不符合要求的联系人 final RxList filteredContacts = [].obs; // 存储联系人按首字母分组 final RxMap> groupedContacts = >{}.obs; // 存储联系人首字母 final RxList initials = [].obs; // 是否全选 final RxBool isAllSelected = false.obs; // 存储选中的联系人 final RxSet selectedContacts = {}.obs; final ItemScrollController itemScrollController = ItemScrollController(); final ItemPositionsListener itemPositionsListener = ItemPositionsListener.create(); // isEdit final RxBool isEdit = false.obs; @override void onInit()async { super.onInit(); } @override void onReady() { // TODO: implement onReady super.onReady(); filterContacts(); groupContacts(); } // 过滤联系人 void filterContacts() { filteredContacts.value = ContactState.contactList.where((contact) { final hasValidPhone = contact.phones.any((p) => isValidPhoneNumber(p.number ?? '')); return contact.phones.isEmpty || !hasValidPhone; }).toList(); } bool isValidPhoneNumber(String phone) { // 如果电话号码为空,则返回false if (phone.isEmpty) return false; // 如果电话号码不是数字、空格、+号,则返回false return RegExp(r'^\+?[0-9 -]+$').hasMatch(phone); } Future deleteBtnClick() async { EventHandler.report(EventId.event_08009); if (!userRepository.isVip()) { StorePage.start(); return; } if (selectedContacts.isEmpty) { ToastUtil.show("Please select a contact"); return; } print("deleteBtnClick selectedContacts: $selectedContacts"); final contactToDelete = ContactState.contactList .where((contact) => selectedContacts.contains(contact.id)) .toList(); LoadingDialog.show(displayTime: 100); for (var contact in contactToDelete) { await contact.delete(); // 删除操作必须 `await` } LoadingDialog.hide(); ToastUtil.show("Successful"); exitEditMode(); await ContactState.loadContacts(); // 确保联系人列表更新 filterContacts(); // 重新筛选联系人 groupContacts(); // 重新分组 debugPrint("filteredContacts.length: ${filteredContacts.length}"); } // 全选/取消全选 void toggleSelectAll() { if (isAllSelected.value) { selectedContacts.clear(); } else { selectedContacts .addAll(filteredContacts.map((contact) => contact.id)); } isAllSelected.value = !isAllSelected.value; } // 退出编辑模式时清空选择 void exitEditMode() { isEdit.value = false; selectedContacts.clear(); isAllSelected.value = false; } // 滚动到指定首字母 void groupContacts() { final Map> map = {}; for (var contact in filteredContacts) { final initial = contact.displayName.isNotEmpty == true ? contact.displayName[0].toUpperCase() : '#'; map.putIfAbsent(initial, () => []).add(contact); } final sortedKeys = map.keys.toList()..sort(); groupedContacts.value = Map.fromEntries(sortedKeys.map((key) => MapEntry(key, map[key]!))); initials.value = sortedKeys; } void scrollToInitial(String initial) { int index = ContactState.initials.indexOf(initial); if (index != -1) { final positions = itemPositionsListener.itemPositions.value; final isVisible = positions.any((position) => position.index == index); if (!isVisible) { itemScrollController.scrollTo( index: index, duration: Duration(milliseconds: 300), ); } } } void toggleSelectContact(Contact selectContact) { print("selectContact: ${selectContact.displayName}"); if (selectedContacts.contains(selectContact.id)) { selectedContacts.remove(selectContact.id); } else { selectedContacts.add(selectContact.id); } isAllSelected.value = selectedContacts.length == filteredContacts.length; } }