修复群公告发布通知消息正文完全不显示、聊天列表预览显示"undefined"
群公告发布后自动生成的通知消息,真实content是{text:"群公告\n<内容>"}这种
扁平对象(不是纯字符串,也不是标准Drafty的{txt,fmt,ent}结构),且
head['x-im-type']是"text"而不是已处理的"system_notice",落到Drafty处理
分支后既渲染不出气泡正文、列表预览也变成字面的"undefined"字符串。
抽出dispatch.ts里原本只服务system_notice的{text}扁平内容识别逻辑
(重命名为flatTextContentOf并导出),在renderDrafty和
formatMessagePreview的Drafty分支之前都接上——不改变已有的居中系统提示
样式(这条消息本来就该是普通气泡,发送者信息一直是正确的,只是正文
丢了),只是把"文本内容是扁平{text}对象"这一种情况也当作合法纯文本处理。
实测:真实发布一条群公告后,气泡正文和列表预览都正确显示"群公告
全功能测试公告内容",不再是空白或"undefined"。
This commit is contained in:
@@ -18,12 +18,28 @@ export function isRecalled(msg: StoredMessage): boolean {
|
||||
return !isServerDeleted(msg) && msg.content == null;
|
||||
}
|
||||
|
||||
interface SystemNoticeContent {
|
||||
interface FlatTextContent {
|
||||
text: string;
|
||||
}
|
||||
|
||||
function isSystemNoticeContent(content: unknown): content is SystemNoticeContent {
|
||||
return !!content && typeof content === 'object' && typeof (content as SystemNoticeContent).text === 'string';
|
||||
function isFlatTextContent(content: unknown): content is FlatTextContent {
|
||||
return !!content && typeof content === 'object' && typeof (content as FlatTextContent).text === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* `{text: "..."}` -- a flat, non-Drafty content shape (no `txt`/`fmt`/`ent`) this backend uses for
|
||||
* more than one kind of message, not just the centered system-event lines `systemNoticeText` below
|
||||
* renders: a real, live-confirmed example is the auto-posted "群公告\n<announcement text>" message
|
||||
* a group's announcement publish creates, which has an ordinary sender/avatar (NOT a centered system
|
||||
* line) and `head['x-im-type']:"text"` (not `system_notice`) -- but the SAME flat `{text}` content
|
||||
* shape regardless. `renderDrafty`/`formatMessagePreview` both need this recognized as plain text
|
||||
* before falling through to real Drafty processing (`Drafty.format`/`Drafty.preview` on an object
|
||||
* with none of the fields they expect renders empty/`undefined`, confirmed live: a group's own
|
||||
* announcement-notice bubble showed no text at all, and the chat list's preview literally read "我:
|
||||
* undefined").
|
||||
*/
|
||||
export function flatTextContentOf(content: unknown): string | null {
|
||||
return isFlatTextContent(content) ? content.text : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,7 +51,7 @@ function isSystemNoticeContent(content: unknown): content is SystemNoticeContent
|
||||
export function systemNoticeText(msg: StoredMessage): string | null {
|
||||
const headType = msg.head?.['x-im-type'];
|
||||
if (headType !== 'system_notice' && headType !== 'system_action') return null;
|
||||
return isSystemNoticeContent(msg.content) ? msg.content.text : null;
|
||||
return flatTextContentOf(msg.content);
|
||||
}
|
||||
|
||||
export interface ContactCardContent {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Drafty, type DraftyContent } from 'tinode-sdk';
|
||||
|
||||
import { AudioAttachment, FileAttachment, ImageAttachment, VideoAttachment } from '@/features/messages/AttachmentPreview';
|
||||
import { SafeLink } from '@/features/messages/SafeLink';
|
||||
import { flatTextContentOf } from '@/lib/messages/dispatch';
|
||||
|
||||
/**
|
||||
* Bubble content renderer for the Drafty style tags this app currently sends/receives. Grown
|
||||
@@ -124,6 +125,8 @@ function makeFormatNode(highlightQuery: string | undefined) {
|
||||
export function renderDrafty(content: DraftyContent | string | null | undefined, highlightQuery?: string): ReactNode {
|
||||
if (content == null) return null;
|
||||
if (typeof content === 'string') return highlightQuery ? <>{highlightMatches(content, highlightQuery, 'plain')}</> : content;
|
||||
const flatText = flatTextContentOf(content);
|
||||
if (flatText != null) return highlightQuery ? <>{highlightMatches(flatText, highlightQuery, 'plain')}</> : flatText;
|
||||
if (Drafty.isPlainText(content)) {
|
||||
const text = Drafty.toPlainText(content);
|
||||
return highlightQuery ? <>{highlightMatches(text, highlightQuery, 'plain')}</> : text;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Drafty, type DraftyContent, type StoredMessage } from 'tinode-sdk';
|
||||
|
||||
import { callResultDisplay, contactCardContentOf, isServerDeleted, systemNoticeText } from '@/lib/messages/dispatch';
|
||||
import { callResultDisplay, contactCardContentOf, flatTextContentOf, isServerDeleted, systemNoticeText } from '@/lib/messages/dispatch';
|
||||
|
||||
/**
|
||||
* One-line chat-list preview text (README §2.1): plain text renders as-is, everything else falls
|
||||
@@ -26,6 +26,13 @@ export function formatMessagePreview(msg: StoredMessage | undefined, myUserId: s
|
||||
if (contactCardContentOf(msg)) return `${prefix}[名片]`;
|
||||
const callResult = callResultDisplay(msg, msg.from === myUserId);
|
||||
if (callResult) return `${prefix}${callResult.text}`;
|
||||
// Same flat `{text}` shape `systemNoticeText` above already knows about, but NOT gated to
|
||||
// `system_notice`/`system_action` -- a real, live-confirmed example is a group's own
|
||||
// announcement-publish notice (`head['x-im-type']:"text"`, ordinary sender, not a centered system
|
||||
// line), which fell through everything above straight into the Drafty-entity branches below and
|
||||
// produced the literal string "undefined" (confirmed live: chat list showed "我:undefined").
|
||||
const flatText = flatTextContentOf(content);
|
||||
if (flatText != null) return prefix + flatText;
|
||||
if (typeof content === 'string' || Drafty.isPlainText(content)) {
|
||||
return prefix + Drafty.toPlainText(content);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user