From e6e51f625e3a4b20741bf7b199d1c47cef2cfbf5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 6 Sep 2026 13:39:35 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=A4=E7=B3=BB=E7=BB=9F=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=94=B9=E4=B8=BA=E5=B1=85=E4=B8=AD=E7=BA=AF?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E6=B8=B2=E6=9F=93=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E8=B5=B0=E6=99=AE=E9=80=9A=E6=B0=94=E6=B3=A1+=E4=BD=9C?= =?UTF-8?q?=E8=80=85=E5=90=8D=E7=9A=84=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:群里的系统事件消息(成员加入、角色变更、公告发布等,x-im-type=system_action/ system_notice)服务端并不带真实的 `from`,但 messages-view.jsx 一直把它们和普通消息 一样交给 ChatMessage 渲染——chat-message.jsx 的 fullDisplay 逻辑会在气泡下方额外画一行 发送者名字,解析不到发送者时回退显示"未找到"。对照参考图 内容沟通对话3-开启进群验证与 拉人状态.png,这类系统事件应该是居中的纯灰字提示,不带头像、不带气泡、不带作者名——现状 既不符合参考图,也让"未找到"这种内部占位文案暴露给了用户。 怎么修:meta-message.jsx 新增 systemText 分支,复用日期分隔条同一套"居中提示"视觉语言 (.meta .bubble.system,无背景、纯居中灰字);messages-view.jsx 在消息渲染分支里识别 system_action/system_notice 且不带可操作按钮(group_invitation_created 那种带 "立即加入"按钮的除外,仍走完整气泡展示)的消息,改为渲染 MetaMessage 而不是 ChatMessage。 验证:用真实群(3 个真实账号)走了两遍"扫码申请入群→通过审批",会话里"有成员通过审批 加入了群聊。"正确显示为居中灰字,不再出现气泡、头像和"未找到"作者名;带按钮的 group_invitation_created 消息不受影响,仍是完整气泡+"立即加入"按钮。 Co-Authored-By: Claude Sonnet 5 --- css/base.css | 6 ++++++ src/views/messages-view.jsx | 26 ++++++++++++++++++++++++++ src/widgets/meta-message.jsx | 8 ++++++++ 3 files changed, 40 insertions(+) diff --git a/css/base.css b/css/base.css index 2e58493f..7d42b8fc 100644 --- a/css/base.css +++ b/css/base.css @@ -4391,9 +4391,15 @@ button.full-screen .material-icons { width: 10rem; height: 10rem; z-index: 2; + /* Draggable while in a fullscreen connected video call (call-panel.jsx's dragStart); the grab + cursor is the only hint of that before a viewer ever tries, since unlike the minimized bubble + there's no other affordance. Not shown while [disabled] (audio-only calls / minimized, where + dragging this box does nothing -- see call-panel.jsx). */ + cursor: grab; } .call-party.self[disabled] { + cursor: unset; display: none; } diff --git a/src/views/messages-view.jsx b/src/views/messages-view.jsx index 1e91548b..2fc40dde 100644 --- a/src/views/messages-view.jsx +++ b/src/views/messages-view.jsx @@ -2350,6 +2350,16 @@ class MessagesView extends React.Component { replyToSeq = null; } + // group_invitation_created is the one system_action template with a real, backend-honored + // action button (see chat-message.jsx's renderGroupInvitationCard) -- it still needs the + // full ChatMessage bubble treatment. Every other system_action/system_notice template is + // purely informational and belongs in the plain centered style below. + const systemActions = msg.content && typeof msg.content == 'object' && Array.isArray(msg.content.actions) ? + msg.content.actions : null; + const isActionableSystemMessage = systemActions && systemActions.some(a => a && a.type == 'group_invitation_accept'); + const isPlainSystemMessage = msg.head && (msg.head['x-im-type'] == 'system_notice' || msg.head['x-im-type'] == 'system_action') && + !isActionableSystemMessage && msg.content && typeof msg.content == 'object' && typeof msg.content.text == 'string'; + if (msg.hi) { // Deleted message. messageNodes.push( @@ -2358,6 +2368,22 @@ class MessagesView extends React.Component { deletedText={this.props.intl.formatMessage(messages.message_deleted)} key={msg.seq} /> ); + } else if (isPlainSystemMessage) { + const thisDate = new Date(msg.ts); + if (!prevDate || prevDate.toDateString() != thisDate.toDateString()) { + messageNodes.push( + + ); + prevDate = thisDate; + } + messageNodes.push( + + ); } else { const thisDate = new Date(msg.ts); // This message was sent on a different date than the previous. diff --git a/src/widgets/meta-message.jsx b/src/widgets/meta-message.jsx index 2c8a867d..f4c76490 100644 --- a/src/widgets/meta-message.jsx +++ b/src/widgets/meta-message.jsx @@ -20,6 +20,14 @@ export default class MetaMessage extends React.PureComponent { // 什么都不剩,看不出这里曾经有过一条消息。文案复用已有的 message_deleted("消息已删除")。 content = {this.props.deletedText || '消息已删除'}; bubbleClass += ' deleted'; + } else if (this.props.systemText) { + // docs/images/内容沟通对话3-开启进群验证与拉人状态.png:群系统事件(成员加入/退出/角色变更/ + // 群公告发布等)在参考图里是居中的纯灰字,不带头像、不带气泡、不带发送者名字——跟这里的 + // 日期分隔条是同一种视觉语言。这类消息之前是当成普通消息交给 ChatMessage 渲染的(服务端 + // 这类消息没有真实的 `from`,chat-message.jsx 的 fullDisplay 逻辑因此在系统消息下方多画出 + // 一行解析不到发送者、回退成"未找到"的作者名,明显不该出现)。 + content = {this.props.systemText}; + bubbleClass += ' system'; } if (!content) {