import 'package:clean/base/base_page.dart'; import 'package:clean/module/contact/duplicate/controller.dart'; import 'package:clean/resource/assets.gen.dart'; import 'package:clean/utils/expand.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_contacts/contact.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:path/path.dart'; class ContactDuplicatePage extends BasePage { const ContactDuplicatePage({super.key}); @override bool immersive() { return true; } @override bool statusBarDarkFont() => false; @override Widget buildBody(BuildContext context) { return Stack( children: [ buildMain(context), IgnorePointer( child: Assets.images.bgHome.image( width: 360.w, ), ), ], ); } Widget buildMain(BuildContext context) { return SafeArea( child: Container( padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w), child: Obx(() { return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ !controller.isEdit.value ? Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { Get.back(); }, child: Assets.images.iconCommonBack .image(width: 28.w, height: 28.w), ), GestureDetector( onTap: () { controller.isEdit.value = true; }, child: Container( width: 71.w, height: 30.h, decoration: BoxDecoration( color: "#1F2D3F".color, borderRadius: BorderRadius.all( Radius.circular(15.h), ), ), child: Center( child: Text( "Select", style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ), ], ) : Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { controller.isEdit.value = false; }, child: Container( width: 71.w, height: 30.h, decoration: BoxDecoration( color: "#1F2D3F".color, borderRadius: BorderRadius.all( Radius.circular(15.h), ), ), child: Center( child: Text( "Cancel", style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ), GestureDetector( onTap: () { controller.toggleSelectAll(); }, child: Text( controller.isAllSelected.value ? "Deselect all" : "Select All", style: TextStyle( color: Colors.white.withOpacity(0.65), fontSize: 14.sp, ), ), ), ], ), SizedBox( height: 12.h, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Duplicate Contacts", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 24.sp, ), ), ], ), SizedBox( height: 20.h, ), Text( "Suggested Merge Contacts", style: TextStyle( color: Colors.white.withOpacity(0.7), fontWeight: FontWeight.w500, fontSize: 16.sp, ), ), _buildDuplicateContact(), ], ); }), ), ); } _buildDuplicateContact() { return Expanded( child: Row( children: [ Expanded( child: ListView.builder( itemCount: controller.contactsByPhoneNumber.length, itemBuilder: (context, index) { final phoneNumber = controller.contactsByPhoneNumber.keys.toList()[index]; final contact = controller.contactsByPhoneNumber[phoneNumber]?.first; List contacts = []; if (controller.contactsByPhoneNumber[phoneNumber] != null) { contacts = controller.contactsByPhoneNumber[phoneNumber]!; } return Column( children: [ SizedBox( height: 24.h, ), Container( padding: EdgeInsets.only(left: 10.w, right: 10.w), height: 62.h, width: double.infinity, decoration: BoxDecoration( color: Colors.white.withOpacity(0.15), borderRadius: BorderRadius.all( Radius.circular(10.r), ), ), child: Row( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( contact?.displayName ?? "", style: TextStyle( color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), Text( contact?.phones.isEmpty ?? true ? 'No contact number' : contact?.phones.first.number ?? "", style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 12.sp, ), ), ], ), Spacer(), Visibility( visible: controller.selectedContacts .contains(contact?.id), child: GestureDetector( onTap: () { if (contacts != null) { controller.mergeBtnClick(contacts); } }, child: Container( height: 34.h, padding: EdgeInsets.symmetric( vertical: 4.h, horizontal: 17.w), decoration: BoxDecoration( color: "#0279FB".color, borderRadius: BorderRadius.all( Radius.circular(8.r), ), ), child: Center( child: Text( "Merge ${contacts?.length}", style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), ), ) ], ), ), SizedBox( height: 12.h, ), ...contacts .asMap() .entries .map((entry) { int index = entry.key; // 当前联系人的索引 Contact contact = entry.value; // 当前联系人 bool isFirst = index == 0; // 是否是第一个 bool isLast = index == (controller.contactsByPhoneNumber[phoneNumber] ?.length ?? 0) - 1; return Container( padding: EdgeInsets.only( left: 20.w, top: 10.h, right: 20.w), width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.vertical( top: isFirst ? Radius.circular(12) : Radius.zero, // 第一个设置上圆角 bottom: isLast ? Radius.circular(12) : Radius.zero, // 最后一个设置下圆角 ), color: Colors.white.withOpacity(0.09), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( contact.displayName.isEmpty ? 'No contact name' : contact.displayName, style: TextStyle( color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), SizedBox( height: 5.h, ), Text( contact.phones.isEmpty ? 'No contact number' : contact.phones.first.number, style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 12.sp, ), ), ], ), // 删除按钮 Visibility( visible: controller.isEdit.value, child: GestureDetector( onTap: () { controller .toggleSelectContact(phoneNumber); }, child: Container( child: controller.selectedContacts .contains(contact.id) ? Center( child: Assets .images.iconSelected .image( width: 20.w, height: 20.h, ), ) : Center( child: Assets .images.iconUnselected .image( width: 20.w, height: 20.h, ), ), ), ), ), ], ), SizedBox( height: 10.h, ), Visibility( visible: !isLast, child: Container( height: 1.h, color: "#3E3E47".color, )), ], ), ); }), ], ); }), ), Container( width: 10.w, ) ], ), ); } }