76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import type { ChatMessage } from '@/lib/api';
|
|
|
|
export interface ChatMediaMetadata {
|
|
fileName?: string;
|
|
fileSize?: number;
|
|
durationMs?: number;
|
|
albumId?: string;
|
|
albumIndex?: number;
|
|
albumCount?: number;
|
|
width?: number;
|
|
height?: number;
|
|
sendAsFile?: boolean;
|
|
e2e?: boolean;
|
|
}
|
|
|
|
export function parseChatMediaMetadata(metadataJson?: string): ChatMediaMetadata {
|
|
if (!metadataJson) return {};
|
|
try {
|
|
return JSON.parse(metadataJson) as ChatMediaMetadata;
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
export type ChatDisplayItem =
|
|
| { kind: 'message'; message: ChatMessage }
|
|
| { kind: 'album'; albumId: string; messages: ChatMessage[] };
|
|
|
|
export function groupChatMessagesForDisplay(messages: ChatMessage[]): ChatDisplayItem[] {
|
|
const items: ChatDisplayItem[] = [];
|
|
let index = 0;
|
|
|
|
while (index < messages.length) {
|
|
const message = messages[index]!;
|
|
const meta = parseChatMediaMetadata(message.metadataJson);
|
|
|
|
if (meta.albumId && message.storageKey) {
|
|
const albumMessages: ChatMessage[] = [message];
|
|
let cursor = index + 1;
|
|
while (cursor < messages.length) {
|
|
const next = messages[cursor]!;
|
|
const nextMeta = parseChatMediaMetadata(next.metadataJson);
|
|
if (
|
|
nextMeta.albumId === meta.albumId &&
|
|
next.senderId === message.senderId &&
|
|
next.storageKey
|
|
) {
|
|
albumMessages.push(next);
|
|
cursor += 1;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
albumMessages.sort((left, right) => {
|
|
const leftIndex = parseChatMediaMetadata(left.metadataJson).albumIndex ?? 0;
|
|
const rightIndex = parseChatMediaMetadata(right.metadataJson).albumIndex ?? 0;
|
|
return leftIndex - rightIndex;
|
|
});
|
|
|
|
items.push({ kind: 'album', albumId: meta.albumId, messages: albumMessages });
|
|
index = cursor;
|
|
continue;
|
|
}
|
|
|
|
items.push({ kind: 'message', message });
|
|
index += 1;
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
export function collectChatImageMessages(messages: ChatMessage[]) {
|
|
return messages.filter((message) => message.type === 'IMAGE' && message.storageKey);
|
|
}
|