2023-10-01 18:40:14 +08:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:hive/hive.dart';
|
2024-04-09 17:23:28 +08:00
|
|
|
|
|
|
|
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';
|
2023-10-01 18:40:14 +08:00
|
|
|
|
|
|
|
const int chunkSize = 1024 * 1024 * 2;
|
|
|
|
|
|
|
|
Future<void> receiveFriendMsg(
|
|
|
|
Map<String, dynamic> msg,
|
|
|
|
bool isShowNotification,
|
|
|
|
) async {
|
|
|
|
print('=================收到了好友信息事件==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
String senderId = msg['senderId'] as String;
|
|
|
|
Box<ChatSetting> chatSettingBox = Hive.box<ChatSetting>('chat_setting');
|
|
|
|
Box<MessageT> messageTBox = await HiveDatabase.openMessageBox(senderId);
|
|
|
|
Box<int> msgIndexBox = await Hive.openBox<int>('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<String> attachments = List.from(msg['attachments']);
|
|
|
|
final DateTime now = DateTime.parse(msg['dateTime'] as String);
|
|
|
|
|
|
|
|
for (var attachment in attachments) {
|
|
|
|
Box<AttachmentProgress> apr =
|
|
|
|
Hive.box<AttachmentProgress>('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<Contact>().friends[senderId]!.friendRemark.isEmpty
|
|
|
|
? getIt.get<ContactAccountProfile>().friends[senderId]!.nickname
|
|
|
|
: getIt.get<Contact>().friends[senderId]!.friendRemark;
|
|
|
|
|
|
|
|
String routeName = getIt.get<RouteState>().currentPathName;
|
|
|
|
|
|
|
|
String avatar = getIt.get<ContactAccountProfile>().friends[senderId]!.avatar;
|
|
|
|
|
|
|
|
if (!getIt.get<RouteState>().isVisible) {
|
|
|
|
NotificationAPI.showMessageNotifications(
|
|
|
|
senderId: senderId,
|
|
|
|
name: name,
|
|
|
|
avatar: avatar,
|
|
|
|
text: msg['text'] as String,
|
|
|
|
);
|
|
|
|
} else if (routeName == 'Message') {
|
|
|
|
if (!getIt.get<RouteState>().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<String, dynamic> msg) {
|
|
|
|
print('=================收到了申请好友事件==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
getIt.get<ApplyList>().addJson(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void receiveFriendAdded(Map<String, dynamic> msg) {
|
|
|
|
print('=================收到了申请好友通过事件==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
getIt.get<Contact>().addFriend(msg['friendId'], msg['setting']);
|
|
|
|
getIt
|
|
|
|
.get<ContactAccountProfile>()
|
|
|
|
.addFriendAccountProfile(msg['friendId'], msg['accountProfile']);
|
|
|
|
}
|
|
|
|
|
|
|
|
void receiveFriendDeleted(Map<String, dynamic> msg) {
|
|
|
|
print('=================收到了解除好友事件==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
getIt.get<Contact>().removeFriend(msg['friendId']);
|
|
|
|
getIt.get<ContactAccountProfile>().removeFriend(msg['friendId']);
|
|
|
|
}
|
|
|
|
|
|
|
|
void receiveGroupChatCreation(Map<String, dynamic> msg) {
|
|
|
|
print('=================收到了群聊邀请事件==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
String groupChatId = msg['groupChat']['id'];
|
|
|
|
getIt.get<Contact>().addGroupChat(groupChatId);
|
|
|
|
getIt.get<ContactAccountProfile>().addGroupChatProfile(groupChatId, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void receiveGroupChatMsg(
|
|
|
|
Map<String, dynamic> msg,
|
|
|
|
bool isShowNotification,
|
|
|
|
) async {
|
|
|
|
print('=================收到了群聊信息事件==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
String senderId = msg['senderId'] as String;
|
|
|
|
String groupChatId = msg['groupChatId'] as String;
|
|
|
|
Box<ChatSetting> chatSettingBox = Hive.box<ChatSetting>('chat_setting');
|
|
|
|
Box<MessageT> messageTBox = await HiveDatabase.openMessageBox(groupChatId);
|
|
|
|
Box<int> msgIndexBox = await Hive.openBox('msg_index_$groupChatId');
|
|
|
|
ChatSetting? chatSetting = chatSettingBox.get(groupChatId);
|
|
|
|
DateTime dateTime = DateTime.parse(msg['dateTime'] as String);
|
|
|
|
|
|
|
|
getIt.get<ContactAccountProfile>().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<String> attachments = List.from(msg['attachments']);
|
|
|
|
final DateTime now = DateTime.parse(msg['dateTime'] as String);
|
|
|
|
|
2023-10-04 11:50:28 +08:00
|
|
|
for (var attachment in attachments) {
|
|
|
|
Box<AttachmentProgress> apr =
|
|
|
|
Hive.box<AttachmentProgress>('attachment_receive');
|
|
|
|
apr.put(attachment, AttachmentProgress(0, 1000, 0, true, false));
|
|
|
|
}
|
|
|
|
|
2023-10-01 18:40:14 +08:00
|
|
|
messageTBox.add(
|
|
|
|
MessageT(
|
|
|
|
msg['msgId'] as String,
|
|
|
|
senderId,
|
|
|
|
msg['text'],
|
|
|
|
msg['type'],
|
|
|
|
now,
|
|
|
|
msg['isShowTime'],
|
|
|
|
attachments,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!isShowNotification) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String avatar =
|
|
|
|
getIt.get<ContactAccountProfile>().groupChats[groupChatId]!.avatar;
|
|
|
|
late String name;
|
|
|
|
|
|
|
|
if (getIt.get<Contact>().friends.containsKey(senderId)) {
|
|
|
|
if (getIt.get<Contact>().friends[senderId]!.friendRemark.isNotEmpty) {
|
|
|
|
name = getIt.get<Contact>().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<RouteState>().currentPathName;
|
|
|
|
|
|
|
|
if (!getIt.get<RouteState>().isVisible) {
|
|
|
|
NotificationAPI.showMessageNotifications(
|
|
|
|
senderId: senderId,
|
|
|
|
name: name,
|
|
|
|
avatar: avatar,
|
|
|
|
text: msg['text'] as String,
|
|
|
|
groupChatId: groupChatId,
|
|
|
|
);
|
|
|
|
} else if (routeName == 'Message') {
|
2023-10-04 11:50:28 +08:00
|
|
|
if (!getIt.get<RouteState>().query.containsValue(groupChatId)) {
|
2023-10-01 18:40:14 +08:00
|
|
|
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<String, dynamic> msg) async {
|
|
|
|
print('=================收到了聊天图片事件==================');
|
2023-10-05 12:12:56 +08:00
|
|
|
// // print(msg);
|
2023-10-01 18:40:14 +08:00
|
|
|
print('=======================================');
|
|
|
|
String chatImageDir = getIt.get<UserProfile>().baseImageDir;
|
|
|
|
String filename = msg['filename'];
|
|
|
|
String filePath = '$chatImageDir/$filename';
|
|
|
|
File file = File(filePath);
|
|
|
|
|
|
|
|
if (await file.exists()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
late Box<AttachmentProgress> aprBox;
|
|
|
|
try {
|
|
|
|
aprBox = Hive.box<AttachmentProgress>('attachment_receive');
|
|
|
|
} catch (_) {
|
|
|
|
aprBox = await Hive.openBox<AttachmentProgress>('attachment_receive');
|
|
|
|
}
|
|
|
|
String dirTime = filename.split('/')[0];
|
|
|
|
Directory dir = Directory('$chatImageDir/$dirTime');
|
|
|
|
|
|
|
|
if (!(await dir.exists())) {
|
|
|
|
await dir.create(recursive: true);
|
|
|
|
}
|
|
|
|
|
2023-10-05 12:12:56 +08:00
|
|
|
int totalChunkNum = msg['totalChunkNum'] as int;
|
2023-10-01 18:40:14 +08:00
|
|
|
|
|
|
|
if (totalChunkNum == 1) {
|
|
|
|
await file.writeAsBytes(List<int>.from(msg['bytes']));
|
2023-10-05 12:12:56 +08:00
|
|
|
await Future.delayed(
|
2023-10-01 18:40:14 +08:00
|
|
|
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())) {
|
2023-10-04 11:50:28 +08:00
|
|
|
await tempFile.create(recursive: true);
|
2023-10-01 18:40:14 +08:00
|
|
|
await tempFile.writeAsBytes(List<int>.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<File> 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<void> receivePullChatImage(Map<String, dynamic> msg) async {
|
|
|
|
print('=================收到了拉取图片请求==================');
|
|
|
|
print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
String baseImageDir = getIt.get<UserProfile>().baseImageDir;
|
|
|
|
Map<String, dynamic> sentMsg = {
|
|
|
|
'event': 'chat-image',
|
|
|
|
'senderId': getIt.get<UserAccount>().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<int> 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<WebSocketManager>().addSendImageTimer(filename, totalChunkNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> receiveCheckChatImage(Map<String, dynamic> msg) async {
|
|
|
|
print('=================收到了服务端确认收到图片事件==================');
|
|
|
|
// print(msg);
|
|
|
|
print('=======================================');
|
|
|
|
int nextChunkNum = msg['currentChunkNum'] + 1;
|
|
|
|
int totalChunkNum = msg['totalChunkNum'];
|
|
|
|
String baseImageDir = getIt.get<UserProfile>().baseImageDir;
|
|
|
|
String filename = msg['filename'];
|
|
|
|
Box<AttachmentProgress> asBox =
|
|
|
|
Hive.box<AttachmentProgress>('attachment_send');
|
|
|
|
AttachmentProgress aps = asBox.get(filename)!;
|
|
|
|
|
|
|
|
getIt.get<WebSocketManager>().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<int> bytes = [];
|
|
|
|
|
|
|
|
if (nextChunkNum + 1 == totalChunkNum) {
|
|
|
|
await file
|
|
|
|
.openRead(start)
|
2024-03-31 21:24:02 +08:00
|
|
|
.forEach((element) => bytes.addAll(element));
|
2023-10-01 18:40:14 +08:00
|
|
|
} else {
|
|
|
|
await file
|
|
|
|
.openRead(start, start + chunkSize)
|
2024-03-31 21:24:02 +08:00
|
|
|
.forEach((element) => bytes.addAll(element));
|
2023-10-01 18:40:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> sentMsg = {
|
|
|
|
'event': 'chat-image',
|
|
|
|
'senderId': getIt.get<UserAccount>().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<WebSocketManager>().addSendImageTimer(filename, totalChunkNum);
|
|
|
|
}
|