import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import TitleBar from './components/TitleBar'; import Sidebar from './components/Sidebar'; import Terminal from './components/Terminal'; import HostManager from './components/HostManager'; import Settings from './components/Settings'; import CommandPalette from './components/CommandPalette'; function App() { const [hosts, setHosts] = useState([]); const [activeTabs, setActiveTabs] = useState([]); const [activeTabId, setActiveTabId] = useState(null); const [showHostManager, setShowHostManager] = useState(false); const [editingHost, setEditingHost] = useState(null); const [showSettings, setShowSettings] = useState(false); const [showCommandPalette, setShowCommandPalette] = useState(false); const [isRemoteConnected, setIsRemoteConnected] = useState(false); const [sidebarCollapsed, setSidebarCollapsed] = useState(false); // 加载主机列表 const loadHosts = useCallback(async () => { if (window.electronAPI) { const hostList = await window.electronAPI.hosts.getAll(); setHosts(hostList); } }, []); // 检查远程连接状态 const checkRemoteStatus = useCallback(async () => { if (window.electronAPI) { const connected = await window.electronAPI.db.isRemoteConnected(); setIsRemoteConnected(connected); // 如果已连接,刷新主机列表(因为启动时可能已自动同步) if (connected) { loadHosts(); } } }, [loadHosts]); useEffect(() => { loadHosts(); checkRemoteStatus(); }, [loadHosts, checkRemoteStatus]); // 键盘快捷键 useEffect(() => { const handleKeyDown = (e) => { if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); setShowCommandPalette(true); } if (e.key === 'Escape') { setShowCommandPalette(false); setShowHostManager(false); setShowSettings(false); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, []); // 连接主机 const connectHost = useCallback((host) => { const tabId = `terminal-${host.id}-${Date.now()}`; const newTab = { id: tabId, hostId: host.id, title: host.name, host: host.host, type: 'terminal', connected: false, }; setActiveTabs((prev) => [...prev, newTab]); setActiveTabId(tabId); setShowHostManager(false); }, []); // 关闭标签页 const closeTab = useCallback((tabId) => { setActiveTabs((prev) => { const newTabs = prev.filter((t) => t.id !== tabId); return newTabs; }); setActiveTabId((prevActiveId) => { if (prevActiveId === tabId) { const remainingTabs = activeTabs.filter((t) => t.id !== tabId); return remainingTabs.length > 0 ? remainingTabs[remainingTabs.length - 1].id : null; } return prevActiveId; }); }, [activeTabs]); // 更新连接状态 const handleConnectionChange = useCallback((tabId, connected) => { setActiveTabs((prev) => prev.map((t) => (t.id === tabId ? { ...t, connected } : t)) ); }, []); // 处理主机更新 const handleHostsUpdate = useCallback(() => { loadHosts(); }, [loadHosts]); // 编辑主机 const handleEditHost = useCallback((host) => { setEditingHost(host); setShowHostManager(true); }, []); const openHostManager = useCallback(() => { setEditingHost(null); setShowHostManager(true); }, []); const openSettings = useCallback(() => { setShowSettings(true); }, []); const openCommandPalette = useCallback(() => { setShowCommandPalette(true); }, []); return (
高颜值远程 Shell 管理终端
按 Ctrl+K 打开命令面板