import 'dart:async'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; import '/database/box_type.dart'; import '/database/hive_database.dart'; import '/models/apply_list_model.dart'; import '/models/contact_model.dart'; import '/models/init_get_it.dart'; import '/models/route_state_model.dart'; import '/models/user_model.dart'; import '/models/websocket_model.dart'; import '/notification_api.dart'; import '/request/message.dart'; const int chunkSize = 1024 * 1024 * 2; Future receiveFriendMsg( Map msg, bool isShowNotification, ) async { print('=================收到了好友信息事件=================='); print(msg); print('======================================='); String senderId = msg['senderId'] as String; Box chatSettingBox = Hive.box('chat_setting'); Box messageTBox = await HiveDatabase.openMessageBox(senderId); Box msgIndexBox = await Hive.openBox('msg_index_$senderId'); ChatSetting? chatSetting = chatSettingBox.get(senderId); DateTime dateTime = DateTime.parse(msg['dateTime'] as String); if (chatSetting == null) { chatSettingBox.put( senderId, ChatSetting( senderId, 0, false, true, false, dateTime, 1, ), ); } else if (msgIndexBox.get(msg['msgId'] as String) != null) { return; } else { chatSetting.isOpen = true; chatSetting.latestDateTime = dateTime; chatSetting.unreadCount++; chatSettingBox.put(senderId, chatSetting); } List attachments = List.from(msg['attachments']); final DateTime now = DateTime.parse(msg['dateTime'] as String); for (var attachment in attachments) { Box apr = Hive.box('attachment_receive'); apr.put(attachment, AttachmentProgress(0, 1000, 0, true, false)); } messageTBox.add( MessageT( msg['msgId'] as String, senderId, msg['text'], msg['type'], now, msg['isShowTime'], attachments, ), ); if (!isShowNotification) { return; } String name = getIt.get().friends[senderId]!.friendRemark.isEmpty ? getIt.get().friends[senderId]!.nickname : getIt.get().friends[senderId]!.friendRemark; String routeName = getIt.get().currentPathName; String avatar = getIt.get().friends[senderId]!.avatar; if (!getIt.get().isVisible) { NotificationAPI.showMessageNotifications( senderId: senderId, name: name, avatar: avatar, text: msg['text'] as String, ); } else if (routeName == 'Message') { if (!getIt.get().query.containsValue(senderId)) { NotificationAPI.showMessageNotifications( senderId: senderId, name: name, avatar: avatar, text: msg['text'] as String, ); } } else if (routeName != 'Chat') { NotificationAPI.showMessageNotifications( senderId: senderId, name: name, avatar: avatar, text: msg['text'] as String, ); } } void receiveApplyFriend(Map msg) { print('=================收到了申请好友事件=================='); print(msg); print('======================================='); getIt.get().addJson(msg); } void receiveFriendAdded(Map msg) { print('=================收到了申请好友通过事件=================='); print(msg); print('======================================='); getIt.get().addFriend(msg['friendId'], msg['setting']); getIt .get() .addFriendAccountProfile(msg['friendId'], msg['accountProfile']); } void receiveFriendDeleted(Map msg) { print('=================收到了解除好友事件=================='); print(msg); print('======================================='); getIt.get().removeFriend(msg['friendId']); getIt.get().removeFriend(msg['friendId']); } void receiveGroupChatCreation(Map msg) { print('=================收到了群聊邀请事件=================='); print(msg); print('======================================='); String groupChatId = msg['groupChat']['id']; getIt.get().addGroupChat(groupChatId); getIt.get().addGroupChatProfile(groupChatId, msg); } void receiveGroupChatMsg( Map msg, bool isShowNotification, ) async { print('=================收到了群聊信息事件=================='); print(msg); print('======================================='); String senderId = msg['senderId'] as String; String groupChatId = msg['groupChatId'] as String; Box chatSettingBox = Hive.box('chat_setting'); Box messageTBox = await HiveDatabase.openMessageBox(groupChatId); Box msgIndexBox = await Hive.openBox('msg_index_$groupChatId'); ChatSetting? chatSetting = chatSettingBox.get(groupChatId); DateTime dateTime = DateTime.parse(msg['dateTime'] as String); getIt.get().addGroupChatMemberProfile( groupChatId, msg['senderId'], { 'avatar': msg['avatar'], 'nickname': msg['nickname'], 'remarkInGroupChat': msg['remarkInGroupChat'], }, ); if (chatSetting == null) { chatSettingBox.put( groupChatId, ChatSetting( groupChatId, 1, false, true, false, dateTime, 1, ), ); } else if (msgIndexBox.get(msg['msgId'] as String) != null) { return; } else { chatSetting.isOpen = true; chatSetting.latestDateTime = dateTime; chatSetting.unreadCount++; chatSettingBox.put(groupChatId, chatSetting); } List attachments = List.from(msg['attachments']); final DateTime now = DateTime.parse(msg['dateTime'] as String); for (var attachment in attachments) { Box apr = Hive.box('attachment_receive'); apr.put(attachment, AttachmentProgress(0, 1000, 0, true, false)); } messageTBox.add( MessageT( msg['msgId'] as String, senderId, msg['text'], msg['type'], now, msg['isShowTime'], attachments, ), ); if (!isShowNotification) { return; } String avatar = getIt.get().groupChats[groupChatId]!.avatar; late String name; if (getIt.get().friends.containsKey(senderId)) { if (getIt.get().friends[senderId]!.friendRemark.isNotEmpty) { name = getIt.get().friends[senderId]!.friendRemark; } else if ((msg['remarkInGroupChat'] as String).isNotEmpty) { name = msg['remarkInGroupChat']; } else { name = msg['nickname']; } } else { name = (msg['remarkInGroupChat'] as String).isNotEmpty ? msg['remarkInGroupChat'] : msg['nickname']; } String routeName = getIt.get().currentPathName; if (!getIt.get().isVisible) { NotificationAPI.showMessageNotifications( senderId: senderId, name: name, avatar: avatar, text: msg['text'] as String, groupChatId: groupChatId, ); } else if (routeName == 'Message') { if (!getIt.get().query.containsValue(groupChatId)) { NotificationAPI.showMessageNotifications( senderId: senderId, name: name, avatar: avatar, text: msg['text'] as String, groupChatId: groupChatId, ); } } else if (routeName != 'Chat') { NotificationAPI.showMessageNotifications( senderId: senderId, name: name, avatar: avatar, text: msg['text'] as String, groupChatId: groupChatId, ); } } void receiveChatImages(Map msg) async { print('=================收到了聊天图片事件=================='); // // print(msg); print('======================================='); String chatImageDir = getIt.get().baseImageDir; String filename = msg['filename']; String filePath = '$chatImageDir/$filename'; File file = File(filePath); if (await file.exists()) { return; } late Box aprBox; try { aprBox = Hive.box('attachment_receive'); } catch (_) { aprBox = await Hive.openBox('attachment_receive'); } String dirTime = filename.split('/')[0]; Directory dir = Directory('$chatImageDir/$dirTime'); if (!(await dir.exists())) { await dir.create(recursive: true); } int totalChunkNum = msg['totalChunkNum'] as int; if (totalChunkNum == 1) { await file.writeAsBytes(List.from(msg['bytes'])); await Future.delayed( const Duration(milliseconds: 200), () { aprBox.put( filename, AttachmentProgress(1, 1, 1.0, true, false), ); }, ); return; } File tempFile = File('$chatImageDir/${msg['tempFilename']}'); AttachmentProgress? ap = aprBox.get(filename); if (!(await tempFile.exists())) { await tempFile.create(recursive: true); await tempFile.writeAsBytes(List.from(msg['bytes'])); } if (ap == null) { aprBox.put( filename, AttachmentProgress( 1, totalChunkNum, 1 / totalChunkNum, true, false, ), ); } else { ap.hasChunkNum += 1; ap.progress = ap.hasChunkNum / totalChunkNum; ap.isValid = true; List tempFiles = List.generate( totalChunkNum, (index) { String tempFilePath = '$chatImageDir/temp/$filename-$totalChunkNum-$index'; return File(tempFilePath); }, ); // assemble chunks when all the chunks are arrived if (tempFiles.every((element) => element.existsSync())) { final openedFile = file.openWrite(mode: FileMode.append); for (var i = 0; i < totalChunkNum; i++) { Uint8List bytes = await tempFiles[i].readAsBytes(); openedFile.add(bytes); await tempFiles[i].delete(); } openedFile.close(); ap.hasChunkNum = totalChunkNum; ap.progress = 1.0; ap.isValid = true; } aprBox.put(filename, ap); } } Future receivePullChatImage(Map msg) async { print('=================收到了拉取图片请求=================='); print(msg); print('======================================='); String baseImageDir = getIt.get().baseImageDir; Map sentMsg = { 'event': 'chat-image', 'senderId': getIt.get().id, }; if (msg['chatType'] == 0) { sentMsg['receiverId'] = msg['receiverId']; } else { sentMsg['receiverIds'] = msg['receiverIds']; } for (var filename in msg['attachments']) { File file = File('$baseImageDir/$filename'); int fileSize = await file.length(); int totalChunkNum = (fileSize / chunkSize).ceil(); int start = 0; int end = fileSize >= chunkSize ? start + chunkSize : start + fileSize; List bytes = []; await file.openRead(start, end).forEach((element) => bytes.addAll(element)); sentMsg['filename'] = filename; sentMsg['totalChunkNum'] = totalChunkNum; sentMsg['tempFilename'] = 'temp/$filename-$totalChunkNum-0'; sentMsg['currentChunkNum'] = 0; sentMsg['bytes'] = bytes; await uploadChatAttachment(sentMsg); getIt.get().addSendImageTimer(filename, totalChunkNum); } } Future receiveCheckChatImage(Map msg) async { print('=================收到了服务端确认收到图片事件=================='); // print(msg); print('======================================='); int nextChunkNum = msg['currentChunkNum'] + 1; int totalChunkNum = msg['totalChunkNum']; String baseImageDir = getIt.get().baseImageDir; String filename = msg['filename']; Box asBox = Hive.box('attachment_send'); AttachmentProgress aps = asBox.get(filename)!; getIt.get().removeSendImageTimer(filename); aps.hasChunkNum += 1; aps.progress = aps.hasChunkNum / aps.totalChunkNum; asBox.put(filename, aps); // print(aps.hasChunkNum); // print(aps.totalChunkNum); // print('已发送了: ${aps.progress}'); if (nextChunkNum == totalChunkNum) { return; } // Start to send next chunk int start = nextChunkNum * chunkSize; File file = File('$baseImageDir/$filename'); List bytes = []; if (nextChunkNum + 1 == totalChunkNum) { await file .openRead(start) .forEach((element) => bytes.addAll(element)); } else { await file .openRead(start, start + chunkSize) .forEach((element) => bytes.addAll(element)); } Map sentMsg = { 'event': 'chat-image', 'senderId': getIt.get().id, }; if (msg['chatType'] == 0) { sentMsg['receiverId'] = msg['receiverId']; } else { sentMsg['receiverIds'] = msg['receiverIds']; } sentMsg['filename'] = filename; sentMsg['totalChunkNum'] = totalChunkNum; sentMsg['tempFilename'] = 'temp/$filename-$totalChunkNum-$nextChunkNum'; sentMsg['currentChunkNum'] = nextChunkNum; sentMsg['bytes'] = bytes; uploadChatAttachment(sentMsg); getIt.get().addSendImageTimer(filename, totalChunkNum); }