import 'dart:convert'; import 'dart:typed_data'; import 'package:agora_rtm/agora_rtm.dart'; import 'package:dating_touchme_app/controller/discover/room_controller.dart'; import 'package:dating_touchme_app/controller/global.dart'; import 'package:dating_touchme_app/controller/message/call_controller.dart'; import 'package:dating_touchme_app/controller/overlay_controller.dart'; import 'package:dating_touchme_app/model/live/live_chat_message.dart'; import 'package:dating_touchme_app/pages/discover/live_end_page.dart'; import 'package:dating_touchme_app/rtc/rtc_manager.dart'; import 'package:dating_touchme_app/rtc/rtm_manager.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; /// 直播间聊天消息服务 /// 负责消息的发送、接收、解析和管理 class LiveChatMessageService { // 单例模式 static final LiveChatMessageService _instance = LiveChatMessageService._internal(); factory LiveChatMessageService() => _instance; static LiveChatMessageService get instance => _instance; final GetStorage _storage = GetStorage(); bool _isListenerRegistered = false; // 消息监听回调 Function(LiveChatMessage message)? onMessageReceived; Function(String error)? onMessageError; LiveChatMessageService._internal(); /// 注册消息监听器 void registerMessageListener({ Function(LiveChatMessage message)? onMessageReceived, Function(String error)? onMessageError, }) { if (_isListenerRegistered) { print('⚠️ 消息监听器已注册,跳过重复注册'); return; } this.onMessageReceived = onMessageReceived; this.onMessageError = onMessageError; RTMManager.instance.onMessageEvent = (MessageEvent event) { _handleIncomingMessage(event); }; _isListenerRegistered = true; print('✅ 消息监听器注册完成'); } /// 移除消息监听器 void unregisterMessageListener() { RTMManager.instance.onMessageEvent = null; _isListenerRegistered = false; onMessageReceived = null; onMessageError = null; print('✅ 消息监听器已移除'); } /// 处理接收到的消息 void _handleIncomingMessage(MessageEvent event) async{ try { // 解析消息内容 final messageText = _parseMessageContent(event.message); final messageData = json.decode(messageText) as Map; print('📥 收到消息: $messageData'); // 处理结束直播消息 if (messageData['type'] == 'end_live') { RoomController controller = Get.find(); await controller.leaveChannel(); handleEndLiveMessage(); return; } // 处理通话消息 if (messageData['type'] == 'call_message') { final event = messageData['event'] as String?; if (event == 'accept') { // 接收方收到 accept 消息,设置远端用户 UID final uid = messageData['uid']; if (uid != null && Get.isRegistered()) { final callController = Get.find(); callController.remoteUid.value = uid is int ? uid : int.tryParse(uid.toString()); print('📞 [LiveChatMessageService] 收到 accept 消息,设置 remoteUid: ${callController.remoteUid.value}'); } } else if (event == 'hangup') { // 接收方收到 hangup 消息,关闭视频通话邀请弹框 SmartDialog.dismiss(); print('📞 [LiveChatMessageService] 收到 hangup 消息,已关闭视频通话邀请弹框'); // 停止播放来电铃声 if (Get.isRegistered()) { final callController = Get.find(); callController.stopCallAudio(); print('📞 [LiveChatMessageService] 已停止播放来电铃声'); } } return; } // 只处理聊天消息类型 if (messageData['type'] == 'chat_message') { final chatMessage = LiveChatMessage.fromJson(messageData); onMessageReceived?.call(chatMessage); }else{ RoomController controller = Get.find(); await controller.receiveRTCMessage(messageData); } } catch (e, stackTrace) { final error = '解析RTM消息失败: $e'; print('❌ $error'); print('❌ 堆栈信息: $stackTrace'); onMessageError?.call(error); } } /// 处理结束直播消息 void handleEndLiveMessage() { try { // 检查 overlay 是否显示,如果显示则关闭 if (Get.isRegistered()) { final overlayController = Get.find(); if (overlayController.showOverlay.value) { overlayController.hide(); print('✅ 已关闭 overlay 小窗'); return; } } // 检查当前是否在 LiveRoomPage,如果是则跳转到 live_end_page final currentRoute = Get.currentRoute; if (currentRoute == '/LiveRoomPage' || currentRoute.contains('LiveRoomPage')) { Get.off(() => const LiveEndPage()); print('✅ 已跳转到直播结束页面'); } } catch (e) { print('❌ 处理结束直播消息失败: $e'); } } /// 解析消息内容(支持 String 和 Uint8List) String _parseMessageContent(dynamic message) { if (message is String) { return message; } else if (message is Uint8List) { return utf8.decode(message); } else { return message.toString(); } } /// 构建消息数据 Map _buildMessageData(String content) { final userId = _storage.read('userId') ?? GlobalData().userId ?? ''; final userData = GlobalData().userData; final userName = userData?.nickName ?? '用户'; final avatar = userData?.profilePhoto; RoomController controller = Get.find(); final uid = controller.rtcChannel.value?.uid; return { 'type': 'chat_message', 'userId': userId, 'userName': userName, 'uid': uid, 'avatar': avatar, 'content': content.trim(), 'timestamp': DateTime.now().millisecondsSinceEpoch, }; } /// 验证消息内容 String? _validateMessage(String content) { final trimmed = content.trim(); if (trimmed.isEmpty) { return '消息内容不能为空'; } if (trimmed.length > 500) { return '消息内容不能超过500个字符'; } return null; } /// 检查发送前置条件 String? _checkSendPreconditions(String channelName) { if (!RTMManager.instance.isInitialized) { return 'RTM 未初始化,无法发送消息'; } if (!RTMManager.instance.isLoggedIn) { return 'RTM 未登录,无法发送消息'; } if (channelName.isEmpty) { return '未加入频道,无法发送消息'; } return null; } /// 发送聊天消息 /// /// [content] 消息内容 /// [channelName] 频道名称,如果为空则从 RTCManager 获取 /// [showToast] 是否显示 Toast 提示,默认为 true /// /// 返回发送结果,true 表示成功,false 表示失败 Future sendMessage({ required String content, String? channelName, bool showToast = true, }) async { // 验证消息内容 final validationError = _validateMessage(content); if (validationError != null) { if (showToast) { SmartDialog.showToast(validationError); } return MessageSendResult.failure(validationError); } // 获取频道名称 final targetChannelName = channelName ?? RTCManager.instance.currentChannelId ?? ''; // 检查前置条件 final preconditionError = _checkSendPreconditions(targetChannelName); if (preconditionError != null) { print('❌ $preconditionError'); if (showToast) { SmartDialog.showToast(preconditionError); } return MessageSendResult.failure(preconditionError); } try { // 构建消息数据 final messageData = _buildMessageData(content); final messageJson = json.encode(messageData); print('📤 发送消息到频道: $targetChannelName'); print('📤 消息内容: $messageJson'); // 通过 RTM 发送消息 final success = await RTMManager.instance.publishChannelMessage( channelName: targetChannelName, message: messageJson, ); if (success) { print('✅ 消息发送成功'); // 创建消息对象(用于立即显示) final chatMessage = LiveChatMessage( userId: messageData['userId'] as String, userName: messageData['userName'] as String, avatar: messageData['avatar'] as String?, content: messageData['content'] as String, timestamp: messageData['timestamp'] as int, ); return MessageSendResult.success(chatMessage); } else { final error = '消息发送失败,请重试'; print('❌ $error'); if (showToast) { SmartDialog.showToast(error); } return MessageSendResult.failure(error); } } catch (e, stackTrace) { final error = '发送消息异常: $e'; print('❌ $error'); print('❌ 堆栈信息: $stackTrace'); if (showToast) { SmartDialog.showToast(error); } return MessageSendResult.failure(error); } } /// 创建消息对象(用于本地显示) LiveChatMessage createLocalMessage(String content) { final messageData = _buildMessageData(content); return LiveChatMessage( userId: messageData['userId'] as String, userName: messageData['userName'] as String, avatar: messageData['avatar'] as String?, content: messageData['content'] as String, timestamp: messageData['timestamp'] as int, ); } } /// 消息发送结果 class MessageSendResult { final bool success; final LiveChatMessage? message; final String? error; MessageSendResult._({ required this.success, this.message, this.error, }); factory MessageSendResult.success(LiveChatMessage message) { return MessageSendResult._( success: true, message: message, ); } factory MessageSendResult.failure(String error) { return MessageSendResult._( success: false, error: error, ); } }