import 'package:dating_touchme_app/pages/message/chat_page.dart'; import 'package:flutter/material.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:get/get.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; import 'package:im_flutter_sdk/im_flutter_sdk.dart'; import '../../controller/message/conversation_controller.dart'; class ConversationTab extends StatefulWidget { const ConversationTab({super.key}); @override State createState() => _ConversationTabState(); } class _ConversationTabState extends State with AutomaticKeepAliveClientMixin { final ConversationController controller = Get.find(); @override Widget build(BuildContext context) { super.build(context); return Column( children: [ // 聊天列表 Expanded( child: Obx(() { if (controller.isLoading.value) { return const Center(child: CircularProgressIndicator()); } if (controller.errorMessage.value.isNotEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(controller.errorMessage.value), ElevatedButton( onPressed: () => controller.refreshConversations(), child: const Text('重试'), ), ], ), ); } // 即使列表为空也显示测试项 return ListView.builder( padding: const EdgeInsets.only(top: 8), itemCount: controller.conversations.length + 1, // 添加测试项 itemBuilder: (context, index) { // 第一个是测试项 if (index == 0) { return _buildTestConversationItem(); } final conversation = controller.conversations[index - 1]; return _buildConversationItem(conversation); }, ); }), ), ], ); } // 构建测试会话项 Widget _buildTestConversationItem() { final double screenWidth = MediaQuery.of(context).size.width; final int testUnreadCount = 3; final String testTime = controller.formatMessageTime( DateTime.now().millisecondsSinceEpoch, ); final Widget cellContent = Builder( builder: (cellContext) => GestureDetector( onTap: () { TDSwipeCellInherited.of(cellContext)?.cellClick(); // 跳转到聊天页面,使用测试用户ID Get.to(ChatPage(userId: 'test_user_001')); }, child: Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(16)), ), margin: const EdgeInsets.only( bottom: 8, left: 16, right: 16, ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 56, height: 56, decoration: BoxDecoration( borderRadius: BorderRadius.circular(28), image: const DecorationImage( image: AssetImage(Assets.imagesAvatarsExample), fit: BoxFit.cover, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Expanded( child: Text( '测试用户', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.black, ), ), ), Text( testTime, style: const TextStyle( fontSize: 12, color: Colors.grey, ), ), ], ), const SizedBox(height: 6), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ const Expanded( child: Text( '这是一条测试消息,用于调试', style: TextStyle( fontSize: 14, color: Colors.grey, ), overflow: TextOverflow.ellipsis, ), ), Container( margin: const EdgeInsets.only(left: 8), padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2, ), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(10), ), child: Text( testUnreadCount.toString(), style: const TextStyle( fontSize: 12, color: Colors.white, ), ), ), ], ), ], ), ), ], ), ), ), ); return TDSwipeCell( slidableKey: const ValueKey('test_conversation'), groupTag: 'conversation_swipe_group', right: TDSwipeCellPanel( extentRatio: 72 / screenWidth, children: [ TDSwipeCellAction( backgroundColor: TDTheme.of(context).errorColor6, label: '删除', onPressed: (actionContext) { Get.snackbar('调试', '删除测试会话'); }, ), ], ), cell: cellContent, ); } // 构建会话项 Widget _buildConversationItem(EMConversation conversation) { return FutureBuilder( future: controller.loadContact(conversation.id), builder: (context, userSnapshot) { final EMUserInfo? userInfo = userSnapshot.data; return FutureBuilder( future: controller.lastMessage(conversation), builder: (context, messageSnapshot) { final EMMessage? message = messageSnapshot.data; return FutureBuilder( future: controller.getUnreadCount(conversation), builder: (context, unreadSnapshot) { final int unreadCount = unreadSnapshot.data ?? 0; final double screenWidth = MediaQuery.of(context).size.width; final Widget cellContent = Builder( builder: (cellContext) => GestureDetector( onTap: () async { TDSwipeCellInherited.of(cellContext)?.cellClick(); Get.to(ChatPage(userId: conversation.id)); }, child: Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(16)), ), margin: const EdgeInsets.only( bottom: 8, left: 16, right: 16, ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 56, height: 56, decoration: BoxDecoration( borderRadius: BorderRadius.circular(28), image: DecorationImage( image: (userInfo?.avatarUrl ?? '').isNotEmpty ? NetworkImage(userInfo!.avatarUrl!) : const AssetImage( Assets.imagesAvatarsExample, ) as ImageProvider, fit: BoxFit.cover, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Text( userInfo?.nickName ?? '联系人', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.black, ), ), ), Text( controller.formatMessageTime( message?.serverTime ?? 0, ), style: const TextStyle( fontSize: 12, color: Colors.grey, ), ), ], ), const SizedBox(height: 6), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Text( controller.getLastMessageContent(message), style: const TextStyle( fontSize: 14, color: Colors.grey, ), overflow: TextOverflow.ellipsis, ), ), if (unreadCount > 0) Container( margin: const EdgeInsets.only(left: 8), padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2, ), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(10), ), child: Text( unreadCount.toString(), style: const TextStyle( fontSize: 12, color: Colors.white, ), ), ), ], ), ], ), ), ], ), ), ), ); return TDSwipeCell( slidableKey: ValueKey('conversation_${conversation.id}'), groupTag: 'conversation_swipe_group', right: TDSwipeCellPanel( extentRatio: 72 / screenWidth, children: [ TDSwipeCellAction( backgroundColor: TDTheme.of(context).errorColor6, label: '删除', onPressed: (actionContext) async { final success = await controller.deleteConversation( conversation.id, ); if (!success) { Get.snackbar('提示', '删除会话失败'); } }, ), ], ), cell: cellContent, ); }, ); }, ); }, ); } @override bool get wantKeepAlive => true; }