import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:im_flutter_sdk/im_flutter_sdk.dart'; import 'package:get/get.dart'; import 'text_item.dart'; import 'image_item.dart'; import 'voice_item.dart'; import 'video_item.dart'; import 'call_item.dart'; import 'gift_item.dart'; import 'room_item.dart'; import '../../controller/message/chat_controller.dart'; class MessageItem extends StatelessWidget { final EMMessage message; final bool isSentByMe; final EMMessage? previousMessage; final ChatController? chatController; // 可选:直接传入的 controller const MessageItem({ required this.message, required this.isSentByMe, this.previousMessage, this.chatController, super.key, }); // 检查是否是通话消息(通过消息内容识别) bool _isCallMessage() { try { if (message.body.type == MessageType.TXT) { final textBody = message.body as EMTextMessageBody; final content = textBody.content; // 检查是否是通话消息(以 [CALL:] 开头) return content.startsWith('[CALL:]'); } } catch (e) { // 解析失败,不是通话消息 } return false; } // 检查是否是礼物消息(通过消息内容识别) bool _isGiftMessage() { try { if (message.body.type == MessageType.TXT) { final textBody = message.body as EMTextMessageBody; final content = textBody.content; // 检查是否是礼物消息(以 [GIFT:] 开头) return content.startsWith('[GIFT:]'); } } catch (e) { // 解析失败,不是礼物消息 } return false; } // 检查是否是直播间邀请消息 bool _isRoomInviteMessage() { try { if (message.body.type == MessageType.CUSTOM) { final customBody = message.body as EMCustomMessageBody; return customBody.event == 'live_room_invite'; } } catch (e) { // 解析失败,不是直播间邀请消息 } return false; } @override Widget build(BuildContext context) { print('📨 [MessageItem] 渲染消息,类型: ${message.body.type}'); // 处理通话消息(通过文本消息的扩展属性识别) if (message.body.type == MessageType.TXT && _isCallMessage()) { return CallItem( message: message, isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), onResend: () { // 通过传入的 controller 或 Get 找到 ChatController 并调用重发方法 try { final controller = chatController ?? Get.find(); controller.resendMessage(message); } catch (e) { print('重发消息失败: $e'); } }, ); } // 处理礼物消息(通过文本消息的扩展属性识别) if (message.body.type == MessageType.TXT && _isGiftMessage()) { return GiftItem( message: message, isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), onResend: () { // 通过传入的 controller 或 Get 找到 ChatController 并调用重发方法 try { final controller = chatController ?? Get.find(); controller.resendMessage(message); } catch (e) { print('重发消息失败: $e'); } }, ); } // 处理直播间邀请消息(自定义消息) if (message.body.type == MessageType.CUSTOM && _isRoomInviteMessage()) { return RoomItem( message: message, isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), onResend: () { // 通过传入的 controller 或 Get 找到 ChatController 并调用重发方法 try { final controller = chatController ?? Get.find(); controller.resendMessage(message); } catch (e) { print('重发消息失败: $e'); } }, ); } // 处理文本消息 if (message.body.type == MessageType.TXT) { final textBody = message.body as EMTextMessageBody; return TextItem( textBody: textBody, isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), message: message, onResend: () { // 通过传入的 controller 或 Get 找到 ChatController 并调用重发方法 try { final controller = chatController ?? Get.find(); controller.resendMessage(message); } catch (e) { print('重发消息失败: $e'); } }, ); } // 处理图片消息 else if (message.body.type == MessageType.IMAGE) { final imageBody = message.body as EMImageMessageBody; return ImageItem( imageBody: imageBody, isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), message: message, onResend: () { // 通过传入的 controller 或 Get 找到 ChatController 并调用重发方法 try { final controller = chatController ?? Get.find(); controller.resendMessage(message); } catch (e) { print('重发消息失败: $e'); } }, ); } // 处理语音消息 else if (message.body.type == MessageType.VOICE) { final voiceBody = message.body as EMVoiceMessageBody; return VoiceItem( voiceBody: voiceBody, messageId: message.msgId, // 传递消息ID作为音频唯一标识 isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), ); } // 处理视频消息 else if (message.body.type == MessageType.VIDEO) { print('🎬 [MessageItem] 检测到视频消息,准备渲染 VideoItem'); final videoBody = message.body as EMVideoMessageBody; return VideoItem( videoBody: videoBody, isSentByMe: isSentByMe, showTime: shouldShowTime(), formattedTime: formatMessageTime(message.serverTime), message: message, onResend: () { // 通过传入的 controller 或 Get 找到 ChatController 并调用重发方法 try { final controller = chatController ?? Get.find(); controller.resendMessage(message); } catch (e) { print('重发消息失败: $e'); } }, ); } // 非文本消息显示占位符 print('⚠️ [MessageItem] 不支持的消息类型: ${message.body.type}'); return Column( children: [ if (shouldShowTime()) _buildTimeLabel(), Container( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), child: Text('不支持的消息类型: ${message.body.type}'), ), ], ); } // 判断是否需要显示时间 bool shouldShowTime() { if (previousMessage == null) { return true; // 第一条消息显示时间 } // 判断距离上一条消息是否超过20分钟(1200000毫秒) return (message.serverTime - previousMessage!.serverTime) > 1200000; } // 构建时间标签 Widget _buildTimeLabel() { final formattedTime = formatMessageTime(message.serverTime); return Container( alignment: Alignment.center, padding: EdgeInsets.symmetric(horizontal: 16.w), child: Container( padding: EdgeInsets.symmetric(horizontal: 12.w), child: Text( formattedTime, style: TextStyle(fontSize: 12.sp, color: Colors.grey), ), ), ); } // 格式化消息时间 String formatMessageTime(int timestamp) { final date = DateTime.fromMillisecondsSinceEpoch(timestamp); final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); final yesterday = DateTime(now.year, now.month, now.day - 1); final messageDate = DateTime(date.year, date.month, date.day); if (messageDate.isAtSameMomentAs(today)) { // 今天的消息显示时间 return '今天 ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}'; } else if (messageDate.isAtSameMomentAs(yesterday)) { // 昨天的消息 return '昨天 ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}'; } else { // 其他日期显示完整日期和时间 return '${date.month}月${date.day}日 ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}'; } } }