import { useState } from 'react'; import { isLocalId, useWorkspace } from '@/store/workspace'; import { useAccount } from '@/store/account'; import { useDownload } from '@/features/item/download'; import { iconOf } from '@/features/item/summary'; import { senderLabel } from '@/lib/sender'; import { formatSize, formatTime, formatTransferProgress } from '@/lib/format'; import { Icon } from '@/ui/Icon'; import { Button } from '@/ui/Button'; import styles from './ChatPane.module.css'; interface Props { id: string; compact?: boolean; onOpenFile: (id: string) => void; onDelete: (id: string) => void } export function ChatMessage({ id, compact = false, onOpenFile, onDelete }: Props) { const item = useWorkspace((s) => s.byId[id]); const owner = useWorkspace((s) => s.channel?.role === 'owner'); const retry = useWorkspace((s) => s.retrySend); const username = useAccount((s) => s.username); const download = useDownload(); const [downloading, setDownloading] = useState(false); if (!item) return null; const sender = item.author; const name = senderLabel(item); const self = sender?.username !== undefined && sender.username === username; const local = isLocalId(id); const sending = local && item.state.kind === 'receiving'; const failed = local && item.state.kind === 'incomplete'; const ready = item.state.kind === 'complete'; const deleteLabel = item.kind === 'file' ? `删除文件消息 ${item.name}` : '删除消息'; async function save() { if (!item || downloading) return; setDownloading(true); try { await download(item); } finally { setDownloading(false); } } return
{compact ? : sender?.avatar ? {`${name} : {Array.from(name)[0] ?? '?'}}
{!compact ?
{name}
: null} {item.state.kind === 'tampered' ?

内容校验失败,已拒绝显示。

: item.kind === 'text' ?

{item.text}

:
} {item.state.kind === 'receiving' && item.kind === 'file' ?
{formatTransferProgress(item.state)}
: failed ? 发送失败。 : item.state.kind === 'incomplete' ? 发送未完成,等待续传。 : null}
{owner || self ?
; }