54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import { createContext, useContext } from 'react';
|
|
import type { ArchiveEntry, Item } from '@/core-bridge/types';
|
|
import { useShareSession } from '@/store/shareSession';
|
|
import { useWorkspace } from '@/store/workspace';
|
|
|
|
export interface ItemActions {
|
|
markSeen: (id: string) => Promise<void>;
|
|
editText: (id: string, text: string) => Promise<void>;
|
|
resolveConflict: (id: string, choice: 'mine' | 'theirs') => Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* 条目组件(行、详情、预览)的数据来源。频道和便捷分享各自提供自己的,
|
|
* 这样条目组件不依赖任何一个 store,两边也不会互相牵连。
|
|
*/
|
|
export interface ItemSource {
|
|
useItem: (id: string) => Item | undefined;
|
|
/** 返回「设备 id → 名字」的函数 */
|
|
useDeviceNamer: () => (deviceId: string | undefined) => string | undefined;
|
|
getBlob: (id: string, versionId?: string) => Promise<Blob>;
|
|
listArchive: (id: string) => Promise<ArchiveEntry[]>;
|
|
/** 只有频道有:分享是只读的 */
|
|
actions?: ItemActions;
|
|
}
|
|
|
|
export const channelSource: ItemSource = {
|
|
useItem: (id) => useWorkspace((s) => s.byId[id]),
|
|
useDeviceNamer: () => {
|
|
const devices = useWorkspace((s) => s.devices);
|
|
return (deviceId) => devices.find((d) => d.id === deviceId)?.name;
|
|
},
|
|
getBlob: (id, versionId) => useWorkspace.getState().getBlob(id, versionId),
|
|
listArchive: (id) => useWorkspace.getState().listArchive(id),
|
|
actions: {
|
|
markSeen: (id) => useWorkspace.getState().markSeen(id),
|
|
editText: (id, text) => useWorkspace.getState().editText(id, text),
|
|
resolveConflict: (id, choice) => useWorkspace.getState().resolveConflict(id, choice),
|
|
},
|
|
};
|
|
|
|
export const shareSource: ItemSource = {
|
|
useItem: (id) => useShareSession((s) => s.byId[id]),
|
|
// 分享里没有「设备」的概念,内容都来自创建者
|
|
useDeviceNamer: () => () => '创建者',
|
|
getBlob: (id) => useShareSession.getState().getBlob(id),
|
|
listArchive: (id) => useShareSession.getState().listArchive(id),
|
|
};
|
|
|
|
export const ItemSourceContext = createContext<ItemSource>(channelSource);
|
|
|
|
export function useItemSource(): ItemSource {
|
|
return useContext(ItemSourceContext);
|
|
}
|