diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3584636..4ba9733 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,4 +2,4 @@ blank_issues_enabled: false contact_links: - name: '常见问题' about: '提出问题前请先查看常见问题' - url: 'https://mihomo.party/guides/issue/general/' \ No newline at end of file + url: 'https://mihomo.party/guides/issue/general/' diff --git a/changelog.md b/changelog.md index 876115d..c273540 100644 --- a/changelog.md +++ b/changelog.md @@ -1,13 +1,9 @@ ### Break Changes -- YAML覆写语法有所变动,请更新后参考文档进行修改 +- 1.2.x YAML覆写语法有所变动,请更新后参考文档进行修改 ### New Features -- YAML覆写功能支持对数组进行覆盖/前置/追加操作 -- 缓存代理组图标 - -### Bug Fixes - -- 修复provider过期时间解析错误 -- 修复订阅名称解析错误 +- 支持使用外部编辑器打开文件 +- 允许禁用系统标题栏 +- 重写连接页面 diff --git a/src/main/index.ts b/src/main/index.ts index 3e72399..cd3dd8c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -103,7 +103,7 @@ app.whenReady().then(async () => { optimizer.watchWindowShortcuts(window) }) registerIpcMainHandlers() - createWindow() + await createWindow() await createTray() await initShortcut() app.on('activate', function () { @@ -140,9 +140,9 @@ async function handleDeepLink(url: string): Promise { } } -export function createWindow(show = false): void { +export async function createWindow(): Promise { Menu.setApplicationMenu(null) - // Create the browser window. + const { useWindowFrame = true } = await getAppConfig() const mainWindowState = windowStateKeeper({ defaultWidth: 800, defaultHeight: 600 @@ -155,13 +155,13 @@ export function createWindow(show = false): void { x: mainWindowState.x, y: mainWindowState.y, show: false, - frame: false, - titleBarStyle: 'hidden', - titleBarOverlay: { - color: '#00000000', - symbolColor: '#8D8D8D', - height: 48 - }, + frame: useWindowFrame, + titleBarStyle: useWindowFrame ? 'default' : 'hidden', + titleBarOverlay: useWindowFrame + ? false + : { + height: 49 + }, autoHideMenuBar: true, ...(process.platform === 'linux' ? { icon: icon } : {}), webPreferences: { @@ -173,7 +173,7 @@ export function createWindow(show = false): void { mainWindowState.manage(mainWindow) mainWindow.on('ready-to-show', async () => { const { silentStart } = await getAppConfig() - if (!silentStart || show) { + if (!silentStart) { mainWindow?.show() mainWindow?.focusOnWebView() } @@ -210,7 +210,5 @@ export function showMainWindow(): void { if (mainWindow) { mainWindow.show() mainWindow.focusOnWebView() - } else { - createWindow(true) } } diff --git a/src/main/resolve/backup.ts b/src/main/resolve/backup.ts index 66009b8..50b61bd 100644 --- a/src/main/resolve/backup.ts +++ b/src/main/resolve/backup.ts @@ -10,7 +10,6 @@ import { profileConfigPath, profilesDir } from '../utils/dirs' -import { app } from 'electron' export async function webdavBackup(): Promise { const webdav = await import('webdav') @@ -52,8 +51,6 @@ export async function webdavRestore(filename: string): Promise { const zipData = await client.getFileContents(`mihomo-party/${filename}`) const zip = new AdmZip(zipData as Buffer) zip.extractAllTo(dataDir(), true) - app.relaunch() - app.quit() } export async function listWebdavBackups(): Promise { diff --git a/src/main/utils/dirs.ts b/src/main/utils/dirs.ts index 98fb03d..21cbd83 100644 --- a/src/main/utils/dirs.ts +++ b/src/main/utils/dirs.ts @@ -16,8 +16,6 @@ export async function setPortable(portable: boolean): Promise { } else { await rm(path.join(exeDir(), 'PORTABLE')) } - app.relaunch() - app.quit() } export function dataDir(): string { diff --git a/src/main/utils/ipc.ts b/src/main/utils/ipc.ts index 29ba94f..dc90e5e 100644 --- a/src/main/utils/ipc.ts +++ b/src/main/utils/ipc.ts @@ -63,6 +63,7 @@ import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '.. import { getInterfaces } from '../sys/interface' import { copyEnv } from '../resolve/tray' import { registerShortcut } from '../resolve/shortcut' +import { mainWindow } from '..' function ipcErrorWrapper( // eslint-disable-next-line @typescript-eslint/no-explicit-any fn: (...args: any[]) => Promise // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -178,11 +179,18 @@ export function registerIpcMainHandlers(): void { ipcMain.handle('setNativeTheme', (_e, theme) => { setNativeTheme(theme) }) + ipcMain.handle('setTitleBarOverlay', (_e, overlay) => { + mainWindow?.setTitleBarOverlay(overlay) + }) ipcMain.handle('openFile', (_e, type, id, ext) => openFile(type, id, ext)) ipcMain.handle('copyEnv', ipcErrorWrapper(copyEnv)) ipcMain.handle('alert', (_e, msg) => { dialog.showErrorBox('Mihomo Party', msg) }) + ipcMain.handle('relaunchApp', () => { + app.relaunch() + app.quit() + }) ipcMain.handle('quitApp', () => app.quit()) } diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index eb125b9..88bd172 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -28,7 +28,9 @@ import MihomoCoreCard from '@renderer/components/sider/mihomo-core-card' import ResourceCard from '@renderer/components/sider/resource-card' import UpdaterButton from '@renderer/components/updater/updater-button' import { useAppConfig } from './hooks/use-app-config' -import { setNativeTheme } from './utils/ipc' +import { setNativeTheme, setTitleBarOverlay } from './utils/ipc' +import { platform } from './utils/init' +import { TitleBarOverlayOptions } from 'electron' const App: React.FC = () => { const { appConfig, patchAppConfig } = useAppConfig() @@ -36,6 +38,7 @@ const App: React.FC = () => { appTheme = 'system', controlDns = true, controlSniff = true, + useWindowFrame = true, siderOrder = [ 'sysproxy', 'tun', @@ -53,7 +56,7 @@ const App: React.FC = () => { } = appConfig || {} const [order, setOrder] = useState(siderOrder) const sensors = useSensors(useSensor(PointerSensor)) - const { setTheme } = useTheme() + const { setTheme, systemTheme } = useTheme() const navigate = useNavigate() const location = useLocation() const page = useRoutes(routes) @@ -71,6 +74,30 @@ const App: React.FC = () => { setNativeTheme('dark') } setTheme(appTheme) + if (!useWindowFrame) { + let theme = appTheme as string + if (appTheme === 'system') { + theme = systemTheme || 'light' + } + const options = { height: 48 } as TitleBarOverlayOptions + try { + if (platform !== 'darwin') { + if (theme.includes('light')) { + options.color = '#FFFFFF' + options.symbolColor = '#000000' + } else if (theme.includes('dark')) { + options.color = '#000000' + options.symbolColor = '#FFFFFF' + } else { + options.color = '#18181b' + options.symbolColor = '#FFFFFF' + } + } + setTitleBarOverlay(options) + } catch (e) { + // ignore + } + } }, [appTheme]) const onDragEnd = async (event: DragEndEvent): Promise => { @@ -108,7 +135,11 @@ const App: React.FC = () => {
-

Mihomo Party

+

+ Mihomo Party +

} > -
+
{ return ( -
+
{ return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('webdavDelete', filename)) } +export async function setTitleBarOverlay(overlay: TitleBarOverlayOptions): Promise { + return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setTitleBarOverlay', overlay)) +} + +export async function relaunchApp(): Promise { + return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('relaunchApp')) +} + export async function quitApp(): Promise { return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('quitApp')) } diff --git a/src/shared/types.d.ts b/src/shared/types.d.ts index b1af30d..10957f7 100644 --- a/src/shared/types.d.ts +++ b/src/shared/types.d.ts @@ -217,6 +217,7 @@ interface IAppConfig { proxyDisplayOrder: 'default' | 'delay' | 'name' envType?: 'bash' | 'cmd' | 'powershell' proxyCols: 'auto' | '1' | '2' | '3' | '4' + useWindowFrame: boolean proxyInTray: boolean siderOrder: string[] appTheme: AppTheme