feat(web): connect quick share flow
Signed-off-by: JustMe <mr.toing@outlook.com>
This commit is contained in:
1 parent
53768a195d
commit
e02e024605
138 files changed
+10614
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import { useState } from 'react';
|
||||
import type { ChannelInfo, Share } from '@/core-bridge/types';
|
||||
import { formatAgo, formatRemaining } from '@/lib/format';
|
||||
import { useChannels } from '@/store/channels';
|
||||
import { useShares } from '@/store/shares';
|
||||
import { Button } from '@/ui/Button';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
import styles from './ChannelList.module.css';
|
||||
|
||||
interface Props {
|
||||
kind: 'channel' | 'share';
|
||||
title: string;
|
||||
onOpen: (c: ChannelInfo | Share) => void;
|
||||
}
|
||||
|
||||
export function ChannelList({ kind, title, onOpen }: Props) {
|
||||
const channels = useChannels((s) => s.list);
|
||||
const forgetChannel = useChannels((s) => s.forget);
|
||||
const shares = useShares((s) => s.list);
|
||||
const forgetShare = useShares((s) => s.forget);
|
||||
const list = kind === 'share' ? shares : channels;
|
||||
const [confirmId, setConfirmId] = useState<string>();
|
||||
if (list.length === 0) return null;
|
||||
|
||||
return (
|
||||
<section aria-label={title}>
|
||||
<h2 className={styles.h}>{title}</h2>
|
||||
<ul className={styles.list}>
|
||||
{list.map((c) => (
|
||||
<li key={c.id} className={styles.row}>
|
||||
<button type="button" className={styles.open} onClick={() => onOpen(c)}>
|
||||
<span className={styles.id}>{c.id.slice(0, 8)}…</span>
|
||||
<span className={styles.meta}>
|
||||
{'state' in c ? (
|
||||
<>
|
||||
<span className={styles.enc}><Icon name="lock" size={12} /> 加密</span>
|
||||
<span className={c.state === 'sealed' ? styles.enc : styles.raw}>{c.state === 'sealed' ? '已封存' : '草稿'}</span>
|
||||
<span>{c.mine ? '我创建的' : '收到的'}</span>
|
||||
<span>{formatRemaining(c.createdAt + c.ttlSeconds * 1000)}</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className={c.mode === 'enc' ? styles.enc : styles.raw}>
|
||||
{c.mode === 'enc' ? <><Icon name="lock" size={12} /> 加密</> : '明文'}
|
||||
</span>
|
||||
<span>{c.role === 'owner' ? '所有者' : '成员'}</span>
|
||||
<span>{c.seats} 台设备</span>
|
||||
<span>{formatAgo(c.createdAt)}创建</span>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</button>
|
||||
{confirmId === c.id ? (
|
||||
<span className={styles.confirm}>
|
||||
<Button variant="ghost" onClick={() => { (kind === 'share' ? forgetShare : forgetChannel)(c.id); setConfirmId(undefined); }}>确认移除</Button>
|
||||
<Button variant="ghost" onClick={() => setConfirmId(undefined)}>取消</Button>
|
||||
</span>
|
||||
) : (
|
||||
<Button variant="ghost" icon="trash" label={kind === 'share' ? '从本机移除' : '从本机移除(不会删除频道)'} onClick={() => setConfirmId(c.id)} />
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user