import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:loopin/IM/im_service.dart'; import 'package:loopin/styles/index.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart'; class InviteActionSheet extends StatefulWidget { final String groupID; final Function(List selected) onAction; final String title; final String actionLabel; final bool showButton; const InviteActionSheet({ super.key, required this.groupID, required this.onAction, this.title = "", this.actionLabel = "确认", this.showButton = true, }); @override State createState() => _MemberActionSheetState(); } class _MemberActionSheetState extends State { String _query = ""; final Set _selectedIDs = {}; // 选中的 userID 集合 late List members = []; String nextSeq = ''; bool hasMore = false; bool loading = false; // @override void initState() { super.initState(); getMemberData(); } //互关好友 Future getMemberData({bool reset = false}) async { if (loading) return; loading = true; final res = await ImService.instance.getMutualFollowersList( nextCursor: nextSeq, ); if (res.success && res.data != null) { final userInfoList = res.data!.userFullInfoList ?? []; final isFinished = res.data!.nextCursor == null || res.data!.nextCursor!.isEmpty; logger.w('获取成功:${res.data!.nextCursor},是否还有更多:$isFinished'); if (isFinished) { hasMore = false; nextSeq = ''; } else { nextSeq = res.data!.nextCursor ?? ''; hasMore = nextSeq.isNotEmpty ? true : false; } final ids = userInfoList.map((item) => item.userID).whereType().toList(); if (ids.isNotEmpty) { getGroupMemberData(userIDs: ids, userList: userInfoList); } } else { logger.e('获取数据失败:${res.desc}'); } } //群成员 Future getGroupMemberData({required List userIDs, required List userList}) async { final res = await ImService.instance.getGroupMembersInfo( groupID: widget.groupID, memberList: userIDs, ); if (res.success && res.data != null) { final List groupMemberList = res.data ?? []; // 已经在群里的 userID final inGroupIds = groupMemberList.map((m) => m.userID).whereType().where((id) => id.isNotEmpty).toSet(); // 过滤掉已经在群里的 final notInGroupUsers = userList.where((user) => user.userID != null && !inGroupIds.contains(user.userID)).toList(); setState(() { members.addAll(notInGroupUsers); }); } setState(() { loading = false; }); } String handleText(String? text, String defaultValue) { if (text == null || text.trim().isEmpty) return defaultValue; return text; } @override Widget build(BuildContext context) { // 搜索过滤 final filteredMembers = members.where((m) { final name = m.nickName ?? ''; return name.contains(_query); }).toList(); return SafeArea( child: GestureDetector( behavior: HitTestBehavior.translucent, // 点击空白区域也能触发 onTap: () { FocusScope.of(context).unfocus(); }, child: Scaffold( backgroundColor: Colors.white, appBar: AppBar( centerTitle: true, forceMaterialTransparency: true, bottom: PreferredSize( preferredSize: const Size.fromHeight(1.0), child: Container( color: Colors.grey[300], height: 1.0, ), ), title: Text( widget.title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { Navigator.pop(context); }, ), ), body: Column( children: [ SizedBox(height: 10), // 搜索框 Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: TextField( decoration: InputDecoration( prefixIcon: const Icon(Icons.search), hintText: "搜索", contentPadding: const EdgeInsets.symmetric(vertical: 8), border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), onChanged: (value) { setState(() { _query = value.trim(); }); }, ), ), const SizedBox(height: 8), // 成员列表 Expanded( child: EasyRefresh( footer: ClassicFooter( dragText: '加载更多', armedText: '释放加载', readyText: '加载中...', processingText: '加载中...', processedText: hasMore ? '加载完成' : '没有更多了~', failedText: '加载失败,请重试', messageText: '最后更新于 %T', ), onLoad: () async { // if (hasMore) { await getMemberData(); } }, child: ListView.builder( itemCount: filteredMembers.length, itemBuilder: (context, index) { final m = filteredMembers[index]; final id = m.userID; final uname = handleText(m.nickName, ''); final nickname = handleText(m.nickName, '未知昵称'); final showName = uname.isEmpty ? nickname : uname; return InkWell( onTap: () { setState(() { if (_selectedIDs.contains(id)) { _selectedIDs.remove(id); } else if (id != null && id.isNotEmpty) { _selectedIDs.add(id); } }); }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Row( children: [ // 左侧圆形头像 CircleAvatar( radius: 20, backgroundImage: m.faceUrl != null ? NetworkImage(m.faceUrl!) : null, child: m.faceUrl == null ? const Icon(Icons.person) : null, ), const SizedBox(width: 12), // 用户名 Expanded( child: Text( showName, style: const TextStyle(fontSize: 14), overflow: TextOverflow.ellipsis, ), ), // 复选框 Container( width: 24, height: 24, alignment: Alignment.center, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: _selectedIDs.contains(id) ? FStyle.primaryColor : Colors.grey), color: _selectedIDs.contains(id) ? FStyle.primaryColor : Colors.transparent, ), child: _selectedIDs.contains(id) ? const Icon(Icons.check, size: 16, color: Colors.white) : null, ), ], ), ), ); }, ), ), ), // 底部操作按钮 if (widget.showButton) Padding( padding: const EdgeInsets.all(16), child: ElevatedButton( style: ElevatedButton.styleFrom( minimumSize: const Size(double.infinity, 48), backgroundColor: FStyle.primaryColor, ), onPressed: _selectedIDs.isEmpty ? null : () { Navigator.pop(context); widget.onAction(_selectedIDs.toList()); }, child: Text( "${widget.actionLabel}(${_selectedIDs.length})", style: TextStyle( color: _selectedIDs.isNotEmpty ? Colors.white : Colors.black, ), ), ), ), ], ), ), ), ); } }