会话数据边缘化处理
This commit is contained in:
parent
0e63d49814
commit
6f11f46706
@ -37,10 +37,15 @@ class ChatController extends GetxController {
|
||||
|
||||
final List<ConversationViewModel> convList = res.data;
|
||||
for (var conv in convList) {
|
||||
logger.w('基本会话: ${conv.conversation.toLogString()}');
|
||||
logger.w('基本会话: ${conv.conversation.toJson()}');
|
||||
}
|
||||
// 去重
|
||||
// 已有会话ID集合
|
||||
final existingIds = chatList.map((e) => e.conversation.conversationID).where((id) => id.isNotEmpty).toSet();
|
||||
// 过滤掉已存在的会话
|
||||
final filtered = convList.where((c) => !existingIds.contains(c.conversation.conversationID)).toList();
|
||||
|
||||
chatList.addAll(convList);
|
||||
chatList.addAll(filtered);
|
||||
// 不包含noFriend才执行加载数据逻辑,分页加载时候过滤
|
||||
final hasNoFriend = chatList.any((item) => item.conversation.conversationGroupList?.contains(myConversationType.ConversationType.noFriend.name) ?? false);
|
||||
logger.e('开始构建陌生人入口是否包含noFriend?:$hasNoFriend');
|
||||
@ -91,16 +96,17 @@ class ChatController extends GetxController {
|
||||
),
|
||||
);
|
||||
if (unread.success) {
|
||||
final conv = convList.first;
|
||||
final faceUrl = 'assets/images/notify/msr.png';
|
||||
conv.showName = '陌生人消息';
|
||||
conv.unreadCount = unread.data;
|
||||
final createItem = ConversationViewModel(
|
||||
conversation: conv,
|
||||
faceUrl: faceUrl,
|
||||
);
|
||||
var viewModelList = await ConversationViewModel.createConversationViewModel(convList: [convList.first]);
|
||||
final conviewModel = viewModelList.first;
|
||||
conviewModel.faceUrl = 'assets/images/notify/msr.png';
|
||||
conviewModel.conversation.showName = '陌生人消息';
|
||||
conviewModel.conversation.unreadCount = unread.data;
|
||||
// final createItem = ConversationViewModel(
|
||||
// conversation: conv,
|
||||
// faceUrl: faceUrl,
|
||||
// );
|
||||
final newList = List<ConversationViewModel>.from(chatList);
|
||||
newList.add(createItem);
|
||||
newList.add(conviewModel);
|
||||
newList.sort((a, b) {
|
||||
final atime = a.conversation.lastMessage?.timestamp ?? 0;
|
||||
final btime = b.conversation.lastMessage?.timestamp ?? 0;
|
||||
|
@ -3,7 +3,9 @@ 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/conversation_view_model.dart';
|
||||
import 'package:loopin/models/tab_type.dart';
|
||||
import 'package:loopin/pages/chat/notify_controller/notify_no_friend_controller.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';
|
||||
@ -31,7 +33,8 @@ class GlobalBadge extends GetxController {
|
||||
},
|
||||
onNewConversation: (List<V2TimConversation> conversationList) {
|
||||
for (var conv in conversationList) {
|
||||
logger.i("新会话创建:${conv.conversationGroupList}");
|
||||
logger.e('新创建会话:${conv.toLogString()}');
|
||||
logger.i("新会话分组类型:${conv.conversationGroupList}");
|
||||
handleCoverstion(conv);
|
||||
}
|
||||
},
|
||||
@ -42,6 +45,8 @@ class GlobalBadge extends GetxController {
|
||||
|
||||
final updatedIds = conversationList.map((e) => e.conversationID).toSet();
|
||||
logger.w('要变更的会话id:$updatedIds');
|
||||
// 收集可能存在后续分页的会话
|
||||
final List<V2TimConversation> willInsert = <V2TimConversation>[];
|
||||
for (int i = 0; i < ctl.chatList.length; i++) {
|
||||
final chatItem = ctl.chatList[i];
|
||||
logger.w('需要更新的ID:${chatItem.conversation.conversationID}');
|
||||
@ -69,8 +74,34 @@ class GlobalBadge extends GetxController {
|
||||
chatItem.conversation = updatedConv;
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
logger.e('会话列表中不包含的会话:$updatedIds');
|
||||
for (var cvID in updatedIds) {
|
||||
// 检测这条会话数据是否存在,如果存在说明在后面的分页中,不存在则是被删除不处理
|
||||
final isReal = await ImService.instance.getConversation(conversationID: cvID);
|
||||
final V2TimConversation realConv = isReal.data;
|
||||
if (isReal.success) {
|
||||
if (realConv.conversationID.isNotEmpty) {
|
||||
// 陌生人会话列表单独处理
|
||||
if (Get.isRegistered<NotifyNoFriendController>()) {
|
||||
final notifyCtl = Get.find<NotifyNoFriendController>();
|
||||
notifyCtl.updateLastMsg(conversation: realConv);
|
||||
} else {
|
||||
// 收集要插入的数据
|
||||
if (realConv.conversationGroupList?.isEmpty ?? false) {
|
||||
willInsert.add(realConv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 添加收集的数据,别忘了分页获取的去重
|
||||
if (willInsert.isNotEmpty) {
|
||||
var viewModelList = await ConversationViewModel.createConversationViewModel(convList: willInsert);
|
||||
ctl.chatList.insertAll(0, viewModelList);
|
||||
}
|
||||
// 如果没当前会话列表为空
|
||||
if (ctl.chatList.isEmpty) {
|
||||
// 重新获取一次
|
||||
|
@ -241,19 +241,20 @@ class ImService {
|
||||
}
|
||||
|
||||
final convList = res.data?.conversationList ?? [];
|
||||
logger.w('未过滤前到会话数据:$convList');
|
||||
|
||||
final userIDList = <String>[];
|
||||
final groupIDList = <String>[];
|
||||
|
||||
// 提前收集所有需要批量查询的 userID 和 groupID
|
||||
for (var conv in convList) {
|
||||
logger.e('未过滤前到会话数据:${conv.toLogString()}');
|
||||
if (conv.userID != null) {
|
||||
userIDList.add(conv.userID!);
|
||||
} else if (conv.groupID != null) {
|
||||
groupIDList.add(conv.groupID!);
|
||||
}
|
||||
}
|
||||
logger.e('用户ID:$userIDList');
|
||||
|
||||
Map<String, String?> userFaceUrlMap = {};
|
||||
Map<String, String?> groupFaceUrlMap = {};
|
||||
@ -268,7 +269,7 @@ class ImService {
|
||||
|
||||
// 读取管理员标识
|
||||
final customInfo = user.customInfo;
|
||||
|
||||
logger.w('自定义信息:${user.toJson()}');
|
||||
if (customInfo != null) {
|
||||
isCustomAdmin[userId] = customInfo['admin'] ?? '0';
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
|
||||
|
||||
class ConversationViewModel {
|
||||
late V2TimConversation conversation;
|
||||
@ -10,4 +12,73 @@ class ConversationViewModel {
|
||||
this.faceUrl,
|
||||
this.isCustomAdmin = '0', // 默认不是管理员
|
||||
});
|
||||
|
||||
static Future<List<ConversationViewModel>> createConversationViewModel({required List<V2TimConversation> convList}) async {
|
||||
final userIDList = <String>[];
|
||||
final groupIDList = <String>[];
|
||||
|
||||
// 提前收集所有需要批量查询的 userID 和 groupID
|
||||
for (var conv in convList) {
|
||||
logger.e('未过滤前到会话数据:${conv.toLogString()}');
|
||||
if (conv.userID != null) {
|
||||
userIDList.add(conv.userID!);
|
||||
} else if (conv.groupID != null) {
|
||||
groupIDList.add(conv.groupID!);
|
||||
}
|
||||
}
|
||||
logger.e('用户ID:$userIDList');
|
||||
|
||||
Map<String, String?> userFaceUrlMap = {};
|
||||
Map<String, String?> groupFaceUrlMap = {};
|
||||
Map<String, String> isCustomAdmin = {};
|
||||
if (userIDList.isNotEmpty) {
|
||||
final userRes = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: userIDList);
|
||||
|
||||
if (userRes.code == 0) {
|
||||
for (var user in userRes.data!) {
|
||||
final userId = user.userID ?? '';
|
||||
userFaceUrlMap[userId] = user.faceUrl;
|
||||
|
||||
// 读取管理员标识
|
||||
final customInfo = user.customInfo;
|
||||
logger.w('自定义信息:${user.toJson()}');
|
||||
if (customInfo != null) {
|
||||
isCustomAdmin[userId] = customInfo['admin'] ?? '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (groupIDList.isNotEmpty) {
|
||||
final groupRes = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getGroupsInfo(groupIDList: groupIDList);
|
||||
if (groupRes.code == 0) {
|
||||
for (var groupResult in groupRes.data!) {
|
||||
final info = groupResult.groupInfo;
|
||||
if (info != null) {
|
||||
groupFaceUrlMap[info.groupID] = info.faceUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final viewList = convList.map((conv) {
|
||||
String? faceUrl = conv.faceUrl;
|
||||
|
||||
if (faceUrl == null || faceUrl.isEmpty) {
|
||||
if (conv.userID != null) {
|
||||
faceUrl = userFaceUrlMap[conv.userID!];
|
||||
} else if (conv.groupID != null) {
|
||||
faceUrl = groupFaceUrlMap[conv.groupID!];
|
||||
}
|
||||
}
|
||||
|
||||
return ConversationViewModel(
|
||||
conversation: conv,
|
||||
faceUrl: faceUrl,
|
||||
isCustomAdmin: isCustomAdmin[conv.userID],
|
||||
);
|
||||
}).toList();
|
||||
|
||||
return viewList;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import 'package:loopin/IM/im_result.dart';
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:loopin/components/preview_video.dart';
|
||||
import 'package:loopin/models/conversation_type.dart';
|
||||
import 'package:loopin/pages/chat/notify_controller/notify_no_friend_controller.dart';
|
||||
import 'package:loopin/utils/snapshot.dart';
|
||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
|
||||
@ -181,9 +182,15 @@ class _ChatNoFriendState extends State<ChatNoFriend> with SingleTickerProviderSt
|
||||
void cleanUnRead() async {
|
||||
if ((arguments.value.unreadCount ?? 0) > 0) {
|
||||
final res = await ImService.instance.clearConversationUnreadCount(conversationID: arguments.value.conversationID);
|
||||
|
||||
if (!res.success) {
|
||||
MyDialog.toast('清理未读异常:${res.desc}', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
|
||||
print('清理未读异常:${res.desc}');
|
||||
}
|
||||
logger.w('清理陌生人会话未读消息,准备刷新消息页的UI,陌生人会话列表的UI');
|
||||
// 是否从未读会话列表而来
|
||||
if (Get.isRegistered<NotifyNoFriendController>()) {
|
||||
final ctl = Get.find<NotifyNoFriendController>();
|
||||
ctl.updateUnread(conversationID: arguments.value.conversationID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import 'package:loopin/components/network_or_asset_image.dart';
|
||||
import 'package:loopin/components/scan_util.dart';
|
||||
import 'package:loopin/models/conversation_type.dart';
|
||||
import 'package:loopin/models/conversation_view_model.dart';
|
||||
import 'package:loopin/utils/index.dart';
|
||||
import 'package:loopin/utils/parse_message_summary.dart';
|
||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||
|
||||
@ -328,7 +329,7 @@ class ChatPageState extends State<ChatPage> {
|
||||
final isNoFriend = chatList[index].conversation.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false;
|
||||
final isAdmin = chatList[index].isCustomAdmin != null && chatList[index].isCustomAdmin != '0';
|
||||
|
||||
logger.e(chatList[index].isCustomAdmin);
|
||||
// logger.e(chatList[index].isCustomAdmin);
|
||||
return Ink(
|
||||
// color: chatList[index]['topMost'] == null ? Colors.white : Colors.grey[100], //置顶颜色
|
||||
child: InkWell(
|
||||
@ -378,9 +379,11 @@ class ChatPageState extends State<ChatPage> {
|
||||
visible: !(isAdmin || isNoFriend),
|
||||
child: Text(
|
||||
// 转成日期字符串显示
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
(chatList[index].conversation.lastMessage!.timestamp ?? 0) * 1000,
|
||||
).toLocal().toString().substring(0, 16), // 简单截取年月日时分
|
||||
// DateTime.fromMillisecondsSinceEpoch(
|
||||
// (chatList[index].conversation.lastMessage!.timestamp ?? 0) * 1000,
|
||||
// ).toLocal().toString().substring(0, 16), // 简单截取年月日时分
|
||||
Utils.formatTime(
|
||||
chatList[index].conversation.lastMessage!.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000),
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 12.0),
|
||||
),
|
||||
),
|
||||
|
@ -1,19 +1,17 @@
|
||||
/// 聊天首页模板
|
||||
library;
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:loopin/behavior/custom_scroll_behavior.dart';
|
||||
import 'package:loopin/components/network_or_asset_image.dart';
|
||||
import 'package:loopin/models/conversation_type.dart';
|
||||
import 'package:loopin/pages/chat/notify_controller/notify_no_friend_controller.dart';
|
||||
import 'package:loopin/styles/index.dart';
|
||||
import 'package:loopin/utils/index.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
|
||||
import 'package:loopin/utils/parse_message_summary.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
|
||||
|
||||
// noFriend, //陌生人消息
|
||||
|
||||
@ -29,10 +27,10 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
|
||||
bool hasMore = true; // 是否还有更多数据
|
||||
final RxBool _throttleFlag = false.obs; // 滚动节流锁
|
||||
final ScrollController chatController = ScrollController();
|
||||
int page = 1;
|
||||
int page = 0;
|
||||
|
||||
///-------------------
|
||||
RxList<V2TimConversation> convList = <V2TimConversation>[].obs;
|
||||
final dataController = Get.put<NotifyNoFriendController>(NotifyNoFriendController());
|
||||
|
||||
RxList demoList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].obs;
|
||||
|
||||
@ -56,27 +54,34 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
logger.e('dispose');
|
||||
Get.delete<NotifyNoFriendController>();
|
||||
chatController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 分页获取全部数据
|
||||
// 分页获取陌生人会话
|
||||
Future<void> getMsgData() async {
|
||||
final res = await ImService.instance.getConversationListByFilter(
|
||||
filter: V2TimConversationFilter(conversationGroup: ConversationType.noFriend.name),
|
||||
nextSeq: page,
|
||||
);
|
||||
logger.i('获取会话数据成功:${res.data!.toJson()}');
|
||||
logger.i('获取会话数据成功:${res.data!.toLogString()}');
|
||||
if (res.success && res.data != null) {
|
||||
final newList = res.data!.conversationList ?? [];
|
||||
// 已有会话ID集合
|
||||
final existingIds = dataController.convList.map((e) => e.conversationID).where((id) => id.isNotEmpty).toSet();
|
||||
// 过滤掉已存在的会话
|
||||
final filtered = newList.where((c) => !existingIds.contains(c.conversationID)).toList();
|
||||
|
||||
final isFinished = res.data!.isFinished ?? true;
|
||||
convList.addAll(newList);
|
||||
dataController.convList.addAll(filtered);
|
||||
if (isFinished) {
|
||||
hasMore = false;
|
||||
// 加载没数据了
|
||||
page = int.parse(res.data!.nextSeq ?? '0');
|
||||
page = 0;
|
||||
} else {
|
||||
page++;
|
||||
page = int.parse(res.data!.nextSeq ?? '0');
|
||||
}
|
||||
logger.i('获取会话数据成功:$newList');
|
||||
} else {
|
||||
@ -106,7 +111,7 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
|
||||
),
|
||||
title: Text(
|
||||
'陌生人消息',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
actions: [],
|
||||
),
|
||||
@ -121,107 +126,88 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
|
||||
displacement: 10.0,
|
||||
onRefresh: handleRefresh,
|
||||
child: Obx(() {
|
||||
// final chatList = controller.chatList;
|
||||
|
||||
return ListView.builder(
|
||||
controller: chatController,
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
// itemCount: convList.length,
|
||||
itemCount: demoList.length,
|
||||
itemCount: dataController.convList.length,
|
||||
itemBuilder: (context, index) {
|
||||
// ----测试数据
|
||||
final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}';
|
||||
final item = jsonDecode(jsonData); // 数据
|
||||
final desc = '测试desc';
|
||||
final cloudCustomData = 'interactionLike';
|
||||
V2TimMessage element = V2TimMessage(elemType: 2, isRead: index > 2 ? true : false);
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
final conv = dataController.convList[index];
|
||||
final isNoFriend = conv.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false;
|
||||
|
||||
return Ink(
|
||||
// color: conv['topMost'] == null ? Colors.white : Colors.grey[100], //置顶颜色
|
||||
child: InkWell(
|
||||
splashColor: Colors.grey[200],
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
|
||||
child: Row(
|
||||
spacing: 10.0,
|
||||
children: <Widget>[
|
||||
// 头像
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
// 点击头像转到对方主页
|
||||
// 先获取视频详情
|
||||
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,
|
||||
//
|
||||
// final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
|
||||
// Get.toNamed('/vloger', arguments: res['data']);
|
||||
Get.toNamed('/vloger');
|
||||
},
|
||||
child: ClipOval(
|
||||
// 头图
|
||||
ClipOval(
|
||||
child: NetworkOrAssetImage(
|
||||
imageUrl: item['faceUrl'],
|
||||
imageUrl: conv.faceUrl,
|
||||
width: 50,
|
||||
height: 50,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 消息
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// 点击头像转到对应的聊天
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
// 昵称
|
||||
Text(
|
||||
item['nickName'] ?? '未知',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
conv.showName ?? '未知',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.normal),
|
||||
),
|
||||
const SizedBox(height: 2.0),
|
||||
// 描述内容
|
||||
Text(
|
||||
maxLines: 2,
|
||||
conv.lastMessage != null ? parseMessageSummary(conv.lastMessage!) : '',
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 13.0),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 12.0),
|
||||
// desc,
|
||||
'很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容',
|
||||
),
|
||||
Text(
|
||||
Utils.formatTime(element.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000),
|
||||
style: TextStyle(
|
||||
color: Colors.grey[600],
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 右侧
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: true,
|
||||
// 视频首图
|
||||
child: NetworkOrAssetImage(
|
||||
imageUrl: item['firstFrameImg'],
|
||||
placeholderAsset: 'assets/images/bk.jpg',
|
||||
width: 40,
|
||||
height: 60,
|
||||
child: Text(
|
||||
// 转成日期字符串显示
|
||||
Utils.formatTime(conv.lastMessage!.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000),
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 12.0),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 5.0),
|
||||
// 角标
|
||||
const SizedBox(height: 5.0),
|
||||
// 数字角标
|
||||
Visibility(
|
||||
visible: !(element.isRead ?? true),
|
||||
child: FStyle.badge(0, isdot: true),
|
||||
visible: (conv.unreadCount ?? 0) > 0,
|
||||
child: FStyle.badge(conv.unreadCount ?? 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
Visibility(
|
||||
visible: false,
|
||||
child: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: Colors.blueGrey,
|
||||
size: 14.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.toNamed('/chatNoFriend', arguments: conv);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -0,0 +1,34 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
|
||||
|
||||
class NotifyNoFriendController extends GetxController {
|
||||
final RxList<V2TimConversation> convList = <V2TimConversation>[].obs;
|
||||
|
||||
void updateUnread({required String conversationID}) {
|
||||
final index = convList.indexWhere((c) => c.conversationID == conversationID);
|
||||
if (index != -1) {
|
||||
final conv = convList[index];
|
||||
convList[index] = conv..unreadCount = 0;
|
||||
} else {
|
||||
logger.e('会话不存在,更新未读失败');
|
||||
}
|
||||
}
|
||||
|
||||
void updateLastMsg({required V2TimConversation conversation}) {
|
||||
final index = convList.indexWhere((c) => c.conversationID == conversation.conversationID);
|
||||
if (index != -1) {
|
||||
convList[index] = conversation;
|
||||
convList.refresh();
|
||||
// convList.value = List.from(convList)..[index] = conversation;
|
||||
} else {
|
||||
// 根据会话id查询会话检测是否存在
|
||||
logger.e('会话不存在,更新会话失败');
|
||||
// 如果存在,说明在后面的分页中,先insert进去 convlist做去重处理
|
||||
}
|
||||
}
|
||||
|
||||
void insertData({required List<V2TimConversation> conversationList}) {
|
||||
convList.insertAll(0, conversationList);
|
||||
}
|
||||
}
|
@ -160,19 +160,33 @@ class Utils {
|
||||
|
||||
// 处理IM消息时间显示
|
||||
static String formatTime(int timestamp) {
|
||||
// 获取消息时间
|
||||
final messageTime = DateTime.fromMillisecondsSinceEpoch(
|
||||
timestamp * 1000,
|
||||
).toLocal();
|
||||
// 获取当前时间
|
||||
// 确保是毫秒级
|
||||
int ms = timestamp.toString().length == 10 ? timestamp * 1000 : timestamp;
|
||||
|
||||
final messageTime = DateTime.fromMillisecondsSinceEpoch(ms).toLocal();
|
||||
final now = DateTime.now();
|
||||
if (messageTime.year == now.year) {
|
||||
// 同一年:显示月-日
|
||||
return '${messageTime.month.toString().padLeft(2, '0')}-${messageTime.day.toString().padLeft(2, '0')}';
|
||||
} else {
|
||||
// 不同年:显示年-月-日 时:分
|
||||
return '${messageTime.year}-${messageTime.month.toString().padLeft(2, '0')}-${messageTime.day.toString().padLeft(2, '0')}';
|
||||
|
||||
bool isSameDay = messageTime.year == now.year && messageTime.month == now.month && messageTime.day == now.day;
|
||||
|
||||
if (isSameDay) {
|
||||
// 同一天:显示时:分
|
||||
return '${messageTime.hour.toString().padLeft(2, '0')}:${messageTime.minute.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
if (messageTime.year == now.year) {
|
||||
// 同一年:显示月-日 时:分
|
||||
return '${messageTime.month.toString().padLeft(2, '0')}-'
|
||||
'${messageTime.day.toString().padLeft(2, '0')} '
|
||||
'${messageTime.hour.toString().padLeft(2, '0')}:'
|
||||
'${messageTime.minute.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
// 不同年:显示完整日期
|
||||
return '${messageTime.year}-'
|
||||
'${messageTime.month.toString().padLeft(2, '0')}-'
|
||||
'${messageTime.day.toString().padLeft(2, '0')} '
|
||||
'${messageTime.hour.toString().padLeft(2, '0')}:'
|
||||
'${messageTime.minute.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
String _formatHourMinute(DateTime dt) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:loopin/IM/push_service.dart';
|
||||
import 'package:loopin/models/notify_message.type.dart';
|
||||
import 'package:loopin/models/summary_type.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
|
||||
@ -52,6 +53,8 @@ String _parseCustomMessage(V2TimMessage? msg) {
|
||||
if (msg == null) return '[null]';
|
||||
final sum = msg.cloudCustomData;
|
||||
final elment = msg.customElem; // 所有服务端发送的通知消息都走【自定义消息类型】
|
||||
logger.w('解析自定义消息:${msg.toJson()}');
|
||||
logger.w('解析element:${elment?.desc ?? 'summary_error'}');
|
||||
try {
|
||||
switch (sum) {
|
||||
case SummaryType.hongbao:
|
||||
|
Loading…
x
Reference in New Issue
Block a user