From 65532c8af370527bf6b3ea4a50db798d68d6c4f6 Mon Sep 17 00:00:00 2001 From: VictoriaShyika Date: Sat, 16 Dec 2023 04:19:57 +0200 Subject: [PATCH 1/9] added cut and past top file api --- src/_node/file/actions.ts | 135 ++++++++++++- src/_node/file/helpers.ts | 179 ++++++++++++++++++ src/_node/file/types.ts | 39 +++- .../helpers/duplicateNode.ts | 9 +- .../helpers/generateNewNameMoveNode.ts | 106 ++++++----- .../workspaceTreeView/helpers/index.ts | 3 - .../workspaceTreeView/helpers/moveActions.ts | 142 -------------- .../workspaceTreeView/helpers/moveFile.ts | 45 ----- .../workspaceTreeView/helpers/renameNode.ts | 7 +- .../helpers/validateAndMoveNode.ts | 84 -------- .../workspaceTreeView/hooks/useCmdk.ts | 41 ++-- .../hooks/useFileOperations.ts | 10 +- .../hooks/useNodeActionsHandler.ts | 82 +++++--- 13 files changed, 478 insertions(+), 404 deletions(-) delete mode 100644 src/components/main/actionsPanel/workspaceTreeView/helpers/moveActions.ts delete mode 100644 src/components/main/actionsPanel/workspaceTreeView/helpers/moveFile.ts delete mode 100644 src/components/main/actionsPanel/workspaceTreeView/helpers/validateAndMoveNode.ts diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index 1fd0f5a6..1cfe428e 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -3,11 +3,20 @@ import { LogAllow } from "@_constants/global"; import { TFileApiPayload, TFileHandlerCollection, + TFileNodeData, TFileNodeTreeData, + TNodeTreeData, TNodeUid, + moveIDBFF, + moveLocalFF, } from "../"; import { TProjectContext } from "@_redux/main/fileTree"; import { FileSystemApis } from "./FileSystemApis"; +import { TClipboardData, setClipboardData } from "@_redux/main/processor"; +import { AnyAction } from "@reduxjs/toolkit"; +import { Dispatch } from "react"; +import { generateNewNameMoveNode } from "@_components/main/actionsPanel/workspaceTreeView/helpers"; +import { verifyFileHandlerPermission } from "@_services/main"; const create = () => {}; const remove = async ({ @@ -40,10 +49,110 @@ const remove = async ({ } }); }; -const cut = () => {}; +const cut = ({ + dispatch, + uids, + fileTree, + currentFileUid, + nodeTree, +}: { + dispatch: Dispatch; + uids: TNodeUid[]; + fileTree: TFileNodeTreeData; + currentFileUid: string; + nodeTree: TNodeTreeData; +}) => { + dispatch( + setClipboardData({ + panel: "file", + type: "cut", + uids, + fileType: fileTree[currentFileUid].data.type, + data: [], + fileUid: currentFileUid, + prevNodeTree: nodeTree, + }), + ); +}; const copy = () => {}; const duplicate = () => {}; -const move = () => {}; +const move = async ({ + projectContext, + fileHandlers, + uids, + clipboardData, + fileTree, + targetNode, +}: { + projectContext: TProjectContext; + fileHandlers: any; + uids: string[]; + clipboardData: TClipboardData | null; + fileTree: TFileNodeTreeData; + targetNode: any; +}) => { + return new Promise((resolve, reject) => { + uids.map(async (uid) => { + const node = fileTree[uid]; + if (node === undefined) { + return false; + } + + const nodeData = node.data as TFileNodeData; + const parentNode = fileTree[node.parentUid as TNodeUid]; + if (parentNode === undefined) { + return false; + } + + const handler = fileHandlers[uid]; + + const parentHandler = fileHandlers[ + parentNode.uid + ] as FileSystemDirectoryHandle; + const targetHandler = fileHandlers[ + targetNode.uid + ] as FileSystemDirectoryHandle; + + if ( + !(await verifyFileHandlerPermission(handler)) || + !(await verifyFileHandlerPermission(parentHandler)) || + !(await verifyFileHandlerPermission(targetHandler)) + ) { + return false; + } + const newFileName = await generateNewNameMoveNode( + nodeData, + targetHandler, + clipboardData?.type === "copy", + ); + + // move + try { + if (projectContext === "local") { + await moveLocalFF( + handler, + parentHandler, + targetHandler, + newFileName, + clipboardData?.type === "copy", + ); + } else if (projectContext === "idb") { + const targetNodeData = fileTree[targetNode.uid].data as TFileNodeData; + await moveIDBFF( + nodeData, + targetNodeData, + newFileName, + clipboardData?.type === "copy", + ); + } + resolve(true); + } catch (err) { + reject(err); + } + }); + }); +}; + const rename = () => {}; export const doFileActions = async ( @@ -59,6 +168,11 @@ export const doFileActions = async ( fileTree, fileHandlers, osType = "Windows", + dispatch, + currentFileUid, + nodeTree, + clipboardData, + targetNode, } = params; let allDone = true; @@ -75,7 +189,13 @@ export const doFileActions = async ( }); break; case "cut": - cut(); + cut({ + dispatch, + uids, + fileTree, + currentFileUid, + nodeTree, + }); break; case "copy": copy(); @@ -84,7 +204,14 @@ export const doFileActions = async ( duplicate(); break; case "move": - move(); + allDone = await move({ + projectContext, + fileHandlers, + uids, + clipboardData, + fileTree, + targetNode, + }); break; case "rename": rename(); diff --git a/src/_node/file/helpers.ts b/src/_node/file/helpers.ts index f9587120..95e4f50b 100644 --- a/src/_node/file/helpers.ts +++ b/src/_node/file/helpers.ts @@ -5,8 +5,16 @@ import { TFileNodeData, TFileNodeTreeData, TNodeUid, + _getIDBDirectoryOrFileStat, _path, + _readIDBFile, + _removeIDBDirectoryOrFile, + _writeIDBFile, } from "../"; +import { + copyDirectory, + moveDirectory, +} from "@_components/main/actionsPanel/workspaceTreeView/helpers"; export const sortFilesByASC = (handlerObj: TFileHandlerInfoObj) => { // sort by ASC directory/file @@ -85,3 +93,174 @@ export const getNormalizedPath = ( const normalizedPath = _path.normalize(path); return { isAbsolutePath, normalizedPath }; }; + +export const moveFile = async ( + handler: FileSystemHandle, + parentHandler: FileSystemDirectoryHandle, + targetHandler: FileSystemDirectoryHandle, + newName: string, + copy: boolean, + // showWarning?: boolean, + // addMessage?: (message: TToast) => void, +) => { + // validate if the new name exists + console.log("move file"); + + let exists = true; + try { + await targetHandler.getFileHandle(newName, { create: false }); + exists = true; + } catch (err) { + exists = false; + } + + if (exists) { + // showWarning && + // addMessage({ + // type: "error", + // content: "File with the same name already exists.", + // }); + return; + } + + // create a new file with the new name and write the content + try { + const newFile = await targetHandler.getFileHandle(newName, { + create: true, + }); + + const content = await (handler as FileSystemFileHandle).getFile(); + + const writableStream = await newFile.createWritable(); + await writableStream.write(content); + await writableStream.close(); + + // handle copy(optional) + !copy && + (await parentHandler.removeEntry(handler.name, { recursive: true })); + } catch (err) { + throw new Error("error"); + } +}; +export const moveLocalFF = async ( + handler: FileSystemHandle, + parentHandler: FileSystemDirectoryHandle, + targetHandler: FileSystemDirectoryHandle, + newName: string, + copy: boolean = false, + showWarning: boolean = false, +) => { + if (handler.kind === "directory") { + // validate if the new name exists + let exists = true; + try { + await targetHandler.getDirectoryHandle(newName, { create: false }); + exists = true; + } catch (err) { + exists = false; + } + if (exists) { + // showWarning && + // addMessage({ + // type: "error", + // content: "Folder with the same name already exists.", + // }); + return; + } + + // move nested handler-dir to targetHandler with the newName - copy (optional) + try { + const newHandler = await targetHandler.getDirectoryHandle(newName, { + create: true, + }); + await copyDirectory( + handler as FileSystemDirectoryHandle, + newHandler, + copy, + ); + } catch (err) { + throw new Error("error"); + } + } else { + await moveFile( + handler, + parentHandler, + targetHandler, + newName, + copy, + // showWarning, + // addMessage, + ); + } +}; + +export const moveIDBFF = async ( + nodeData: TFileNodeData, + targetNodeData: TFileNodeData, + newName: string, + copy: boolean = false, +) => { + if (nodeData.kind === "directory") { + // validate if the new name exists + let exists = true; + try { + await _getIDBDirectoryOrFileStat(`${targetNodeData.path}/${newName}`); + exists = true; + } catch (err) { + exists = false; + } + if (exists) { + // showWarning && + // addMessage({ + // type: "error", + // content: "Folder with the same name already exists.", + // }); + return; + } + + // move nested handler-dir to targetHandler with the newName - copy (optional) + try { + const dirs = [ + { + orgPath: nodeData.path, + newPath: `${targetNodeData.path}/${newName}`, + }, + ]; + for (const { orgPath, newPath } of dirs) { + await moveDirectory(orgPath, newPath, copy, nodeData); + } + } catch (err) { + throw "error"; + } + } else { + // validate if the new name exists + let exists = true; + try { + await _getIDBDirectoryOrFileStat(`${targetNodeData.path}/${newName}`); + exists = true; + } catch (err) { + exists = false; + } + if (exists) { + // showWarning && + // addMessage({ + // type: "error", + // content: "File with the same name already exists.", + // }); + return; + } + + // create a new file with the new name and write the content + try { + await _writeIDBFile( + `${targetNodeData.path}/${newName}`, + await _readIDBFile(nodeData.path), + ); + + // handle copy(optional) + !copy && (await _removeIDBDirectoryOrFile(nodeData.path)); + } catch (err) { + throw "error"; + } + } +}; diff --git a/src/_node/file/types.ts b/src/_node/file/types.ts index 0b09e071..d4431698 100644 --- a/src/_node/file/types.ts +++ b/src/_node/file/types.ts @@ -10,6 +10,9 @@ import { TNodeUid, } from "../"; import { TFileActionType, TProjectContext } from "@_redux/main/fileTree"; +import { AnyAction } from "@reduxjs/toolkit"; +import { Dispatch } from "react"; +import { TClipboardData } from "@_redux/main/processor"; export type TFileNode = TNode & { data: TFileNodeData; @@ -79,8 +82,40 @@ export type TFileApiPayloadBase = { }; export type TFileApiPayload = TFileApiPayloadBase & ( - | { action: Extract; uids: TNodeUid[] } - | { action: Exclude; uids?: never } + | { + action: Extract; + uids: TNodeUid[]; + } + | { + action: Exclude; + uids?: never; + } + ) & + ( + | { action: Extract; currentFileUid: string } + | { action: Exclude; currentFileUid?: never } + ) & + ( + | { action: Extract; nodeTree: TNodeTreeData } + | { action: Exclude; nodeTree?: never } + ) & + ( + | { action: Extract; dispatch: Dispatch } + | { action: Exclude; dispatch?: never } + ) & + ( + | { + action: Extract; + clipboardData: TClipboardData | null; + } + | { action: Exclude; clipboardData?: never } + ) & + ( + | { + action: Extract; + targetNode: TFileNode; + } + | { action: Exclude; targetNode?: never } ); export type TZipFileInfo = { diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/duplicateNode.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/duplicateNode.ts index 92cb98db..6cd305f9 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/duplicateNode.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/helpers/duplicateNode.ts @@ -1,11 +1,14 @@ -import { TFileHandlerCollection, TFileNodeData } from "@_node/file"; +import { + TFileHandlerCollection, + TFileNodeData, + moveLocalFF, +} from "@_node/file"; import { TNodeTreeData, TNodeUid } from "@_node/types"; import { verifyFileHandlerPermission } from "@_services/main"; import { TToast } from "@_types/global"; import { duplicatingWarning, invalidDirError } from "../errors"; import { generateNewNodeName } from "./"; -import { moveActions } from "./moveActions"; export const duplicateNode = async ( uid: TNodeUid, @@ -16,8 +19,6 @@ export const duplicateNode = async ( addInvalidNodes: any, invalidNodes: { [uid: string]: boolean }, ) => { - const { moveLocalFF } = moveActions(addMessage); - const node = ffTree[uid]; if (!node) return; diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts index d862c158..7f39e86f 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts @@ -8,12 +8,23 @@ export const generateNewNameMoveNode = async ( let newName = nodeData.kind === "directory" ? nodeData.name - : `${nodeData.name}${nodeData.ext}`; - if (copy) { - if (nodeData.kind === "directory") { - let folderName = nodeData.name; - let exists = false; + : `${nodeData.name}.${nodeData.ext}`; + + // if (copy) { + if (nodeData.kind === "directory") { + let folderName = nodeData.name; + let exists = false; + try { + await targetHandler.getDirectoryHandle(folderName, { + create: false, + }); + exists = true; + } catch (err) { + exists = false; + } + if (exists) { try { + folderName = `${nodeData.name} copy`; await targetHandler.getDirectoryHandle(folderName, { create: false, }); @@ -22,35 +33,35 @@ export const generateNewNameMoveNode = async ( exists = false; } if (exists) { - try { - folderName = `${nodeData.name} copy`; - await targetHandler.getDirectoryHandle(folderName, { - create: false, - }); - exists = true; - } catch (err) { - exists = false; - } - if (exists) { - let index = 0; - while (exists) { - try { - folderName = `${nodeData.name} copy (${++index})`; - await targetHandler.getDirectoryHandle(folderName, { - create: false, - }); - exists = true; - } catch (err) { - exists = false; - } + let index = 0; + while (exists) { + try { + folderName = `${nodeData.name} copy (${++index})`; + await targetHandler.getDirectoryHandle(folderName, { + create: false, + }); + exists = true; + } catch (err) { + exists = false; } } } - newName = folderName; - } else { - let fileName = `${nodeData.name}${nodeData.ext}`; - let exists = false; + } + newName = folderName; + } else { + let fileName = `${nodeData.name}.${nodeData.ext}`; + let exists = false; + try { + await targetHandler.getFileHandle(fileName, { + create: false, + }); + exists = true; + } catch (err) { + exists = false; + } + if (exists) { try { + fileName = `${nodeData.name} copy.${nodeData.ext}`; await targetHandler.getFileHandle(fileName, { create: false, }); @@ -59,32 +70,23 @@ export const generateNewNameMoveNode = async ( exists = false; } if (exists) { - try { - fileName = `${nodeData.name} copy${nodeData.ext}`; - await targetHandler.getFileHandle(fileName, { - create: false, - }); - exists = true; - } catch (err) { - exists = false; - } - if (exists) { - let index = 0; - while (exists) { - try { - fileName = `${nodeData.name} copy (${++index})${nodeData.ext}`; - await targetHandler.getFileHandle(fileName, { - create: false, - }); - exists = true; - } catch (err) { - exists = false; - } + let index = 0; + while (exists) { + try { + fileName = `${nodeData.name} copy (${++index}).${nodeData.ext}`; + await targetHandler.getFileHandle(fileName, { + create: false, + }); + exists = true; + } catch (err) { + exists = false; } } - newName = fileName; } + newName = fileName; } } + // } + return newName; }; diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/index.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/index.ts index c88c8b73..55ead0df 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/index.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/helpers/index.ts @@ -1,12 +1,9 @@ -export * from "./moveActions"; export * from "./copyDirectory"; -export * from "./moveFile"; export * from "./moveDirectory"; export * from "./createFileOrFolder"; export * from "./deleteFileOrFolder"; export * from "./generateNewName"; export * from "./renameNode"; -export * from "./validateAndMoveNode"; export * from "./generateNewNameMoveNode"; export * from "./duplicateNode"; export * from "./generateNewNodeName"; diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/moveActions.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/moveActions.ts deleted file mode 100644 index 1224f7c2..00000000 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/moveActions.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { - _getIDBDirectoryOrFileStat, - _readIDBFile, - _removeIDBDirectoryOrFile, - TFileNodeData, - _writeIDBFile, -} from "@_node/file"; -import { TToast } from "@_types/global"; - -import { copyDirectory, moveDirectory, moveFile } from "./"; - -export const moveActions = (addMessage: (message: TToast) => void) => { - const moveLocalFF = async ( - handler: FileSystemHandle, - parentHandler: FileSystemDirectoryHandle, - targetHandler: FileSystemDirectoryHandle, - newName: string, - copy: boolean = false, - showWarning: boolean = false, - ) => { - if (handler.kind === "directory") { - // validate if the new name exists - let exists = true; - try { - await targetHandler.getDirectoryHandle(newName, { create: false }); - exists = true; - } catch (err) { - exists = false; - } - if (exists) { - showWarning && - addMessage({ - type: "error", - content: "Folder with the same name already exists.", - }); - return; - } - - // move nested handler-dir to targetHandler with the newName - copy (optional) - try { - const newHandler = await targetHandler.getDirectoryHandle(newName, { - create: true, - }); - await copyDirectory( - handler as FileSystemDirectoryHandle, - newHandler, - copy, - ); - } catch (err) { - throw new Error("error"); - } - } else { - await moveFile( - handler, - parentHandler, - targetHandler, - newName, - copy, - showWarning, - addMessage, - ); - } - }; - - const moveIDBFF = async ( - nodeData: TFileNodeData, - targetNodeData: TFileNodeData, - newName: string, - copy: boolean = false, - showWarning: boolean = false, - ) => { - if (nodeData.kind === "directory") { - // validate if the new name exists - let exists = true; - try { - await _getIDBDirectoryOrFileStat(`${targetNodeData.path}/${newName}`); - exists = true; - } catch (err) { - exists = false; - } - if (exists) { - showWarning && - addMessage({ - type: "error", - content: "Folder with the same name already exists.", - }); - return; - } - - // move nested handler-dir to targetHandler with the newName - copy (optional) - try { - const dirs = [ - { - orgPath: nodeData.path, - newPath: `${targetNodeData.path}/${newName}`, - }, - ]; - - for (const { orgPath, newPath } of dirs) { - await moveDirectory(orgPath, newPath, copy, nodeData); - } - } catch (err) { - throw "error"; - } - } else { - // validate if the new name exists - let exists = true; - try { - await _getIDBDirectoryOrFileStat(`${targetNodeData.path}/${newName}`); - exists = true; - } catch (err) { - exists = false; - } - if (exists) { - showWarning && - addMessage({ - type: "error", - content: "File with the same name already exists.", - }); - return; - } - - // create a new file with the new name and write the content - try { - await _writeIDBFile( - `${targetNodeData.path}/${newName}`, - await _readIDBFile(nodeData.path), - ); - - // handle copy(optional) - !copy && (await _removeIDBDirectoryOrFile(nodeData.path)); - } catch (err) { - throw "error"; - } - } - }; - - return { - moveLocalFF, - moveIDBFF, - }; -}; diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/moveFile.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/moveFile.ts deleted file mode 100644 index 116e113b..00000000 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/moveFile.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { TToast } from "@_types/global"; - -export const moveFile = async ( - handler: FileSystemHandle, - parentHandler: FileSystemDirectoryHandle, - targetHandler: FileSystemDirectoryHandle, - newName: string, - copy: boolean, - showWarning: boolean, - addMessage: (message: TToast) => void, -) => { - // validate if the new name exists - let exists = true; - try { - await targetHandler.getFileHandle(newName, { create: false }); - exists = true; - } catch (err) { - exists = false; - } - if (exists) { - showWarning && - addMessage({ - type: "error", - content: "File with the same name already exists.", - }); - return; - } - - // create a new file with the new name and write the content - try { - const newFile = await targetHandler.getFileHandle(newName, { - create: true, - }); - const content = await (handler as FileSystemFileHandle).getFile(); - const writableStream = await newFile.createWritable(); - await writableStream.write(content); - await writableStream.close(); - - // handle copy(optional) - !copy && - (await parentHandler.removeEntry(handler.name, { recursive: true })); - } catch (err) { - throw new Error("error"); - } -}; diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/renameNode.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/renameNode.ts index c4d3fa14..abdeefe4 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/renameNode.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/helpers/renameNode.ts @@ -2,7 +2,7 @@ import { useContext } from "react"; import { useDispatch } from "react-redux"; -import { TFileNodeData } from "@_node/file"; +import { TFileNodeData, moveIDBFF, moveLocalFF } from "@_node/file"; import { TNode, TNodeUid } from "@_node/types"; import { MainContext } from "@_redux/main"; import { @@ -14,7 +14,6 @@ import { useAppState } from "@_redux/useAppState"; import { verifyFileHandlerPermission } from "@_services/main"; import { useInvalidNodes } from "../hooks"; -import { moveActions } from "./moveActions"; export const renameNode = async ( ext: string, @@ -32,8 +31,6 @@ export const renameNode = async ( const { removeInvalidNodes, addInvalidNodes } = useInvalidNodes(); - const { moveIDBFF, moveLocalFF } = moveActions(() => {}); - const _orgName = ext === "*folder" ? `${nodeData.name}` : `${nodeData.name}${nodeData.ext}`; @@ -77,7 +74,7 @@ export const renameNode = async ( addInvalidNodes(newUid); try { - await moveIDBFF(nodeData, parentNodeData, _newName, false, true); + await moveIDBFF(nodeData, parentNodeData, _newName, false); removeInvalidNodes(newUid); } catch (err) { // addMessage(renamingError); diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/validateAndMoveNode.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/validateAndMoveNode.ts deleted file mode 100644 index 7aa4a24e..00000000 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/validateAndMoveNode.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { useContext } from "react"; - -import { TFileNodeData } from "@_node/file"; -import { TNodeUid } from "@_node/types"; -import { MainContext } from "@_redux/main"; -import { useAppState } from "@_redux/useAppState"; -import { verifyFileHandlerPermission } from "@_services/main"; - -import { useInvalidNodes } from "../hooks"; -import { generateNewNameMoveNode } from "./generateNewNameMoveNode"; -import { moveActions } from "./moveActions"; - -export const validateAndMoveNode = async ( - uid: string, - targetUid: TNodeUid, - copy: boolean = false, -) => { - const { project, fileTree } = useAppState(); - - const { fileHandlers } = useContext(MainContext); - - const { addInvalidNodes }: any = useInvalidNodes(); - - const { moveIDBFF, moveLocalFF } = moveActions(() => {}); - - const node = fileTree[uid]; - - if (node === undefined) { - return false; - } - - const nodeData = node.data as TFileNodeData; - const parentNode = fileTree[node.parentUid as TNodeUid]; - - if (parentNode === undefined) { - return false; - } - - const handler = fileHandlers[uid]; - const parentHandler = fileHandlers[ - parentNode.uid - ] as FileSystemDirectoryHandle; - - if ( - !(await verifyFileHandlerPermission(handler)) || - !(await verifyFileHandlerPermission(parentHandler)) - ) { - return false; - } - - const newUid = `${targetUid}/${await generateNewNameMoveNode( - nodeData, - parentHandler, - copy, - )}`; - - // update invalidNodes - addInvalidNodes((prevState: Record) => ({ - ...prevState, - [uid]: true, - [newUid]: true, - })); - - // move - try { - if (project.context === "local") { - await moveLocalFF(handler, parentHandler, parentHandler, newUid, copy); - } else if (project.context === "idb") { - const targetNode = fileTree[targetUid]; - const targetNodeData = targetNode.data as TFileNodeData; - await moveIDBFF(nodeData, targetNodeData, newUid, copy); - } - return true; - } catch (err) { - return false; - } finally { - // update invalidNodes - addInvalidNodes((prevState: Record) => { - delete prevState[uid]; - delete prevState[newUid]; - return { ...prevState }; - }); - } -}; diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts index 50567ffb..efb24333 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts @@ -44,7 +44,7 @@ export const useCmdk = ({ currentCommand, } = useAppState(); - const { createTmpFFNode, cb_deleteNode, cb_moveNode, cb_duplicateNode } = + const { createTmpFFNode, onDelete, onCut, cb_moveNode, cb_duplicateNode } = useNodeActionsHandler({ invalidNodes, addInvalidNodes, @@ -64,15 +64,12 @@ export const useCmdk = ({ }, [createTmpFFNode], ); - const onDelete = useCallback(() => { - cb_deleteNode(); - }, [cb_deleteNode]); - const onCut = useCallback(() => { + const onCopy = useCallback(() => { dispatch( setClipboardData({ panel: "file", - type: "cut", + type: "copy", uids: selectedItems, fileType: fileTree[currentFileUid].data.type, data: [], @@ -82,18 +79,6 @@ export const useCmdk = ({ ); }, [selectedItems, fileTree[currentFileUid], nodeTree]); - const onCopy = useCallback(() => { - setClipboardData({ - panel: "file", - type: "copy", - uids: selectedItems, - fileType: fileTree[currentFileUid].data.type, - data: [], - fileUid: currentFileUid, - prevNodeTree: nodeTree, - }); - }, [selectedItems, fileTree[currentFileUid], nodeTree]); - const onPaste = useCallback(() => { if (clipboardData?.panel !== "file") return; @@ -103,15 +88,17 @@ export const useCmdk = ({ if (uids.length === 0) return; if (clipboardData.type === "cut") { - setClipboardData({ - panel: "file", - type: "cut", - uids: [], - fileType: "html", - data: [], - fileUid: "", - prevNodeTree: {}, - }); + dispatch( + setClipboardData({ + panel: "file", + type: "cut", + uids: [], + fileType: "html", + data: [], + fileUid: "", + prevNodeTree: {}, + }), + ); cb_moveNode(uids, focusedItem); } else if (clipboardData.type === "copy") { cb_moveNode(uids, focusedItem, true); diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useFileOperations.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useFileOperations.ts index 4d137994..d1f8e783 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useFileOperations.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useFileOperations.ts @@ -1,17 +1,13 @@ import { useCallback, useContext } from "react"; -import { TFileNodeData } from "@_node/file"; +import { TFileNodeData, moveIDBFF, moveLocalFF } from "@_node/file"; import { TNodeUid } from "@_node/types"; import { MainContext } from "@_redux/main"; import { useAppState } from "@_redux/useAppState"; import { verifyFileHandlerPermission } from "@_services/main"; import { TFileNodeType } from "@_types/main"; -import { - createFileOrFolder, - deleteFileOrFolder, - moveActions, -} from "../helpers"; +import { createFileOrFolder, deleteFileOrFolder } from "../helpers"; import { LogAllow } from "@_constants/global"; interface IUseFileOperations { @@ -38,8 +34,6 @@ export const useFileOperations = ({ const { addRunningActions, removeRunningActions, fileHandlers } = useContext(MainContext); - const { moveIDBFF, moveLocalFF } = moveActions(() => {}); - const _create = useCallback( async (params: { parentUid: TNodeUid; diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts index 6db9f00e..c821b9eb 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts @@ -14,7 +14,6 @@ import { TFileNodeData, _writeIDBFile, confirmAlert, - loadLocalProject, } from "@_node/file"; import { getValidNodeUids } from "@_node/helpers"; import { TNode, TNodeTreeData, TNodeUid } from "@_node/types"; @@ -36,12 +35,7 @@ import { useAppState } from "@_redux/useAppState"; import { verifyFileHandlerPermission } from "@_services/main"; import { TFileNodeType } from "@_types/main"; -import { - duplicateNode, - generateNewName, - renameNode, - validateAndMoveNode, -} from "../helpers"; +import { duplicateNode, generateNewName, renameNode } from "../helpers"; import { callFileApi } from "@_node/apis"; import { LogAllow } from "@_constants/global"; @@ -77,6 +71,8 @@ export const useNodeActionsHandler = ({ fFocusedItem: focusedItem, fExpandedItemsObj: expandedItemsObj, fSelectedItems: selectedItems, + nodeTree, + clipboardData, } = useAppState(); const { addRunningActions, @@ -303,8 +299,27 @@ export const useNodeActionsHandler = ({ removeInvalidNodes, ], ); + const onCut = useCallback(async () => { + const uids = selectedItems.filter((uid) => !invalidNodes[uid]); + if (uids.length === 0) return; - const cb_deleteNode = useCallback(async () => { + await callFileApi( + { + projectContext: project.context, + dispatch, + action: "cut", + fileTree, + currentFileUid, + uids, + nodeTree, + }, + () => { + LogAllow && console.error("error while cutting file system"); + }, + ); + }, [selectedItems, fileTree[currentFileUid], nodeTree]); + + const onDelete = useCallback(async () => { const uids = selectedItems.filter((uid) => !invalidNodes[uid]); if (uids.length === 0) return; @@ -349,46 +364,56 @@ export const useNodeActionsHandler = ({ ]); const cb_moveNode = useCallback( - async (uids: TNodeUid[], targetUid: TNodeUid, copy: boolean = false) => { + async (uids: string[], targetUid: TNodeUid, copy: boolean = false) => { // validate const targetNode = fileTree[targetUid]; - if (targetNode === undefined) { return; } - const validatedUids = getValidNodeUids(fileTree, uids, targetUid); - if (validatedUids.length === 0) { return; } - - // confirm files' changes + // confirm files changes const hasChangedFile = validatedUids.some((uid) => { const _file = fileTree[uid]; const _fileData = _file.data as TFileNodeData; return _file && _fileData.changed; }); - if (hasChangedFile && !confirmAlert(FileChangeAlertMessage)) return; - addRunningActions(["fileTreeView-move"]); - - const _uids = await Promise.all( - validatedUids.map((uid) => validateAndMoveNode(uid, targetUid, copy)), + addInvalidNodes(...validatedUids); + await callFileApi( + { + projectContext: project.context, + action: "move", + fileHandlers, + uids, + fileTree, + targetNode, + clipboardData, + }, + () => { + LogAllow && console.error("error while pasting file system"); + }, + (allDone: boolean) => { + reloadCurrentProject(fileTree, currentProjectFileHandle); + LogAllow && + console.log( + allDone ? "all is successfully past" : "some is not past", + ); + }, ); - - if (_uids.some((result) => !result)) { - // addMessage(movingError); - } - + removeInvalidNodes(...validatedUids); + // if (_uids.some((result) => !result)) { + // // addMessage(movingError); + // } const action: TFileAction = { type: copy ? "copy" : "cut", - param1: _uids, - param2: _uids.map(() => targetUid), + // param1: _uids, + // param2: _uids.map(() => targetUid), }; dispatch(setFileAction(action)); - removeRunningActions(["fileTreeView-move"]); }, [ @@ -536,7 +561,8 @@ export const useNodeActionsHandler = ({ cb_abortRenamingNode, cb_renameNode, _cb_renameNode, - cb_deleteNode, + onCut, + onDelete, cb_moveNode, cb_duplicateNode, cb_readNode, From e547bbab9b038845c80adfb0af319ca0b8b2ccca Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:13:53 +0530 Subject: [PATCH 2/9] Add copy functionality to file actions --- src/_node/file/actions.ts | 31 ++++++++++++++++++++++++++++--- src/_node/file/types.ts | 28 ++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index 1cfe428e..6e700a26 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -74,7 +74,33 @@ const cut = ({ }), ); }; -const copy = () => {}; + +const copy = ({ + dispatch, + uids, + fileTree, + currentFileUid, + nodeTree, +}: { + dispatch: Dispatch; + uids: TNodeUid[]; + fileTree: TFileNodeTreeData; + currentFileUid: string; + nodeTree: TNodeTreeData; +}) => { + dispatch( + setClipboardData({ + panel: "file", + type: "copy", + uids, + fileType: fileTree[currentFileUid].data.type, + data: [], + fileUid: currentFileUid, + prevNodeTree: nodeTree, + }), + ); +}; + const duplicate = () => {}; const move = async ({ projectContext, @@ -167,7 +193,6 @@ export const doFileActions = async ( uids, fileTree, fileHandlers, - osType = "Windows", dispatch, currentFileUid, nodeTree, @@ -198,7 +223,7 @@ export const doFileActions = async ( }); break; case "copy": - copy(); + copy({ dispatch, uids, fileTree, currentFileUid, nodeTree }); break; case "duplicate": duplicate(); diff --git a/src/_node/file/types.ts b/src/_node/file/types.ts index d4431698..f07bfef2 100644 --- a/src/_node/file/types.ts +++ b/src/_node/file/types.ts @@ -83,25 +83,37 @@ export type TFileApiPayloadBase = { export type TFileApiPayload = TFileApiPayloadBase & ( | { - action: Extract; + action: Extract; uids: TNodeUid[]; } | { - action: Exclude; + action: Exclude; uids?: never; } ) & ( - | { action: Extract; currentFileUid: string } - | { action: Exclude; currentFileUid?: never } + | { + action: Extract; + currentFileUid: string; + } + | { + action: Exclude; + currentFileUid?: never; + } ) & ( - | { action: Extract; nodeTree: TNodeTreeData } - | { action: Exclude; nodeTree?: never } + | { + action: Extract; + nodeTree: TNodeTreeData; + } + | { action: Exclude; nodeTree?: never } ) & ( - | { action: Extract; dispatch: Dispatch } - | { action: Exclude; dispatch?: never } + | { + action: Extract; + dispatch: Dispatch; + } + | { action: Exclude; dispatch?: never } ) & ( | { From 5781e66922b015de905ae1bb208d23d09400e08b Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:58:01 +0530 Subject: [PATCH 3/9] Refactor file actions and use file API --- src/_node/file/actions.ts | 103 +++++++++--------- .../workspaceTreeView/hooks/useCmdk.ts | 72 ++++++------ 2 files changed, 92 insertions(+), 83 deletions(-) diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index 6e700a26..401b5c14 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -49,57 +49,6 @@ const remove = async ({ } }); }; -const cut = ({ - dispatch, - uids, - fileTree, - currentFileUid, - nodeTree, -}: { - dispatch: Dispatch; - uids: TNodeUid[]; - fileTree: TFileNodeTreeData; - currentFileUid: string; - nodeTree: TNodeTreeData; -}) => { - dispatch( - setClipboardData({ - panel: "file", - type: "cut", - uids, - fileType: fileTree[currentFileUid].data.type, - data: [], - fileUid: currentFileUid, - prevNodeTree: nodeTree, - }), - ); -}; - -const copy = ({ - dispatch, - uids, - fileTree, - currentFileUid, - nodeTree, -}: { - dispatch: Dispatch; - uids: TNodeUid[]; - fileTree: TFileNodeTreeData; - currentFileUid: string; - nodeTree: TNodeTreeData; -}) => { - dispatch( - setClipboardData({ - panel: "file", - type: "copy", - uids, - fileType: fileTree[currentFileUid].data.type, - data: [], - fileUid: currentFileUid, - prevNodeTree: nodeTree, - }), - ); -}; const duplicate = () => {}; const move = async ({ @@ -179,6 +128,58 @@ const move = async ({ }); }; +const cut = ({ + dispatch, + uids, + fileTree, + currentFileUid, + nodeTree, +}: { + dispatch: Dispatch; + uids: TNodeUid[]; + fileTree: TFileNodeTreeData; + currentFileUid: string; + nodeTree: TNodeTreeData; +}) => { + dispatch( + setClipboardData({ + panel: "file", + type: "cut", + uids, + fileType: fileTree[currentFileUid].data.type, + data: [], + fileUid: currentFileUid, + prevNodeTree: nodeTree, + }), + ); +}; + +const copy = ({ + dispatch, + uids, + fileTree, + currentFileUid, + nodeTree, +}: { + dispatch: Dispatch; + uids: TNodeUid[]; + fileTree: TFileNodeTreeData; + currentFileUid: string; + nodeTree: TNodeTreeData; +}) => { + dispatch( + setClipboardData({ + panel: "file", + type: "copy", + uids, + fileType: fileTree[currentFileUid].data.type, + data: [], + fileUid: currentFileUid, + prevNodeTree: nodeTree, + }), + ); +}; + const rename = () => {}; export const doFileActions = async ( diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts index efb24333..d4cf9259 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect } from "react"; +import { useCallback, useContext, useEffect } from "react"; import { useDispatch } from "react-redux"; @@ -9,6 +9,8 @@ import { TFileNodeType } from "@_types/main"; import { useNodeActionsHandler } from "./useNodeActionsHandler"; import { isAddFileAction } from "@_node/helpers"; +import { TFileApiPayload, doFileActions } from "@_node/index"; +import { MainContext } from "@_redux/main"; interface IUseCmdk { invalidNodes: { @@ -44,7 +46,8 @@ export const useCmdk = ({ currentCommand, } = useAppState(); - const { createTmpFFNode, onDelete, onCut, cb_moveNode, cb_duplicateNode } = + const { fileHandlers } = useContext(MainContext); + const { createTmpFFNode, onCut, cb_moveNode, cb_duplicateNode } = useNodeActionsHandler({ invalidNodes, addInvalidNodes, @@ -66,49 +69,54 @@ export const useCmdk = ({ ); const onCopy = useCallback(() => { - dispatch( - setClipboardData({ - panel: "file", - type: "copy", - uids: selectedItems, - fileType: fileTree[currentFileUid].data.type, - data: [], - fileUid: currentFileUid, - prevNodeTree: nodeTree, - }), - ); + const params: TFileApiPayload = { + projectContext: "idb", + action: "copy", + uids: selectedItems, + fileTree, + fileHandlers, + dispatch, + currentFileUid, + nodeTree, + }; + doFileActions(params); }, [selectedItems, fileTree[currentFileUid], nodeTree]); const onPaste = useCallback(() => { if (clipboardData?.panel !== "file") return; - + const params: TFileApiPayload = { + projectContext: "idb", + fileHandlers, + uids: selectedItems, + clipboardData, + fileTree, + action: "move", + targetNode: fileTree[focusedItem], + }; // validate if (invalidNodes[focusedItem]) return; const uids = clipboardData.uids.filter((uid) => !invalidNodes[uid]); if (uids.length === 0) return; - - if (clipboardData.type === "cut") { - dispatch( - setClipboardData({ - panel: "file", - type: "cut", - uids: [], - fileType: "html", - data: [], - fileUid: "", - prevNodeTree: {}, - }), - ); - cb_moveNode(uids, focusedItem); - } else if (clipboardData.type === "copy") { - cb_moveNode(uids, focusedItem, true); - } + doFileActions(params); }, [clipboardData, invalidNodes, focusedItem, cb_moveNode]); const onDuplicate = useCallback(() => { - cb_duplicateNode(); + if (clipboardData?.panel !== "file") return; + onCopy(); + onPaste(); }, [cb_duplicateNode]); + const onDelete = useCallback(() => { + const params: TFileApiPayload = { + projectContext: "idb", + action: "remove", + uids: selectedItems, + fileTree, + fileHandlers, + }; + doFileActions(params); + }, [selectedItems, fileTree[currentFileUid], nodeTree]); + useEffect(() => { if (!currentCommand) return; if (isAddFileAction(currentCommand.action)) { From 7f05692950174d76f3c0aa2f825e46968a71a9a7 Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Mon, 18 Dec 2023 12:31:18 +0530 Subject: [PATCH 4/9] Fix file system removal bug in useCmdk --- .../workspaceTreeView/hooks/useCmdk.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts index d4cf9259..ebbc189b 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts @@ -11,6 +11,7 @@ import { useNodeActionsHandler } from "./useNodeActionsHandler"; import { isAddFileAction } from "@_node/helpers"; import { TFileApiPayload, doFileActions } from "@_node/index"; import { MainContext } from "@_redux/main"; +import { LogAllow } from "@_constants/global"; interface IUseCmdk { invalidNodes: { @@ -46,7 +47,8 @@ export const useCmdk = ({ currentCommand, } = useAppState(); - const { fileHandlers } = useContext(MainContext); + const { fileHandlers, reloadCurrentProject, currentProjectFileHandle } = + useContext(MainContext); const { createTmpFFNode, onCut, cb_moveNode, cb_duplicateNode } = useNodeActionsHandler({ invalidNodes, @@ -97,7 +99,19 @@ export const useCmdk = ({ if (invalidNodes[focusedItem]) return; const uids = clipboardData.uids.filter((uid) => !invalidNodes[uid]); if (uids.length === 0) return; - doFileActions(params); + doFileActions( + params, + () => { + LogAllow && console.error("error while removing file system"); + }, + (allDone: boolean) => { + reloadCurrentProject(fileTree, currentProjectFileHandle); + LogAllow && + console.log( + allDone ? "all is successfully removed" : "some is not removed", + ); + }, + ); }, [clipboardData, invalidNodes, focusedItem, cb_moveNode]); const onDuplicate = useCallback(() => { From af6f91581be153b6ba1d517fad6f7d80605ceceb Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Wed, 20 Dec 2023 10:35:47 +0530 Subject: [PATCH 5/9] Remove duplicate file action and fix file context --- src/_node/file/actions.ts | 5 +- .../workspaceTreeView/hooks/useCmdk.ts | 49 +++++++++++++------ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index 401b5c14..c23953a0 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -50,7 +50,6 @@ const remove = async ({ }); }; -const duplicate = () => {}; const move = async ({ projectContext, fileHandlers, @@ -226,9 +225,7 @@ export const doFileActions = async ( case "copy": copy({ dispatch, uids, fileTree, currentFileUid, nodeTree }); break; - case "duplicate": - duplicate(); - break; + case "move": allDone = await move({ projectContext, diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts index ebbc189b..3465908a 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts @@ -49,16 +49,15 @@ export const useCmdk = ({ const { fileHandlers, reloadCurrentProject, currentProjectFileHandle } = useContext(MainContext); - const { createTmpFFNode, onCut, cb_moveNode, cb_duplicateNode } = - useNodeActionsHandler({ - invalidNodes, - addInvalidNodes, - removeInvalidNodes, - temporaryNodes, - addTemporaryNodes, - removeTemporaryNodes, - openFileUid, - }); + const { createTmpFFNode } = useNodeActionsHandler({ + invalidNodes, + addInvalidNodes, + removeInvalidNodes, + temporaryNodes, + addTemporaryNodes, + removeTemporaryNodes, + openFileUid, + }); const onAddNode = useCallback( (actionName: string) => { @@ -72,7 +71,7 @@ export const useCmdk = ({ const onCopy = useCallback(() => { const params: TFileApiPayload = { - projectContext: "idb", + projectContext: "local", action: "copy", uids: selectedItems, fileTree, @@ -87,7 +86,7 @@ export const useCmdk = ({ const onPaste = useCallback(() => { if (clipboardData?.panel !== "file") return; const params: TFileApiPayload = { - projectContext: "idb", + projectContext: "local", fileHandlers, uids: selectedItems, clipboardData, @@ -112,25 +111,43 @@ export const useCmdk = ({ ); }, ); - }, [clipboardData, invalidNodes, focusedItem, cb_moveNode]); + }, [clipboardData, selectedItems, fileTree[currentFileUid], nodeTree]); const onDuplicate = useCallback(() => { if (clipboardData?.panel !== "file") return; onCopy(); onPaste(); - }, [cb_duplicateNode]); + }, []); const onDelete = useCallback(() => { const params: TFileApiPayload = { - projectContext: "idb", + projectContext: "local", action: "remove", uids: selectedItems, fileTree, fileHandlers, }; - doFileActions(params); + doFileActions( + params, + () => { + LogAllow && console.error("error while removing file system"); + }, + (allDone: boolean) => { + reloadCurrentProject(fileTree, currentProjectFileHandle); + LogAllow && + console.log( + allDone ? "all is successfully removed" : "some is not removed", + ); + }, + ); }, [selectedItems, fileTree[currentFileUid], nodeTree]); + const onCut = useCallback(() => { + if (clipboardData?.panel !== "file") return; + onCopy(); + onDelete(); + }, []); + useEffect(() => { if (!currentCommand) return; if (isAddFileAction(currentCommand.action)) { From c8332a521558193df8658502a7c570852227b379 Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Wed, 20 Dec 2023 11:45:47 +0530 Subject: [PATCH 6/9] fix: cut and copy functionality --- src/_node/file/actions.ts | 14 +++++++--- src/_node/file/helpers.ts | 12 ++++----- .../workspaceTreeView/hooks/useCmdk.ts | 27 ++++++++++++------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index c23953a0..3da7d8f4 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -83,10 +83,16 @@ const move = async ({ const parentHandler = fileHandlers[ parentNode.uid ] as FileSystemDirectoryHandle; - const targetHandler = fileHandlers[ - targetNode.uid - ] as FileSystemDirectoryHandle; - + let targetHandler = null; + if (targetNode.data.type === "file") { + targetHandler = fileHandlers[ + targetNode.parentUid + ] as FileSystemDirectoryHandle; + } else { + targetHandler = fileHandlers[ + targetNode.uid + ] as FileSystemDirectoryHandle; + } if ( !(await verifyFileHandlerPermission(handler)) || !(await verifyFileHandlerPermission(parentHandler)) || diff --git a/src/_node/file/helpers.ts b/src/_node/file/helpers.ts index 95e4f50b..83c3d4dd 100644 --- a/src/_node/file/helpers.ts +++ b/src/_node/file/helpers.ts @@ -100,7 +100,7 @@ export const moveFile = async ( targetHandler: FileSystemDirectoryHandle, newName: string, copy: boolean, - // showWarning?: boolean, + showWarning?: boolean, // addMessage?: (message: TToast) => void, ) => { // validate if the new name exists @@ -108,18 +108,16 @@ export const moveFile = async ( let exists = true; try { - await targetHandler.getFileHandle(newName, { create: false }); + const handlerExists = await targetHandler.getFileHandle(newName, { + create: false, + }); exists = true; } catch (err) { exists = false; } if (exists) { - // showWarning && - // addMessage({ - // type: "error", - // content: "File with the same name already exists.", - // }); + showWarning && alert("File with the same name already exists."); return; } diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts index 3465908a..3bef79b7 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts @@ -85,19 +85,20 @@ export const useCmdk = ({ const onPaste = useCallback(() => { if (clipboardData?.panel !== "file") return; + + // validate + if (invalidNodes[focusedItem]) return; + const uids = clipboardData.uids.filter((uid) => !invalidNodes[uid]); + if (uids.length === 0) return; const params: TFileApiPayload = { projectContext: "local", fileHandlers, - uids: selectedItems, + uids, clipboardData, fileTree, action: "move", targetNode: fileTree[focusedItem], }; - // validate - if (invalidNodes[focusedItem]) return; - const uids = clipboardData.uids.filter((uid) => !invalidNodes[uid]); - if (uids.length === 0) return; doFileActions( params, () => { @@ -143,10 +144,18 @@ export const useCmdk = ({ }, [selectedItems, fileTree[currentFileUid], nodeTree]); const onCut = useCallback(() => { - if (clipboardData?.panel !== "file") return; - onCopy(); - onDelete(); - }, []); + const params: TFileApiPayload = { + projectContext: "local", + action: "cut", + uids: selectedItems, + fileTree, + fileHandlers, + dispatch, + currentFileUid, + nodeTree, + }; + doFileActions(params); + }, [selectedItems, fileTree[currentFileUid], nodeTree, clipboardData]); useEffect(() => { if (!currentCommand) return; From c0998801fbebaba30b6d5f38bec4c797d82d0d51 Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:09:57 +0530 Subject: [PATCH 7/9] Fix targetNode data property name in move function --- src/_node/file/actions.ts | 3 ++- src/_node/file/helpers.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index 3da7d8f4..809d53dd 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -84,7 +84,8 @@ const move = async ({ parentNode.uid ] as FileSystemDirectoryHandle; let targetHandler = null; - if (targetNode.data.type === "file") { + + if (targetNode.data.kind === "file") { targetHandler = fileHandlers[ targetNode.parentUid ] as FileSystemDirectoryHandle; diff --git a/src/_node/file/helpers.ts b/src/_node/file/helpers.ts index 83c3d4dd..cca7ed63 100644 --- a/src/_node/file/helpers.ts +++ b/src/_node/file/helpers.ts @@ -108,7 +108,7 @@ export const moveFile = async ( let exists = true; try { - const handlerExists = await targetHandler.getFileHandle(newName, { + await targetHandler.getFileHandle(newName, { create: false, }); exists = true; From be42d5d733b148a4a4477345c9341cc76e338228 Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:21:35 +0530 Subject: [PATCH 8/9] Fix file move bug --- src/_node/file/actions.ts | 1 - .../workspaceTreeView/helpers/generateNewNameMoveNode.ts | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/_node/file/actions.ts b/src/_node/file/actions.ts index 809d53dd..e70400d9 100644 --- a/src/_node/file/actions.ts +++ b/src/_node/file/actions.ts @@ -104,7 +104,6 @@ const move = async ({ const newFileName = await generateNewNameMoveNode( nodeData, targetHandler, - clipboardData?.type === "copy", ); // move diff --git a/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts b/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts index 7f39e86f..57ee7162 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/helpers/generateNewNameMoveNode.ts @@ -3,14 +3,12 @@ import { TFileNodeData } from "@_node/file"; export const generateNewNameMoveNode = async ( nodeData: TFileNodeData, targetHandler: FileSystemDirectoryHandle, - copy: boolean, ) => { let newName = nodeData.kind === "directory" ? nodeData.name : `${nodeData.name}.${nodeData.ext}`; - // if (copy) { if (nodeData.kind === "directory") { let folderName = nodeData.name; let exists = false; @@ -86,7 +84,6 @@ export const generateNewNameMoveNode = async ( newName = fileName; } } - // } return newName; }; From 6cefb40d54c9b8df353d50e9b221756daadd5b3f Mon Sep 17 00:00:00 2001 From: Atul Bhatt <38177419+atulbhatt-system32@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:57:14 +0530 Subject: [PATCH 9/9] fix: duplicate functionality --- .../main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts index 3bef79b7..129302a2 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useCmdk.ts @@ -115,10 +115,9 @@ export const useCmdk = ({ }, [clipboardData, selectedItems, fileTree[currentFileUid], nodeTree]); const onDuplicate = useCallback(() => { - if (clipboardData?.panel !== "file") return; onCopy(); onPaste(); - }, []); + }, [selectedItems, fileTree[currentFileUid], nodeTree, clipboardData]); const onDelete = useCallback(() => { const params: TFileApiPayload = {