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) {