diff --git a/.gitignore b/.gitignore index bc165d6..3bea14c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ frontend/release/ **/release/ **/dist/ -**/build/ +build/bin/ # wails / node artifacts (按需) node_modules/ @@ -17,3 +17,5 @@ dist/ GoNavi-Wails GoNavi-Wails.exe .ace-tool/ +.claude/ +tmpclaude-* diff --git a/build/appicon.png b/build/appicon.png new file mode 100644 index 0000000..be7bc98 Binary files /dev/null and b/build/appicon.png differ diff --git a/build/windows/icon.ico b/build/windows/icon.ico new file mode 100644 index 0000000..7cb1a1d Binary files /dev/null and b/build/windows/icon.ico differ diff --git a/build/windows/info.json b/build/windows/info.json new file mode 100644 index 0000000..9727946 --- /dev/null +++ b/build/windows/info.json @@ -0,0 +1,15 @@ +{ + "fixed": { + "file_version": "{{.Info.ProductVersion}}" + }, + "info": { + "0000": { + "ProductVersion": "{{.Info.ProductVersion}}", + "CompanyName": "{{.Info.CompanyName}}", + "FileDescription": "{{.Info.ProductName}}", + "LegalCopyright": "{{.Info.Copyright}}", + "ProductName": "{{.Info.ProductName}}", + "Comments": "{{.Info.Comments}}" + } + } +} \ No newline at end of file diff --git a/build/windows/wails.exe.manifest b/build/windows/wails.exe.manifest new file mode 100644 index 0000000..17e1a23 --- /dev/null +++ b/build/windows/wails.exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + true/pm + permonitorv2,permonitor + + + \ No newline at end of file diff --git a/frontend/package.json.md5 b/frontend/package.json.md5 index 0f8f4fe..a7661c0 100755 --- a/frontend/package.json.md5 +++ b/frontend/package.json.md5 @@ -1 +1 @@ -5b8157374dae5f9340e31b2d0bd2c00e \ No newline at end of file +d0f9366af59a6367ad3c7e2d4185ead4 \ No newline at end of file diff --git a/frontend/src/App.css b/frontend/src/App.css index 556c56d..b8e73f2 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -3,6 +3,7 @@ html, body, #root { margin: 0; padding: 0; overflow: hidden; /* Disable global scrollbar */ + background-color: transparent !important; /* CRITICAL: Allow Wails window transparency */ } /* 侧边栏 Tree 样式优化 */ @@ -30,4 +31,40 @@ html, body, #root { text-overflow: ellipsis; white-space: nowrap; padding-right: 8px; -} \ No newline at end of file +} + +/* Scrollbar styling for dark mode */ +body[data-theme='dark'] ::-webkit-scrollbar { + width: 10px; + height: 10px; +} +body[data-theme='dark'] ::-webkit-scrollbar-track { + background: #1f1f1f; +} +body[data-theme='dark'] ::-webkit-scrollbar-corner { + background: #1f1f1f; +} +body[data-theme='dark'] ::-webkit-scrollbar-thumb { + background: #424242; + border-radius: 4px; + border: 2px solid #1f1f1f; +} +body[data-theme='dark'] ::-webkit-scrollbar-thumb:hover { + background: #666; +} + +/* Ensure body background matches theme to avoid white flashes, but kept transparent for window composition */ +body { + transition: color 0.3s; +} + +body[data-theme='dark'] { + /* Improve contrast on transparent backgrounds */ + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8); +} + +/* Custom Title Bar Close Button Hover */ +.titlebar-close-btn:hover { + background-color: #ff4d4f !important; + color: #fff !important; +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 0f33b56..162c895 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; -import { Layout, Button, ConfigProvider, theme, Dropdown, MenuProps, message, Modal, Spin } from 'antd'; +import { Layout, Button, ConfigProvider, theme, Dropdown, MenuProps, message, Modal, Spin, Slider, Popover } from 'antd'; import zhCN from 'antd/locale/zh_CN'; -import { PlusOutlined, BulbOutlined, BulbFilled, ConsoleSqlOutlined, UploadOutlined, DownloadOutlined, CloudDownloadOutlined, BugOutlined, ToolOutlined, InfoCircleOutlined, GithubOutlined } from '@ant-design/icons'; +import { PlusOutlined, BulbOutlined, BulbFilled, ConsoleSqlOutlined, UploadOutlined, DownloadOutlined, CloudDownloadOutlined, BugOutlined, ToolOutlined, InfoCircleOutlined, GithubOutlined, SkinOutlined, CheckOutlined, MinusOutlined, BorderOutlined, CloseOutlined, SettingOutlined } from '@ant-design/icons'; import Sidebar from './components/Sidebar'; import TabManager from './components/TabManager'; import ConnectionModal from './components/ConnectionModal'; @@ -17,8 +17,27 @@ function App() { const [isModalOpen, setIsModalOpen] = useState(false); const [isSyncModalOpen, setIsSyncModalOpen] = useState(false); const [editingConnection, setEditingConnection] = useState(null); - const darkMode = useStore(state => state.darkMode); - const toggleDarkMode = useStore(state => state.toggleDarkMode); + const themeMode = useStore(state => state.theme); + const setTheme = useStore(state => state.setTheme); + const appearance = useStore(state => state.appearance); + const setAppearance = useStore(state => state.setAppearance); + const darkMode = themeMode === 'dark'; + + // Background Helper + const getBg = (darkHex: string, lightHex: string) => { + if (!darkMode) return `rgba(255, 255, 255, ${appearance.opacity ?? 0.95})`; // Light mode usually white + + // Parse hex to rgb + const hex = darkHex.replace('#', ''); + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + return `rgba(${r}, ${g}, ${b}, ${appearance.opacity ?? 0.95})`; + }; + // Specific colors + const bgMain = getBg('#141414', '#ffffff'); + const bgContent = getBg('#1d1d1d', '#ffffff'); + const addTab = useStore(state => state.addTab); const activeContext = useStore(state => state.activeContext); const connections = useStore(state => state.connections); @@ -228,6 +247,30 @@ function App() { } ]; + const themeMenu: MenuProps['items'] = [ + { + key: 'light', + label: '亮色主题', + icon: themeMode === 'light' ? : undefined, + onClick: () => setTheme('light') + }, + { + key: 'dark', + label: '暗色主题', + icon: themeMode === 'dark' ? : undefined, + onClick: () => setTheme('dark') + }, + { type: 'divider' }, + { + key: 'settings', + label: '外观设置...', + icon: , + onClick: () => setIsAppearanceModalOpen(true) + } + ]; + + const [isAppearanceModalOpen, setIsAppearanceModalOpen] = useState(false); + // Log Panel const [logPanelHeight, setLogPanelHeight] = useState(200); @@ -383,9 +426,91 @@ function App() { locale={zhCN} theme={{ algorithm: darkMode ? theme.darkAlgorithm : theme.defaultAlgorithm, + token: { + colorBgLayout: 'transparent', + colorBgContainer: darkMode + ? `rgba(29, 29, 29, ${appearance.opacity ?? 0.95})` + : `rgba(255, 255, 255, ${appearance.opacity ?? 0.95})`, + colorBgElevated: darkMode + ? '#1f1f1f' + : '#ffffff', + colorFillAlter: darkMode + ? `rgba(38, 38, 38, ${appearance.opacity ?? 0.95})` + : `rgba(250, 250, 250, ${appearance.opacity ?? 0.95})`, + }, + components: { + Layout: { + colorBgBody: 'transparent', + colorBgHeader: 'transparent', + bodyBg: 'transparent', + headerBg: 'transparent', + siderBg: 'transparent', + triggerBg: 'transparent' + }, + Table: { + headerBg: 'transparent', + rowHoverBg: darkMode ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.02)', + }, + Tabs: { + cardBg: 'transparent', + itemActiveColor: darkMode ? '#177ddc' : '#1890ff', + } + } }} > - + + {/* Custom Title Bar */} +
+
+ {/* Logo can be added here if available */} + GoNavi +
+
+
+
+
+ + +
-
- GoNavi +
+
-
@@ -428,9 +556,9 @@ function App() {
{/* Sidebar Footer for Log Toggle */} -
+