tencent_cloud_chat_uikit_fl.../lib/ui/utils/message.dart

363 lines
13 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.

// ignore_for_file: unrelated_type_equality_checks, avoid_print
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
import 'package:tencent_cloud_chat_uikit/ui/constants/time.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/tui_theme.dart';
class MessageUtils {
// 判断CallingData的方式和Trtc的方法一致
static isCallingData(String data) {
try {
Map<String, dynamic> customMap = jsonDecode(data);
if (customMap.containsKey('businessID') && customMap['businessID'] == 1) {
return true;
}
} catch (e) {
print("isCallingData json parse error");
return false;
}
return false;
}
// 是否是群组TRTC信息
static isGroupCallingMessage(V2TimMessage message) {
final isGroup = message.groupID != null;
final isCustomMessage =
message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM;
if (isCustomMessage) {
final customElemData = message.customElem?.data ?? "";
return isCallingData(customElemData) && isGroup;
}
return false;
}
static String _getGroupChangeType(V2TimGroupChangeInfo info) {
int? type = info.type;
var value = info.value;
String s = TIM_t('群资料信息');
switch (type) {
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_CUSTOM:
s = TIM_t("自定义字段");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_FACE_URL:
s = TIM_t("群头像");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_INTRODUCTION:
s = TIM_t("群简介");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_NAME:
s = TIM_t("群名称");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_NOTIFICATION:
s = TIM_t("群公告");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_OWNER:
s = TIM_t("群主");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_SHUT_UP_ALL:
s = TIM_t("全员禁言状态");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_RECEIVE_MESSAGE_OPT:
s = TIM_t("消息接收方式");
break;
case GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_GROUP_ADD_OPT:
s = TIM_t("加群方式");
break;
}
final String option8 = s;
if (value != null && value.isNotEmpty) {
return TIM_t_para("{{option8}}为 ", "$option8为 ")(option8: option8) +
' $value';
} else {
return option8;
}
}
static String? _getOpUserNick(V2TimGroupMemberInfo opUser) {
return opUser.friendRemark == null || opUser.friendRemark == ''
? opUser.nickName == null || opUser.nickName == ''
? opUser.userID
: opUser.nickName
: opUser.friendRemark;
}
static String? _getMemberNickName(V2TimGroupMemberInfo e) {
final friendRemark = e.friendRemark;
final nameCard = e.nameCard;
final nickName = e.nickName;
final userID = e.userID;
if (friendRemark != null && friendRemark != "") {
return friendRemark;
} else if (nameCard != null && nameCard != "") {
return nameCard;
} else if (nickName != null && nickName != "") {
return nickName;
} else {
return userID;
}
}
static String groupTipsMessageAbstract(V2TimGroupTipsElem groupTipsElem) {
String displayMessage;
final operationType = groupTipsElem.type;
final operationMember = groupTipsElem.opMember;
final memberList = groupTipsElem.memberList;
final opUserNickName = _getOpUserNick(operationMember);
switch (operationType) {
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE:
final groupChangeInfoList = groupTipsElem.groupChangeInfoList;
final String? option7 = opUserNickName ?? "";
var changedInfoString =
groupChangeInfoList!.map((e) => _getGroupChangeType(e!)).join("");
if (changedInfoString.isEmpty) {
changedInfoString = TIM_t("群资料");
}
displayMessage =
TIM_t_para("{{option7}}修改", "$option7修改")(option7: option7) +
changedInfoString;
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_QUIT:
final String? option6 = opUserNickName ?? "";
displayMessage =
TIM_t_para("{{option6}}退出群聊", "$option6退出群聊")(option6: option6);
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_INVITE:
final option5 =
memberList!.map((e) => _getMemberNickName(e!).toString()).join("");
final inviteUser = _getOpUserNick(operationMember);
displayMessage = '$inviteUser' +
TIM_t_para("邀请{{option5}}加入群组", "邀请$option5加入群组")(option5: option5);
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_KICKED:
final option4 =
memberList!.map((e) => _getMemberNickName(e!).toString()).join("");
final kickUser = _getOpUserNick(operationMember);
displayMessage = '$kickUser' +
TIM_t_para("将{{option4}}踢出群组", "$option4踢出群组")(option4: option4);
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_JOIN:
final option3 =
memberList!.map((e) => _getMemberNickName(e!).toString()).join("");
displayMessage = TIM_t_para("用户{{option3}}加入了群聊", "用户$option3加入了群聊")(
option3: option3);
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE:
displayMessage = groupTipsElem.memberList!.map((e) {
final changedMember = groupTipsElem.memberChangeInfoList!
.firstWhere((element) => element!.userID == e!.userID);
final isMute = changedMember!.muteTime != 0;
final option2 = _getMemberNickName(e!);
final displayMessage = isMute ? TIM_t("禁言") : TIM_t("解除禁言");
return TIM_t_para("{{option2}} 被", "$option2")(option2: option2) +
displayMessage;
}).join("");
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_SET_ADMIN:
final adminMember =
memberList!.map((e) => _getMemberNickName(e!).toString()).join("");
final opMember = _getOpUserNick(operationMember);
final option1 = adminMember;
displayMessage = '$opMember' +
TIM_t_para("将 {{option1}} 设置为管理员", "$option1 设置为管理员")(
option1: option1);
break;
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_CANCEL_ADMIN:
final adminMember =
memberList!.map((e) => _getMemberNickName(e!).toString()).join("");
final opMember = _getOpUserNick(operationMember);
final option1 = adminMember;
displayMessage = '$opMember' +
TIM_t_para("将 {{option1}} 取消管理员", "$option1 取消管理员")(
option1: option1);
break;
default:
final String option2 = operationType.toString();
displayMessage =
TIM_t_para("系统消息 {{option2}}", "系统消息 $option2")(option2: option2);
break;
}
return displayMessage;
}
static String formatVideoTime(int time) {
List<int> times = [];
if (time <= 0) return '0:01';
if (time >= TimeConst.DAY_SEC) return '1d+';
for (int idx = 0; idx < TimeConst.SEC_SERIES.length; idx++) {
int sec = TimeConst.SEC_SERIES[idx];
if (time >= sec) {
times.add((time / sec).floor());
time = time % sec;
} else if (idx > 0) {
times.add(0);
}
}
times.add(time);
String formatTime = times[0].toString();
for (int idx = 1; idx < times.length; idx++) {
if (times[idx] < 10) {
formatTime += ':0${times[idx].toString()}';
} else {
formatTime += ':${times[idx].toString()}';
}
}
return formatTime;
}
static String handleCustomMessageString(V2TimMessage message) {
final customElem = message.customElem;
final callingMessage = CallingMessage.getCallMessage(customElem);
if (callingMessage != null) {
// 如果是结束消息
final isCallEnd = CallingMessage.isCallEndExist(callingMessage);
String? option2 = "";
if (isCallEnd) {
option2 = CallingMessage.getShowTime(callingMessage.callEnd!);
}
return isCallEnd
? (TIM_t_para("通话时间:{{option2}}", "通话时间:$option2")(option2: option2))
: (CallingMessage.getActionType(callingMessage.actionType!));
} else {
return TIM_t("自定义消息");
}
}
static handleCustomMessage(V2TimMessage message, context) {
// 这个函数应该返回String目前已经切走用不上了但是不敢删QAQ就这么留着吧。
final customElem = message.customElem;
final callingMessage = CallingMessage.getCallMessage(customElem);
if (callingMessage != null) {
// 如果是结束消息
final isCallEnd = CallingMessage.isCallEndExist(callingMessage);
final isVoiceCall = callingMessage.callType == 1;
String? option2 = "";
if (isCallEnd) {
option2 = CallingMessage.getShowTime(callingMessage.callEnd!);
}
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(right: 4),
child: Image.asset(
isVoiceCall ? "images/voice_call.png" : "images/video_call.png",
package: 'tencent_cloud_chat_uikit',
height: 16,
width: 16,
),
),
isCallEnd
? Text(TIM_t_para("通话时间:{{option2}}", "通话时间:$option2")(
option2: option2))
: Text(
CallingMessage.getActionType(callingMessage.actionType!)),
// if (isFromSelf)
// Padding(
// padding: const EdgeInsets.only(left: 4),
// child: Image.asset(
// isVoiceCall
// ? "images/voice_call.png"
// : "images/video_call_self.png",
// package: 'tencent_cloud_chat_uikit',
// height: 16,
// width: 16,
// ),
// ),
],
);
} else {
return const Text("[自定义]");
}
}
static Widget wrapMessageTips(Widget child, TUITheme? theme) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 10), child: child);
}
static String getAbstractMessage(V2TimMessage message) {
final msgType = message.elemType;
switch (msgType) {
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
return handleCustomMessageString(message);
case MessageElemType.V2TIM_ELEM_TYPE_SOUND:
return TIM_t("[语音]");
case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
return message.textElem!.text as String;
case MessageElemType.V2TIM_ELEM_TYPE_FACE:
return TIM_t("[表情]");
case MessageElemType.V2TIM_ELEM_TYPE_FILE:
final String? option2 = message.fileElem!.fileName ?? "";
return TIM_t_para("[文件] {{option2}}", "[文件] $option2")(
option2: option2);
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
return MessageUtils.groupTipsMessageAbstract(message.groupTipsElem!);
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
return TIM_t("[图片]");
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
return TIM_t("[视频]");
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
return TIM_t("[位置]");
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
return TIM_t("[聊天记录]");
default:
return TIM_t("未知消息");
}
}
static V2TimImage? getImageFromImgList(
List<V2TimImage?>? list, List<String> order) {
V2TimImage? img;
try {
for (String type in order) {
img = list?.firstWhere(
(e) =>
e?.type == HistoryMessageDartConstant.V2_TIM_IMAGE_TYPES[type],
orElse: () => null);
}
} catch (e) {
print('getImageFromImgList error ${e.toString()}');
}
return img;
}
static String getDisplayName(V2TimMessage message) {
final friendRemark = message.friendRemark ?? "";
final nameCard = message.nameCard ?? "";
final nickName = message.nickName ?? "";
final sender = message.sender ?? "";
final displayName = friendRemark.isNotEmpty
? friendRemark
: nameCard.isNotEmpty
? nameCard
: nickName.isNotEmpty
? nickName
: sender;
return displayName.toString();
}
static Future<V2TimValueCallback<V2TimMessage>?> handleMessageError(
Future<V2TimValueCallback<V2TimMessage>?> fun,
BuildContext context) async {
final res = await fun;
return handleMessageErrorCode(res, context);
}
static V2TimValueCallback<V2TimMessage>? handleMessageErrorCode(
V2TimValueCallback<V2TimMessage>? sendMsgRes, BuildContext context) {
if (sendMsgRes == null) return null;
return sendMsgRes;
}
}