@powerhousedao/reactor-browser 1.10.2 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +47 -0
- package/dist/src/context/index.d.ts +1 -1
- package/dist/src/context/index.d.ts.map +1 -1
- package/dist/src/context/index.js +1 -0
- package/dist/src/context/read-mode.d.ts +3 -3
- package/dist/src/context/read-mode.d.ts.map +1 -1
- package/dist/src/context/read-mode.js +198 -0
- package/dist/src/crypto/browser.d.ts +1 -1
- package/dist/src/crypto/browser.d.ts.map +1 -1
- package/dist/src/crypto/browser.js +49 -0
- package/dist/src/crypto/index.js +121 -0
- package/dist/src/document-model.d.ts +3 -3
- package/dist/src/document-model.d.ts.map +1 -1
- package/dist/src/document-model.js +5 -0
- package/dist/src/hooks/index.d.ts +9 -5
- package/dist/src/hooks/index.d.ts.map +1 -1
- package/dist/src/hooks/index.js +9 -0
- package/dist/src/hooks/useAddDebouncedOperations.d.ts +3 -3
- package/dist/src/hooks/useAddDebouncedOperations.d.ts.map +1 -1
- package/dist/src/hooks/useAddDebouncedOperations.js +55 -0
- package/dist/src/hooks/useConnectCrypto.d.ts +1 -1
- package/dist/src/hooks/useConnectCrypto.d.ts.map +1 -1
- package/dist/src/hooks/useConnectCrypto.js +40 -0
- package/dist/src/hooks/useDocument.d.ts +3 -3
- package/dist/src/hooks/useDocument.d.ts.map +1 -1
- package/dist/src/hooks/useDocument.js +37 -0
- package/dist/src/hooks/useDocumentDispatch.d.ts +6 -10
- package/dist/src/hooks/useDocumentDispatch.d.ts.map +1 -1
- package/dist/src/hooks/useDocumentDispatch.js +41 -0
- package/dist/src/hooks/useDocumentDrives.d.ts +4 -3
- package/dist/src/hooks/useDocumentDrives.d.ts.map +1 -1
- package/dist/src/hooks/useDocumentDrives.js +84 -0
- package/dist/src/hooks/useDocumentEditor.d.ts +13 -13
- package/dist/src/hooks/useDocumentEditor.d.ts.map +1 -1
- package/dist/src/hooks/useDocumentEditor.js +30 -0
- package/dist/src/hooks/useDriveActions.d.ts +82 -0
- package/dist/src/hooks/useDriveActions.d.ts.map +1 -0
- package/dist/src/hooks/useDriveActions.js +125 -0
- package/dist/src/hooks/useDriveActionsWithUiNodes.d.ts +17 -0
- package/dist/src/hooks/useDriveActionsWithUiNodes.d.ts.map +1 -0
- package/dist/src/hooks/useDriveActionsWithUiNodes.js +71 -0
- package/dist/src/hooks/useDriveContext.d.ts +66 -0
- package/dist/src/hooks/useDriveContext.d.ts.map +1 -0
- package/dist/src/hooks/useDriveContext.js +25 -0
- package/dist/src/hooks/useUiNodesContext.d.ts +25 -0
- package/dist/src/hooks/useUiNodesContext.d.ts.map +1 -0
- package/dist/src/hooks/useUiNodesContext.js +167 -0
- package/dist/src/hooks/useUserPermissions.js +6 -0
- package/dist/src/index.d.ts +5 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/reactor.d.ts +3 -3
- package/dist/src/reactor.d.ts.map +1 -1
- package/dist/src/reactor.js +54 -0
- package/dist/src/renown/constants.js +39 -0
- package/dist/src/renown/types.d.ts +3 -3
- package/dist/src/renown/types.d.ts.map +1 -1
- package/dist/src/renown/types.js +1 -0
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.d.ts.map +1 -1
- package/dist/src/storage/index.js +1 -0
- package/dist/src/storage/types.js +1 -0
- package/dist/src/uiNodes/constants.d.ts +17 -0
- package/dist/src/uiNodes/constants.d.ts.map +1 -0
- package/dist/src/uiNodes/constants.js +23 -0
- package/dist/src/uiNodes/types.d.ts +61 -0
- package/dist/src/uiNodes/types.d.ts.map +1 -0
- package/dist/src/uiNodes/types.js +1 -0
- package/dist/src/utils/index.d.ts +3 -3
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +8 -0
- package/dist/src/utils/signature.d.ts +3 -3
- package/dist/src/utils/signature.d.ts.map +1 -1
- package/dist/src/utils/signature.js +39 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +15 -22
- package/dist/_virtual/__vite-browser-external.js +0 -5
- package/dist/_virtual/__vite-browser-external.js.map +0 -1
- package/dist/context/read-mode.js +0 -159
- package/dist/context/read-mode.js.map +0 -1
- package/dist/crypto/browser.js +0 -50
- package/dist/crypto/browser.js.map +0 -1
- package/dist/crypto/index.js +0 -109
- package/dist/crypto/index.js.map +0 -1
- package/dist/document-model.js +0 -11
- package/dist/document-model.js.map +0 -1
- package/dist/hooks/useAddDebouncedOperations.js +0 -54
- package/dist/hooks/useAddDebouncedOperations.js.map +0 -1
- package/dist/hooks/useConnectCrypto.js +0 -34
- package/dist/hooks/useConnectCrypto.js.map +0 -1
- package/dist/hooks/useDocument.js +0 -20
- package/dist/hooks/useDocument.js.map +0 -1
- package/dist/hooks/useDocumentDispatch.js +0 -30
- package/dist/hooks/useDocumentDispatch.js.map +0 -1
- package/dist/hooks/useDocumentDrives.js +0 -86
- package/dist/hooks/useDocumentDrives.js.map +0 -1
- package/dist/hooks/useDocumentEditor.js +0 -46
- package/dist/hooks/useDocumentEditor.js.map +0 -1
- package/dist/hooks/useUserPermissions.js +0 -10
- package/dist/hooks/useUserPermissions.js.map +0 -1
- package/dist/index.js +0 -26
- package/dist/index.js.map +0 -1
- package/dist/reactor.js +0 -59
- package/dist/reactor.js.map +0 -1
- package/dist/utils/index.js +0 -16
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/signature.js +0 -35
- package/dist/utils/signature.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocument.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocument.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDocument.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAgB,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,WAAW,CACzB,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,YAAY,GAAE,YAAiB,0BA2ChC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
export function useDocument(reactor, documentMeta = {}) {
|
|
3
|
+
const { documentId, documentType, driveId } = documentMeta;
|
|
4
|
+
const [document, setDocument] = useState();
|
|
5
|
+
const onStrandUpdate = useCallback((cb) => {
|
|
6
|
+
if (!reactor) {
|
|
7
|
+
throw new Error("Reactor is not loaded");
|
|
8
|
+
}
|
|
9
|
+
return reactor.on("strandUpdate", cb);
|
|
10
|
+
}, [reactor]);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!reactor)
|
|
13
|
+
return;
|
|
14
|
+
if (!driveId || !documentId || !documentType)
|
|
15
|
+
return;
|
|
16
|
+
reactor
|
|
17
|
+
.getDocument(driveId, documentId)
|
|
18
|
+
.then(setDocument)
|
|
19
|
+
.catch(console.error);
|
|
20
|
+
}, [driveId, documentId, documentType, reactor]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!reactor)
|
|
23
|
+
return;
|
|
24
|
+
if (!driveId || !documentId || !documentType)
|
|
25
|
+
return;
|
|
26
|
+
const removeListener = onStrandUpdate((strand) => {
|
|
27
|
+
if (strand.driveId === driveId && strand.documentId === documentId) {
|
|
28
|
+
reactor
|
|
29
|
+
.getDocument(driveId, documentId)
|
|
30
|
+
.then(setDocument)
|
|
31
|
+
.catch(console.error);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return removeListener;
|
|
35
|
+
}, [onStrandUpdate, driveId, documentId, documentType]);
|
|
36
|
+
return document;
|
|
37
|
+
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type DocumentDispatchCallback<
|
|
3
|
-
prevState:
|
|
4
|
-
newState:
|
|
1
|
+
import type { ActionErrorCallback, ActionFromDocument, OperationFromDocument, PHDocument, Reducer } from "document-model";
|
|
2
|
+
export type DocumentDispatchCallback<TDocument extends PHDocument> = (operation: OperationFromDocument<TDocument>, state: {
|
|
3
|
+
prevState: TDocument;
|
|
4
|
+
newState: TDocument;
|
|
5
5
|
}) => void;
|
|
6
|
-
export type DocumentDispatch<
|
|
6
|
+
export type DocumentDispatch<TDocument extends PHDocument> = (action: ActionFromDocument<TDocument>, callback?: DocumentDispatchCallback<TDocument>, onErrorCallback?: ActionErrorCallback) => void;
|
|
7
7
|
type OnErrorHandler = (error: unknown) => void;
|
|
8
|
-
export declare function useDocumentDispatch<
|
|
9
|
-
Document<State, A, LocalState> | undefined,
|
|
10
|
-
DocumentDispatch<State, A, LocalState>,
|
|
11
|
-
unknown
|
|
12
|
-
];
|
|
8
|
+
export declare function useDocumentDispatch<TDocument extends PHDocument>(documentReducer: Reducer<TDocument> | undefined, initialState: TDocument | undefined, onError?: OnErrorHandler): readonly [TDocument | undefined, DocumentDispatch<TDocument>, unknown];
|
|
13
9
|
export {};
|
|
14
10
|
//# sourceMappingURL=useDocumentDispatch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocumentDispatch.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"useDocumentDispatch.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,EACV,OAAO,EACR,MAAM,gBAAgB,CAAC;AAGxB,MAAM,MAAM,wBAAwB,CAAC,SAAS,SAAS,UAAU,IAAI,CACnE,SAAS,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAC3C,KAAK,EAAE;IACL,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB,KACE,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,CAAC,SAAS,SAAS,UAAU,IAAI,CAC3D,MAAM,EAAE,kBAAkB,CAAC,SAAS,CAAC,EACrC,QAAQ,CAAC,EAAE,wBAAwB,CAAC,SAAS,CAAC,EAC9C,eAAe,CAAC,EAAE,mBAAmB,KAClC,IAAI,CAAC;AAEV,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,SAAS,SAAS,UAAU,EAC9D,eAAe,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,EAC/C,YAAY,EAAE,SAAS,GAAG,SAAS,EACnC,OAAO,GAAE,cAA8B,GACtC,SAAS,CAAC,SAAS,GAAG,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAkDxE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
export function useDocumentDispatch(documentReducer, initialState, onError = console.error) {
|
|
3
|
+
const [state, setState] = useState(initialState);
|
|
4
|
+
const [error, setError] = useState();
|
|
5
|
+
const onErrorHandler = (error) => {
|
|
6
|
+
setError(error);
|
|
7
|
+
onError(error);
|
|
8
|
+
};
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
setState(initialState);
|
|
11
|
+
}, [initialState]);
|
|
12
|
+
const dispatch = (action, callback, onErrorCallback) => {
|
|
13
|
+
setError(undefined);
|
|
14
|
+
setState((_state) => {
|
|
15
|
+
if (!documentReducer || !_state)
|
|
16
|
+
return _state;
|
|
17
|
+
try {
|
|
18
|
+
const newState = documentReducer(_state, action);
|
|
19
|
+
const scope = action.scope ?? "global";
|
|
20
|
+
const operations = newState.operations[scope];
|
|
21
|
+
const operation = operations[operations.length - 1];
|
|
22
|
+
if (operation.error) {
|
|
23
|
+
const error = new Error(operation.error);
|
|
24
|
+
onErrorHandler(error);
|
|
25
|
+
onErrorCallback?.(error);
|
|
26
|
+
}
|
|
27
|
+
callback?.(operation, {
|
|
28
|
+
prevState: { ..._state },
|
|
29
|
+
newState: { ...newState },
|
|
30
|
+
});
|
|
31
|
+
return newState;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
onErrorHandler(error);
|
|
35
|
+
onErrorCallback?.(error);
|
|
36
|
+
return _state;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
return [state, dispatch, error];
|
|
41
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { IDocumentDriveServer } from
|
|
2
|
-
import { DocumentDriveDocument
|
|
1
|
+
import type { IDocumentDriveServer } from "document-drive";
|
|
2
|
+
import { DocumentDriveDocument } from "document-drive";
|
|
3
|
+
import { Trigger } from "document-drive";
|
|
3
4
|
export declare function drivesToHash(drives: DocumentDriveDocument[]): string;
|
|
4
5
|
export type IDrivesState = "INITIAL" | "LOADING" | "LOADED" | "ERROR";
|
|
5
|
-
export declare const documentDrivesInitializedMapAtomFamily: import(
|
|
6
|
+
export declare const documentDrivesInitializedMapAtomFamily: import("jotai/vanilla/utils/atomFamily").AtomFamily<unknown, import("jotai").PrimitiveAtom<IDrivesState> & {
|
|
6
7
|
init: IDrivesState;
|
|
7
8
|
}>;
|
|
8
9
|
export type ClientErrorHandler = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocumentDrives.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDrives.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useDocumentDrives.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDrives.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAQzC,wBAAgB,YAAY,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAEpE;AAuBD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AACtE,eAAO,MAAM,sCAAsC;;EAElD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,mBAAmB,EAAE,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,oBAAoB,gFAwCvC,kBAAkB,6CA2C1C"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { useMemo, useCallback } from "react";
|
|
2
|
+
import { atom, useAtom } from "jotai";
|
|
3
|
+
import { atomFamily } from "jotai/utils";
|
|
4
|
+
import { documentToHash } from "../utils/index.js";
|
|
5
|
+
const documentDrivesAtom = atom(new Map());
|
|
6
|
+
export function drivesToHash(drives) {
|
|
7
|
+
return drives.map(documentToHash).join("&");
|
|
8
|
+
}
|
|
9
|
+
const readWriteDocumentDrivesAtom = (server) => () => atom((get) => (server ? (get(documentDrivesAtom).get(server) ?? []) : []), (_get, set, newDrives) => {
|
|
10
|
+
set(documentDrivesAtom, (map) => {
|
|
11
|
+
if (!server) {
|
|
12
|
+
return new Map();
|
|
13
|
+
}
|
|
14
|
+
const currentDrives = map.get(server) ?? [];
|
|
15
|
+
if (currentDrives.length !== newDrives.length ||
|
|
16
|
+
drivesToHash(currentDrives) !== drivesToHash(newDrives)) {
|
|
17
|
+
return new Map(map).set(server, newDrives);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return map;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
export const documentDrivesInitializedMapAtomFamily = atomFamily(() => atom("INITIAL"));
|
|
25
|
+
export function useDocumentDrives(reactor) {
|
|
26
|
+
const [documentDrives, setDocumentDrives] = useAtom(useMemo(readWriteDocumentDrivesAtom(reactor), [reactor]));
|
|
27
|
+
const refreshDocumentDrives = useCallback(async () => {
|
|
28
|
+
if (!reactor) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const documentDrives = [];
|
|
32
|
+
try {
|
|
33
|
+
const driveIds = await reactor.getDrives();
|
|
34
|
+
for (const id of driveIds) {
|
|
35
|
+
try {
|
|
36
|
+
const drive = await reactor.getDrive(id);
|
|
37
|
+
documentDrives.push(drive);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error(error);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
setDocumentDrives(documentDrives);
|
|
49
|
+
}
|
|
50
|
+
}, [reactor]);
|
|
51
|
+
const [status, setStatus] = useAtom(documentDrivesInitializedMapAtomFamily(reactor));
|
|
52
|
+
if (status === "INITIAL") {
|
|
53
|
+
setStatus("LOADING");
|
|
54
|
+
refreshDocumentDrives()
|
|
55
|
+
.then(() => setStatus("LOADED"))
|
|
56
|
+
.catch(() => setStatus("ERROR"));
|
|
57
|
+
}
|
|
58
|
+
const serverSubscribeUpdates = useCallback((clientErrorhandler) => {
|
|
59
|
+
if (!reactor) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const unsub1 = reactor.on("syncStatus", async (_event, _status, error) => {
|
|
63
|
+
if (error) {
|
|
64
|
+
console.error(error);
|
|
65
|
+
}
|
|
66
|
+
await refreshDocumentDrives();
|
|
67
|
+
});
|
|
68
|
+
const unsub2 = reactor.on("strandUpdate", () => refreshDocumentDrives());
|
|
69
|
+
const unsubOnSyncError = reactor.on("clientStrandsError", clientErrorhandler.strandsErrorHandler);
|
|
70
|
+
const unsub3 = reactor.on("defaultRemoteDrive", () => refreshDocumentDrives());
|
|
71
|
+
return () => {
|
|
72
|
+
unsub1();
|
|
73
|
+
unsub2();
|
|
74
|
+
unsubOnSyncError();
|
|
75
|
+
unsub3();
|
|
76
|
+
};
|
|
77
|
+
}, [reactor, refreshDocumentDrives]);
|
|
78
|
+
return useMemo(() => [
|
|
79
|
+
documentDrives,
|
|
80
|
+
refreshDocumentDrives,
|
|
81
|
+
serverSubscribeUpdates,
|
|
82
|
+
status,
|
|
83
|
+
], [documentDrives, status]);
|
|
84
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { User } from
|
|
4
|
-
export type DocumentDispatchCallback<
|
|
5
|
-
prevState:
|
|
6
|
-
newState:
|
|
1
|
+
import { IDocumentDriveServer } from "document-drive";
|
|
2
|
+
import { ActionErrorCallback, ActionFromDocument, DocumentModelModule, OperationFromDocument, PHDocument } from "document-model";
|
|
3
|
+
import { User } from "../renown/types.js";
|
|
4
|
+
export type DocumentDispatchCallback<TDocument extends PHDocument> = (operation: OperationFromDocument<TDocument>, state: {
|
|
5
|
+
prevState: TDocument;
|
|
6
|
+
newState: TDocument;
|
|
7
7
|
}) => void;
|
|
8
|
-
export type UseDocumentEditorProps<
|
|
8
|
+
export type UseDocumentEditorProps<TDocument extends PHDocument> = {
|
|
9
9
|
driveId: string;
|
|
10
10
|
nodeId: string;
|
|
11
|
-
document:
|
|
12
|
-
|
|
11
|
+
document: TDocument | undefined;
|
|
12
|
+
documentModelModule: DocumentModelModule<TDocument>;
|
|
13
13
|
user?: User;
|
|
14
14
|
onExport?: () => void;
|
|
15
15
|
onOpenSwitchboardLink?: () => Promise<void>;
|
|
16
|
-
onChange?: (document:
|
|
16
|
+
onChange?: (document: TDocument) => void;
|
|
17
17
|
};
|
|
18
|
-
export declare function useDocumentEditor(reactor: IDocumentDriveServer | undefined, props: UseDocumentEditorProps): {
|
|
19
|
-
dispatch: (action:
|
|
20
|
-
document:
|
|
18
|
+
export declare function useDocumentEditor<TDocument extends PHDocument>(reactor: IDocumentDriveServer | undefined, props: UseDocumentEditorProps<TDocument>): {
|
|
19
|
+
dispatch: (action: ActionFromDocument<TDocument>, onErrorCallback?: ActionErrorCallback) => void;
|
|
20
|
+
document: TDocument | undefined;
|
|
21
21
|
error: unknown;
|
|
22
22
|
};
|
|
23
23
|
//# sourceMappingURL=useDocumentEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocumentEditor.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentEditor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"useDocumentEditor.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAM1C,MAAM,MAAM,wBAAwB,CAAC,SAAS,SAAS,UAAU,IAAI,CACnE,SAAS,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAC3C,KAAK,EAAE;IACL,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB,KACE,IAAI,CAAC;AAEV,MAAM,MAAM,sBAAsB,CAAC,SAAS,SAAS,UAAU,IAAI;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;IAChC,mBAAmB,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,SAAS,SAAS,UAAU,EAC5D,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,KAAK,EAAE,sBAAsB,CAAC,SAAS,CAAC;uBAwB9B,kBAAkB,CAAC,SAAS,CAAC,oBACnB,mBAAmB;;;EAkCxC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { addActionContext, signOperation } from "../utils/signature.js";
|
|
2
|
+
import { useAddDebouncedOperations } from "./useAddDebouncedOperations.js";
|
|
3
|
+
import { useConnectCrypto, useConnectDid } from "./useConnectCrypto.js";
|
|
4
|
+
import { useDocumentDispatch } from "./useDocumentDispatch.js";
|
|
5
|
+
export function useDocumentEditor(reactor, props) {
|
|
6
|
+
const { nodeId, driveId, documentModelModule, document: initialDocument, user, } = props;
|
|
7
|
+
const connectDid = useConnectDid();
|
|
8
|
+
const { sign } = useConnectCrypto();
|
|
9
|
+
const addDebouncedOprations = useAddDebouncedOperations(reactor, {
|
|
10
|
+
driveId,
|
|
11
|
+
documentId: nodeId,
|
|
12
|
+
});
|
|
13
|
+
const [document, _dispatch, error] = useDocumentDispatch(documentModelModule.reducer, initialDocument);
|
|
14
|
+
function dispatch(action, onErrorCallback) {
|
|
15
|
+
const callback = (operation, state) => {
|
|
16
|
+
const { prevState } = state;
|
|
17
|
+
signOperation(operation, sign, nodeId, prevState, documentModelModule.reducer, user)
|
|
18
|
+
.then((op) => {
|
|
19
|
+
return addDebouncedOprations(op);
|
|
20
|
+
})
|
|
21
|
+
.catch(console.error);
|
|
22
|
+
};
|
|
23
|
+
_dispatch(addActionContext(action, connectDid, user), callback, onErrorCallback);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
dispatch,
|
|
27
|
+
document,
|
|
28
|
+
error,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { DocumentDriveAction, DocumentDriveDocument } from "document-drive";
|
|
2
|
+
import { EditorDispatch, PHDocument } from "document-model";
|
|
3
|
+
import { UiNode } from "../uiNodes/types.js";
|
|
4
|
+
import { IDriveContext } from "./useDriveContext.js";
|
|
5
|
+
/**
|
|
6
|
+
* Actions for managing a document drive
|
|
7
|
+
*/
|
|
8
|
+
export interface IDriveActions {
|
|
9
|
+
/** The drive context provided by the host application */
|
|
10
|
+
context: IDriveContext;
|
|
11
|
+
/** Selects a node in the drive */
|
|
12
|
+
selectNode: (node: UiNode | null) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new folder in the drive
|
|
15
|
+
* @param name - Name of the folder
|
|
16
|
+
* @param parentFolder - Optional ID of parent folder
|
|
17
|
+
* @param id - Optional custom ID for the folder
|
|
18
|
+
*/
|
|
19
|
+
addFolder: (name: string, parentFolder?: string | null, id?: string) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Adds a file to the drive
|
|
22
|
+
* @param file - File to be added
|
|
23
|
+
* @param parentFolder - Optional ID of parent folder (defaults to selected folder)
|
|
24
|
+
* @param name - Optional custom name for the file
|
|
25
|
+
*/
|
|
26
|
+
addFile: (file: File, parentFolder?: string, name?: string) => Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new document in the drive
|
|
29
|
+
* @param name - Name of the document
|
|
30
|
+
* @param documentType - Type of document to create
|
|
31
|
+
* @param document - Optional document content
|
|
32
|
+
* @param parentFolder - Optional ID of parent folder
|
|
33
|
+
* @param id - Optional custom ID for the document
|
|
34
|
+
*/
|
|
35
|
+
addDocument: (name: string, documentType: string, document?: PHDocument, parentFolder?: string, id?: string) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Deletes a node from the drive
|
|
38
|
+
* @param id - ID of the node to delete
|
|
39
|
+
*/
|
|
40
|
+
deleteNode: (id: string) => Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Renames a node in the drive
|
|
43
|
+
* @param id - ID of the node to rename
|
|
44
|
+
* @param name - New name for the node
|
|
45
|
+
*/
|
|
46
|
+
renameNode: (id: string, name: string) => Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Moves a node to a new parent folder
|
|
49
|
+
* @param sourceId - ID of the node to move
|
|
50
|
+
* @param targetId - ID of the target parent folder
|
|
51
|
+
*/
|
|
52
|
+
moveNode: (sourceId: string, targetId: string) => Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Copies a node to a new location
|
|
55
|
+
* @param sourceId - ID of the node to copy
|
|
56
|
+
* @param targetFolderId - Optional ID of the target folder
|
|
57
|
+
*/
|
|
58
|
+
copyNode: (sourceId: string, targetFolderId: string | undefined) => Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a copy of a node in the same folder
|
|
61
|
+
* @param sourceId - ID of the node to duplicate
|
|
62
|
+
*/
|
|
63
|
+
duplicateNode: (sourceId: string) => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Hook that provides actions for managing a document drive
|
|
67
|
+
*
|
|
68
|
+
* @param document - The document drive document
|
|
69
|
+
* @param dispatch - Function to dispatch drive actions
|
|
70
|
+
* @param context - The drive context containing UI-related functions
|
|
71
|
+
* @returns Object containing drive management actions
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const {
|
|
75
|
+
* addFolder,
|
|
76
|
+
* addFile,
|
|
77
|
+
* deleteNode,
|
|
78
|
+
* moveNode
|
|
79
|
+
* } = useDriveActions(document, dispatch, driveContext);
|
|
80
|
+
*/
|
|
81
|
+
export declare function useDriveActions(document: DocumentDriveDocument, dispatch: EditorDispatch<DocumentDriveAction>, context: IDriveContext): IDriveActions;
|
|
82
|
+
//# sourceMappingURL=useDriveActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDriveActions.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDriveActions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAUtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,UAAU,EAEX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAcrD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,OAAO,EAAE,aAAa,CAAC;IAEvB,kCAAkC;IAClC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE1C;;;;;OAKG;IACH,SAAS,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,EAC5B,EAAE,CAAC,EAAE,MAAM,KACR,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;;;OAKG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7E;;;;;;;OAOG;IACH,WAAW,EAAE,CACX,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,UAAU,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,EAAE,CAAC,EAAE,MAAM,KACR,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;;;OAIG;IACH,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;;OAIG;IACH,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;;OAIG;IACH,QAAQ,EAAE,CACR,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GAAG,SAAS,KAC/B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAyJD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,cAAc,CAAC,mBAAmB,CAAC,EAC7C,OAAO,EAAE,aAAa,GACrB,aAAa,CAKf"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { addFolder, copyNode, deleteNode, generateAddNodeAction, generateNodesCopy, isFileNode, isFolderNode, moveNode, updateNode, } from "document-drive";
|
|
2
|
+
import { generateId as _generateId, } from "document-model";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
const generateId = () => _generateId().toString();
|
|
5
|
+
/**
|
|
6
|
+
* Retrieves a node from the drive by its ID
|
|
7
|
+
* @param id - The ID of the node to find
|
|
8
|
+
* @param drive - The document drive to search in
|
|
9
|
+
* @returns The found node or undefined
|
|
10
|
+
*/
|
|
11
|
+
function getNode(id, drive) {
|
|
12
|
+
return drive.state.global.nodes.find((node) => node.id === id);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates an object containing actions for managing a document drive
|
|
16
|
+
* @param document - The document drive document
|
|
17
|
+
* @param dispatch - Function to dispatch drive actions
|
|
18
|
+
* @param context - The drive context provided by the host application
|
|
19
|
+
*/
|
|
20
|
+
function createDriveActions(document, dispatch, context) {
|
|
21
|
+
const drive = document;
|
|
22
|
+
const { id: driveId } = drive.state.global;
|
|
23
|
+
const { selectedNode } = context;
|
|
24
|
+
const handleAddFolder = async (name, parentFolder, id = generateId()) => {
|
|
25
|
+
dispatch(addFolder({
|
|
26
|
+
id,
|
|
27
|
+
name,
|
|
28
|
+
parentFolder: parentFolder ?? null,
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
const addDocument = async (name, documentType, document, parentFolder, id = generateId()) => {
|
|
32
|
+
const action = generateAddNodeAction(drive.state.global, {
|
|
33
|
+
id,
|
|
34
|
+
name,
|
|
35
|
+
parentFolder: parentFolder ?? null,
|
|
36
|
+
documentType,
|
|
37
|
+
document,
|
|
38
|
+
}, ["global"]);
|
|
39
|
+
dispatch(action);
|
|
40
|
+
};
|
|
41
|
+
const addFile = async (file, parentFolder = selectedNode && isFileNode(selectedNode)
|
|
42
|
+
? undefined
|
|
43
|
+
: selectedNode?.id, name = file.name.replace(/\.zip$/gim, "")) => {
|
|
44
|
+
const folder = parentFolder ? getNode(parentFolder, drive) : undefined;
|
|
45
|
+
if (parentFolder && !folder) {
|
|
46
|
+
throw new Error(`Parent folder with id "${parentFolder}" not found`);
|
|
47
|
+
}
|
|
48
|
+
if (folder && !isFolderNode(folder)) {
|
|
49
|
+
throw new Error(`Parent folder with id "${parentFolder}" is not a folder`);
|
|
50
|
+
}
|
|
51
|
+
await context.addFile(file, driveId, name, parentFolder);
|
|
52
|
+
};
|
|
53
|
+
const handleDeleteNode = async (id) => {
|
|
54
|
+
dispatch(deleteNode({ id }));
|
|
55
|
+
};
|
|
56
|
+
const renameNode = async (id, name) => {
|
|
57
|
+
dispatch(updateNode({ id, name }));
|
|
58
|
+
};
|
|
59
|
+
const handleMoveNode = async (sourceId, targetId) => {
|
|
60
|
+
dispatch(moveNode({
|
|
61
|
+
srcFolder: sourceId,
|
|
62
|
+
targetParentFolder: targetId,
|
|
63
|
+
}));
|
|
64
|
+
};
|
|
65
|
+
const handleCopyNode = async (sourceId, targetFolderId) => {
|
|
66
|
+
const target = targetFolderId ? getNode(targetFolderId, drive) : undefined;
|
|
67
|
+
if (targetFolderId && !target) {
|
|
68
|
+
throw new Error(`Target node with id "${targetFolderId}" not found`);
|
|
69
|
+
}
|
|
70
|
+
if (target && !isFolderNode(target)) {
|
|
71
|
+
throw new Error(`Target node with id "${targetFolderId}" is not a folder`);
|
|
72
|
+
}
|
|
73
|
+
const source = getNode(sourceId, drive);
|
|
74
|
+
if (!source) {
|
|
75
|
+
throw new Error(`Source node with id "${sourceId}" not found`);
|
|
76
|
+
}
|
|
77
|
+
const copyNodesInput = generateNodesCopy({
|
|
78
|
+
srcId: sourceId,
|
|
79
|
+
targetParentFolder: target?.id,
|
|
80
|
+
targetName: source.name,
|
|
81
|
+
}, generateId, drive.state.global.nodes);
|
|
82
|
+
const copyActions = copyNodesInput.map((copyNodeInput) => copyNode(copyNodeInput));
|
|
83
|
+
for (const copyAction of copyActions) {
|
|
84
|
+
dispatch(copyAction); // TODO support batching dispatch
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const duplicateNode = async (sourceId) => {
|
|
88
|
+
const node = getNode(sourceId, drive);
|
|
89
|
+
if (!node) {
|
|
90
|
+
throw new Error(`Node with id "${sourceId}" not found`);
|
|
91
|
+
}
|
|
92
|
+
await handleCopyNode(node.id, node.parentFolder || undefined);
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
context,
|
|
96
|
+
selectNode: context.selectNode,
|
|
97
|
+
addFolder: handleAddFolder,
|
|
98
|
+
addFile,
|
|
99
|
+
addDocument,
|
|
100
|
+
deleteNode: handleDeleteNode,
|
|
101
|
+
renameNode,
|
|
102
|
+
moveNode: handleMoveNode,
|
|
103
|
+
copyNode: handleCopyNode,
|
|
104
|
+
duplicateNode,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Hook that provides actions for managing a document drive
|
|
109
|
+
*
|
|
110
|
+
* @param document - The document drive document
|
|
111
|
+
* @param dispatch - Function to dispatch drive actions
|
|
112
|
+
* @param context - The drive context containing UI-related functions
|
|
113
|
+
* @returns Object containing drive management actions
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* const {
|
|
117
|
+
* addFolder,
|
|
118
|
+
* addFile,
|
|
119
|
+
* deleteNode,
|
|
120
|
+
* moveNode
|
|
121
|
+
* } = useDriveActions(document, dispatch, driveContext);
|
|
122
|
+
*/
|
|
123
|
+
export function useDriveActions(document, dispatch, context) {
|
|
124
|
+
return useMemo(() => createDriveActions(document, dispatch, context), [document, dispatch, context]);
|
|
125
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DocumentDriveAction, DocumentDriveDocument } from "document-drive";
|
|
2
|
+
import { EditorDispatch } from "document-model";
|
|
3
|
+
import type { UiNode } from "../uiNodes/types.js";
|
|
4
|
+
import { IDriveContext } from "./useDriveContext.js";
|
|
5
|
+
export declare function useDriveActionsWithUiNodes(document: DocumentDriveDocument, dispatch: EditorDispatch<DocumentDriveAction>): {
|
|
6
|
+
addFile: (file: File, parentNode: UiNode | null) => Promise<void>;
|
|
7
|
+
addFolder: (name: string, parentFolder?: string | undefined) => Promise<void>;
|
|
8
|
+
renameNode: (name: string, node: UiNode) => Promise<void>;
|
|
9
|
+
deleteNode: (node: UiNode) => Promise<void>;
|
|
10
|
+
moveNode: (src: UiNode, target: UiNode) => Promise<void>;
|
|
11
|
+
copyNode: (src: UiNode, target: UiNode) => Promise<void>;
|
|
12
|
+
duplicateNode: (node: UiNode) => Promise<void>;
|
|
13
|
+
context: IDriveContext;
|
|
14
|
+
selectNode: (node: UiNode | null) => void;
|
|
15
|
+
addDocument: (name: string, documentType: string, document?: import("document-model").PHDocument, parentFolder?: string, id?: string) => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useDriveActionsWithUiNodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDriveActionsWithUiNodes.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDriveActionsWithUiNodes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAItB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAmB,MAAM,sBAAsB,CAAC;AAiEtE,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,cAAc,CAAC,mBAAmB,CAAC;oBApC3B,IAAI,cAAc,MAAM,GAAG,IAAI;sBAG7B,MAAM,iBAA8B,MAAM,GAAG,SAAS;uBAGrD,MAAM,QAAQ,MAAM;uBAKpB,MAAM;oBAKH,MAAM,UAAU,MAAM;oBAO5B,MAAM,UAAU,MAAM;0BAIhB,MAAM;;;8DAPwB,CAAC,mDAGzC,CAAC,YAAgB,CAAC;EAuCjC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { FILE } from "../uiNodes/constants.js";
|
|
3
|
+
import { useDriveActions } from "./useDriveActions.js";
|
|
4
|
+
import { useDriveContext } from "./useDriveContext.js";
|
|
5
|
+
import { useUiNodesContext } from "./useUiNodesContext.js";
|
|
6
|
+
function toNode(uiNode) {
|
|
7
|
+
if (uiNode.kind === "DRIVE") {
|
|
8
|
+
throw new Error("Cannot convert drive node to regular node");
|
|
9
|
+
}
|
|
10
|
+
const { id, name, parentFolder, kind } = uiNode;
|
|
11
|
+
if (kind === "FOLDER") {
|
|
12
|
+
return { id, name, parentFolder, kind: "folder" };
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
// Remove after ts reset is fixed
|
|
16
|
+
const fileNode = uiNode;
|
|
17
|
+
return {
|
|
18
|
+
id,
|
|
19
|
+
name,
|
|
20
|
+
parentFolder,
|
|
21
|
+
kind: "file",
|
|
22
|
+
documentType: fileNode.documentType,
|
|
23
|
+
synchronizationUnits: fileNode.synchronizationUnits,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Adapter to convert between UiNodes and drive actions
|
|
28
|
+
function createUiNodeAdapter(driveActions) {
|
|
29
|
+
return {
|
|
30
|
+
...driveActions,
|
|
31
|
+
addFile: (file, parentNode) => driveActions.addFile(file, parentNode?.id),
|
|
32
|
+
addFolder: (name, parentFolder = undefined) => driveActions.addFolder(name, parentFolder),
|
|
33
|
+
renameNode: (name, node) => {
|
|
34
|
+
const converted = toNode(node);
|
|
35
|
+
return driveActions.renameNode(converted.id, name);
|
|
36
|
+
},
|
|
37
|
+
deleteNode: (node) => {
|
|
38
|
+
const converted = toNode(node);
|
|
39
|
+
return driveActions.deleteNode(converted.id);
|
|
40
|
+
},
|
|
41
|
+
moveNode: async (src, target) => {
|
|
42
|
+
if (target.kind === FILE || src.parentFolder === target.id)
|
|
43
|
+
return;
|
|
44
|
+
const srcNode = toNode(src);
|
|
45
|
+
const targetNode = toNode(target);
|
|
46
|
+
return driveActions.moveNode(srcNode.id, targetNode.id);
|
|
47
|
+
},
|
|
48
|
+
copyNode: (src, target) => {
|
|
49
|
+
return driveActions.copyNode(src.id, target.id);
|
|
50
|
+
},
|
|
51
|
+
duplicateNode: (node) => {
|
|
52
|
+
const converted = toNode(node);
|
|
53
|
+
return driveActions.duplicateNode(converted.id);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function useDriveActionsWithUiNodes(document, dispatch) {
|
|
58
|
+
const { selectedNode, selectedDriveNode, setSelectedNode, getNodeById } = useUiNodesContext();
|
|
59
|
+
const _driveContext = useDriveContext();
|
|
60
|
+
const driveContext = useMemo(() => ({
|
|
61
|
+
..._driveContext,
|
|
62
|
+
selectedNode: selectedNode,
|
|
63
|
+
onSelectNode: (node) => {
|
|
64
|
+
_driveContext.selectNode(node);
|
|
65
|
+
setSelectedNode(getNodeById(node.id));
|
|
66
|
+
},
|
|
67
|
+
}), [selectedNode, selectedDriveNode?.driveId, setSelectedNode, getNodeById]);
|
|
68
|
+
const driveActions = useDriveActions(document, dispatch, driveContext);
|
|
69
|
+
const uiNodeActions = useMemo(() => createUiNodeAdapter(driveActions), [driveActions]);
|
|
70
|
+
return uiNodeActions;
|
|
71
|
+
}
|