会话数据边缘化处理

This commit is contained in:
abu 2025-08-27 23:26:29 +08:00
parent 0e63d49814
commit 6f11f46706
10 changed files with 283 additions and 127 deletions

View File

@ -37,10 +37,15 @@ class ChatController extends GetxController {
final List<ConversationViewModel> convList = res.data; final List<ConversationViewModel> convList = res.data;
for (var conv in convList) { 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才执行加载数据逻辑, // noFriend才执行加载数据逻辑,
final hasNoFriend = chatList.any((item) => item.conversation.conversationGroupList?.contains(myConversationType.ConversationType.noFriend.name) ?? false); final hasNoFriend = chatList.any((item) => item.conversation.conversationGroupList?.contains(myConversationType.ConversationType.noFriend.name) ?? false);
logger.e('开始构建陌生人入口是否包含noFriend?$hasNoFriend'); logger.e('开始构建陌生人入口是否包含noFriend?$hasNoFriend');
@ -91,16 +96,17 @@ class ChatController extends GetxController {
), ),
); );
if (unread.success) { if (unread.success) {
final conv = convList.first; var viewModelList = await ConversationViewModel.createConversationViewModel(convList: [convList.first]);
final faceUrl = 'assets/images/notify/msr.png'; final conviewModel = viewModelList.first;
conv.showName = '陌生人消息'; conviewModel.faceUrl = 'assets/images/notify/msr.png';
conv.unreadCount = unread.data; conviewModel.conversation.showName = '陌生人消息';
final createItem = ConversationViewModel( conviewModel.conversation.unreadCount = unread.data;
conversation: conv, // final createItem = ConversationViewModel(
faceUrl: faceUrl, // conversation: conv,
); // faceUrl: faceUrl,
// );
final newList = List<ConversationViewModel>.from(chatList); final newList = List<ConversationViewModel>.from(chatList);
newList.add(createItem); newList.add(conviewModel);
newList.sort((a, b) { newList.sort((a, b) {
final atime = a.conversation.lastMessage?.timestamp ?? 0; final atime = a.conversation.lastMessage?.timestamp ?? 0;
final btime = b.conversation.lastMessage?.timestamp ?? 0; final btime = b.conversation.lastMessage?.timestamp ?? 0;

View File

@ -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/controller/tab_bar_controller.dart';
import 'package:loopin/IM/im_service.dart'; import 'package:loopin/IM/im_service.dart';
import 'package:loopin/models/conversation_type.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/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/enum/V2TimConversationListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.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/models/v2_tim_conversation_filter.dart';
@ -31,7 +33,8 @@ class GlobalBadge extends GetxController {
}, },
onNewConversation: (List<V2TimConversation> conversationList) { onNewConversation: (List<V2TimConversation> conversationList) {
for (var conv in conversationList) { for (var conv in conversationList) {
logger.i("新会话创建:${conv.conversationGroupList}"); logger.e('新创建会话:${conv.toLogString()}');
logger.i("新会话分组类型:${conv.conversationGroupList}");
handleCoverstion(conv); handleCoverstion(conv);
} }
}, },
@ -42,6 +45,8 @@ class GlobalBadge extends GetxController {
final updatedIds = conversationList.map((e) => e.conversationID).toSet(); final updatedIds = conversationList.map((e) => e.conversationID).toSet();
logger.w('要变更的会话id$updatedIds'); logger.w('要变更的会话id$updatedIds');
//
final List<V2TimConversation> willInsert = <V2TimConversation>[];
for (int i = 0; i < ctl.chatList.length; i++) { for (int i = 0; i < ctl.chatList.length; i++) {
final chatItem = ctl.chatList[i]; final chatItem = ctl.chatList[i];
logger.w('需要更新的ID:${chatItem.conversation.conversationID}'); logger.w('需要更新的ID:${chatItem.conversation.conversationID}');
@ -69,8 +74,34 @@ class GlobalBadge extends GetxController {
chatItem.conversation = updatedConv; chatItem.conversation = updatedConv;
update(); 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) { if (ctl.chatList.isEmpty) {
// //

View File

@ -241,19 +241,20 @@ class ImService {
} }
final convList = res.data?.conversationList ?? []; final convList = res.data?.conversationList ?? [];
logger.w('未过滤前到会话数据:$convList');
final userIDList = <String>[]; final userIDList = <String>[];
final groupIDList = <String>[]; final groupIDList = <String>[];
// userID groupID // userID groupID
for (var conv in convList) { for (var conv in convList) {
logger.e('未过滤前到会话数据:${conv.toLogString()}');
if (conv.userID != null) { if (conv.userID != null) {
userIDList.add(conv.userID!); userIDList.add(conv.userID!);
} else if (conv.groupID != null) { } else if (conv.groupID != null) {
groupIDList.add(conv.groupID!); groupIDList.add(conv.groupID!);
} }
} }
logger.e('用户ID$userIDList');
Map<String, String?> userFaceUrlMap = {}; Map<String, String?> userFaceUrlMap = {};
Map<String, String?> groupFaceUrlMap = {}; Map<String, String?> groupFaceUrlMap = {};
@ -268,7 +269,7 @@ class ImService {
// //
final customInfo = user.customInfo; final customInfo = user.customInfo;
logger.w('自定义信息:${user.toJson()}');
if (customInfo != null) { if (customInfo != null) {
isCustomAdmin[userId] = customInfo['admin'] ?? '0'; isCustomAdmin[userId] = customInfo['admin'] ?? '0';
} }

View File

@ -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/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
class ConversationViewModel { class ConversationViewModel {
late V2TimConversation conversation; late V2TimConversation conversation;
@ -10,4 +12,73 @@ class ConversationViewModel {
this.faceUrl, this.faceUrl,
this.isCustomAdmin = '0', // 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;
}
} }

View File

@ -9,6 +9,7 @@ import 'package:loopin/IM/im_result.dart';
import 'package:loopin/IM/im_service.dart'; import 'package:loopin/IM/im_service.dart';
import 'package:loopin/components/preview_video.dart'; import 'package:loopin/components/preview_video.dart';
import 'package:loopin/models/conversation_type.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:loopin/utils/snapshot.dart';
import 'package:shirne_dialog/shirne_dialog.dart'; import 'package:shirne_dialog/shirne_dialog.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.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 { void cleanUnRead() async {
if ((arguments.value.unreadCount ?? 0) > 0) { if ((arguments.value.unreadCount ?? 0) > 0) {
final res = await ImService.instance.clearConversationUnreadCount(conversationID: arguments.value.conversationID); final res = await ImService.instance.clearConversationUnreadCount(conversationID: arguments.value.conversationID);
if (!res.success) { if (!res.success) {
MyDialog.toast('清理未读异常:${res.desc}', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200))); 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);
} }
} }
} }

View File

@ -11,6 +11,7 @@ import 'package:loopin/components/network_or_asset_image.dart';
import 'package:loopin/components/scan_util.dart'; import 'package:loopin/components/scan_util.dart';
import 'package:loopin/models/conversation_type.dart'; import 'package:loopin/models/conversation_type.dart';
import 'package:loopin/models/conversation_view_model.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:loopin/utils/parse_message_summary.dart';
import 'package:shirne_dialog/shirne_dialog.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 isNoFriend = chatList[index].conversation.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false;
final isAdmin = chatList[index].isCustomAdmin != null && chatList[index].isCustomAdmin != '0'; final isAdmin = chatList[index].isCustomAdmin != null && chatList[index].isCustomAdmin != '0';
logger.e(chatList[index].isCustomAdmin); // logger.e(chatList[index].isCustomAdmin);
return Ink( return Ink(
// color: chatList[index]['topMost'] == null ? Colors.white : Colors.grey[100], // // color: chatList[index]['topMost'] == null ? Colors.white : Colors.grey[100], //
child: InkWell( child: InkWell(
@ -378,9 +379,11 @@ class ChatPageState extends State<ChatPage> {
visible: !(isAdmin || isNoFriend), visible: !(isAdmin || isNoFriend),
child: Text( child: Text(
// //
DateTime.fromMillisecondsSinceEpoch( // DateTime.fromMillisecondsSinceEpoch(
(chatList[index].conversation.lastMessage!.timestamp ?? 0) * 1000, // (chatList[index].conversation.lastMessage!.timestamp ?? 0) * 1000,
).toLocal().toString().substring(0, 16), // // ).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), style: const TextStyle(color: Colors.grey, fontSize: 12.0),
), ),
), ),

View File

@ -1,19 +1,17 @@
/// ///
library; library;
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:loopin/IM/im_service.dart'; import 'package:loopin/IM/im_service.dart';
import 'package:loopin/behavior/custom_scroll_behavior.dart'; import 'package:loopin/behavior/custom_scroll_behavior.dart';
import 'package:loopin/components/network_or_asset_image.dart'; import 'package:loopin/components/network_or_asset_image.dart';
import 'package:loopin/models/conversation_type.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/styles/index.dart';
import 'package:loopin/utils/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_conversation_filter.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
// noFriend, // // noFriend, //
@ -29,10 +27,10 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
bool hasMore = true; // bool hasMore = true; //
final RxBool _throttleFlag = false.obs; // final RxBool _throttleFlag = false.obs; //
final ScrollController chatController = ScrollController(); 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; 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 @override
void dispose() { void dispose() {
super.dispose(); logger.e('dispose');
Get.delete<NotifyNoFriendController>();
chatController.dispose(); chatController.dispose();
super.dispose();
} }
// //
Future<void> getMsgData() async { Future<void> getMsgData() async {
final res = await ImService.instance.getConversationListByFilter( final res = await ImService.instance.getConversationListByFilter(
filter: V2TimConversationFilter(conversationGroup: ConversationType.noFriend.name), filter: V2TimConversationFilter(conversationGroup: ConversationType.noFriend.name),
nextSeq: page, nextSeq: page,
); );
logger.i('获取会话数据成功:${res.data!.toJson()}'); logger.i('获取会话数据成功:${res.data!.toLogString()}');
if (res.success && res.data != null) { if (res.success && res.data != null) {
final newList = res.data!.conversationList ?? []; 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; final isFinished = res.data!.isFinished ?? true;
convList.addAll(newList); dataController.convList.addAll(filtered);
if (isFinished) { if (isFinished) {
hasMore = false; hasMore = false;
// //
page = int.parse(res.data!.nextSeq ?? '0'); page = 0;
} else { } else {
page++; page = int.parse(res.data!.nextSeq ?? '0');
} }
logger.i('获取会话数据成功:$newList'); logger.i('获取会话数据成功:$newList');
} else { } else {
@ -106,7 +111,7 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
), ),
title: Text( title: Text(
'陌生人消息', '陌生人消息',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
), ),
actions: [], actions: [],
), ),
@ -121,107 +126,88 @@ class NofriendState extends State<Nofriend> with SingleTickerProviderStateMixin
displacement: 10.0, displacement: 10.0,
onRefresh: handleRefresh, onRefresh: handleRefresh,
child: Obx(() { child: Obx(() {
// final chatList = controller.chatList;
return ListView.builder( return ListView.builder(
controller: chatController,
shrinkWrap: true, shrinkWrap: true,
physics: BouncingScrollPhysics(), physics: BouncingScrollPhysics(),
// itemCount: convList.length, itemCount: dataController.convList.length,
itemCount: demoList.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
// ---- final conv = dataController.convList[index];
final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}'; final isNoFriend = conv.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false;
final item = jsonDecode(jsonData); //
final desc = '测试desc'; return Ink(
final cloudCustomData = 'interactionLike'; // color: conv['topMost'] == null ? Colors.white : Colors.grey[100], //
V2TimMessage element = V2TimMessage(elemType: 2, isRead: index > 2 ? true : false); child: InkWell(
return Container( splashColor: Colors.grey[200],
width: double.infinity, child: Container(
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0), padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
child: Row( child: Row(
spacing: 10.0, spacing: 10.0,
children: <Widget>[ children: <Widget>[
// //
InkWell( ClipOval(
onTap: () async {
//
//
// cloudCustomData是interactionCommentinteractionAtinteractionReply,id
//
// final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
// Get.toNamed('/vloger', arguments: res['data']);
Get.toNamed('/vloger');
},
child: ClipOval(
child: NetworkOrAssetImage( child: NetworkOrAssetImage(
imageUrl: item['faceUrl'], imageUrl: conv.faceUrl,
width: 50, width: 50,
height: 50, height: 50,
), ),
), ),
),
// //
Expanded( Expanded(
child: InkWell(
onTap: () {
//
},
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
//
Text( Text(
item['nickName'] ?? '未知', conv.showName ?? '未知',
style: TextStyle( style: TextStyle(fontSize: 16, fontWeight: FontWeight.normal),
fontSize: 16,
fontWeight: FontWeight.normal,
),
), ),
const SizedBox(height: 2.0), const SizedBox(height: 2.0),
//
Text( Text(
maxLines: 2, conv.lastMessage != null ? parseMessageSummary(conv.lastMessage!) : '',
style: const TextStyle(color: Colors.grey, fontSize: 13.0),
overflow: TextOverflow.ellipsis, 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>[ children: <Widget>[
Visibility( Visibility(
visible: true, visible: true,
// child: Text(
child: NetworkOrAssetImage( //
imageUrl: item['firstFrameImg'], Utils.formatTime(conv.lastMessage!.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000),
placeholderAsset: 'assets/images/bk.jpg', style: const TextStyle(color: Colors.grey, fontSize: 12.0),
width: 40,
height: 60,
), ),
), ),
const SizedBox(width: 5.0), const SizedBox(height: 5.0),
// //
Visibility( Visibility(
visible: !(element.isRead ?? true), visible: (conv.unreadCount ?? 0) > 0,
child: FStyle.badge(0, isdot: true), 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);
},
),
); );
}, },
); );

View File

@ -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);
}
}

View File

@ -160,19 +160,33 @@ class Utils {
// IM消息时间显示 // IM消息时间显示
static String formatTime(int timestamp) { static String formatTime(int timestamp) {
// //
final messageTime = DateTime.fromMillisecondsSinceEpoch( int ms = timestamp.toString().length == 10 ? timestamp * 1000 : timestamp;
timestamp * 1000,
).toLocal(); final messageTime = DateTime.fromMillisecondsSinceEpoch(ms).toLocal();
//
final now = DateTime.now(); final now = DateTime.now();
if (messageTime.year == now.year) {
// - bool isSameDay = messageTime.year == now.year && messageTime.month == now.month && messageTime.day == now.day;
return '${messageTime.month.toString().padLeft(2, '0')}-${messageTime.day.toString().padLeft(2, '0')}';
} else { if (isSameDay) {
// -- : // :
return '${messageTime.year}-${messageTime.month.toString().padLeft(2, '0')}-${messageTime.day.toString().padLeft(2, '0')}'; 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) { String _formatHourMinute(DateTime dt) {

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:loopin/IM/push_service.dart';
import 'package:loopin/models/notify_message.type.dart'; import 'package:loopin/models/notify_message.type.dart';
import 'package:loopin/models/summary_type.dart'; import 'package:loopin/models/summary_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_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]'; if (msg == null) return '[null]';
final sum = msg.cloudCustomData; final sum = msg.cloudCustomData;
final elment = msg.customElem; // final elment = msg.customElem; //
logger.w('解析自定义消息:${msg.toJson()}');
logger.w('解析element${elment?.desc ?? 'summary_error'}');
try { try {
switch (sum) { switch (sum) {
case SummaryType.hongbao: case SummaryType.hongbao: