mirror of
https://github.com/WuKongIM/WuKongIMFlutterSDK
synced 2025-05-29 07:02:19 +00:00
fix:新增修改频道头像方法,优化example
This commit is contained in:
parent
c0bb596c6a
commit
66fb59ac67
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"DockerRun.DisableDockerrc": true
|
"DockerRun.DisableDockerrc": true,
|
||||||
|
"java.compile.nullAnalysis.mode": "automatic"
|
||||||
}
|
}
|
||||||
|
@ -126,3 +126,5 @@
|
|||||||
* fix: 修改数据库解码错误数据导致oom
|
* fix: 修改数据库解码错误数据导致oom
|
||||||
### 1.6.3
|
### 1.6.3
|
||||||
* fix: 优化在未收到服务端心跳消息时主动断开重连
|
* fix: 优化在未收到服务端心跳消息时主动断开重连
|
||||||
|
### 1.6.4
|
||||||
|
* fix: 新增监听头像改变事件
|
@ -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, // 当前客户端的会话最大版本号(从保存的结果里取最大的version,如果本地没有数据则传0),
|
"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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
// 分批处理,每200个UID查询一次数据库
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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>{};
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user