import 'dart:io'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:im_flutter_sdk/im_flutter_sdk.dart'; import 'package:video_thumbnail/video_thumbnail.dart'; import 'package:path_provider/path_provider.dart'; import '../controller/message/conversation_controller.dart'; import '../controller/message/chat_controller.dart'; // 完整的IM管理器实现,使用实际的SDK类型和方法 class IMManager { // 单例模式 static final IMManager _instance = IMManager._internal(); factory IMManager() => _instance; final storage = GetStorage(); // 静态getter用于instance访问 static IMManager get instance => _instance; bool _isInitialized = false; // 存储活跃的 ChatController 实例,key 为 userId final Map _activeChatControllers = {}; IMManager._internal() { print('IMManager instance created'); } /// 初始化IM SDK Future initialize(String appKey) async { try { if (_isInitialized) { print('IM SDK already initialized'); return true; } // 创建EMOptions实例 final options = EMOptions( appKey: appKey, autoLogin: false, acceptInvitationAlways: false, ); // 初始化SDK await EMClient.getInstance.init(options); _isInitialized = true; print('IM SDK initialized successfully'); return true; } catch (e) { print('Failed to initialize IM SDK: $e'); return false; } } // 注册监听器 void _registerListeners() { try { // 消息监听器 // 连接监听器 EMClient.getInstance.addConnectionEventHandler( '', EMConnectionEventHandler( onConnected: () { print('Connected to IM server'); }, onDisconnected: () { print('Disconnected from IM server:'); }, onTokenDidExpire: () { print('IM token about to expire'); }, onUserKickedByOtherDevice: () { print('User kicked out of IM server'); }, ), ); EMClient.getInstance.chatManager.addEventHandler( // EMChatEventHandler 对应的 key。 "", EMChatEventHandler( onMessagesReceived: (messages) { // 收到新消息时,更新会话列表 _refreshConversationList(); // 通知对应的 ChatController 更新消息列表 _notifyChatControllers(messages); for (var msg in messages) { switch (msg.body.type) { case MessageType.TXT: {} break; case MessageType.IMAGE: {} break; case MessageType.VIDEO: {} break; case MessageType.LOCATION: {} break; case MessageType.VOICE: {} break; case MessageType.FILE: {} break; case MessageType.CUSTOM: {} break; case MessageType.COMBINE: {} break; case MessageType.CMD: { // 当前回调中不会有 CMD 类型消息,CMD 类型消息通过 `EMChatEventHandler#onCmdMessagesReceived` 回调接收 } break; } } }, ), ); } catch (e) { print('Failed to register listeners: $e'); } } /// 登录IM服务 Future login(String token) async { try { if (!_isInitialized) { print('IM SDK not initialized'); return false; } var userId = storage.read('userId'); await EMClient.getInstance.logout(); await EMClient.getInstance.loginWithToken(userId, token); // 注册监听器 _registerListeners(); print('IM login successful'); return true; } catch (e) { print('IM login failed: $e'); return false; } } /// 登出IM服务 Future logout() async { try { await EMClient.getInstance.logout(); print('IM logout successful'); return true; } catch (e) { print('IM logout failed: $e'); return false; } } /// 发送文本消息 Future sendTextMessage( String content, String toChatUsername, ) async { print('Text message sent'); try { // 创建文本消息 final message = EMMessage.createTxtSendMessage( targetId: toChatUsername, content: content, ); print('Text message sent successfully'); return await EMClient.getInstance.chatManager.sendMessage(message); } catch (e) { print('Failed to send text message: $e'); return null; } } /// 发送语音消息 Future sendVoiceMessage( String filePath, String toChatUsername, int duration, ) async { try { // 创建图片消息 final message = EMMessage.createVoiceSendMessage( targetId: toChatUsername, filePath: filePath, duration: duration, ); // 发送消息 await EMClient.getInstance.chatManager.sendMessage(message); print('Image message sent successfully'); return message; } catch (e) { print('Failed to send image message: $e'); return null; } } /// 发送图片消息 Future sendImageMessage( String imagePath, String toChatUsername, ) async { try { // 创建图片消息 final message = EMMessage.createImageSendMessage( targetId: toChatUsername, filePath: imagePath, sendOriginalImage: false, ); // 发送消息 await EMClient.getInstance.chatManager.sendMessage(message); print('Image message sent successfully'); return message; } catch (e) { print('Failed to send image message: $e'); return null; } } /// 发送视频消息 Future sendVideoMessage( String videoPath, String toChatUsername, int duration, ) async { try { print('🎬 [IMManager] 创建视频消息'); print('视频路径: $videoPath'); print('接收用户: $toChatUsername'); print('视频时长: $duration 秒'); // 🎯 手动生成视频缩略图 String? thumbnailPath; try { print('📸 [IMManager] 开始生成视频缩略图...'); // 获取临时目录 final tempDir = await getTemporaryDirectory(); final fileName = videoPath.split('/').last.split('.').first; final thumbFileName = '${fileName}_thumb.jpg'; thumbnailPath = '${tempDir.path}/$thumbFileName'; // 使用 video_thumbnail 生成缩略图 final uint8list = await VideoThumbnail.thumbnailFile( video: videoPath, thumbnailPath: thumbnailPath, imageFormat: ImageFormat.JPEG, maxWidth: 400, // 缩略图最大宽度 quality: 75, // 图片质量 ); if (uint8list != null && File(uint8list).existsSync()) { thumbnailPath = uint8list; print('✅ [IMManager] 缩略图生成成功: $thumbnailPath'); } else { print('⚠️ [IMManager] 缩略图生成返回null'); thumbnailPath = null; } } catch (e) { print('❌ [IMManager] 生成缩略图失败: $e'); thumbnailPath = null; } // 创建视频消息 final message = EMMessage.createVideoSendMessage( targetId: toChatUsername, filePath: videoPath, duration: duration, thumbnailLocalPath: thumbnailPath, // 🎯 指定缩略图路径 ); print('消息创建成功,消息类型: ${message.body.type}'); print('消息体是否为视频: ${message.body is EMVideoMessageBody}'); // 检查缩略图信息 if (message.body is EMVideoMessageBody) { final videoBody = message.body as EMVideoMessageBody; print('📸 [IMManager] 缩略图本地路径: ${videoBody.thumbnailLocalPath}'); print('📸 [IMManager] 缩略图远程路径: ${videoBody.thumbnailRemotePath}'); // 验证缩略图文件是否存在 if (videoBody.thumbnailLocalPath != null) { final thumbFile = File(videoBody.thumbnailLocalPath!); print('📸 [IMManager] 缩略图文件是否存在: ${thumbFile.existsSync()}'); } } // 发送消息 await EMClient.getInstance.chatManager.sendMessage(message); print('✅ [IMManager] 视频消息发送成功'); return message; } catch (e) { print('❌ [IMManager] 发送视频消息失败: $e'); return null; } } /// 获取会话列表 Future> getConversations() async { return EMClient.getInstance.chatManager.loadAllConversations(); } /// 获取好有列表 Future> getContacts(String userId) async { return await EMClient.getInstance.userInfoManager.fetchUserInfoById([ userId, ]); } /// 获取指定会话的消息记录 Future> getMessages( String conversationId, { int pageSize = 20, String? startMsgId, }) async { EMConversationType convType = EMConversationType.Chat; EMCursorResult cursor = await EMClient.getInstance.chatManager .fetchHistoryMessagesByOption( conversationId, convType, pageSize: pageSize, ); return cursor.data; } /// 获取用户信息 Future getUserInfo(String userId) async { var data = await EMClient.getInstance.userInfoManager.fetchUserInfoById([ userId, ]); return data[userId]; } /// 注册 ChatController void registerChatController(ChatController controller) { _activeChatControllers[controller.userId] = controller; if (Get.isLogEnable) { Get.log('注册 ChatController: ${controller.userId}'); } } /// 注销 ChatController void unregisterChatController(String userId) { _activeChatControllers.remove(userId); if (Get.isLogEnable) { Get.log('注销 ChatController: $userId'); } } /// 通知 ChatController 更新消息列表 void _notifyChatControllers(List messages) { try { // 遍历所有收到的消息 for (var message in messages) { // 只处理接收到的消息(direction == RECEIVE) if (message.direction == MessageDirection.RECEIVE) { // 获取消息的发送者ID(from 属性) final fromId = message.from; if (fromId != null && fromId.isNotEmpty) { // 查找对应的 ChatController final controller = _activeChatControllers[fromId]; if (controller != null) { controller.addReceivedMessage(message); if (Get.isLogEnable) { Get.log('通知 ChatController 更新消息: $fromId'); } } } } } } catch (e) { if (Get.isLogEnable) { Get.log('通知 ChatController 更新消息列表失败: $e'); } } } /// 刷新会话列表 void _refreshConversationList() { try { // 尝试获取 ConversationController 并刷新会话列表 if (Get.isRegistered()) { final conversationController = Get.find(); conversationController.refreshConversations(); } } catch (e) { // ConversationController 可能未注册,忽略错误 if (Get.isLogEnable) { Get.log('刷新会话列表失败: $e'); } } } /// 添加用户到黑名单 Future addToBlacklist(String userId) async { try { await EMClient.getInstance.contactManager.addUserToBlockList(userId); print('已将用户 $userId 添加到黑名单'); } catch (e) { print('添加黑名单失败: $e'); rethrow; } } /// 从黑名单移除用户 Future removeFromBlacklist(String userId) async { try { await EMClient.getInstance.contactManager.removeUserFromBlockList(userId); print('已将用户 $userId 从黑名单移除'); } catch (e) { print('移除黑名单失败: $e'); rethrow; } } /// 获取黑名单列表 Future> getBlacklist() async { try { final list = await EMClient.getInstance.contactManager.getBlockListFromServer(); print('获取黑名单列表成功,共 ${list.length} 个用户'); return list; } catch (e) { print('获取黑名单列表失败: $e'); return []; } } /// 清理资源 void dispose() { try { EMClient.getInstance.removeConnectionEventHandler(""); } catch (e) { print('Failed to dispose resources: $e'); } } } // 导出单例实例 final IMManager imManager = IMManager();