From c39ac13610cd97660f0bca552fb6b946d09c319e Mon Sep 17 00:00:00 2001 From: Rahul Yadav Date: Thu, 17 Oct 2024 07:36:30 +0530 Subject: [PATCH] fix: syntax highlighting and tab inconsistency on rename --- src/components/workspace/Editor/Editor.tsx | 9 +++++-- src/components/workspace/Tabs/Tabs.tsx | 13 +++++++++- .../workspace/tree/FileTree/TreeNode.tsx | 12 ++++++++- src/hooks/fileTabs.hooks.ts | 25 +++++++++++++++++++ src/hooks/projectV2.hooks.ts | 5 ++-- src/utility/eventEmitter.ts | 3 ++- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/components/workspace/Editor/Editor.tsx b/src/components/workspace/Editor/Editor.tsx index 7728055..2ff310c 100644 --- a/src/components/workspace/Editor/Editor.tsx +++ b/src/components/workspace/Editor/Editor.tsx @@ -122,11 +122,16 @@ const Editor: FC = ({ className = '' }) => { EventEmitter.on('SAVE_FILE', updateFileSaveCounter); // If file is changed e.g. in case of build process then force update in editor - EventEmitter.on('FORCE_UPDATE_FILE', (filePath: string) => { - if (!activeProject?.path || latestFile.current?.includes('setting.json')) + EventEmitter.on('FORCE_UPDATE_FILE', (file) => { + if ( + !activeProject?.path || + (latestFile.current?.includes('setting.json') && + typeof file == 'string') + ) return; (async () => { + const filePath = typeof file === 'string' ? file : file.newPath; if (filePath !== latestFile.current) return; await fetchFileContent(true); })().catch((error) => { diff --git a/src/components/workspace/Tabs/Tabs.tsx b/src/components/workspace/Tabs/Tabs.tsx index bbcfa2e..26ecfd7 100644 --- a/src/components/workspace/Tabs/Tabs.tsx +++ b/src/components/workspace/Tabs/Tabs.tsx @@ -6,8 +6,13 @@ import { delay, fileTypeFromFileName } from '@/utility/utils'; import { FC, useEffect } from 'react'; import s from './Tabs.module.scss'; +interface IRenameFile { + oldPath: string; + newPath: string; +} + const Tabs: FC = () => { - const { fileTab, open, close, syncTabSettings, updateFileDirty } = + const { fileTab, open, close, rename, syncTabSettings, updateFileDirty } = useFileTab(); const { activeProject } = useProject(); @@ -21,6 +26,10 @@ const Tabs: FC = () => { updateFileDirty(filePath, false); }; + const onFileRename = ({ oldPath, newPath }: IRenameFile) => { + rename(oldPath, newPath); + }; + useEffect(() => { (async () => { await delay(200); @@ -30,8 +39,10 @@ const Tabs: FC = () => { useEffect(() => { EventEmitter.on('FILE_SAVED', onFileSave); + EventEmitter.on('FILE_RENAMED', onFileRename); return () => { EventEmitter.off('FILE_SAVED', onFileSave); + EventEmitter.off('FILE_RENAMED', onFileRename); }; }, [updateFileDirty]); diff --git a/src/components/workspace/tree/FileTree/TreeNode.tsx b/src/components/workspace/tree/FileTree/TreeNode.tsx index b73b1e3..390f8e0 100644 --- a/src/components/workspace/tree/FileTree/TreeNode.tsx +++ b/src/components/workspace/tree/FileTree/TreeNode.tsx @@ -2,6 +2,7 @@ import { useFile, useFileTab } from '@/hooks'; import { useLogActivity } from '@/hooks/logActivity.hooks'; import { useProject } from '@/hooks/projectV2.hooks'; import { Project, Tree } from '@/interfaces/workspace.interface'; +import EventEmitter from '@/utility/eventEmitter'; import { encodeBase64, fileTypeFromFileName } from '@/utility/utils'; import { NodeModel } from '@minoru/react-dnd-treeview'; import { message } from 'antd'; @@ -59,7 +60,16 @@ const TreeNode: FC = ({ node, depth, isOpen, onToggle }) => { const commitEditing = async (name: string) => { try { - await renameProjectFile(node.data?.path as string, name); + const { success, oldPath, newPath } = await renameProjectFile( + node.data?.path as string, + name, + ); + if (success && newPath) { + EventEmitter.emit('FILE_RENAMED', { + oldPath, + newPath, + }); + } reset(); } catch (error) { createLog((error as Error).message, 'error'); diff --git a/src/hooks/fileTabs.hooks.ts b/src/hooks/fileTabs.hooks.ts index d8d0aa0..291cd0a 100644 --- a/src/hooks/fileTabs.hooks.ts +++ b/src/hooks/fileTabs.hooks.ts @@ -106,6 +106,30 @@ const useFileTab = () => { syncTabSettings(updatedTab); }; + const rename = (oldPath: string, newPath: string) => { + const updatedItems = fileTab.items.map((item) => { + if (item.path === oldPath) { + return { + ...item, + path: newPath, + name: newPath.split('/').pop() ?? item.name, + }; + } + return item; + }); + + // Check if the old path was the active tab + const isActiveTab = fileTab.active === oldPath; + + const updatedTab = { + items: updatedItems, + active: isActiveTab ? newPath : fileTab.active, // Set the active tab to the new path if it was renamed + }; + + syncTabSettings(updatedTab); + EventEmitter.emit('FORCE_UPDATE_FILE', newPath); + }; + const updateFileDirty = (filePath: string, isDirty: boolean) => { const updatedItems = cloneDeep(fileTab).items.map((item) => { if (item.path === filePath) { @@ -126,6 +150,7 @@ const useFileTab = () => { fileTab, open, close, + rename, syncTabSettings, updateFileDirty, hasDirtyFiles, diff --git a/src/hooks/projectV2.hooks.ts b/src/hooks/projectV2.hooks.ts index 502e20d..3fe0c09 100644 --- a/src/hooks/projectV2.hooks.ts +++ b/src/hooks/projectV2.hooks.ts @@ -266,14 +266,15 @@ export const useProject = () => { }; const renameProjectFile = async (oldPath: string, newName: string) => { - if (!activeProject?.path) return; + if (!activeProject?.path) return { success: false }; const newPath = oldPath.includes('/') ? oldPath.split('/').slice(0, -1).join('/') + '/' + newName : newName; const success = await fileSystem.rename(oldPath, newPath); - if (!success) return; + if (!success) return { success: false }; await loadProjectFiles(activeProject.path); + return { success: true, oldPath, newPath }; }; const updateActiveProject = async ( diff --git a/src/utility/eventEmitter.ts b/src/utility/eventEmitter.ts index e494285..e9e87ba 100644 --- a/src/utility/eventEmitter.ts +++ b/src/utility/eventEmitter.ts @@ -9,8 +9,9 @@ export interface EventEmitterPayloads { LOG: LogEntry; ON_SPLIT_DRAG_END: { position?: number }; SAVE_FILE: undefined | { fileId: string; content: string }; - FORCE_UPDATE_FILE: string; + FORCE_UPDATE_FILE: string | { oldPath: string; newPath: string }; FILE_SAVED: { filePath: string }; + FILE_RENAMED: { oldPath: string; newPath: string }; TEST_CASE_LOG: string; RELOAD_PROJECT_FILES: string; OPEN_PROJECT: string;