flutter/lib/IM/global_badge.dart

185 lines
7.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:get/get.dart';
import 'package:loopin/IM/controller/chat_controller.dart';
import 'package:loopin/IM/controller/tab_bar_controller.dart';
import 'package:loopin/IM/im_service.dart';
import 'package:loopin/models/conversation_type.dart';
import 'package:loopin/models/tab_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
class GlobalBadge extends GetxController {
/// 全局未读消息总数
RxInt totalUnread = 0.obs;
/// 监听器对象(用于 add/remove
late final V2TimConversationListener _listener;
void rest() {
totalUnread.value = 0;
}
@override
void onInit() {
super.onInit();
_listener = V2TimConversationListener(
onTotalUnreadMessageCountChanged: (int count) {
logger.i('未读数发生变化$count');
totalUnread.value = count;
Get.find<TabBarController>().setBadge(TabType.chat, totalUnread.value);
},
onNewConversation: (List<V2TimConversation> conversationList) {
for (var conv in conversationList) {
logger.i("新会话创建:${conv.conversationGroupList}");
handleCoverstion(conv);
}
},
onConversationChanged: (List<V2TimConversation> conversationList) async {
logger.w('会话变更:会话分组:${conversationList.first.conversationGroupList},会话内容${conversationList.first.toLogString()}');
final ctl = Get.find<ChatController>();
logger.w('当前会话列表内容:${ctl.chatList.length}');
final updatedIds = conversationList.map((e) => e.conversationID).toSet();
logger.w('要变更的会话id$updatedIds');
for (int i = 0; i < ctl.chatList.length; i++) {
final chatItem = ctl.chatList[i];
logger.w('需要更新的ID:${chatItem.conversation.conversationID}');
if (updatedIds.contains(chatItem.conversation.conversationID)) {
logger.w('找到的chatList的ID:${chatItem.conversation.conversationID}');
final updatedConv = conversationList.firstWhere(
(c) => c.conversationID == chatItem.conversation.conversationID,
orElse: () => V2TimConversation(conversationID: ''),
);
if (updatedConv.conversationID != '' && (updatedConv.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false)) {
// 单独处理陌生人会话
final unread = await ImService.instance.getUnreadMessageCountByFilter(
filter: V2TimConversationFilter(
conversationGroup: ConversationType.noFriend.name,
hasUnreadCount: true,
),
);
chatItem.conversation.lastMessage = updatedConv.lastMessage;
chatItem.conversation.unreadCount = unread.data; // 获取陌生人未读总数
} else {
// 其他类型统一更新处理
logger.w('不需要分组的会话,正常更新');
chatItem.conversation = updatedConv;
update();
}
}
}
// 如果没当前会话列表为空
if (ctl.chatList.isEmpty) {
// 重新获取一次
logger.w('重新获取会话');
ctl.initChatData();
ctl.getConversationList();
}
//重新排序
ctl.chatList.sort((a, b) {
final atime = a.conversation.lastMessage?.timestamp ?? 0;
final btime = b.conversation.lastMessage?.timestamp ?? 0;
return btime.compareTo(atime); // 降序
});
ctl.chatList.refresh();
},
);
// final ctl = Get.find<ChatController>();
// ctl.getConversationList();
_initUnreadCount();
_addListener();
}
// final rr = await ImService.instance.deleteConversationsFromGroup(
// conversationIDList: [cov.conversationID],
// groupName: 'noFriend',
// );
// logger.w(rr.desc);
/// 新建会话时候,根据消息的自定义属性给会话分组
void handleCoverstion(V2TimConversation cov) async {
final message = cov.lastMessage;
final isSelfSend = message!.isSelf; // 是否本人发送的消息
final typeEnum = conversationTypeFromString(message.cloudCustomData); // 会话类型
final needAdd = cov.conversationGroupList!.isEmpty == true; // 当前会话是否已加入了分组中
if (typeEnum != null && needAdd && isSelfSend == false) {
logger.i('当前会话的类型要加入的组是:$typeEnum');
// 当前会话需要进行分组,检测 组 是否存在
final hasGroupRes = await ImService.instance.getConversationGroupList();
if (hasGroupRes.success) {
final exists = hasGroupRes.data?.any((item) => item == typeEnum) ?? false;
if (!exists) {
// 组不存在创建组并把会话加入group中
await ImService.instance.createConversationGroup(
groupName: typeEnum,
conversationIDList: ['c2c_${message.sender}'],
);
logger.i('首次创建会话分组$typeEnum');
} else {
// 分组存在直接添加
await ImService.instance.addConversationsToGroup(
groupName: typeEnum,
conversationIDList: ['c2c_${message.sender}'],
);
logger.i('添加会话分组$typeEnum成功');
}
if (typeEnum == ConversationType.noFriend.name) {
//陌生人分组特殊处理 满足分组条件且已经有分组,
final ctl = Get.find<ChatController>();
// 这个方法执行的逻辑:已有则刷新菜单入口数据,没有则创建菜单入口
ctl.getNoFriendData(csion: cov);
}
}
} else {
logger.w('新会话不需分组');
}
}
/// 初始化时获取一次未读总数
void _initUnreadCount() async {
final res = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getTotalUnreadMessageCount();
if (res.code == 0) {
totalUnread.value = res.data ?? 0;
Get.find<TabBarController>().setBadge(TabType.chat, totalUnread.value);
final to = res.data;
logger.i('初始化未读消息数$to');
} else {
//处理安卓端重新登录后获取未读数量失败的问题
logger.e('获取初始化未读数失败:${res.desc},重新补偿获取');
Future.delayed(Duration(seconds: 1), handAndroid);
}
}
/// 处理安卓端异常的问题
handAndroid() {
_initUnreadCount();
final ctl = Get.find<ChatController>();
ctl.initChatData();
ctl.getConversationList();
}
/// 添加会话未读数监听器
void _addListener() {
TencentImSDKPlugin.v2TIMManager.getConversationManager().addConversationListener(listener: _listener);
logger.i('未读数监听器注册成功');
}
/// 手动更新total
Future<void> refreshUnreadCount() async {
_initUnreadCount();
}
/// 移除监听器,防止重复注册
@override
void onClose() {
logger.i(_listener);
logger.i('移除global未读监听器');
TencentImSDKPlugin.v2TIMManager.getConversationManager().removeConversationListener(listener: _listener);
super.onClose();
}
}