From 6abff8474c593118fc52afaa9e0b432346aeffa5 Mon Sep 17 00:00:00 2001 From: blackhao <13851610112@163.com> Date: Tue, 9 Dec 2025 17:32:10 -0600 Subject: file management sys --- frontend/src/App.tsx | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'frontend/src/App.tsx') diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 5776091..8ae93c7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,4 +1,4 @@ -import { useCallback, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import ReactFlow, { Background, Controls, @@ -47,7 +47,10 @@ function Flow() { theme, toggleTheme, autoLayout, - findNonOverlappingPosition + findNonOverlappingPosition, + setLastViewport, + saveCurrentBlueprint, + currentBlueprintPath } = useFlowStore(); const reactFlowWrapper = useRef(null); @@ -190,6 +193,22 @@ function Flow() { createNodeFromArchive(archiveId, position); }; + // Ctrl/Cmd + S manual save + useEffect(() => { + const handler = (e: KeyboardEvent) => { + const isMac = navigator.platform.toLowerCase().includes('mac'); + if ((isMac ? e.metaKey : e.ctrlKey) && e.key.toLowerCase() === 's') { + e.preventDefault(); + const path = currentBlueprintPath; + if (path) { + saveCurrentBlueprint(path, getViewport()); + } + } + }; + window.addEventListener('keydown', handler); + return () => window.removeEventListener('keydown', handler); + }, [currentBlueprintPath, saveCurrentBlueprint, getViewport]); + return (
setIsLeftOpen(!isLeftOpen)} /> @@ -206,6 +225,7 @@ function Flow() { onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} + onMoveEnd={(_, viewport) => setLastViewport(viewport)} nodeTypes={nodeTypes} edgeTypes={edgeTypes} defaultEdgeOptions={{ type: 'merged' }} -- cgit v1.2.3