UNPKG

vzcode

Version:
168 lines (159 loc) 4.44 kB
import { useCallback } from 'react'; import { FileTreePath } from '../types'; import { VizFileId, VizContent } from '@vizhub/viz-types'; import { randomId } from '../randomId'; // CRUD operations for files and directories // CRUD = Create, Read, Update, Delete export const useFileCRUD = ({ submitOperation, closeTabs, openTab, }: { submitOperation: ( operation: (document: VizContent) => VizContent, ) => void; closeTabs: (idsToDelete: Array<VizFileId>) => void; openTab: ({ fileId, isTransient, }: { fileId: VizFileId; isTransient: boolean; }) => void; }) => { // Create a new file const createFile = useCallback( (name: string, text = '') => { if (name) { const fileId: VizFileId = randomId(); submitOperation((document: VizContent) => ({ ...document, files: { ...document.files, [fileId]: { name, text }, }, })); // When a new file is created, open it in a new tab // and focus the editor on it. openTab({ fileId, isTransient: false }); } }, [submitOperation], ); const createDirectory = useCallback( (name: string, text = null) => { if (name) { name += '/'; const fileId: VizFileId = randomId(); submitOperation((document: VizContent) => ({ ...document, files: { ...document.files, [fileId]: { name, text }, }, })); } }, [submitOperation], ); // Called when a file in the sidebar is renamed. const renameFile = useCallback( (fileId: VizFileId, newName: string) => { submitOperation((document: VizContent) => ({ ...document, files: { ...document.files, [fileId]: { ...document.files[fileId], name: document.files[fileId].name.substring( 0, document.files[fileId].name.lastIndexOf( '/', ) + 1, ) + newName, }, }, })); }, [submitOperation], ); // Renames a directory const renameDirectory = useCallback( ( path: FileTreePath, oldName: string, newName: string, ) => { submitOperation((document: VizContent) => { const updatedFiles = Object.keys( document.files, ).reduce((acc, key) => { const file = document.files[key]; const fileName = file.name; //See if it's actually in directory if (fileName.includes(path + '/')) { //Create New Name for System const pathPart = fileName.substring( 0, fileName.indexOf(path) + path.length, ); const oldNamePos = pathPart.lastIndexOf(oldName); const fileNewName = fileName.substring(0, oldNamePos) + newName + fileName.substring( oldNamePos + oldName.length, ); //Return with new names acc[key] = { ...file, name: fileNewName }; } else { acc[key] = file; } return acc; }, {}); return { ...document, files: updatedFiles }; }); }, [submitOperation], ); // Deletes a file const deleteFile = useCallback( (fileId: VizFileId) => { closeTabs([fileId]); submitOperation((document) => { const updatedFiles = { ...document.files }; delete updatedFiles[fileId]; return { ...document, files: updatedFiles }; }); }, [submitOperation, closeTabs], ); // Deletes a directory and all files within it const deleteDirectory = useCallback( (path: FileTreePath) => { const tabsToClose: Array<VizFileId> = []; submitOperation((document: VizContent) => { const updatedFiles = { ...document.files }; for (const key in updatedFiles) { if (updatedFiles[key].name.includes(path + '/')) { tabsToClose.push(key); delete updatedFiles[key]; } } return { ...document, files: updatedFiles }; }); closeTabs(tabsToClose); }, [submitOperation, closeTabs], ); return { createFile, renameFile, deleteFile, createDirectory, renameDirectory, deleteDirectory, }; };