feat(web): add account workspaces and signed content flows
This commit is contained in:
1 parent
7b8d61d1ba
commit
b5cf3d5958
117 files changed
+2789
-1674
No files matched your search
+16
-46
@@ -18,9 +18,8 @@ export interface WorkspaceData {
|
||||
devices: Device[];
|
||||
threads: ThreadInfo[];
|
||||
groups: ChannelGroupInfo[];
|
||||
threadGroups: Record<string, string | null>;
|
||||
folders: FolderInfo[];
|
||||
locations: Record<string, { threadId: string; folderId?: string }>;
|
||||
locations: Record<string, { threadId: string; folderId?: string; authorAccount?: string }>;
|
||||
byId: Record<string, Item>;
|
||||
authors: Record<string, SenderInfo>;
|
||||
/** 新的在前 */
|
||||
@@ -36,7 +35,6 @@ export const initialData: WorkspaceData = {
|
||||
devices: [],
|
||||
threads: [],
|
||||
groups: [],
|
||||
threadGroups: {},
|
||||
folders: [],
|
||||
locations: {},
|
||||
byId: {},
|
||||
@@ -55,6 +53,20 @@ function insertByTime(order: string[], byId: Record<string, Item>, item: Item):
|
||||
|
||||
export function reduce(s: WorkspaceData, e: WorkspaceEvent): WorkspaceData {
|
||||
switch (e.t) {
|
||||
case 'structure': {
|
||||
const people = new Map(e.people.map(person => [person.username, person]));
|
||||
const locations = Object.fromEntries(e.state.locations.map(location => [location.itemId, { threadId: location.threadId, folderId: location.folderId ?? undefined, authorAccount: location.authorAccount ?? undefined }]));
|
||||
const authors = { ...s.authors };
|
||||
for (const location of e.state.locations) {
|
||||
const person = location.authorAccount ? people.get(location.authorAccount) : undefined;
|
||||
if (person) authors[location.itemId] = { username: person.username, displayName: person.displayName || person.username, avatar: person.avatar ?? undefined };
|
||||
}
|
||||
const byId = Object.fromEntries(Object.entries(s.byId).map(([id, item]) => [id, {
|
||||
...item, ...(locations[id] ?? {}), ...(authors[id] ? { author: authors[id] } : {}),
|
||||
}]));
|
||||
return { ...s, threads: e.state.channels.map(c => ({ ...c, groupId: c.groupId ?? undefined })), groups: e.state.groups,
|
||||
folders: e.state.folders.map(f => ({ ...f, parentId: f.parentId ?? undefined })), locations, authors, byId };
|
||||
}
|
||||
case 'reset':
|
||||
return { ...initialData, connection: s.connection };
|
||||
case 'error':
|
||||
@@ -67,56 +79,14 @@ export function reduce(s: WorkspaceData, e: WorkspaceEvent): WorkspaceData {
|
||||
return { ...s, channel: e.info };
|
||||
case 'devices':
|
||||
return { ...s, devices: e.devices };
|
||||
case 'thread-created': {
|
||||
const thread = { ...e.thread };
|
||||
if (thread.id in s.threadGroups) {
|
||||
const groupId = s.threadGroups[thread.id];
|
||||
if (groupId) thread.groupId = groupId;
|
||||
else delete thread.groupId;
|
||||
}
|
||||
return { ...s, threads: [thread, ...s.threads.filter((entry) => entry.id !== thread.id)] };
|
||||
}
|
||||
case 'thread-renamed':
|
||||
return { ...s, threads: s.threads.map((thread) => thread.id === e.id ? { ...thread, name: e.name } : thread) };
|
||||
case 'group-created':
|
||||
return { ...s, groups: [...s.groups.filter((group) => group.id !== e.group.id), e.group] };
|
||||
case 'group-renamed':
|
||||
return { ...s, groups: s.groups.map((group) => group.id === e.id ? { ...group, name: e.name } : group) };
|
||||
case 'thread-grouped':
|
||||
return { ...s, threadGroups: { ...s.threadGroups, [e.id]: e.groupId ?? null },
|
||||
threads: s.threads.map((thread) => thread.id === e.id ? { ...thread, groupId: e.groupId } : thread) };
|
||||
case 'folder-created':
|
||||
return { ...s, folders: [e.folder, ...s.folders.filter((folder) => folder.id !== e.folder.id)] };
|
||||
case 'folder-renamed':
|
||||
return { ...s, folders: s.folders.map((folder) => folder.id === e.id ? { ...folder, name: e.name } : folder) };
|
||||
case 'items-moved': {
|
||||
const byId = { ...s.byId };
|
||||
const locations = { ...s.locations };
|
||||
for (const id of e.itemIds) {
|
||||
locations[id] = { threadId: e.threadId, ...(e.folderId ? { folderId: e.folderId } : {}) };
|
||||
const item = byId[id];
|
||||
if (!item) continue;
|
||||
if (item.kind === 'file' && item.metadataHidden) continue;
|
||||
const moved = { ...item, threadId: e.threadId };
|
||||
if (e.folderId === undefined) delete moved.folderId;
|
||||
else moved.folderId = e.folderId;
|
||||
byId[id] = moved;
|
||||
}
|
||||
return { ...s, byId, locations };
|
||||
}
|
||||
case 'snapshot':
|
||||
return { ...s, snapshot: e.snapshot };
|
||||
case 'item-author': {
|
||||
const item = s.byId[e.id];
|
||||
return { ...s, authors: { ...s.authors, [e.id]: e.author },
|
||||
byId: item ? { ...s.byId, [e.id]: { ...item, author: e.author } } : s.byId };
|
||||
}
|
||||
case 'file-catalog':
|
||||
case 'item': {
|
||||
const known = e.item.id in s.byId;
|
||||
let item = e.item;
|
||||
const current = s.byId[item.id];
|
||||
const author = item.author ?? s.authors[item.id] ?? current?.author;
|
||||
const author = s.authors[item.id] ?? item.author ?? current?.author;
|
||||
if (author) item = { ...item, author };
|
||||
if (e.t === 'item' && item.kind === 'file' && item.metadataHidden && current?.kind === 'file' && !current.metadataHidden) return s;
|
||||
const location = s.locations[item.id];
|
||||
|
||||
Reference in new issue
Block a user