fix:新增修改频道头像方法,优化example

This commit is contained in:
SL 2025-04-26 12:59:17 +08:00
parent c0bb596c6a
commit 66fb59ac67
10 changed files with 512 additions and 445 deletions

View File

@ -1,3 +1,4 @@
{ {
"DockerRun.DisableDockerrc": true "DockerRun.DisableDockerrc": true,
"java.compile.nullAnalysis.mode": "automatic"
} }

View File

@ -126,3 +126,5 @@
* fix: 修改数据库解码错误数据导致oom * fix: 修改数据库解码错误数据导致oom
### 1.6.3 ### 1.6.3
* fix: 优化在未收到服务端心跳消息时主动断开重连 * fix: 优化在未收到服务端心跳消息时主动断开重连
### 1.6.4
* fix: 新增监听头像改变事件

View File

@ -13,98 +13,90 @@ class HttpUtils {
// static String apiURL = "https://api.githubim.com"; // static String apiURL = "https://api.githubim.com";
static String apiURL = "http://62.234.8.38:7090/v1"; static String apiURL = "http://62.234.8.38:7090/v1";
// static String apiURL = "http://175.27.245.108:15001"; // static String apiURL = "http://175.27.245.108:15001";
static getAvatarUrl(String uid) {
static Dio? _dio;
/// Get Dio instance with trust all certificates configuration
static Dio get dio {
if (_dio == null) {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) => true; // Trust all certificates
_dio = Dio(BaseOptions(
baseUrl: apiURL,
//
validateStatus: (status) => true,
));
(_dio!.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) => httpClient;
}
return _dio!;
}
static String getAvatarUrl(String uid) {
return "$apiURL/users/$uid/avatar"; return "$apiURL/users/$uid/avatar";
} }
static getGroupAvatarUrl(String gid) { static String getGroupAvatarUrl(String gid) {
return "$apiURL/groups/$gid/avatar"; return "$apiURL/groups/$gid/avatar";
} }
static Future<int> login(String uid, String token) async { static Future<int> login(String uid, String token) async {
final httpClient = HttpClient(); try {
httpClient.badCertificateCallback = final response = await dio.post("/user/login", data: {
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
final response = await dio.post("$apiURL/user/login", data: {
'uid': uid, 'uid': uid,
'token': token, 'token': token,
'device_flag': 0, 'device_flag': 0,
'device_level': 1 'device_level': 1
}); });
try {
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
UserInfo.name = response.data['name']; UserInfo.name = response.data['name'];
} }
return response.statusCode ?? HttpStatus.badRequest;
} catch (e) { } catch (e) {
print('获取用户信息失败'); print('Login error: $e');
return HttpStatus.internalServerError;
} }
return response.statusCode!;
} }
static Future<String> getIP(String uid) async { static Future<String> getIP(String uid) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
String ip = '';
try { try {
final response = await dio.get('$apiURL/users/$uid/route'); final response = await dio.get('/users/$uid/route');
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
ip = response.data['tcp_addr']; return response.data['tcp_addr'] ?? '';
} }
} catch (e) { } catch (e) {
ip = ''; print('Get IP error: $e');
}
return '';
} }
return ip; static Future<void> syncConversation(String lastSsgSeqs, int msgCount, int version,
}
static syncConversation(String lastSsgSeqs, int msgCount, int version,
Function(WKSyncConversation) back) async { Function(WKSyncConversation) back) async {
final httpClient = HttpClient(); try {
httpClient.badCertificateCallback = //
(X509Certificate cert, String host, int port) { if (UserInfo.uid.isEmpty) {
// print('请先登录');
return true; back(WKSyncConversation()..conversations = []);
}; return;
final dio = Dio(); }
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
final response = await dio.post('$apiURL/conversation/sync', data: { final response = await dio.post('/conversation/sync', data: {
"login_uid": UserInfo.uid, // uid "login_uid": UserInfo.uid,
"version": version, // (version0) "version": version,
"last_msg_seqs": "last_msg_seqs": lastSsgSeqs,
lastSsgSeqs, // channelID:channelType:last_msg_seq|channelID:channelType:last_msg_seq "msg_count": msgCount,
"msg_count": 10, // app点进去第一屏的数据
"device_uuid": UserInfo.uid, "device_uuid": UserInfo.uid,
}); });
// print(response.data);
WKSyncConversation conversation = WKSyncConversation(); WKSyncConversation conversation = WKSyncConversation();
conversation.conversations = []; conversation.conversations = [];
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
try { try {
var list = response.data['conversations']; var list = response.data['conversations'];
// var list = jsonDecode(response.data);
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
var json = list[i]; var json = list[i];
WKSyncConvMsg convMsg = WKSyncConvMsg(); WKSyncConvMsg convMsg = WKSyncConvMsg();
@ -128,10 +120,19 @@ class HttpUtils {
conversation.conversations!.add(convMsg); conversation.conversations!.add(convMsg);
} }
} catch (e) { } catch (e) {
print('同步最近会话错误'); print('解析会话数据错误: $e');
}
} else {
print('同步会话失败: HTTP ${response.statusCode}');
if (response.data != null && response.data is Map) {
print('错误信息: ${response.data['message'] ?? response.data}');
} }
} }
back(conversation); back(conversation);
} catch (e) {
print('同步会话错误: $e');
back(WKSyncConversation()..conversations = []);
}
} }
static syncChannelMsg( static syncChannelMsg(
@ -142,26 +143,17 @@ class HttpUtils {
int limit, int limit,
int pullMode, int pullMode,
Function(WKSyncChannelMsg) back) async { Function(WKSyncChannelMsg) back) async {
final httpClient = HttpClient(); try {
httpClient.badCertificateCallback = final response = await dio.post('/message/channel/sync', data: {
(X509Certificate cert, String host, int port) { "login_uid": UserInfo.uid,
// "channel_id": channelID,
return true; "channel_type": channelType,
}; "start_message_seq": startMsgSeq,
final dio = Dio(); "end_message_seq": endMsgSeq,
dio.httpClientAdapter = DefaultHttpClientAdapter() "limit": limit,
..onHttpClientCreate = (client) { "pull_mode": pullMode
return httpClient;
};
final response = await dio.post('$apiURL/message/channel/sync', data: {
"login_uid": UserInfo.uid, // uid
"channel_id": channelID, // ID
"channel_type": channelType, //
"start_message_seq": startMsgSeq, // start_message_seq的消息
"end_message_seq": endMsgSeq, // end_message_seq的消息
"limit": limit, //
"pull_mode": pullMode // 0: 1:
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var data = response.data; var data = response.data;
WKSyncChannelMsg msg = WKSyncChannelMsg(); WKSyncChannelMsg msg = WKSyncChannelMsg();
@ -179,6 +171,10 @@ class HttpUtils {
msg.messages = msgList; msg.messages = msgList;
back(msg); back(msg);
} }
} catch (e) {
print('Sync channel message error: $e');
back(WKSyncChannelMsg());
}
} }
static WKSyncMsg getWKSyncMsg(dynamic json) { static WKSyncMsg getWKSyncMsg(dynamic json) {
@ -221,19 +217,22 @@ class HttpUtils {
return extra; return extra;
} }
static getGroupInfo(String groupId) async { static Future<void> getGroupInfo(String groupId) async {
final httpClient = HttpClient(); try {
httpClient.badCertificateCallback = // ID是否有效
(X509Certificate cert, String host, int port) { if (groupId.isEmpty) {
// print('群ID不能为空');
return true; return;
}; }
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter() //
..onHttpClientCreate = (client) { if (UserInfo.uid.isEmpty) {
return httpClient; print('请先登录');
}; return;
final response = await dio.get('$apiURL/groups/$groupId'); }
final response = await dio.get('/groups/$groupId');
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var json = response.data; var json = response.data;
var channel = WKChannel(groupId, WKChannelType.group); var channel = WKChannel(groupId, WKChannelType.group);
@ -241,51 +240,67 @@ class HttpUtils {
channel.avatar = json['avatar']; channel.avatar = json['avatar'];
WKIM.shared.channelManager.addOrUpdateChannel(channel); WKIM.shared.channelManager.addOrUpdateChannel(channel);
} else { } else {
print('获取群信息失败'); print('获取群信息失败: HTTP ${response.statusCode}');
//
if (response.data != null && response.data is Map) {
print('错误信息: ${response.data['message'] ?? response.data}');
}
}
} catch (e) {
print('获取群信息错误: $e');
} }
} }
static getUserInfo(String uid) async { static Future<void> getUserInfo(String uid) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.get('$apiURL/users/$uid'); // UID是否有效
if (uid.isEmpty) {
print('用户ID不能为空');
return;
}
//
if (UserInfo.uid.isEmpty) {
print('请先登录');
return;
}
final response = await dio.get('/users/$uid');
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var json = response.data; var json = response.data;
var channel = WKChannel(uid, WKChannelType.personal); var channel = WKChannel(uid, WKChannelType.personal);
channel.channelName = json['name']; channel.channelName = json['name'];
channel.avatar = json['avatar']; channel.avatar = json['avatar'];
WKIM.shared.channelManager.addOrUpdateChannel(channel); WKIM.shared.channelManager.addOrUpdateChannel(channel);
} else {
print('获取用户信息失败: HTTP ${response.statusCode}');
//
if (response.data != null && response.data is Map) {
print('错误信息: ${response.data['message'] ?? response.data}');
}
} }
} catch (e) { } catch (e) {
print('获取用户信息失败$e'); print('获取用户信息错误: $e');
} }
} }
static revokeMsg(String clientMsgNo, String channelId, int channelType, static Future<bool> revokeMsg(String clientMsgNo, String channelId, int channelType,
int msgSeq, String msgId) async { int msgSeq, String msgId) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.post('$apiURL/message/revoke', data: { //
if (clientMsgNo.isEmpty || channelId.isEmpty || msgId.isEmpty) {
print('撤回消息需提供完整的消息信息');
return false;
}
//
if (UserInfo.uid.isEmpty) {
print('请先登录');
return false;
}
final response = await dio.post('/message/revoke', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'channel_id': channelId, 'channel_id': channelId,
'channel_type': channelType, 'channel_type': channelType,
@ -293,57 +308,66 @@ class HttpUtils {
'message_seq': msgSeq, 'message_seq': msgSeq,
'message_id': msgId, 'message_id': msgId,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
print('撤回消息成功'); print('消息撤回成功');
return true;
} else {
print('撤回消息失败: HTTP ${response.statusCode}');
if (response.data != null && response.data is Map) {
print('错误信息: ${response.data['message'] ?? response.data}');
}
return false;
} }
} catch (e) { } catch (e) {
print('获取用户信息失败$e'); print('撤回消息错误: $e');
return false;
} }
} }
static deleteMsg(String clientMsgNo, String channelId, int channelType, static Future<bool> deleteMsg(String clientMsgNo, String channelId, int channelType,
int msgSeq, String msgId) async { int msgSeq, String msgId) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.post('$apiURL/message/delete', data: { //
if (clientMsgNo.isEmpty || channelId.isEmpty || msgId.isEmpty) {
print('删除消息需提供完整的消息信息');
return false;
}
//
if (UserInfo.uid.isEmpty) {
print('请先登录');
return false;
}
final response = await dio.post('/message/delete', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'channel_id': channelId, 'channel_id': channelId,
'channel_type': channelType, 'channel_type': channelType,
'message_seq': msgSeq, 'message_seq': msgSeq,
'message_id': msgId, 'message_id': msgId,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
WKIM.shared.messageManager.deleteWithClientMsgNo(clientMsgNo); WKIM.shared.messageManager.deleteWithClientMsgNo(clientMsgNo);
print('消息删除成功');
return true;
} else {
print('删除消息失败: HTTP ${response.statusCode}');
if (response.data != null && response.data is Map) {
print('错误信息: ${response.data['message'] ?? response.data}');
}
return false;
} }
} catch (e) { } catch (e) {
print('删除消息失败$e'); print('删除消息错误: $e');
return false;
} }
} }
static syncMsgExtra(String channelId, int channelType, int version) async { static Future<void> syncMsgExtra(String channelId, int channelType, int version) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.post('$apiURL/message/extra/sync', data: { final response = await dio.post('/message/extra/sync', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'channel_id': channelId, 'channel_id': channelId,
'channel_type': channelType, 'channel_type': channelType,
@ -351,6 +375,7 @@ class HttpUtils {
'limit': 100, 'limit': 100,
'extra_version': version, 'extra_version': version,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
var arrJson = response.data; var arrJson = response.data;
if (arrJson != null && arrJson.length > 0) { if (arrJson != null && arrJson.length > 0) {
@ -371,122 +396,73 @@ class HttpUtils {
} }
} }
} catch (e) { } catch (e) {
print('同步消息扩展失败$e'); print('Sync message extra error: $e');
} }
} }
// //
static clearUnread(String channelId, int channelType) async { static Future<void> clearUnread(String channelId, int channelType) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.put('$apiURL/conversation/clearUnread', data: { final response = await dio.put('/conversation/clearUnread', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'channel_id': channelId, 'channel_id': channelId,
'channel_type': channelType, 'channel_type': channelType,
'unread': 0, 'unread': 0,
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
print('清空红点成功'); print('Unread count cleared successfully');
} }
} catch (e) { } catch (e) {
print('清空红点失败$e'); print('Clear unread count error: $e');
} }
} }
// //
static clearChannelMsg(String channelId, int channelType) async { static Future<void> clearChannelMsg(String channelId, int channelType) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
int maxSeq = await WKIM.shared.messageManager int maxSeq = await WKIM.shared.messageManager
.getMaxMessageSeq(channelId, channelType); .getMaxMessageSeq(channelId, channelType);
final response = await dio.post('$apiURL/message/offset', data: {
final response = await dio.post('/message/offset', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'channel_id': channelId, 'channel_id': channelId,
'channel_type': channelType, 'channel_type': channelType,
'message_seq': maxSeq 'message_seq': maxSeq
}); });
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
WKIM.shared.messageManager.clearWithChannel(channelId, channelType); WKIM.shared.messageManager.clearWithChannel(channelId, channelType);
} }
} catch (e) { } catch (e) {
print('清除频道消息失败$e'); print('Clear channel message error: $e');
} }
} }
// //
static Future<bool> createGroup(String groupNo) async { static Future<bool> createGroup(String groupNo) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.post('$apiURL/group/create', data: { final response = await dio.post('/group/create', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'group_no': groupNo, 'group_no': groupNo,
}); });
if (response.statusCode == HttpStatus.ok) { return response.statusCode == HttpStatus.ok;
return true;
} else {
return false;
}
} catch (e) { } catch (e) {
print('创建群失败$e'); print('Create group error: $e');
return false; return false;
} }
} }
// //
static Future<bool> updateGroupName(String groupNo, String groupName) async { static Future<bool> updateGroupName(String groupNo, String groupName) async {
final httpClient = HttpClient();
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
//
return true;
};
final dio = Dio();
dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (client) {
return httpClient;
};
try { try {
final response = await dio.put('$apiURL/groups/$groupNo', data: { final response = await dio.put('/groups/$groupNo', data: {
'login_uid': UserInfo.uid, 'login_uid': UserInfo.uid,
'name': groupName, 'name': groupName,
}); });
if (response.statusCode == HttpStatus.ok) { return response.statusCode == HttpStatus.ok;
return true;
} else {
return false;
}
} catch (e) { } catch (e) {
print('修改群名称失败$e'); print('Update group name error: $e');
return false; return false;
} }
} }

View File

@ -81,6 +81,10 @@ class ListViewShowDataState extends State<ListViewShowData> {
for (var i = 0; i < msgList.length; i++) { for (var i = 0; i < msgList.length; i++) {
msgList[i].msg.unreadCount = 0; msgList[i].msg.unreadCount = 0;
} }
//
_sortMessagesByTimestamp();
setState(() {}); setState(() {});
}); });
WKIM.shared.conversationManager WKIM.shared.conversationManager
@ -107,6 +111,9 @@ class ListViewShowDataState extends State<ListViewShowData> {
if (list.isNotEmpty) { if (list.isNotEmpty) {
msgList.addAll(list); msgList.addAll(list);
} }
_sortMessagesByTimestamp();
if (mounted) { if (mounted) {
setState(() {}); setState(() {});
} }
@ -120,6 +127,10 @@ class ListViewShowDataState extends State<ListViewShowData> {
msgList[i].msg.setWkChannel(channel); msgList[i].msg.setWkChannel(channel);
msgList[i].channelAvatar = "${HttpUtils.apiURL}/${channel.avatar}"; msgList[i].channelAvatar = "${HttpUtils.apiURL}/${channel.avatar}";
msgList[i].channelName = channel.channelName; msgList[i].channelName = channel.channelName;
//
_sortMessagesByTimestamp();
setState(() {}); setState(() {});
break; break;
} }
@ -127,6 +138,11 @@ class ListViewShowDataState extends State<ListViewShowData> {
}); });
} }
///
void _sortMessagesByTimestamp() {
msgList.sort((a, b) => b.msg.lastMsgTimestamp.compareTo(a.msg.lastMsgTimestamp));
}
void _getDataList() { void _getDataList() {
Future<List<WKUIConversationMsg>> list = Future<List<WKUIConversationMsg>> list =
WKIM.shared.conversationManager.getAll(); WKIM.shared.conversationManager.getAll();
@ -135,6 +151,7 @@ class ListViewShowDataState extends State<ListViewShowData> {
msgList.add(UIConversation(result[i])); msgList.add(UIConversation(result[i]));
} }
_sortMessagesByTimestamp();
setState(() {}); setState(() {});
}); });
} }
@ -315,7 +332,7 @@ class ListViewShowDataState extends State<ListViewShowData> {
style: const TextStyle(color: Colors.black, fontSize: 16), style: const TextStyle(color: Colors.black, fontSize: 16),
) )
], ],
) ),
], ],
), ),
), ),

View File

@ -4,13 +4,17 @@ import '../db/channel.dart';
import '../entity/channel.dart'; import '../entity/channel.dart';
class WKChannelManager { class WKChannelManager {
WKChannelManager._privateConstructor(); WKChannelManager._privateConstructor() {
_refreshChannelMap = HashMap<String, Function(WKChannel)>();
_refreshChannelAvatarMap = HashMap<String, Function(WKChannel)>();
}
static final WKChannelManager _instance = static final WKChannelManager _instance =
WKChannelManager._privateConstructor(); WKChannelManager._privateConstructor();
static WKChannelManager get shared => _instance; static WKChannelManager get shared => _instance;
final List<WKChannel> _list = []; final List<WKChannel> _list = [];
HashMap<String, Function(WKChannel)>? _refeshChannelMap; late final HashMap<String, Function(WKChannel)> _refreshChannelMap;
late final HashMap<String, Function(WKChannel)> _refreshChannelAvatarMap;
Function(String channelID, int channelType, Function(WKChannel) back)? Function(String channelID, int channelType, Function(WKChannel) back)?
_getChannelInfoBack; _getChannelInfoBack;
@ -70,6 +74,21 @@ class WKChannelManager {
.searchWithChannelTypeAndFollow(searchKey, channelType, follow); .searchWithChannelTypeAndFollow(searchKey, channelType, follow);
} }
//
updateAvatarCacheKey(
String channelID, int channelType, String avatarCacheKey) async {
WKChannel? channel = await getChannel(channelID, channelType);
if (channel == null) {
return;
}
channel.avatarCacheKey = avatarCacheKey;
_updateChannel(channel);
ChannelDB.shared.saveOrUpdate(channel);
_refreshChannelAvatarMap.forEach((key, back) {
back(channel);
});
}
addOrUpdateChannel(WKChannel channel) { addOrUpdateChannel(WKChannel channel) {
_updateChannel(channel); _updateChannel(channel);
_setRefresh(channel); _setRefresh(channel);
@ -115,25 +134,28 @@ class WKChannelManager {
} }
_setRefresh(WKChannel liMChannel) { _setRefresh(WKChannel liMChannel) {
if (_refeshChannelMap != null) { _refreshChannelMap.forEach((key, back) {
_refeshChannelMap!.forEach((key, back) {
back(liMChannel); back(liMChannel);
}); });
} }
}
addOnRefreshListener(String key, Function(WKChannel) back) { addOnRefreshListener(String key, Function(WKChannel) back) {
_refeshChannelMap ??= HashMap(); _refreshChannelMap[key] = back;
_refeshChannelMap![key] = back;
} }
removeOnRefreshListener(String key) { removeOnRefreshListener(String key) {
if (_refeshChannelMap != null) { _refreshChannelMap.remove(key);
_refeshChannelMap!.remove(key);
}
} }
addOnGetChannelListener(Function(String, int, Function(WKChannel)) back) { addOnGetChannelListener(Function(String, int, Function(WKChannel)) back) {
_getChannelInfoBack = back; _getChannelInfoBack = back;
} }
addOnRefreshAvatarListener(String key, Function(WKChannel) back) {
_refreshChannelAvatarMap[key] = back;
}
removeOnRefreshAvatarListener(String key) {
_refreshChannelAvatarMap.remove(key);
}
} }

View File

@ -5,14 +5,18 @@ import 'package:wukongimfluttersdk/db/channel_member.dart';
import '../entity/channel_member.dart'; import '../entity/channel_member.dart';
class WKChannelMemberManager { class WKChannelMemberManager {
WKChannelMemberManager._privateConstructor(); WKChannelMemberManager._privateConstructor() {
_newMembersBack = HashMap<String, Function(List<WKChannelMember>)>();
_refreshMembersBack = HashMap<String, Function(WKChannelMember, bool)>();
_deleteMembersBack = HashMap<String, Function(List<WKChannelMember>)>();
}
static final WKChannelMemberManager _instance = static final WKChannelMemberManager _instance =
WKChannelMemberManager._privateConstructor(); WKChannelMemberManager._privateConstructor();
static WKChannelMemberManager get shared => _instance; static WKChannelMemberManager get shared => _instance;
HashMap<String, Function(List<WKChannelMember>)>? _newMembersBack; late final HashMap<String, Function(List<WKChannelMember>)> _newMembersBack;
HashMap<String, Function(WKChannelMember, bool)>? _refreshMembersBack; late final HashMap<String, Function(WKChannelMember, bool)> _refreshMembersBack;
HashMap<String, Function(List<WKChannelMember>)>? _deleteMembersBack; late final HashMap<String, Function(List<WKChannelMember>)> _deleteMembersBack;
Future<int> getMaxVersion(String channelID, int channelType) async { Future<int> getMaxVersion(String channelID, int channelType) async {
return ChannelMemberDB.shared.getMaxVersion(channelID, channelType); return ChannelMemberDB.shared.getMaxVersion(channelID, channelType);
@ -29,8 +33,9 @@ class WKChannelMemberManager {
.queryWithUID(channelID, channelType, memberUID); .queryWithUID(channelID, channelType, memberUID);
} }
saveOrUpdateList(List<WKChannelMember> list) async { Future<void> saveOrUpdateList(List<WKChannelMember> list) async {
if (list.isEmpty) return; if (list.isEmpty) return;
String channelID = list[0].channelID; String channelID = list[0].channelID;
int channelType = list[0].channelType; int channelType = list[0].channelType;
@ -40,7 +45,9 @@ class WKChannelMemberManager {
List<WKChannelMember> existList = []; List<WKChannelMember> existList = [];
List<String> uidList = []; List<String> uidList = [];
for (WKChannelMember channelMember in list) { for (WKChannelMember channelMember in list) {
// 200UID查询一次数据库
if (uidList.length == 200) { if (uidList.length == 200) {
List<WKChannelMember> tempList = await ChannelMemberDB.shared List<WKChannelMember> tempList = await ChannelMemberDB.shared
.queryWithUIDs( .queryWithUIDs(
@ -54,16 +61,16 @@ class WKChannelMemberManager {
uidList.add(channelMember.memberUID); uidList.add(channelMember.memberUID);
} }
// UID
if (uidList.isNotEmpty) { if (uidList.isNotEmpty) {
List<WKChannelMember> tempList = await ChannelMemberDB.shared List<WKChannelMember> tempList = await ChannelMemberDB.shared
.queryWithUIDs(channelID, channelType, uidList); .queryWithUIDs(channelID, channelType, uidList);
if (tempList.isNotEmpty) { if (tempList.isNotEmpty) {
existList.addAll(tempList); existList.addAll(tempList);
} }
uidList.clear();
} }
//
for (WKChannelMember channelMember in list) { for (WKChannelMember channelMember in list) {
bool isNewMember = true; bool isNewMember = true;
for (int i = 0, size = existList.length; i < size; i++) { for (int i = 0, size = existList.length; i < size; i++) {
@ -86,77 +93,62 @@ class WKChannelMemberManager {
} }
} }
// //
ChannelMemberDB.shared.insertList(list); await ChannelMemberDB.shared.insertList(list);
//
if (addList.isNotEmpty) { if (addList.isNotEmpty) {
setOnNewChannelMember(addList); _notifyNewChannelMembers(addList);
} }
if (deleteList.isNotEmpty) { if (deleteList.isNotEmpty) {
setDeleteChannelMember(deleteList); _notifyDeleteChannelMembers(deleteList);
} }
if (updateList.isNotEmpty) { if (updateList.isNotEmpty) {
for (int i = 0, size = updateList.length; i < size; i++) { for (int i = 0, size = updateList.length; i < size; i++) {
setRefreshChannelMember(updateList[i], i == updateList.length - 1); _notifyRefreshChannelMember(updateList[i], i == updateList.length - 1);
} }
} }
} }
setRefreshChannelMember(WKChannelMember member, bool isEnd) { void _notifyRefreshChannelMember(WKChannelMember member, bool isEnd) {
if (_refreshMembersBack != null) { _refreshMembersBack.forEach((key, back) {
_refreshMembersBack!.forEach((key, back) {
back(member, isEnd); back(member, isEnd);
}); });
} }
void addOnRefreshMemberListener(String key, Function(WKChannelMember, bool) back) {
_refreshMembersBack[key] = back;
} }
addOnRefreshMemberListener(String key, Function(WKChannelMember, bool) back) { void removeRefreshMemberListener(String key) {
_refreshMembersBack ??= HashMap(); _refreshMembersBack.remove(key);
_refreshMembersBack![key] = back;
} }
removeRefreshMemberListener(String key) { void _notifyDeleteChannelMembers(List<WKChannelMember> list) {
if (_refreshMembersBack != null) { _deleteMembersBack.forEach((key, back) {
_refreshMembersBack!.remove(key);
}
}
setDeleteChannelMember(List<WKChannelMember> list) {
if (_deleteMembersBack != null) {
_deleteMembersBack!.forEach((key, back) {
back(list); back(list);
}); });
} }
void addOnDeleteMemberListener(String key, Function(List<WKChannelMember>) back) {
_deleteMembersBack[key] = back;
} }
addOnDeleteMemberListener(String key, Function(List<WKChannelMember>) back) { void removeDeleteMemberListener(String key) {
_deleteMembersBack ??= HashMap(); _deleteMembersBack.remove(key);
_deleteMembersBack![key] = back;
} }
removeDeleteMemberListener(String key) { void _notifyNewChannelMembers(List<WKChannelMember> list) {
if (_deleteMembersBack != null) { _newMembersBack.forEach((key, back) {
_deleteMembersBack!.remove(key);
}
}
setOnNewChannelMember(List<WKChannelMember> list) {
if (_newMembersBack != null) {
_newMembersBack!.forEach((key, back) {
back(list); back(list);
}); });
} }
void addOnNewMemberListener(String key, Function(List<WKChannelMember>) back) {
_newMembersBack[key] = back;
} }
addOnNewMemberListener(String key, Function(List<WKChannelMember>) back) { void removeNewMemberListener(String key) {
_newMembersBack ??= HashMap(); _newMembersBack.remove(key);
_newMembersBack![key] = back;
}
removeNewMemberListener(String key) {
if (_newMembersBack != null) {
_newMembersBack!.remove(key);
}
} }
} }

View File

@ -4,43 +4,55 @@ import 'package:wukongimfluttersdk/db/const.dart';
import '../entity/cmd.dart'; import '../entity/cmd.dart';
///
class WKCMDManager { class WKCMDManager {
WKCMDManager._privateConstructor(); WKCMDManager._privateConstructor() {
_cmdListeners = HashMap<String, Function(WKCMD)>();
}
static final WKCMDManager _instance = WKCMDManager._privateConstructor(); static final WKCMDManager _instance = WKCMDManager._privateConstructor();
static WKCMDManager get shared => _instance; static WKCMDManager get shared => _instance;
HashMap<String, Function(WKCMD)>? _cmdback; ///
handleCMD(dynamic json) { late final HashMap<String, Function(WKCMD)> _cmdListeners;
///
void handleCMD(dynamic json) {
//
String cmd = WKDBConst.readString(json, 'cmd'); String cmd = WKDBConst.readString(json, 'cmd');
dynamic param = json['param']; dynamic param = json['param'];
//
if (param != null && param is Map) { if (param != null && param is Map) {
if (!param.containsKey('channel_id')) { if (!param.containsKey('channel_id')) {
param['channel_id'] = json['channel_id']; param['channel_id'] = json['channel_id'];
param['channel_type'] = json['channel_type']; param['channel_type'] = json['channel_type'];
} }
} }
//
WKCMD wkcmd = WKCMD(); WKCMD wkcmd = WKCMD();
wkcmd.cmd = cmd; wkcmd.cmd = cmd;
wkcmd.param = param; wkcmd.param = param;
pushCMD(wkcmd); _notifyListeners(wkcmd);
} }
pushCMD(WKCMD wkcmd) { ///
if (_cmdback != null) { void _notifyListeners(WKCMD wkcmd) {
_cmdback!.forEach((key, back) { _cmdListeners.forEach((key, listener) {
back(wkcmd); listener(wkcmd);
}); });
} }
///
/// [key]
/// [listener]
void addOnCmdListener(String key, Function(WKCMD) listener) {
_cmdListeners[key] = listener;
} }
addOnCmdListener(String key, Function(WKCMD) back) { ///
_cmdback ??= HashMap(); /// [key]
_cmdback![key] = back; void removeCmdListener(String key) {
} _cmdListeners.remove(key);
removeCmdListener(String key) {
if (_cmdback != null) {
_cmdback!.remove(key);
}
} }
} }

View File

@ -315,6 +315,7 @@ class WKConnectionManager {
} }
} else if (packet.header.packetType == PacketType.sendack) { } else if (packet.header.packetType == PacketType.sendack) {
var sendack = packet as SendAckPacket; var sendack = packet as SendAckPacket;
Logs.debug('发送结果:${sendack.reasonCode}');
WKIM.shared.messageManager.updateSendResult(sendack.messageID, WKIM.shared.messageManager.updateSendResult(sendack.messageID,
sendack.clientSeq, sendack.messageSeq, sendack.reasonCode); sendack.clientSeq, sendack.messageSeq, sendack.reasonCode);
if (_sendingMsgMap.containsKey(sendack.clientSeq)) { if (_sendingMsgMap.containsKey(sendack.clientSeq)) {

View File

@ -9,37 +9,54 @@ import '../db/conversation.dart';
import '../entity/conversation.dart'; import '../entity/conversation.dart';
import '../type/const.dart'; import '../type/const.dart';
///
class WKConversationManager { class WKConversationManager {
WKConversationManager._privateConstructor(); WKConversationManager._privateConstructor() {
_refreshMsgMap = HashMap<String, Function(WKUIConversationMsg, bool)>();
_refreshMsgListMap = HashMap<String, Function(List<WKUIConversationMsg>)>();
_deleteMsgMap = HashMap<String, Function(String, int)>();
_clearAllRedDotMap = HashMap<String, Function()>();
}
static final WKConversationManager _instance = static final WKConversationManager _instance =
WKConversationManager._privateConstructor(); WKConversationManager._privateConstructor();
static WKConversationManager get shared => _instance; static WKConversationManager get shared => _instance;
HashMap<String, Function(WKUIConversationMsg, bool)>? _refeshMsgMap; ///
HashMap<String, Function(List<WKUIConversationMsg>)>? _refreshMsgListMap; late final HashMap<String, Function(WKUIConversationMsg, bool)> _refreshMsgMap;
HashMap<String, Function(String, int)>? _deleteMsgMap;
HashMap<String, Function()>? _clearAllRedDotMap;
///
late final HashMap<String, Function(List<WKUIConversationMsg>)> _refreshMsgListMap;
///
late final HashMap<String, Function(String, int)> _deleteMsgMap;
///
late final HashMap<String, Function()> _clearAllRedDotMap;
///
Function(String lastSsgSeqs, int msgCount, int version, Function(String lastSsgSeqs, int msgCount, int version,
Function(WKSyncConversation))? _syncConersationBack; Function(WKSyncConversation))? _syncConversationBack;
///
Future<List<WKUIConversationMsg>> getAll() async { Future<List<WKUIConversationMsg>> getAll() async {
return await ConversationDB.shared.queryAll(); return await ConversationDB.shared.queryAll();
} }
///
Future<bool> deleteMsg(String channelID, int channelType) async { Future<bool> deleteMsg(String channelID, int channelType) async {
bool result = await ConversationDB.shared.delete(channelID, channelType); bool result = await ConversationDB.shared.delete(channelID, channelType);
if (result) { if (result) {
_setDeleteMsg(channelID, channelType); _notifyDeleteMsg(channelID, channelType);
} }
return result; return result;
} }
///
Future<WKUIConversationMsg?> saveWithLiMMsg(WKMsg msg, int redDot) async { Future<WKUIConversationMsg?> saveWithLiMMsg(WKMsg msg, int redDot) async {
WKConversationMsg wkConversationMsg = WKConversationMsg(); WKConversationMsg wkConversationMsg = WKConversationMsg();
if (msg.channelType == WKChannelType.communityTopic && if (msg.channelType == WKChannelType.communityTopic &&
msg.channelID != '') { msg.channelID.isNotEmpty) {
if (msg.channelID.contains("@")) { if (msg.channelID.contains("@")) {
var str = msg.channelID.split("@"); var str = msg.channelID.split("@");
wkConversationMsg.parentChannelID = str[0]; wkConversationMsg.parentChannelID = str[0];
@ -57,14 +74,17 @@ class WKConversationManager {
return uiMsg; return uiMsg;
} }
///
Future<int> getAllUnreadCount() async { Future<int> getAllUnreadCount() async {
return ConversationDB.shared.queryAllUnreadCount(); return ConversationDB.shared.queryAllUnreadCount();
} }
///
Future<int> getExtraMaxVersion() async { Future<int> getExtraMaxVersion() async {
return ConversationDB.shared.queryExtraMaxVersion(); return ConversationDB.shared.queryExtraMaxVersion();
} }
///
Future<WKUIConversationMsg?> getWithChannel( Future<WKUIConversationMsg?> getWithChannel(
String channelID, int channelType) async { String channelID, int channelType) async {
var msg = await ConversationDB.shared var msg = await ConversationDB.shared
@ -75,165 +95,172 @@ class WKConversationManager {
return null; return null;
} }
clearAll() { ///
ConversationDB.shared.clearAll(); Future<void> clearAll() async {
await ConversationDB.shared.clearAll();
} }
clearAllRedDot() async { ///
Future<void> clearAllRedDot() async {
int row = await ConversationDB.shared.clearAllRedDot(); int row = await ConversationDB.shared.clearAllRedDot();
if (row > 0) { if (row > 0) {
_setClearAllRedDot(); _notifyClearAllRedDot();
} }
} }
updateRedDot(String channelID, int channelType, int redDot) async { ///
Future<void> updateRedDot(String channelID, int channelType, int redDot) async {
var map = <String, Object>{}; var map = <String, Object>{};
map['unread_count'] = redDot; map['unread_count'] = redDot;
var result = await ConversationDB.shared var result = await ConversationDB.shared
.updateWithField(map, channelID, channelType); .updateWithField(map, channelID, channelType);
if (result > 0) { if (result > 0) {
_refreshMsg(channelID, channelType); await _refreshChannelMsg(channelID, channelType);
} }
} }
_refreshMsg(String channelID, int channelType) async { ///
Future<void> _refreshChannelMsg(String channelID, int channelType) async {
var msg = await ConversationDB.shared var msg = await ConversationDB.shared
.queryMsgByMsgChannelId(channelID, channelType); .queryMsgByMsgChannelId(channelID, channelType);
if (msg != null) { if (msg != null) {
var uiMsg = ConversationDB.shared.getUIMsg(msg); var uiMsg = ConversationDB.shared.getUIMsg(msg);
List<WKUIConversationMsg> uiMsgs = []; List<WKUIConversationMsg> uiMsgs = [uiMsg];
uiMsgs.add(uiMsg);
setRefreshUIMsgs(uiMsgs); setRefreshUIMsgs(uiMsgs);
} }
} }
addOnClearAllRedDotListener(String key, Function() back) { ///
_clearAllRedDotMap ??= HashMap(); void addOnClearAllRedDotListener(String key, Function() listener) {
_clearAllRedDotMap![key] = back; _clearAllRedDotMap[key] = listener;
} }
removeClearAllRedDotListener(String key) { ///
if (_clearAllRedDotMap != null) { void removeClearAllRedDotListener(String key) {
_clearAllRedDotMap!.remove(key); _clearAllRedDotMap.remove(key);
}
} }
_setClearAllRedDot() { ///
if (_clearAllRedDotMap != null) { void _notifyClearAllRedDot() {
_clearAllRedDotMap!.forEach((key, back) { _clearAllRedDotMap.forEach((_, listener) {
back(); listener();
}); });
} }
///
void addOnDeleteMsgListener(String key, Function(String, int) listener) {
_deleteMsgMap[key] = listener;
} }
addOnDeleteMsgListener(String key, Function(String, int) back) { ///
_deleteMsgMap ??= HashMap(); void removeDeleteMsgListener(String key) {
_deleteMsgMap![key] = back; _deleteMsgMap.remove(key);
} }
removeDeleteMsgListener(String key) { ///
if (_deleteMsgMap != null) { void _notifyDeleteMsg(String channelID, int channelType) {
_deleteMsgMap!.remove(key); _deleteMsgMap.forEach((_, listener) {
} listener(channelID, channelType);
}
_setDeleteMsg(String channelID, int channelType) {
if (_deleteMsgMap != null) {
_deleteMsgMap!.forEach((key, back) {
back(channelID, channelType);
}); });
} }
}
_setRefreshMsg(WKUIConversationMsg msg, bool isEnd) { ///
if (_refeshMsgMap != null) { void _notifyRefreshMsg(WKUIConversationMsg msg, bool isEnd) {
_refeshMsgMap!.forEach((key, back) { _refreshMsgMap.forEach((_, listener) {
back(msg, isEnd); listener(msg, isEnd);
}); });
} }
///
@Deprecated("请使用 addOnRefreshMsgListListener 方法替代")
void addOnRefreshMsgListener(
String key, Function(WKUIConversationMsg, bool) listener) {
_refreshMsgMap[key] = listener;
} }
@Deprecated("Please replace with `addOnRefreshMsgListListener` method") ///
addOnRefreshMsgListener( void removeOnRefreshMsg(String key) {
String key, Function(WKUIConversationMsg, bool) back) { _refreshMsgMap.remove(key);
_refeshMsgMap ??= HashMap();
_refeshMsgMap![key] = back;
} }
removeOnRefreshMsg(String key) { /// UI列表
if (_refeshMsgMap != null) { void setRefreshUIMsgs(List<WKUIConversationMsg> msgs) {
_refeshMsgMap!.remove(key); _notifyRefreshMsgList(msgs);
}
}
setRefreshUIMsgs(List<WKUIConversationMsg> msgs) {
_setRefreshMsgList(msgs);
for (int i = 0, size = msgs.length; i < size; i++) { for (int i = 0, size = msgs.length; i < size; i++) {
_setRefreshMsg(msgs[i], i == msgs.length - 1); _notifyRefreshMsg(msgs[i], i == msgs.length - 1);
} }
} }
_setRefreshMsgList(List<WKUIConversationMsg> msgs) { ///
if (_refreshMsgListMap != null) { void _notifyRefreshMsgList(List<WKUIConversationMsg> msgs) {
_refreshMsgListMap!.forEach((key, back) { _refreshMsgListMap.forEach((_, listener) {
back(msgs); listener(msgs);
}); });
} }
///
void addOnRefreshMsgListListener(
String key, Function(List<WKUIConversationMsg>) listener) {
_refreshMsgListMap[key] = listener;
} }
addOnRefreshMsgListListener( ///
String key, Function(List<WKUIConversationMsg>) back) { void removeOnRefreshMsgListListener(String key) {
_refreshMsgListMap ??= HashMap(); _refreshMsgListMap.remove(key);
_refreshMsgListMap![key] = back;
} }
removeOnRefreshMsgListListener(String key) { ///
if (_refreshMsgListMap != null) { void addOnSyncConversationListener(
_refreshMsgListMap!.remove(key);
}
}
addOnSyncConversationListener(
Function(String lastSsgSeqs, int msgCount, int version, Function(String lastSsgSeqs, int msgCount, int version,
Function(WKSyncConversation)) Function(WKSyncConversation))
back) { listener) {
_syncConersationBack = back; _syncConversationBack = listener;
} }
setSyncConversation(Function() back) async { ///
Future<void> setSyncConversation(Function() callback) async {
WKIM.shared.connectionManager.setConnectionStatus(WKConnectStatus.syncMsg); WKIM.shared.connectionManager.setConnectionStatus(WKConnectStatus.syncMsg);
if (_syncConersationBack != null) { if (_syncConversationBack != null) {
int version = await ConversationDB.shared.getMaxVersion(); int version = await ConversationDB.shared.getMaxVersion();
String lastMsgSeqStr = await ConversationDB.shared.getLastMsgSeqs(); String lastMsgSeqStr = await ConversationDB.shared.getLastMsgSeqs();
_syncConersationBack!(lastMsgSeqStr, 200, version, (msgs) { _syncConversationBack!(lastMsgSeqStr, 200, version, (msgs) {
_saveSyncCoversation(msgs); _saveSyncConversation(msgs);
back(); callback();
}); });
} }
} }
_saveSyncCoversation(WKSyncConversation? syncChat) { ///
void _saveSyncConversation(WKSyncConversation? syncChat) {
if (syncChat == null || if (syncChat == null ||
syncChat.conversations == null || syncChat.conversations == null ||
syncChat.conversations!.isEmpty) { syncChat.conversations!.isEmpty) {
return; return;
} }
//
List<WKConversationMsg> conversationMsgList = []; List<WKConversationMsg> conversationMsgList = [];
List<WKMsg> msgList = []; List<WKMsg> msgList = [];
List<WKMsgReaction> msgReactionList = []; List<WKMsgReaction> msgReactionList = [];
List<WKMsgExtra> msgExtraList = []; List<WKMsgExtra> msgExtraList = [];
List<WKUIConversationMsg> uiMsgList = []; List<WKUIConversationMsg> uiMsgList = [];
//
if (syncChat.conversations != null && syncChat.conversations!.isNotEmpty) { if (syncChat.conversations != null && syncChat.conversations!.isNotEmpty) {
for (int i = 0, size = syncChat.conversations!.length; i < size; i++) { for (int i = 0, size = syncChat.conversations!.length; i < size; i++) {
WKConversationMsg conversationMsg = WKConversationMsg(); WKConversationMsg conversationMsg = WKConversationMsg();
int channelType = syncChat.conversations![i].channelType; int channelType = syncChat.conversations![i].channelType;
String channelID = syncChat.conversations![i].channelID; String channelID = syncChat.conversations![i].channelID;
//
if (channelType == WKChannelType.communityTopic) { if (channelType == WKChannelType.communityTopic) {
var str = channelID.split("@"); var str = channelID.split("@");
conversationMsg.parentChannelID = str[0]; conversationMsg.parentChannelID = str[0];
conversationMsg.parentChannelType = WKChannelType.community; conversationMsg.parentChannelType = WKChannelType.community;
} }
//
conversationMsg.channelID = syncChat.conversations![i].channelID; conversationMsg.channelID = syncChat.conversations![i].channelID;
conversationMsg.channelType = syncChat.conversations![i].channelType; conversationMsg.channelType = syncChat.conversations![i].channelType;
conversationMsg.lastMsgSeq = syncChat.conversations![i].lastMsgSeq; conversationMsg.lastMsgSeq = syncChat.conversations![i].lastMsgSeq;
@ -242,57 +269,74 @@ class WKConversationManager {
conversationMsg.lastMsgTimestamp = syncChat.conversations![i].timestamp; conversationMsg.lastMsgTimestamp = syncChat.conversations![i].timestamp;
conversationMsg.unreadCount = syncChat.conversations![i].unread; conversationMsg.unreadCount = syncChat.conversations![i].unread;
conversationMsg.version = syncChat.conversations![i].version; conversationMsg.version = syncChat.conversations![i].version;
WKUIConversationMsg uiMsg = WKUIConversationMsg uiMsg =
ConversationDB.shared.getUIMsg(conversationMsg); ConversationDB.shared.getUIMsg(conversationMsg);
//
//
if (syncChat.conversations![i].recents != null && if (syncChat.conversations![i].recents != null &&
syncChat.conversations![i].recents!.isNotEmpty) { syncChat.conversations![i].recents!.isNotEmpty) {
for (WKSyncMsg wkSyncRecent in syncChat.conversations![i].recents!) { for (WKSyncMsg wkSyncRecent in syncChat.conversations![i].recents!) {
WKMsg msg = wkSyncRecent.getWKMsg(); WKMsg msg = wkSyncRecent.getWKMsg();
//
if (msg.reactionList != null && msg.reactionList!.isNotEmpty) { if (msg.reactionList != null && msg.reactionList!.isNotEmpty) {
msgReactionList.addAll(msg.reactionList!); msgReactionList.addAll(msg.reactionList!);
} }
// fromUID // fromUID
if (conversationMsg.lastClientMsgNO == msg.clientMsgNO) { if (conversationMsg.lastClientMsgNO == msg.clientMsgNO) {
conversationMsg.isDeleted = msg.isDeleted; conversationMsg.isDeleted = msg.isDeleted;
uiMsg.isDeleted = conversationMsg.isDeleted; uiMsg.isDeleted = conversationMsg.isDeleted;
uiMsg.setWkMsg(msg); uiMsg.setWkMsg(msg);
} }
//
if (wkSyncRecent.messageExtra != null) { if (wkSyncRecent.messageExtra != null) {
WKMsgExtra extra = WKIM.shared.messageManager WKMsgExtra extra = WKIM.shared.messageManager
.wkSyncExtraMsg2WKMsgExtra(msg.channelID, msg.channelType, .wkSyncExtraMsg2WKMsgExtra(msg.channelID, msg.channelType,
wkSyncRecent.messageExtra!); wkSyncRecent.messageExtra!);
msgExtraList.add(extra); msgExtraList.add(extra);
} }
msgList.add(msg); msgList.add(msg);
} }
} }
conversationMsgList.add(conversationMsg); conversationMsgList.add(conversationMsg);
uiMsgList.add(uiMsg); uiMsgList.add(uiMsg);
} }
} }
//
if (msgExtraList.isNotEmpty) { if (msgExtraList.isNotEmpty) {
MessageDB.shared.insertMsgExtras(msgExtraList); MessageDB.shared.insertMsgExtras(msgExtraList);
// MessageDB.shared.insertOrUpdateMsgExtras(msgExtraList);
} }
if (msgList.isNotEmpty) { if (msgList.isNotEmpty) {
MessageDB.shared.insertMsgList(msgList); MessageDB.shared.insertMsgList(msgList);
} }
if (conversationMsgList.isNotEmpty) { if (conversationMsgList.isNotEmpty) {
// ConversationDB.shared.insertMsgList(conversationMsgList);
ConversationDB.shared.insetMsgs(conversationMsgList); ConversationDB.shared.insetMsgs(conversationMsgList);
} }
if (msgReactionList.isNotEmpty) { if (msgReactionList.isNotEmpty) {
ReactionDB.shared.insertOrUpdateReactionList(msgReactionList); ReactionDB.shared.insertOrUpdateReactionList(msgReactionList);
} }
// 20
if (msgList.isNotEmpty && msgList.length < 20) { if (msgList.isNotEmpty && msgList.length < 20) {
msgList.sort((a, b) => a.messageSeq.compareTo(b.messageSeq)); msgList.sort((a, b) => a.messageSeq.compareTo(b.messageSeq));
WKIM.shared.messageManager.pushNewMsg(msgList); WKIM.shared.messageManager.pushNewMsg(msgList);
} }
// UI
if (uiMsgList.isNotEmpty) { if (uiMsgList.isNotEmpty) {
setRefreshUIMsgs(uiMsgList); setRefreshUIMsgs(uiMsgList);
} }
//
if (syncChat.cmds != null && syncChat.cmds!.isNotEmpty) { if (syncChat.cmds != null && syncChat.cmds!.isNotEmpty) {
for (int i = 0, size = syncChat.cmds!.length; i < size; i++) { for (int i = 0, size = syncChat.cmds!.length; i < size; i++) {
dynamic json = <String, dynamic>{}; dynamic json = <String, dynamic>{};

View File

@ -15,7 +15,7 @@ description: wukong IM flutter sdk
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.6.3 version: 1.6.4
homepage: https://github.com/WuKongIM/WuKongIMFlutterSDK homepage: https://github.com/WuKongIM/WuKongIMFlutterSDK
environment: environment: