feat: integrate client and server sharing workflows

This commit is contained in:
justme committed 2026-10-02 10:49:45 +08:00
1 parent 42b93ae2d8
commit 7406e2fe37
101 files changed
+3153 -253

No files matched your search

+16 -5
View File
@@ -6,28 +6,32 @@ import type { ParsedChannelLink } from '@/lib/channelLink';
interface ChannelsState {
/** 我的频道(原型:只在内存里,刷新即清空;真实实现存 IndexedDB,architecture §6) */
list: ChannelInfo[];
hydrated: boolean;
/** 从链接进来、还没确认加入的频道;含密钥,只放内存 */
pendingLink: ParsedChannelLink | null;
/** 刚创建的频道:进入时直接展示分享面板与二维码 */
justCreatedId: string | null;
create: (opts: CreateOptions) => Promise<ChannelInfo>;
create: (opts: CreateOptions, captchaToken?: string) => Promise<ChannelInfo>;
join: (link: ParsedChannelLink) => Promise<ChannelInfo>;
forget: (id: string) => void;
hydrate: () => Promise<void>;
forget: (id: string) => Promise<void>;
loadDemo: () => void;
setPendingLink: (link: ParsedChannelLink | null) => void;
clearJustCreated: () => void;
}
const upsert = (list: ChannelInfo[], c: ChannelInfo) => [c, ...list.filter((x) => x.id !== c.id)];
let hydration: Promise<void> | undefined;
export const useChannels = create<ChannelsState>()((set) => ({
list: [],
hydrated: false,
pendingLink: null,
justCreatedId: null,
create: async (opts) => {
const c = await api.createChannel(opts);
create: async (opts, captchaToken) => {
const c = await api.createChannel(opts, captchaToken);
set((s) => ({ list: upsert(s.list, c), justCreatedId: c.id }));
return c;
},
@@ -36,7 +40,14 @@ export const useChannels = create<ChannelsState>()((set) => ({
set((s) => ({ list: upsert(s.list, c), pendingLink: null }));
return c;
},
forget: (id) => set((s) => ({ list: s.list.filter((c) => c.id !== id) })),
hydrate: () => {
hydration ??= api.listSaved().then((list) => set({ list, hydrated: true }), () => set({ hydrated: true }));
return hydration;
},
forget: async (id) => {
await api.forget(id);
set((s) => ({ list: s.list.filter((c) => c.id !== id) }));
},
loadDemo: () => {
const demo = api.loadDemo?.() ?? [];
set((s) => ({ list: demo.reduce(upsert, s.list) }));