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<HTMLDivElement>(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 (
     <div className={`w-screen h-screen flex ${theme === 'dark' ? 'dark bg-gray-900' : 'bg-white'}`}>
       <LeftSidebar isOpen={isLeftOpen} onToggle={() => 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

