feat(web): connect quick share flow

Signed-off-by: JustMe <mr.toing@outlook.com>
This commit is contained in:
justme committed 2026-10-02 00:59:37 +08:00
1 parent 53768a195d
commit e02e024605
138 files changed
+10614

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
import { formatSize, formatTime } from '@/lib/format';
import { useDownload } from '@/features/item/download';
import { InlineContent, inlineKindOf } from '@/features/item/InlineContent';
import { shortDevice, titleOf } from '@/features/item/summary';
import { Tile } from '@/features/item/Tile';
import { useWorkspace } from '@/store/workspace';
import { Button } from '@/ui/Button';
import { CopyButton } from '@/ui/CopyButton';
import styles from './LatestCard.module.css';
interface Props {
id: string;
onOpen: (id: string) => void;
}
/** 手机首屏:最新一项放大,拇指区一键取走 */
export function LatestCard({ id, onOpen }: Props) {
const item = useWorkspace((s) => s.byId[id]);
const device = useWorkspace((s) => s.devices.find((d) => d.id === s.byId[id]?.deviceId)?.name);
const download = useDownload();
if (!item) return null;
const receiving = item.state.kind === 'receiving' ? item.state.progress : null;
const inline = inlineKindOf(item);
const size = item.kind === 'file' ? item.size : new Blob([item.text]).size;
return (
<section className={styles.card} aria-label="最新">
<div className={styles.label}>最新</div>
<button type="button" className={styles.open} onClick={() => onOpen(id)}>
{inline ? null : <Tile item={item} size={56} />}
<span className={styles.text}>
{inline === 'text' ? null : <span className={styles.title}>{titleOf(item)}</span>}
<span className={styles.sub}>
{shortDevice(device)} · {formatTime(item.ts)} · {formatSize(size)}
</span>
</span>
</button>
{inline ? <InlineContent item={item} onOpen={() => onOpen(id)} /> : null}
{receiving !== null ? (
<div className={styles.bar} role="progressbar" aria-valuenow={Math.round(receiving * 100)}>
<div className={styles.fill} style={{ width: `${Math.round(receiving * 100)}%` }} />
</div>
) : (
<div className={styles.actions}>
{item.kind === 'text' ? (
<CopyButton text={item.text} variant="primary" />
) : (
<>
{item.preview !== 'none' ? <Button variant="primary" icon="eye" onClick={() => onOpen(id)}>预览</Button> : null}
<Button variant="primary" icon="download" onClick={() => void download(item)}>下载</Button>
</>
)}
</div>
)}
</section>
);
}