fix:会话列表的最近消息项未对齐;修改群昵称格式验证

This commit is contained in:
Zeew 2025-08-07 10:27:52 +08:00
parent 4cf3be0670
commit 319ed953a7
3 changed files with 143 additions and 51 deletions

View File

@ -173,6 +173,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget {
height: 6, height: 6,
), ),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded(child: _getShowMsgWidget(context)), Expanded(child: _getShowMsgWidget(context)),
if (isDisturb) if (isDisturb)

View File

@ -90,15 +90,20 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
final isAdminRevoke = revokeStatus.$2; final isAdminRevoke = revokeStatus.$2;
if (isRevokedMessage) { if (isRevokedMessage) {
final isSelf = widget.lastMsg!.isSelf ?? true; final isSelf = widget.lastMsg!.isSelf ?? true;
final option1 = final option1 = isAdminRevoke
isAdminRevoke ? TIM_t("管理员") : (isSelf ? TIM_t("") : widget.lastMsg!.nickName ?? widget.lastMsg?.sender); ? TIM_t("管理员")
: (isSelf
? TIM_t("")
: widget.lastMsg!.nickName ?? widget.lastMsg?.sender);
if (mounted) { if (mounted) {
setState(() { setState(() {
groupTipsAbstractText = TIM_t_para("{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1); groupTipsAbstractText = TIM_t_para(
"{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1);
}); });
} }
} else { } else {
String msgShowText = await _getLastMsgShowText(widget.lastMsg, widget.context) ?? ""; String msgShowText =
await _getLastMsgShowText(widget.lastMsg, widget.context) ?? "";
if (mounted) { if (mounted) {
setState(() { setState(() {
groupTipsAbstractText = msgShowText; groupTipsAbstractText = msgShowText;
@ -110,14 +115,16 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
String _getDisturbUnreadCountInfo() { String _getDisturbUnreadCountInfo() {
if (widget.isDisturb && widget.unreadCount > 0) { if (widget.isDisturb && widget.unreadCount > 0) {
final option1 = widget.unreadCount.toString(); final option1 = widget.unreadCount.toString();
String unreadCountText = TIM_t_para("[{{option1}} 条]", "[$option1 条]")(option1: option1); String unreadCountText =
TIM_t_para("[{{option1}}条] ", "[$option1 条]")(option1: option1);
return unreadCountText; return unreadCountText;
} }
return ""; return "";
} }
Future<String?> _getLastMsgShowText(V2TimMessage? message, BuildContext context) async { Future<String?> _getLastMsgShowText(
V2TimMessage? message, BuildContext context) async {
final msgType = message!.elemType; final msgType = message!.elemType;
switch (msgType) { switch (msgType) {
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM: case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
@ -130,9 +137,11 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
return TIM_t("[表情]"); return TIM_t("[表情]");
case MessageElemType.V2TIM_ELEM_TYPE_FILE: case MessageElemType.V2TIM_ELEM_TYPE_FILE:
final option1 = widget.lastMsg!.fileElem!.fileName; final option1 = widget.lastMsg!.fileElem!.fileName;
return TIM_t_para("[文件] {{option1}}", "[文件] $option1")(option1: option1); return TIM_t_para("[文件] {{option1}}", "[文件] $option1")(
option1: option1);
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS: case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
return await MessageUtils.groupTipsMessageAbstract(widget.lastMsg!.groupTipsElem!, []); return await MessageUtils.groupTipsMessageAbstract(
widget.lastMsg!.groupTipsElem!, []);
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE: case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
return TIM_t("[图片]"); return TIM_t("[图片]");
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO: case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
@ -194,49 +203,91 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final isDesktopScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
final TUITheme theme = value.theme; final TUITheme theme = value.theme;
final icon = _getIconByMsgStatus(context); final icon = _getIconByMsgStatus(context);
String disturbUnreadCountInfo = _getDisturbUnreadCountInfo(); String disturbUnreadCountInfo = _getDisturbUnreadCountInfo();
return Row(children: [ return Row(
if (icon != null) crossAxisAlignment: CrossAxisAlignment.center,
Container( children: [
margin: const EdgeInsets.only(right: 2), if (icon != null)
child: icon, Container(
), margin: const EdgeInsets.only(right: 2),
if (widget.groupAtInfoList.isNotEmpty) child: icon,
Text(_getAtMessage(), style: TextStyle(color: theme.cautionColor, fontSize: widget.fontSize)), ),
if (widget.draftText != null && widget.draftText != "") if (widget.groupAtInfoList.isNotEmpty)
Text(_getDraftShowText(), Baseline(
style: TextStyle(color: theme.conversationItemDraftTextColor, fontSize: widget.fontSize)), baseline: widget.fontSize,
if (disturbUnreadCountInfo != "") baselineType: TextBaseline.alphabetic,
Text(disturbUnreadCountInfo, style: TextStyle(color: theme.weakTextColor, fontSize: widget.fontSize)), child: Text(_getAtMessage(),
if (widget.draftText != null && widget.draftText != "") style: TextStyle(
Expanded( color: theme.cautionColor,
child: ExtendedText(groupTipsAbstractText, fontSize: widget.fontSize,
softWrap: true, height: 1.0)),
maxLines: 1, ),
overflow: TextOverflow.ellipsis, if (widget.draftText != null && widget.draftText != "")
style: TextStyle(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize), Baseline(
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( baseline: widget.fontSize,
isUseQQPackage: true, baselineType: TextBaseline.alphabetic,
isUseTencentCloudChatPackage: true, child: Text(_getDraftShowText(),
showAtBackground: true, style: TextStyle(
)), color: theme.conversationItemDraftTextColor,
), fontSize: widget.fontSize,
if (widget.draftText == null || widget.draftText == "" && TencentUtils.checkString(groupTipsAbstractText) != null) height: 1.0)),
Expanded( ),
child: ExtendedText(groupTipsAbstractText, if (disturbUnreadCountInfo != "")
softWrap: true, Baseline(
maxLines: 1, baseline: widget.fontSize,
overflow: TextOverflow.ellipsis, baselineType: TextBaseline.alphabetic,
style: TextStyle(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize), child: Text(disturbUnreadCountInfo,
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( style: TextStyle(
isUseQQPackage: true, color: theme.weakTextColor,
isUseTencentCloudChatPackage: true, fontSize: widget.fontSize,
showAtBackground: true, height: 1.0)),
)), ),
) if (widget.draftText != null && widget.draftText != "")
]); Expanded(
child: Baseline(
baseline: widget.fontSize,
baselineType: TextBaseline.alphabetic,
child: ExtendedText(groupTipsAbstractText,
softWrap: true,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: theme.weakTextColor,
fontSize: widget.fontSize,
height: 1.0),
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
isUseQQPackage: true,
isUseTencentCloudChatPackage: true,
showAtBackground: true,
)),
),
),
if (widget.draftText == null ||
widget.draftText == "" &&
TencentUtils.checkString(groupTipsAbstractText) != null)
Expanded(
child: Baseline(
baseline: widget.fontSize,
baselineType: TextBaseline.alphabetic,
child: ExtendedText(groupTipsAbstractText,
softWrap: true,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: theme.weakTextColor,
fontSize: widget.fontSize,
height: 1.0),
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
isUseQQPackage: true,
isUseTencentCloudChatPackage: true,
showAtBackground: true,
)),
),
)
]);
} }
} }

View File

@ -52,7 +52,18 @@ class GroupProfileNameCardState extends TIMUIKitState<GroupProfileNameCard>{
tips: TIM_t("仅限中文、字母、数字和下划线2-20个字"), tips: TIM_t("仅限中文、字母、数字和下划线2-20个字"),
onSubmitted: (String nameCard) async { onSubmitted: (String nameCard) async {
final text = nameCard.trim(); final text = nameCard.trim();
model.setNameCard(text); //
if (_validateNameCard(text)) {
model.setNameCard(text);
} else {
//
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(TIM_t("仅限中文、字母、数字和下划线2-20个字")),
backgroundColor: Colors.red,
),
);
}
}, },
theme: theme); theme: theme);
} }
@ -104,7 +115,19 @@ class GroupProfileNameCardState extends TIMUIKitState<GroupProfileNameCard>{
controller: controller, controller: controller,
maxLines: 1, maxLines: 1,
onSubmitted: (text) { onSubmitted: (text) {
model.setNameCard(text.trim()); final trimmedText = text.trim();
//
if (_validateNameCard(trimmedText)) {
model.setNameCard(trimmedText);
} else {
//
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(TIM_t("仅限中文、字母、数字和下划线2-20个字")),
backgroundColor: Colors.red,
),
);
}
}, },
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
autofocus: true, autofocus: true,
@ -142,4 +165,21 @@ class GroupProfileNameCardState extends TIMUIKitState<GroupProfileNameCard>{
), ),
); );
} }
///
/// 线2-20
bool _validateNameCard(String text) {
if (text.isEmpty) {
return false;
}
// 2-20
if (text.length < 2 || text.length > 20) {
return false;
}
// 线
final RegExp regex = RegExp(r'^[\u4e00-\u9fa5a-zA-Z0-9_]+$');
return regex.hasMatch(text);
}
} }