From eecb1ea51e88f3f0eaeafda051d8a683dffadbd0 Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 4 Dec 2023 23:56:14 +0800 Subject: [PATCH 1/9] typo fixes --- .../main/stageView/iFrame/hooks/useCmdk.ts | 1 - .../stageView/iFrame/hooks/useMouseEvents.ts | 1 - .../main/processor/hooks/useNodeTreeEvent.ts | 20 +++++++++---------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/components/main/stageView/iFrame/hooks/useCmdk.ts b/src/components/main/stageView/iFrame/hooks/useCmdk.ts index caa869b6..9392240d 100644 --- a/src/components/main/stageView/iFrame/hooks/useCmdk.ts +++ b/src/components/main/stageView/iFrame/hooks/useCmdk.ts @@ -10,7 +10,6 @@ import { TCmdkKeyMap } from "@_types/main"; import { useAppState } from "@_redux/useAppState"; import { TNodeTreeData, TNodeUid } from "@_node/types"; import { editHtmlContent } from "../helpers"; -import { ShortDelay } from "@_constants/main"; interface IUseCmdkProps { iframeRefRef: React.MutableRefObject; diff --git a/src/components/main/stageView/iFrame/hooks/useMouseEvents.ts b/src/components/main/stageView/iFrame/hooks/useMouseEvents.ts index 290c027f..4829e7ac 100644 --- a/src/components/main/stageView/iFrame/hooks/useMouseEvents.ts +++ b/src/components/main/stageView/iFrame/hooks/useMouseEvents.ts @@ -14,7 +14,6 @@ import { THtmlNodeData } from "@_node/node"; import { setActivePanel } from "@_redux/main/processor"; import { MainContext } from "@_redux/main"; import { LogAllow } from "@_constants/global"; -import { debounce } from "lodash"; import { ShortDelay } from "@_constants/main"; interface IUseMouseEventsProps { diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index 58433c36..af77a199 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -4,15 +4,12 @@ import morphdom from "morphdom"; import { useDispatch } from "react-redux"; import { LogAllow } from "@_constants/global"; -import { RootNodeUid } from "@_constants/main"; import { parseFile, PreserveRnbwNode, StageNodeIdAttr, writeFile, } from "@_node/file"; -import { getSubNodeUidsByBfs } from "@_node/helpers"; -import { TNodeTreeData } from "@_node/types"; import { MainContext } from "@_redux/main"; import { setDoingFileAction, @@ -62,11 +59,11 @@ export const useNodeTreeEvent = () => { const { addRunningActions, removeRunningActions } = useContext(MainContext); useEffect(() => { - /* LogAllow && + LogAllow && console.log("useNodeTreeEvent - selectedNodeUids", { selectedNodeUids, currentFileContent, - }); */ + }); // focus node dispatch( @@ -86,20 +83,22 @@ export const useNodeTreeEvent = () => { ); }, [selectedNodeUids]); - /* useEffect(() => { + useEffect(() => { + return; + // validate expanded node uids const _expandedItems = nExpandedItems.filter( (uid) => validNodeTree[uid] && validNodeTree[uid].isEntity === false, ); dispatch(setExpandedNodeTreeNodes([..._expandedItems])); - }, [validNodeTree]); */ + }, [validNodeTree]); useEffect(() => { - /* LogAllow && + LogAllow && console.log("useNodeTreeEvent - currentFileContent", { selectedNodeUids, currentFileContent, - }); */ + }); // validate if (!fileTree[currentFileUid]) return; @@ -116,11 +115,10 @@ export const useNodeTreeEvent = () => { fileData.content = currentFileContent; fileData.contentInApp = contentInApp; fileData.changed = fileData.content !== fileData.orgContent; - if (fileData.changed && file.parentUid) { markChangedFolders(fileTree, file, dispatch); } - + // when "Save" while text-editing, we need to call "Save" command after file-content updated. // after fileTree has been updated exactly. so when "Save" while text-editing, we first call "SaveForce" if (currentCommand?.action === "SaveForce") { From 4c87be1f2ba34ddb64d536c1862ecf74f634aaa2 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 19:58:35 +0800 Subject: [PATCH 2/9] sync expand status in Processor --- src/_redux/main/nodeTree/slice.ts | 4 +- .../main/processor/hooks/useNodeTreeEvent.ts | 56 ++++++++++++------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/_redux/main/nodeTree/slice.ts b/src/_redux/main/nodeTree/slice.ts index 814c9f2f..6994f8a6 100644 --- a/src/_redux/main/nodeTree/slice.ts +++ b/src/_redux/main/nodeTree/slice.ts @@ -36,11 +36,13 @@ const nodeTreeSlice = createSlice({ }, setExpandedNodeTreeNodes(state, action: PayloadAction) { const expandedItems = action.payload; - state.nodeTreeViewState.expandedItems = expandedItems; state.nodeTreeViewState.expandedItemsObj = {}; for (const uid of expandedItems) { state.nodeTreeViewState.expandedItemsObj[uid] = true; } + state.nodeTreeViewState.expandedItems = Object.keys( + state.nodeTreeViewState.expandedItemsObj, + ); }, expandNodeTreeNodes(state, action: PayloadAction) { const uids = action.payload; diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index af77a199..1cba4211 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -1,4 +1,4 @@ -import { useContext, useEffect } from "react"; +import { useContext, useEffect, useRef } from "react"; import morphdom from "morphdom"; import { useDispatch } from "react-redux"; @@ -54,10 +54,15 @@ export const useNodeTreeEvent = () => { validNodeTree, nExpandedItems, + didRedo, + didUndo, + syncConfigs, } = useAppState(); const { addRunningActions, removeRunningActions } = useContext(MainContext); + const isSelectedNodeUidsChanged = useRef(false); + useEffect(() => { LogAllow && console.log("useNodeTreeEvent - selectedNodeUids", { @@ -75,23 +80,9 @@ export const useNodeTreeEvent = () => { ); // select nodes dispatch(selectNodeTreeNodes(selectedNodeUids)); - // expand nodes - dispatch( - expandNodeTreeNodes( - getNeedToExpandNodeUids(validNodeTree, selectedNodeUids), - ), - ); - }, [selectedNodeUids]); - useEffect(() => { - return; - - // validate expanded node uids - const _expandedItems = nExpandedItems.filter( - (uid) => validNodeTree[uid] && validNodeTree[uid].isEntity === false, - ); - dispatch(setExpandedNodeTreeNodes([..._expandedItems])); - }, [validNodeTree]); + isSelectedNodeUidsChanged.current = true; + }, [selectedNodeUids]); useEffect(() => { LogAllow && @@ -120,7 +111,7 @@ export const useNodeTreeEvent = () => { } // when "Save" while text-editing, we need to call "Save" command after file-content updated. - // after fileTree has been updated exactly. so when "Save" while text-editing, we first call "SaveForce" + // after fileTree has been updated exactly. so when "Save" while text-editing, we should call "SaveForce" first. if (currentCommand?.action === "SaveForce") { dispatch(setCurrentCommand({ action: "Save" })); } @@ -154,14 +145,41 @@ export const useNodeTreeEvent = () => { LogAllow && console.log("it's a new project"); dispatch(setInitialFileUidToOpen("")); dispatch(setSelectedNodeUids([uid])); + dispatch( + setExpandedNodeTreeNodes( + getNeedToExpandNodeUids(_validNodeTree, [uid]), + ), + ); } else if (prevFileUid !== currentFileUid) { LogAllow && console.log("it's a new file"); dispatch(setSelectedNodeUids([uid])); + dispatch( + setExpandedNodeTreeNodes( + getNeedToExpandNodeUids(_validNodeTree, [uid]), + ), + ); + } else { + if (isSelectedNodeUidsChanged.current) { + isSelectedNodeUidsChanged.current = false; + const validExpandedItems = nExpandedItems.filter( + (uid) => + _validNodeTree[uid] && _validNodeTree[uid].isEntity === false, + ); + const needToExpandItems = getNeedToExpandNodeUids( + _validNodeTree, + selectedNodeUids, + ); + dispatch( + setExpandedNodeTreeNodes([ + ...validExpandedItems, + ...needToExpandItems, + ]), + ); + } } // sync stage-view if (prevFileUid !== currentFileUid) { - // reload if it's a new file. LogAllow && console.log("need to refresh iframe"); dispatch(setNeedToReloadIframe(true)); } else { From b4fd51ae9ac97753dde610a652ebc29ef1f2bc55 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 20:10:43 +0800 Subject: [PATCH 3/9] sync node-expand-status with correct hooks --- .../main/processor/hooks/useNodeTreeEvent.ts | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index 1cba4211..8c92f048 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -54,22 +54,15 @@ export const useNodeTreeEvent = () => { validNodeTree, nExpandedItems, - didRedo, - didUndo, - syncConfigs, } = useAppState(); const { addRunningActions, removeRunningActions } = useContext(MainContext); const isSelectedNodeUidsChanged = useRef(false); + const isCurrentFileContentChanged = useRef(false); useEffect(() => { - LogAllow && - console.log("useNodeTreeEvent - selectedNodeUids", { - selectedNodeUids, - currentFileContent, - }); - + isSelectedNodeUidsChanged.current = true; // focus node dispatch( focusNodeTreeNode( @@ -80,17 +73,10 @@ export const useNodeTreeEvent = () => { ); // select nodes dispatch(selectNodeTreeNodes(selectedNodeUids)); - - isSelectedNodeUidsChanged.current = true; }, [selectedNodeUids]); useEffect(() => { - LogAllow && - console.log("useNodeTreeEvent - currentFileContent", { - selectedNodeUids, - currentFileContent, - }); - + isCurrentFileContentChanged.current = true; // validate if (!fileTree[currentFileUid]) return; @@ -274,4 +260,16 @@ export const useNodeTreeEvent = () => { removeRunningActions(["processor-update"]); }, [currentFileContent]); + + // expand nodes that need to be expanded when it's just select-event + useEffect(() => { + if (!isCurrentFileContentChanged.current) { + const needToExpandItems = getNeedToExpandNodeUids( + validNodeTree, + selectedNodeUids, + ); + dispatch(expandNodeTreeNodes(needToExpandItems)); + } + isCurrentFileContentChanged.current = false; + }, [selectedNodeUids]); }; From 23306fbe2f7c5f5d9d96e81fc76c0aec16fb03a0 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 20:13:58 +0800 Subject: [PATCH 4/9] log --- src/pages/main/processor/hooks/useNodeTreeEvent.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index 8c92f048..47aacc5e 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -145,6 +145,7 @@ export const useNodeTreeEvent = () => { ), ); } else { + LogAllow && console.log("it's a rnbw-change"); if (isSelectedNodeUidsChanged.current) { isSelectedNodeUidsChanged.current = false; const validExpandedItems = nExpandedItems.filter( From e2da21c7c0994bebac797b7cf3faba662073313a Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 20:17:02 +0800 Subject: [PATCH 5/9] reference fix in useNodeTreeEvent --- src/pages/main/processor/hooks/useNodeTreeEvent.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index 47aacc5e..735f35f7 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -60,6 +60,10 @@ export const useNodeTreeEvent = () => { const isSelectedNodeUidsChanged = useRef(false); const isCurrentFileContentChanged = useRef(false); + useEffect(() => { + isSelectedNodeUidsChanged.current = false; + isCurrentFileContentChanged.current = false; + }, [selectedNodeUids, currentFileContent]); useEffect(() => { isSelectedNodeUidsChanged.current = true; @@ -147,7 +151,6 @@ export const useNodeTreeEvent = () => { } else { LogAllow && console.log("it's a rnbw-change"); if (isSelectedNodeUidsChanged.current) { - isSelectedNodeUidsChanged.current = false; const validExpandedItems = nExpandedItems.filter( (uid) => _validNodeTree[uid] && _validNodeTree[uid].isEntity === false, @@ -271,6 +274,5 @@ export const useNodeTreeEvent = () => { ); dispatch(expandNodeTreeNodes(needToExpandItems)); } - isCurrentFileContentChanged.current = false; }, [selectedNodeUids]); }; From 506056697ff0c63e93600ec69d353ff612d5040d Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 21:07:33 +0800 Subject: [PATCH 6/9] use jumpToPast instead of clearHistory --- src/_redux/main/nodeTree/event/constants.ts | 1 + src/_redux/main/nodeTree/event/slice.ts | 2 ++ .../nodeTreeView/hooks/useNodeViewState.ts | 10 +++++----- .../workspaceTreeView/hooks/useNodeActionsHandler.ts | 4 ++-- src/pages/main/helper.ts | 9 +++------ 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/_redux/main/nodeTree/event/constants.ts b/src/_redux/main/nodeTree/event/constants.ts index f44d9591..662000d4 100644 --- a/src/_redux/main/nodeTree/event/constants.ts +++ b/src/_redux/main/nodeTree/event/constants.ts @@ -2,3 +2,4 @@ export const NodeTree_Event_StoreLimit = 10000; export const NodeTree_Event_UndoActionType = "main/NodeEvent/undo"; export const NodeTree_Event_RedoActionType = "main/NodeEvent/redo"; export const NodeTree_Event_ClearActionType = "main/NodeEvent/clear"; +export const NodeTree_Event_JumpToPastActionType = "main/NodeEvent/jumpToPast"; diff --git a/src/_redux/main/nodeTree/event/slice.ts b/src/_redux/main/nodeTree/event/slice.ts index 6f50302a..de16ea02 100644 --- a/src/_redux/main/nodeTree/event/slice.ts +++ b/src/_redux/main/nodeTree/event/slice.ts @@ -5,6 +5,7 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { NodeTree_Event_ClearActionType, + NodeTree_Event_JumpToPastActionType, NodeTree_Event_RedoActionType, NodeTree_Event_StoreLimit, NodeTree_Event_UndoActionType, @@ -36,4 +37,5 @@ export const NodeEventReducer = undoable(nodeEventSlice.reducer, { undoType: NodeTree_Event_UndoActionType, redoType: NodeTree_Event_RedoActionType, clearHistoryType: NodeTree_Event_ClearActionType, + jumpToPastType: NodeTree_Event_JumpToPastActionType, }); diff --git a/src/components/main/actionsPanel/nodeTreeView/hooks/useNodeViewState.ts b/src/components/main/actionsPanel/nodeTreeView/hooks/useNodeViewState.ts index 981c2d43..09b47fed 100644 --- a/src/components/main/actionsPanel/nodeTreeView/hooks/useNodeViewState.ts +++ b/src/components/main/actionsPanel/nodeTreeView/hooks/useNodeViewState.ts @@ -58,11 +58,11 @@ export function useNodeViewState() { // update file - WIP if (currentFileUid !== prevRenderableFileUid) { - const file = fileTree[prevRenderableFileUid]; - const fileData = file.data as TFileNodeData; - dispatch(setCurrentFileUid(prevRenderableFileUid)); - dispatch(setCurrentFileContent(fileData.content)); - dispatch(selectFileTreeNodes([prevRenderableFileUid])); + // const file = fileTree[prevRenderableFileUid]; + // const fileData = file.data as TFileNodeData; + // dispatch(setCurrentFileUid(prevRenderableFileUid)); + // dispatch(setCurrentFileContent(fileData.content)); + // dispatch(selectFileTreeNodes([prevRenderableFileUid])); // dispatch({ type: NodeTree_Event_ClearActionType }); } diff --git a/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts b/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts index 3e4d6164..3cedd762 100644 --- a/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts +++ b/src/components/main/actionsPanel/workspaceTreeView/hooks/useNodeActionsHandler.ts @@ -37,6 +37,7 @@ import { import { useInvalidNodes } from "./useInvalidNodes"; import { useTemporaryNodes } from "./useTemporaryNodes"; import { useAppState } from "@_redux/useAppState"; +import { clearFileSession } from "@_pages/main/helper"; export const useNodeActionsHandler = ( openFileUid: React.MutableRefObject, @@ -476,8 +477,7 @@ export const useNodeActionsHandler = ( return; } - dispatch(clearNodeTreeViewState()); - dispatch({ type: NodeTree_Event_ClearActionType }); + clearFileSession(dispatch); const nodeData = node.data as TFileNodeData; if (RednerableFileTypes[nodeData.ext]) { diff --git a/src/pages/main/helper.ts b/src/pages/main/helper.ts index 52c18d5b..cb9f8e7d 100644 --- a/src/pages/main/helper.ts +++ b/src/pages/main/helper.ts @@ -1,5 +1,3 @@ -import { useDispatch } from "react-redux"; - import { clearFileTreeViewState, setCurrentFileUid, @@ -17,7 +15,7 @@ import { } from "@_redux/main/nodeTree"; import { NodeTree_Event_ClearActionType, - setCurrentFileContent, + NodeTree_Event_JumpToPastActionType, } from "@_redux/main/nodeTree/event"; import { setIframeSrc } from "@_redux/main/stageView"; import { TCmdkReferenceData } from "@_types/main"; @@ -111,18 +109,17 @@ export const clearProjectSession = (dispatch: Dispatch) => { dispatch(setCurrentFileUid("")); dispatch(setPrevFileUid("")); dispatch(setPrevRenderableFileUid("")); - dispatch(setCurrentFileContent("")); dispatch(clearFileTreeViewState()); dispatch({ type: FileTree_Event_ClearActionType }); - - clearFileSession(dispatch); }; export const clearFileSession = (dispatch: Dispatch) => { + console.log("clearFileSession"); dispatch(setNodeTree({})); dispatch(setValidNodeTree({})); dispatch(clearNodeTreeViewState()); dispatch({ type: NodeTree_Event_ClearActionType }); + dispatch({ type: NodeTree_Event_JumpToPastActionType, payload: 0 }); dispatch(setIframeSrc(null)); }; From 3fc97103625322c323ce6ef07c076b9b735cd84e Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 21:11:59 +0800 Subject: [PATCH 7/9] add clearFileSession in clearProjectSession --- src/pages/main/helper.ts | 3 ++- src/pages/main/processor/hooks/useNodeTreeEvent.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/main/helper.ts b/src/pages/main/helper.ts index cb9f8e7d..f9e1c420 100644 --- a/src/pages/main/helper.ts +++ b/src/pages/main/helper.ts @@ -111,10 +111,11 @@ export const clearProjectSession = (dispatch: Dispatch) => { dispatch(setPrevRenderableFileUid("")); dispatch(clearFileTreeViewState()); dispatch({ type: FileTree_Event_ClearActionType }); + + clearFileSession(dispatch); }; export const clearFileSession = (dispatch: Dispatch) => { - console.log("clearFileSession"); dispatch(setNodeTree({})); dispatch(setValidNodeTree({})); dispatch(clearNodeTreeViewState()); diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index 735f35f7..4ca36f82 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -21,6 +21,7 @@ import { expandNodeTreeNodes, focusNodeTreeNode, selectNodeTreeNodes, + setCurrentFileContent, setExpandedNodeTreeNodes, setNodeTree, setSelectedNodeUids, From 88f157c12e2eeccfb54caf4fed5990401e12c62d Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 21:12:19 +0800 Subject: [PATCH 8/9] typo fix --- src/pages/main/processor/hooks/useNodeTreeEvent.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/main/processor/hooks/useNodeTreeEvent.ts b/src/pages/main/processor/hooks/useNodeTreeEvent.ts index 4ca36f82..735f35f7 100644 --- a/src/pages/main/processor/hooks/useNodeTreeEvent.ts +++ b/src/pages/main/processor/hooks/useNodeTreeEvent.ts @@ -21,7 +21,6 @@ import { expandNodeTreeNodes, focusNodeTreeNode, selectNodeTreeNodes, - setCurrentFileContent, setExpandedNodeTreeNodes, setNodeTree, setSelectedNodeUids, From d50733c25a60e2e42ffa2529af3e1591309fb652 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 5 Dec 2023 21:19:46 +0800 Subject: [PATCH 9/9] call clearProjectSession at the correct place --- src/pages/main/MainPage.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/main/MainPage.tsx b/src/pages/main/MainPage.tsx index 6bcf6365..df63762c 100644 --- a/src/pages/main/MainPage.tsx +++ b/src/pages/main/MainPage.tsx @@ -939,6 +939,8 @@ export default function MainPage() { osType, ); + clearProjectSession(dispatch); + // build nohost idb handlerArr && buildNohostIDB(handlerArr); @@ -977,6 +979,8 @@ export default function MainPage() { const { _fileTree, _initialFileUidToOpen } = await loadIDBProject(DefaultProjectPath); + clearProjectSession(dispatch); + dispatch( setProject({ context: "idb", @@ -1057,14 +1061,12 @@ export default function MainPage() { _preferPolyfill: false, mode: "readwrite", } as CustomDirectoryPickerOptions); - clearProjectSession(dispatch); await importProject(fsType, projectHandle); } catch (err) { reject(err); } } else if (fsType === "idb") { try { - clearProjectSession(dispatch); await importProject(fsType, null); } catch (err) { reject(err); @@ -1676,7 +1678,6 @@ export default function MainPage() { } } } - clearProjectSession(dispatch); importProject(projectContext, projectHandler); } else if ( currentCmdkPage === "Add" &&