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,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(child: _getShowMsgWidget(context)),
if (isDisturb)

View File

@ -90,15 +90,20 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
final isAdminRevoke = revokeStatus.$2;
if (isRevokedMessage) {
final isSelf = widget.lastMsg!.isSelf ?? true;
final option1 =
isAdminRevoke ? TIM_t("管理员") : (isSelf ? TIM_t("") : widget.lastMsg!.nickName ?? widget.lastMsg?.sender);
final option1 = isAdminRevoke
? TIM_t("管理员")
: (isSelf
? TIM_t("")
: widget.lastMsg!.nickName ?? widget.lastMsg?.sender);
if (mounted) {
setState(() {
groupTipsAbstractText = TIM_t_para("{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1);
groupTipsAbstractText = TIM_t_para(
"{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1);
});
}
} else {
String msgShowText = await _getLastMsgShowText(widget.lastMsg, widget.context) ?? "";
String msgShowText =
await _getLastMsgShowText(widget.lastMsg, widget.context) ?? "";
if (mounted) {
setState(() {
groupTipsAbstractText = msgShowText;
@ -110,14 +115,16 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
String _getDisturbUnreadCountInfo() {
if (widget.isDisturb && widget.unreadCount > 0) {
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 "";
}
Future<String?> _getLastMsgShowText(V2TimMessage? message, BuildContext context) async {
Future<String?> _getLastMsgShowText(
V2TimMessage? message, BuildContext context) async {
final msgType = message!.elemType;
switch (msgType) {
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
@ -130,9 +137,11 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
return TIM_t("[表情]");
case MessageElemType.V2TIM_ELEM_TYPE_FILE:
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:
return await MessageUtils.groupTipsMessageAbstract(widget.lastMsg!.groupTipsElem!, []);
return await MessageUtils.groupTipsMessageAbstract(
widget.lastMsg!.groupTipsElem!, []);
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
return TIM_t("[图片]");
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
@ -194,48 +203,90 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
@override
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 icon = _getIconByMsgStatus(context);
String disturbUnreadCountInfo = _getDisturbUnreadCountInfo();
return Row(children: [
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (icon != null)
Container(
margin: const EdgeInsets.only(right: 2),
child: icon,
),
if (widget.groupAtInfoList.isNotEmpty)
Text(_getAtMessage(), style: TextStyle(color: theme.cautionColor, fontSize: widget.fontSize)),
Baseline(
baseline: widget.fontSize,
baselineType: TextBaseline.alphabetic,
child: Text(_getAtMessage(),
style: TextStyle(
color: theme.cautionColor,
fontSize: widget.fontSize,
height: 1.0)),
),
if (widget.draftText != null && widget.draftText != "")
Text(_getDraftShowText(),
style: TextStyle(color: theme.conversationItemDraftTextColor, fontSize: widget.fontSize)),
Baseline(
baseline: widget.fontSize,
baselineType: TextBaseline.alphabetic,
child: Text(_getDraftShowText(),
style: TextStyle(
color: theme.conversationItemDraftTextColor,
fontSize: widget.fontSize,
height: 1.0)),
),
if (disturbUnreadCountInfo != "")
Text(disturbUnreadCountInfo, style: TextStyle(color: theme.weakTextColor, fontSize: widget.fontSize)),
Baseline(
baseline: widget.fontSize,
baselineType: TextBaseline.alphabetic,
child: Text(disturbUnreadCountInfo,
style: TextStyle(
color: theme.weakTextColor,
fontSize: widget.fontSize,
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(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize),
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)
),
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(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize),
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个字"),
onSubmitted: (String nameCard) async {
final text = nameCard.trim();
//
if (_validateNameCard(text)) {
model.setNameCard(text);
} else {
//
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(TIM_t("仅限中文、字母、数字和下划线2-20个字")),
backgroundColor: Colors.red,
),
);
}
},
theme: theme);
}
@ -104,7 +115,19 @@ class GroupProfileNameCardState extends TIMUIKitState<GroupProfileNameCard>{
controller: controller,
maxLines: 1,
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,
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);
}
}