feat: integrate client and server sharing workflows
This commit is contained in:
1 parent
42b93ae2d8
commit
7406e2fe37
101 files changed
+3153
-253
No files matched your search
@@ -0,0 +1,62 @@
|
||||
|
||||
import { previewKindOf } from '@/lib/fileKind';
|
||||
import type { FileItem } from '../types';
|
||||
import { apiFetch } from './http';
|
||||
import { blobs, getSession } from './sessions';
|
||||
|
||||
|
||||
|
||||
import { stopChannel, connectChannel } from './channelTransport';
|
||||
import { downloadDecrypted } from './transfer';
|
||||
import { publishWorkspace } from './presentation';
|
||||
import { IntegrityError } from '@webdrop/core';
|
||||
|
||||
export function connectChannelResource(id: string): () => void {
|
||||
void connectChannel(id);
|
||||
return () => stopChannel(id);
|
||||
}
|
||||
|
||||
export async function removeChannelItem(resourceId: string, itemId: string): Promise<void> {
|
||||
const { session } = await getSession(resourceId);
|
||||
const role = session.can('owner') ? 'owner' : session.can('write') ? 'write' : 'read';
|
||||
await apiFetch(`/channels/${resourceId}/items/${itemId}`, {
|
||||
method: 'DELETE', headers: session.authHeaders(role),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getChannelBlob(resourceId: string, itemId: string, versionId?: string): Promise<Blob> {
|
||||
if (versionId) throw new Error('此版本暂不可下载');
|
||||
const cached = blobs.get(`${resourceId}:${itemId}`);
|
||||
if (cached) return cached;
|
||||
const { session, resource } = await getSession(resourceId);
|
||||
if (resource.kind !== 'channel') throw new Error('资源类型不匹配');
|
||||
let result: Awaited<ReturnType<typeof downloadDecrypted>>;
|
||||
try { result = await downloadDecrypted(session, resource, itemId); }
|
||||
catch (error) {
|
||||
if (error instanceof IntegrityError) publishWorkspace(resourceId, { t: 'item', item: { id: itemId, kind: 'text', ts: Date.now(), deviceId: '', text: '', state: { kind: 'tampered' } } });
|
||||
throw error;
|
||||
}
|
||||
blobs.set(`${resourceId}:${itemId}`, result.blob);
|
||||
if (result.meta?.kind === 'file') {
|
||||
const item: FileItem = {
|
||||
id: itemId, kind: 'file', ts: result.meta.ts, deviceId: result.meta.dev ?? '未知设备', state: { kind: 'complete' },
|
||||
name: result.meta.name ?? '加密文件', mime: result.meta.mime ?? result.blob.type, size: result.blob.size,
|
||||
remaining: null, preview: 'none', gated: true,
|
||||
};
|
||||
item.preview = previewKindOf(item.mime, item.name);
|
||||
publishWorkspace(resourceId, { t: 'item', item });
|
||||
}
|
||||
return result.blob;
|
||||
}
|
||||
|
||||
export async function resolveTextConflict(): Promise<void> {
|
||||
throw new Error('此条目没有可合并的冲突版本');
|
||||
}
|
||||
|
||||
export async function markChannelSeen(): Promise<void> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function listArchive(_id: string): Promise<never[]> {
|
||||
throw new Error('服务端没有提供压缩包目录接口,可以直接下载。');
|
||||
}
|
||||
Reference in new issue
Block a user