feat(group): 群消息提示中新增姓名高亮显示及点击跳转用户详情功能
This commit is contained in:
parent
e427047752
commit
d4ffbf2165
|
|
@ -30,6 +30,26 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||||
|
|
||||||
|
/// 群提示消息文本片段数据类
|
||||||
|
class TipsTextSegment {
|
||||||
|
final String text;
|
||||||
|
final String? userID;
|
||||||
|
final bool isClickable;
|
||||||
|
|
||||||
|
TipsTextSegment({
|
||||||
|
required this.text,
|
||||||
|
this.userID,
|
||||||
|
required this.isClickable,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 群提示消息富文本数据类
|
||||||
|
class GroupTipsRichTextData {
|
||||||
|
final List<TipsTextSegment> segments;
|
||||||
|
|
||||||
|
GroupTipsRichTextData({required this.segments});
|
||||||
|
}
|
||||||
|
|
||||||
class MessageUtils {
|
class MessageUtils {
|
||||||
// 判断CallingData的方式和Trtc的方法一致
|
// 判断CallingData的方式和Trtc的方法一致
|
||||||
static isCallingData(String data) {
|
static isCallingData(String data) {
|
||||||
|
|
@ -241,6 +261,251 @@ class MessageUtils {
|
||||||
return displayMessage;
|
return displayMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 生成群提示消息的富文本数据,支持点击用户名跳转
|
||||||
|
static Future<GroupTipsRichTextData> groupTipsMessageRichText(
|
||||||
|
V2TimGroupTipsElem groupTipsElem, List<V2TimGroupMemberFullInfo?> groupMemberList) async {
|
||||||
|
final operationType = groupTipsElem.type;
|
||||||
|
final operationMember = groupTipsElem.opMember;
|
||||||
|
final memberList = groupTipsElem.memberList;
|
||||||
|
final opUserNickName = _getOpUserNick(operationMember);
|
||||||
|
|
||||||
|
// 获取当前登录用户ID
|
||||||
|
final currentUserID = (await TencentImSDKPlugin.v2TIMManager.getLoginUser()).data;
|
||||||
|
|
||||||
|
List<TipsTextSegment> segments = [];
|
||||||
|
|
||||||
|
switch (operationType) {
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE:
|
||||||
|
final userName = opUserNickName ?? "";
|
||||||
|
final userID = operationMember?.userID;
|
||||||
|
final isCurrentUser = userID == currentUserID;
|
||||||
|
final displayName = isCurrentUser ? "你" : userName;
|
||||||
|
|
||||||
|
if (userID != null && !isCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: displayName, userID: userID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: displayName, isClickable: false));
|
||||||
|
}
|
||||||
|
|
||||||
|
final groupChangeInfoList = groupTipsElem.groupChangeInfoList ?? [];
|
||||||
|
String changedInfoString = "";
|
||||||
|
bool changedValue = false;
|
||||||
|
for (V2TimGroupChangeInfo? element in groupChangeInfoList) {
|
||||||
|
final newText = await _getGroupChangeType(element!, groupMemberList);
|
||||||
|
changedInfoString += (changedInfoString.isEmpty ? "" : " / ") + newText;
|
||||||
|
changedValue = element!.boolValue ?? false;
|
||||||
|
}
|
||||||
|
if (changedInfoString.isEmpty) {
|
||||||
|
changedInfoString = TIM_t("群资料");
|
||||||
|
}
|
||||||
|
if (changedInfoString == TIM_t("全员禁言状态")) {
|
||||||
|
changedInfoString = TIM_t("全员禁言");
|
||||||
|
segments.add(TipsTextSegment(text: changedValue == false ? " 取消" + changedInfoString : " 开启" + changedInfoString, isClickable: false));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: "修改" + changedInfoString, isClickable: false));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_QUIT:
|
||||||
|
final userName = opUserNickName ?? "";
|
||||||
|
final userID = operationMember?.userID;
|
||||||
|
final isCurrentUser = userID == currentUserID;
|
||||||
|
final displayName = isCurrentUser ? "你" : userName;
|
||||||
|
|
||||||
|
if (userID != null && !isCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: displayName, userID: userID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: displayName, isClickable: false));
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "退出群聊", isClickable: false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_INVITE:
|
||||||
|
final inviteUser = _getOpUserNick(operationMember);
|
||||||
|
final opUserID = operationMember?.userID;
|
||||||
|
final isOpCurrentUser = opUserID == currentUserID;
|
||||||
|
final opDisplayName = isOpCurrentUser ? "你" : (inviteUser ?? "");
|
||||||
|
|
||||||
|
if (opUserID != null && !isOpCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, userID: opUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "邀请", isClickable: false));
|
||||||
|
|
||||||
|
// 添加被邀请的用户
|
||||||
|
for (int i = 0; i < memberList!.length; i++) {
|
||||||
|
final member = memberList[i]!;
|
||||||
|
final memberName = _getMemberNickName(member);
|
||||||
|
final memberUserID = member.userID;
|
||||||
|
final isMemberCurrentUser = memberUserID == currentUserID;
|
||||||
|
final memberDisplayName = isMemberCurrentUser ? "你" : memberName!;
|
||||||
|
|
||||||
|
if (memberUserID != null && !isMemberCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, userID: memberUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
if (i < memberList.length - 1) {
|
||||||
|
segments.add(TipsTextSegment(text: "、", isClickable: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "加入群组", isClickable: false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_KICKED:
|
||||||
|
final kickUser = _getOpUserNick(operationMember);
|
||||||
|
final opUserID = operationMember?.userID;
|
||||||
|
final isOpCurrentUser = opUserID == currentUserID;
|
||||||
|
final opDisplayName = isOpCurrentUser ? "你" : (kickUser ?? "");
|
||||||
|
|
||||||
|
if (opUserID != null && !isOpCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, userID: opUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "将", isClickable: false));
|
||||||
|
|
||||||
|
// 添加被踢的用户
|
||||||
|
for (int i = 0; i < memberList!.length; i++) {
|
||||||
|
final member = memberList[i]!;
|
||||||
|
final memberName = _getMemberNickName(member);
|
||||||
|
final memberUserID = member.userID;
|
||||||
|
final isMemberCurrentUser = memberUserID == currentUserID;
|
||||||
|
final memberDisplayName = isMemberCurrentUser ? "你" : memberName!;
|
||||||
|
|
||||||
|
if (memberUserID != null && !isMemberCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, userID: memberUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
if (i < memberList.length - 1) {
|
||||||
|
segments.add(TipsTextSegment(text: "、", isClickable: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "踢出群组", isClickable: false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_JOIN:
|
||||||
|
segments.add(TipsTextSegment(text: "用户", isClickable: false));
|
||||||
|
// 添加加入的用户
|
||||||
|
for (int i = 0; i < memberList!.length; i++) {
|
||||||
|
final member = memberList[i]!;
|
||||||
|
final memberName = _getMemberNickName(member);
|
||||||
|
final memberUserID = member.userID;
|
||||||
|
final isMemberCurrentUser = memberUserID == currentUserID;
|
||||||
|
final memberDisplayName = isMemberCurrentUser ? "你" : memberName!;
|
||||||
|
|
||||||
|
if (memberUserID != null && !isMemberCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, userID: memberUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
if (i < memberList.length - 1) {
|
||||||
|
segments.add(TipsTextSegment(text: "、", isClickable: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "加入了群聊", isClickable: false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE:
|
||||||
|
for (int i = 0; i < groupTipsElem.memberList!.length; i++) {
|
||||||
|
final member = groupTipsElem.memberList![i]!;
|
||||||
|
final changedMember =
|
||||||
|
groupTipsElem.memberChangeInfoList!.firstWhere((element) => element!.userID == member.userID);
|
||||||
|
final isMute = changedMember!.muteTime != 0;
|
||||||
|
final memberName = _getMemberNickName(member);
|
||||||
|
final memberUserID = member.userID;
|
||||||
|
final isMemberCurrentUser = memberUserID == currentUserID;
|
||||||
|
final memberDisplayName = isMemberCurrentUser ? "你" : memberName!;
|
||||||
|
|
||||||
|
if (memberUserID != null && !isMemberCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, userID: memberUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: " 被" + (isMute ? TIM_t("禁言") : TIM_t("解除禁言")), isClickable: false));
|
||||||
|
if (i < groupTipsElem.memberList!.length - 1) {
|
||||||
|
segments.add(TipsTextSegment(text: "、", isClickable: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_SET_ADMIN:
|
||||||
|
final opMember = _getOpUserNick(operationMember);
|
||||||
|
final opUserID = operationMember?.userID;
|
||||||
|
final isOpCurrentUser = opUserID == currentUserID;
|
||||||
|
final opDisplayName = isOpCurrentUser ? "你" : (opMember ?? "");
|
||||||
|
|
||||||
|
if (opUserID != null && !isOpCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, userID: opUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "将 ", isClickable: false));
|
||||||
|
|
||||||
|
// 添加被设置为管理员的用户
|
||||||
|
for (int i = 0; i < memberList!.length; i++) {
|
||||||
|
final member = memberList[i]!;
|
||||||
|
final memberName = _getMemberNickName(member);
|
||||||
|
final memberUserID = member.userID;
|
||||||
|
final isMemberCurrentUser = memberUserID == currentUserID;
|
||||||
|
final memberDisplayName = isMemberCurrentUser ? "你" : memberName!;
|
||||||
|
|
||||||
|
if (memberUserID != null && !isMemberCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, userID: memberUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
if (i < memberList.length - 1) {
|
||||||
|
segments.add(TipsTextSegment(text: "、", isClickable: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: " 设置为管理员", isClickable: false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_CANCEL_ADMIN:
|
||||||
|
final opMember = _getOpUserNick(operationMember);
|
||||||
|
final opUserID = operationMember?.userID;
|
||||||
|
final isOpCurrentUser = opUserID == currentUserID;
|
||||||
|
final opDisplayName = isOpCurrentUser ? "你" : (opMember ?? "");
|
||||||
|
|
||||||
|
if (opUserID != null && !isOpCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, userID: opUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: opDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: "将 ", isClickable: false));
|
||||||
|
|
||||||
|
// 添加被取消管理员的用户
|
||||||
|
for (int i = 0; i < memberList!.length; i++) {
|
||||||
|
final member = memberList[i]!;
|
||||||
|
final memberName = _getMemberNickName(member);
|
||||||
|
final memberUserID = member.userID;
|
||||||
|
final isMemberCurrentUser = memberUserID == currentUserID;
|
||||||
|
final memberDisplayName = isMemberCurrentUser ? "你" : memberName!;
|
||||||
|
|
||||||
|
if (memberUserID != null && !isMemberCurrentUser) {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, userID: memberUserID, isClickable: true));
|
||||||
|
} else {
|
||||||
|
segments.add(TipsTextSegment(text: memberDisplayName, isClickable: false));
|
||||||
|
}
|
||||||
|
if (i < memberList.length - 1) {
|
||||||
|
segments.add(TipsTextSegment(text: "、", isClickable: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
segments.add(TipsTextSegment(text: " 取消管理员", isClickable: false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
final String option2 = operationType.toString();
|
||||||
|
segments.add(TipsTextSegment(text: TIM_t_para("系统消息 {{option2}}", "系统消息 $option2")(option2: option2), isClickable: false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GroupTipsRichTextData(segments: segments);
|
||||||
|
}
|
||||||
|
|
||||||
static String formatVideoTime(int time) {
|
static String formatVideoTime(int time) {
|
||||||
List<int> times = [];
|
List<int> times = [];
|
||||||
if (time <= 0) return '0:01';
|
if (time <= 0) return '0:01';
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,9 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
/// If provided, the default message action functionality will appear in the right-click context menu instead.
|
/// If provided, the default message action functionality will appear in the right-click context menu instead.
|
||||||
final Widget? Function(V2TimMessage message)? customMessageHoverBarOnDesktop;
|
final Widget? Function(V2TimMessage message)? customMessageHoverBarOnDesktop;
|
||||||
|
|
||||||
|
/// Callback for tapping user names in group tips messages
|
||||||
|
final Function(String userID, int conversationType)? onTapUserName;
|
||||||
|
|
||||||
const TIMUIKitHistoryMessageListItem(
|
const TIMUIKitHistoryMessageListItem(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.message,
|
required this.message,
|
||||||
|
|
@ -312,7 +315,8 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
this.textFieldController,
|
this.textFieldController,
|
||||||
this.onSecondaryTapForOthersPortrait,
|
this.onSecondaryTapForOthersPortrait,
|
||||||
this.groupMemberInfo,
|
this.groupMemberInfo,
|
||||||
this.customMessageHoverBarOnDesktop})
|
this.customMessageHoverBarOnDesktop,
|
||||||
|
this.onTapUserName})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -627,7 +631,9 @@ class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState<TIMUIKitHistory
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.only(bottom: 20),
|
padding: const EdgeInsets.only(bottom: 20),
|
||||||
child: TIMUIKitGroupTipsElem(
|
child: TIMUIKitGroupTipsElem(
|
||||||
groupTipsElem: messageItem.groupTipsElem!, groupMemberList: model.groupMemberList ?? []));
|
groupTipsElem: messageItem.groupTipsElem!,
|
||||||
|
groupMemberList: model.groupMemberList ?? [],
|
||||||
|
onTapUserName: widget.onTapUserName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) {
|
Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) {
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,9 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget {
|
||||||
/// If provided, the default message action functionality will appear in the right-click context menu instead.
|
/// If provided, the default message action functionality will appear in the right-click context menu instead.
|
||||||
final Widget? Function(V2TimMessage message)? customMessageHoverBarOnDesktop;
|
final Widget? Function(V2TimMessage message)? customMessageHoverBarOnDesktop;
|
||||||
|
|
||||||
|
/// Callback for tapping user names in group tips messages
|
||||||
|
final Function(String userID, int conversationType)? onTapUserName;
|
||||||
|
|
||||||
const TIMUIKitHistoryMessageListContainer({
|
const TIMUIKitHistoryMessageListContainer({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.itemBuilder,
|
this.itemBuilder,
|
||||||
|
|
@ -112,6 +115,7 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget {
|
||||||
this.onSecondaryTapAvatar,
|
this.onSecondaryTapAvatar,
|
||||||
this.groupMemberInfo,
|
this.groupMemberInfo,
|
||||||
this.customMessageHoverBarOnDesktop,
|
this.customMessageHoverBarOnDesktop,
|
||||||
|
this.onTapUserName,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -188,7 +192,8 @@ class _TIMUIKitHistoryMessageListContainerState extends TIMUIKitState<TIMUIKitHi
|
||||||
allowAtUserWhenReply: chatConfig.isAtWhenReply,
|
allowAtUserWhenReply: chatConfig.isAtWhenReply,
|
||||||
allowAvatarTap: chatConfig.isAllowClickAvatar,
|
allowAvatarTap: chatConfig.isAllowClickAvatar,
|
||||||
allowLongPress: chatConfig.isAllowLongPressMessage,
|
allowLongPress: chatConfig.isAllowLongPressMessage,
|
||||||
isUseMessageReaction: chatConfig.isUseMessageReaction);
|
isUseMessageReaction: chatConfig.isUseMessageReaction,
|
||||||
|
onTapUserName: widget.onTapUserName);
|
||||||
},
|
},
|
||||||
tongueItemBuilder: widget.tongueItemBuilder,
|
tongueItemBuilder: widget.tongueItemBuilder,
|
||||||
initFindingMsg: widget.initFindingMsg,
|
initFindingMsg: widget.initFindingMsg,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_tips_elem.dart'
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_tips_elem.dart'
|
||||||
|
|
@ -12,8 +13,14 @@ import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||||
class TIMUIKitGroupTipsElem extends StatefulWidget {
|
class TIMUIKitGroupTipsElem extends StatefulWidget {
|
||||||
final V2TimGroupTipsElem groupTipsElem;
|
final V2TimGroupTipsElem groupTipsElem;
|
||||||
final List<V2TimGroupMemberFullInfo?> groupMemberList;
|
final List<V2TimGroupMemberFullInfo?> groupMemberList;
|
||||||
|
final Function(String userID, int conversationType)? onTapUserName;
|
||||||
|
|
||||||
const TIMUIKitGroupTipsElem({Key? key, required this.groupMemberList, required this.groupTipsElem}) : super(key: key);
|
const TIMUIKitGroupTipsElem({
|
||||||
|
Key? key,
|
||||||
|
required this.groupMemberList,
|
||||||
|
required this.groupTipsElem,
|
||||||
|
this.onTapUserName,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<TIMUIKitGroupTipsElem> createState() => _TIMUIKitGroupTipsElemState();
|
State<TIMUIKitGroupTipsElem> createState() => _TIMUIKitGroupTipsElemState();
|
||||||
|
|
@ -21,6 +28,7 @@ class TIMUIKitGroupTipsElem extends StatefulWidget {
|
||||||
|
|
||||||
class _TIMUIKitGroupTipsElemState extends TIMUIKitState<TIMUIKitGroupTipsElem> {
|
class _TIMUIKitGroupTipsElemState extends TIMUIKitState<TIMUIKitGroupTipsElem> {
|
||||||
String groupTipsAbstractText = "";
|
String groupTipsAbstractText = "";
|
||||||
|
GroupTipsRichTextData? richTextData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -30,23 +38,63 @@ class _TIMUIKitGroupTipsElemState extends TIMUIKitState<TIMUIKitGroupTipsElem> {
|
||||||
|
|
||||||
void getText() async {
|
void getText() async {
|
||||||
final newText = await MessageUtils.groupTipsMessageAbstract(widget.groupTipsElem, widget.groupMemberList);
|
final newText = await MessageUtils.groupTipsMessageAbstract(widget.groupTipsElem, widget.groupMemberList);
|
||||||
|
final richData = await MessageUtils.groupTipsMessageRichText(widget.groupTipsElem, widget.groupMemberList);
|
||||||
setState(() {
|
setState(() {
|
||||||
groupTipsAbstractText = newText;
|
groupTipsAbstractText = newText;
|
||||||
|
richTextData = richData;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildRichText(TUITheme theme) {
|
||||||
|
if (richTextData == null || widget.onTapUserName == null) {
|
||||||
|
// 如果没有富文本数据或回调函数,使用原来的简单文本
|
||||||
|
return Text(
|
||||||
|
groupTipsAbstractText,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w400, color: hexToColor("888888")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<TextSpan> spans = richTextData!.segments.map((segment) {
|
||||||
|
if (segment.isClickable && segment.userID != null) {
|
||||||
|
return TextSpan(
|
||||||
|
text: segment.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: const Color(0xFF006CFF), // 蓝色
|
||||||
|
),
|
||||||
|
recognizer: TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
widget.onTapUserName!(segment.userID!, 1); // 1 表示群组对话
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return TextSpan(
|
||||||
|
text: segment.text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: hexToColor("888888"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return RichText(
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
text: TextSpan(children: spans),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||||
final TUITheme theme = value.theme;
|
final TUITheme theme = value.theme;
|
||||||
|
|
||||||
return MessageUtils.wrapMessageTips(
|
return MessageUtils.wrapMessageTips(_buildRichText(theme), theme);
|
||||||
Text(
|
|
||||||
groupTipsAbstractText,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w400, color: hexToColor("888888")),
|
|
||||||
),
|
|
||||||
theme);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,9 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
/// additional network requests to fetch the group member information internally.
|
/// additional network requests to fetch the group member information internally.
|
||||||
List<V2TimGroupMemberFullInfo?>? groupMemberList;
|
List<V2TimGroupMemberFullInfo?>? groupMemberList;
|
||||||
|
|
||||||
|
/// Callback for tapping user names in group tips messages
|
||||||
|
final Function(String userID, int conversationType)? onTapUserName;
|
||||||
|
|
||||||
TIMUIKitChat(
|
TIMUIKitChat(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
this.groupID,
|
this.groupID,
|
||||||
|
|
@ -216,7 +219,8 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
this.customAppBar,
|
this.customAppBar,
|
||||||
this.inputTopBuilder,
|
this.inputTopBuilder,
|
||||||
this.onSecondaryTapAvatar,
|
this.onSecondaryTapAvatar,
|
||||||
this.customMessageHoverBarOnDesktop})
|
this.customMessageHoverBarOnDesktop,
|
||||||
|
this.onTapUserName})
|
||||||
: super(key: key) {
|
: super(key: key) {
|
||||||
startTime = DateTime.now().millisecondsSinceEpoch;
|
startTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
}
|
}
|
||||||
|
|
@ -536,6 +540,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
showNickName: widget.showNickName,
|
showNickName: widget.showNickName,
|
||||||
messageItemBuilder: widget.messageItemBuilder,
|
messageItemBuilder: widget.messageItemBuilder,
|
||||||
conversationID: _getConvID(),
|
conversationID: _getConvID(),
|
||||||
|
onTapUserName: widget.onTapUserName,
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue