fix: render chat media by URL (images/video/voice) instead of unknown-type placeholder
MessageBubble.vue was keys off the (incomplete) type code, so many messages with real OSS media URLs (https://wx.oss.yunkecn.com/.../*.webp|*.mp4) showed as '[未知消息]'. Rendering is now URL-driven: pick the best http URL from file_url > file_hd_url > file_th_url, then render by extension (image/video/audio/file). Type code is only used as a last-resort label. - MessageBubble.vue: URL-driven cascade (URL by ext → duration → transcription → text → structured-type placeholder → localized tag). Image/video/audio/file children @click.stop so the all-fields drawer still opens on bubble click but not on media interactions. - format.ts: wechatTypeLabel(type_raw) maps known codes (3→图片, 34→语音, 43→图片/表情, 49→文件/名片, 42→名片, 9→表情, 20→红包/转账). - ChatTimeline.vue drawer type tag uses wechatTypeLabel for WeChat msgs. - style.css: compact .yk-msg__audio player for voice-with-URL messages. Verified against smoke.db: 25 type-3 images + 3 type-43 videos that previously showed '[未知消息]' now render as images/video. Build clean. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,38 @@ export function channelLabel(channel?: string | null): string {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// WeChat message type labels
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 中文 label for the upstream WeChat `type_raw` numeric code. The label is
|
||||
* best-effort — different upstream sources disagree on some codes (e.g. 43 is
|
||||
* variously 图片/表情/视频). Rendering is URL-driven (see MessageBubble.vue),
|
||||
* so this label only informs the unknown-fallback bubble and the message
|
||||
* detail drawer tag — never the actual media display.
|
||||
*
|
||||
* WhatsApp type codes (0→文字, 1→图片) are intentionally NOT mapped here:
|
||||
* the structured `type` field already classifies them, and WA media uses a
|
||||
* `mediaName` filename rather than an http URL, so it can't render without the
|
||||
* download endpoint and degrades to a placeholder either way.
|
||||
*/
|
||||
const WECHAT_TYPE_LABELS: Record<number, string> = {
|
||||
3: '图片',
|
||||
34: '语音',
|
||||
42: '名片',
|
||||
43: '图片/表情',
|
||||
49: '文件/名片',
|
||||
9: '表情',
|
||||
20: '红包/转账',
|
||||
}
|
||||
|
||||
/** 中文 label for a WeChat type_raw code; `未知(typeRaw)` when unknown. */
|
||||
export function wechatTypeLabel(typeRaw?: number | null): string {
|
||||
if (typeRaw == null) return '未知'
|
||||
return WECHAT_TYPE_LABELS[typeRaw] ?? `未知(${typeRaw})`
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Phone / voice call rendering
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user