| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ==================================================================== |
| | | // IM ä¼è¯ / æ¤åå±ç¤º utility |
| | | // ==================================================================== |
| | | // åºäº conversation ä¸ä¸æ + sender ä¿¡æ¯å®æ¶ç®"å±ç¤ºææ¡"ã |
| | | // 1. åé人åä¸å¾ç± utils/user.getSenderDisplayName 宿¶ç®ï¼æ¬æä»¶åªè´è´£æ¼"æ¤å tip / æè¦"çææ¡ã |
| | | // 2. fallbackName ç±è°ç¨æ¹ä¼ å
¥ï¼å
¸åæ¥æºï¼Conversation.lastSenderDisplayName å¿«ç
§ï¼ï¼éä¼ å° getSenderDisplayName å
é¨ï¼ç®ä¸åºçåæ¶å
åº |
| | | // ==================================================================== |
| | | |
| | | import type { Message } from '../home/types' |
| | | |
| | | import { ImContentType, ImConversationType, isFriendChatTip, isGroupNotification, isRtcCallTip } from './constants' |
| | | import { |
| | | type CardMessage, |
| | | type FaceMessage, |
| | | type FileMessage, |
| | | getCardLabelInfo, |
| | | type MaterialMessage, |
| | | parseMessage, |
| | | segmentsToText, |
| | | type TextMessage, |
| | | tipMention, |
| | | type TipSegment, |
| | | tipText |
| | | } from './message' |
| | | import { resolveFriendNotificationText, resolveGroupNotificationText, resolveRtcCallLastContent } from './message' |
| | | import { getSenderDisplayName } from './user' |
| | | |
| | | /** ä¼è¯ä¸»é®ï¼`type-targetId` æ¼æç¨³å®å符串ï¼ç» v-for :keyãactive æ¯å¯¹ãmap key çåºæ¯å
±ç¨ */ |
| | | export function getConversationKey(conversation: { targetId: number; type: number; }): string { |
| | | return `${conversation.type}-${conversation.targetId}` |
| | | } |
| | | |
| | | /** ææµç§°æ¨¡ç³è¿æ»¤ä¼è¯å表ï¼ç©º keyword åæ ·è¿åï¼å½ä¸èµ° toLowerCase ä¸åºå大å°å */ |
| | | export function filterConversationsByKeyword<T extends { name?: string }>( |
| | | list: T[], |
| | | keyword: string |
| | | ): T[] { |
| | | const trimmed = keyword.trim().toLowerCase() |
| | | if (!trimmed) { |
| | | return list |
| | | } |
| | | return list.filter((c) => (c.name || '').toLowerCase().includes(trimmed)) |
| | | } |
| | | |
| | | /** |
| | | * 表æ
æ¶æ¯çç»ä¸ææ¬é¢è§ï¼æè¦ / åå²æç´¢ / å¼ç¨å / 管çåå°é¢è§å
±ç¨ä¸ä»½ |
| | | * æ name æ¶èµ° `[表æ
] name`ï¼ç³»ç»å
ï¼ï¼æ name æ¶èµ° `[表æ
]`ï¼ä¸ªäººè¡¨æ
é常æ nameï¼ |
| | | */ |
| | | export function buildFacePreviewText(facePayload: null | undefined | { name?: string }): string { |
| | | return facePayload?.name ? `[表æ
] ${facePayload.name}` : '[表æ
]' |
| | | } |
| | | |
| | | /** |
| | | * æ¤åæç¤º segments |
| | | * |
| | | * senderId 缺失æ¶ä¸æ mention 段ï¼é¿å
ç¹åºéå·ï¼ç®ä¸åºçåé级为ã对æ¹ãçº¯ææ¬ |
| | | */ |
| | | export function buildRecallTipSegments( |
| | | senderId: number, |
| | | selfSend: boolean, |
| | | conversationType: number, |
| | | conversationTargetId: number, |
| | | fallbackName?: string |
| | | ): TipSegment[] { |
| | | if (selfSend) { |
| | | return [tipText('ä½ æ¤åäºä¸æ¡æ¶æ¯')] |
| | | } |
| | | const senderDisplayName = getSenderDisplayName( |
| | | senderId, |
| | | conversationType, |
| | | conversationTargetId, |
| | | fallbackName |
| | | ) |
| | | if (!senderId) { |
| | | return [tipText(`${senderDisplayName || '对æ¹'} æ¤åäºä¸æ¡æ¶æ¯`)] |
| | | } |
| | | return [ |
| | | tipMention(senderId, senderDisplayName || '对æ¹'), |
| | | tipText(' æ¤åäºä¸æ¡æ¶æ¯') |
| | | ] |
| | | } |
| | | |
| | | /** æ¤åæç¤ºææ¡ï¼èªå·±æ¤ååºå®ææ¡ï¼å¯¹æ¹æ¤å带 sender åï¼å®æ¶ç® + fallbackName å
åºï¼ */ |
| | | export function buildRecallTip( |
| | | senderId: number, |
| | | selfSend: boolean, |
| | | conversationType: number, |
| | | conversationTargetId: number, |
| | | fallbackName?: string |
| | | ): string { |
| | | return segmentsToText( |
| | | buildRecallTipSegments(senderId, selfSend, conversationType, conversationTargetId, fallbackName) |
| | | ) |
| | | } |
| | | |
| | | /** |
| | | * åæ¡æ¶æ¯ççº¯ææ¬æè¦ï¼ä¸ä¾èµ conversation ä¸ä¸æ |
| | | * |
| | | * - withFileName=true æ¶æä»¶æ¶æ¯é带æä»¶åï¼å并转å详æ
ç¨ï¼ |
| | | * - ä¸å¤ç RECALL / 群广æ / 好åéç¥ï¼ç±è°ç¨æ¹å
ä¸å± |
| | | */ |
| | | export function summarizeMessageContent( |
| | | message: Pick<Message, 'content' | 'type'>, |
| | | opts?: { withFileName?: boolean } |
| | | ): string { |
| | | switch (message.type) { |
| | | case ImContentType.CARD: { |
| | | return `[${getCardLabelInfo(parseMessage<CardMessage>(message.content)).label}]` |
| | | } |
| | | case ImContentType.FACE: { |
| | | return buildFacePreviewText(parseMessage<FaceMessage>(message.content)) |
| | | } |
| | | case ImContentType.FILE: { |
| | | if (opts?.withFileName) { |
| | | const file = parseMessage<FileMessage>(message.content) |
| | | return file?.name ? `[æä»¶] ${file.name}` : '[æä»¶]' |
| | | } |
| | | return '[æä»¶]' |
| | | } |
| | | case ImContentType.IMAGE: { |
| | | return '[å¾ç]' |
| | | } |
| | | case ImContentType.MATERIAL: { |
| | | const material = parseMessage<MaterialMessage>(message.content) |
| | | return material?.title ? `[é¢é] ${material.title}` : '[é¢é]' |
| | | } |
| | | case ImContentType.MERGE: { |
| | | return '[è天记å½]' |
| | | } |
| | | case ImContentType.RTC_CALL_END: |
| | | case ImContentType.RTC_CALL_START: { |
| | | return '[è¯é³éè¯]' |
| | | } |
| | | case ImContentType.TEXT: { |
| | | return parseMessage<TextMessage>(message.content)?.content ?? '' |
| | | } |
| | | case ImContentType.VIDEO: { |
| | | return '[è§é¢]' |
| | | } |
| | | case ImContentType.VOICE: { |
| | | return '[è¯é³]' |
| | | } |
| | | default: { |
| | | return '' |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** ä¼è¯å表æå䏿¡æè¦ï¼RECALL èµ° buildRecallTip + fallbackNameï¼å
¶å®æå
å®¹ç±»åæ´¾ç */ |
| | | export function resolveConversationLastContent( |
| | | message: Message, |
| | | conversationType: number, |
| | | conversationTargetId: number, |
| | | fallbackName?: string |
| | | ): string { |
| | | if (message.type === ImContentType.RECALL) { |
| | | return buildRecallTip( |
| | | message.senderId, |
| | | message.selfSend, |
| | | conversationType, |
| | | conversationTargetId, |
| | | fallbackName |
| | | ) |
| | | } |
| | | if (isFriendChatTip(message.type)) { |
| | | return resolveFriendNotificationText(message) |
| | | } |
| | | if (isGroupNotification(message.type)) { |
| | | return resolveGroupNotificationText(message, (id) => |
| | | getSenderDisplayName(id, ImConversationType.GROUP, message.targetId ?? 0) |
| | | ) |
| | | } |
| | | if (isRtcCallTip(message.type)) { |
| | | return resolveRtcCallLastContent(message, conversationType) |
| | | } |
| | | return summarizeMessageContent(message) |
| | | } |