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

+66
View File
@@ -0,0 +1,66 @@
import type {
ChannelInfo,
ConnectionState,
Device,
Item,
Snapshot,
WorkspaceEvent,
} from '@/core-bridge/types';
export interface WorkspaceData {
ready: boolean;
connection: ConnectionState;
channel: ChannelInfo | null;
devices: Device[];
byId: Record<string, Item>;
/** 新的在前 */
order: string[];
snapshot: Snapshot;
}
export const initialData: WorkspaceData = {
ready: false,
connection: 'offline',
channel: null,
devices: [],
byId: {},
order: [],
snapshot: { text: '', updatedBy: '', updatedAt: 0 },
};
function insertByTime(order: string[], byId: Record<string, Item>, item: Item): string[] {
const at = order.findIndex((id) => (byId[id]?.ts ?? 0) < item.ts);
const next = order.slice();
next.splice(at === -1 ? next.length : at, 0, item.id);
return next;
}
export function reduce(s: WorkspaceData, e: WorkspaceEvent): WorkspaceData {
switch (e.t) {
case 'ready':
return { ...s, ready: true };
case 'connection':
return { ...s, connection: e.state };
case 'channel':
return { ...s, channel: e.info };
case 'devices':
return { ...s, devices: e.devices };
case 'snapshot':
return { ...s, snapshot: e.snapshot };
case 'item': {
const known = e.item.id in s.byId;
const byId = { ...s.byId, [e.item.id]: e.item };
return { ...s, byId, order: known ? s.order : insertByTime(s.order, byId, e.item) };
}
case 'removed': {
if (!(e.id in s.byId)) return s;
const byId = { ...s.byId };
delete byId[e.id];
return { ...s, byId, order: s.order.filter((id) => id !== e.id) };
}
default: {
const exhaustive: never = e;
return exhaustive;
}
}
}