show proxy in tray menu

This commit is contained in:
pompurin404 2024-08-19 11:28:31 +08:00
parent 87b7ed4edc
commit 206255d1bd
No known key found for this signature in database
9 changed files with 77 additions and 33 deletions

View File

@ -2,3 +2,4 @@
- 添加覆写脚本执行日志功能 - 添加覆写脚本执行日志功能
- 支持查看局域网网络信息 - 支持查看局域网网络信息
- 支持托盘菜单显示节点信息

View File

@ -7,9 +7,14 @@ import {
import icoIcon from '../../../resources/icon.ico?asset' import icoIcon from '../../../resources/icon.ico?asset'
import pngIcon from '../../../resources/icon.png?asset' import pngIcon from '../../../resources/icon.png?asset'
import templateIcon from '../../../resources/iconTemplate.png?asset' import templateIcon from '../../../resources/iconTemplate.png?asset'
import { patchMihomoConfig } from '../core/mihomoApi' import {
mihomoChangeProxy,
mihomoCloseAllConnections,
mihomoGroups,
patchMihomoConfig
} from '../core/mihomoApi'
import { mainWindow, showMainWindow } from '..' import { mainWindow, showMainWindow } from '..'
import { app, ipcMain, Menu, nativeImage, shell, Tray } from 'electron' import { app, Menu, nativeImage, shell, Tray } from 'electron'
import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from '../utils/dirs' import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from '../utils/dirs'
import { triggerSysProxy } from '../sys/sysproxy' import { triggerSysProxy } from '../sys/sysproxy'
@ -17,7 +22,47 @@ export let tray: Tray | null = null
const buildContextMenu = async (): Promise<Menu> => { const buildContextMenu = async (): Promise<Menu> => {
const { mode, tun } = await getControledMihomoConfig() const { mode, tun } = await getControledMihomoConfig()
const { sysProxy } = await getAppConfig() const { sysProxy, autoCloseConnection, proxyInTray = true } = await getAppConfig()
let groupsMenu: Electron.MenuItemConstructorOptions[] = []
if (proxyInTray) {
try {
const groups = await mihomoGroups()
groupsMenu = groups.map((group) => {
return {
id: group.name,
label: group.name,
type: 'submenu',
submenu: group.all.map((proxy) => {
const delay = proxy.history.length ? proxy.history[proxy.history.length - 1].delay : -1
let displayDelay = `(${delay}ms)`
if (delay === -1) {
displayDelay = ''
}
if (delay === 0) {
displayDelay = '(Timeout)'
}
return {
id: proxy.name,
label: `${proxy.name} ${displayDelay}`,
type: 'radio',
checked: proxy.name === group.now,
click: async (): Promise<void> => {
await mihomoChangeProxy(group.name, proxy.name)
if (autoCloseConnection) {
await mihomoCloseAllConnections()
}
}
}
})
}
})
groupsMenu.unshift({ type: 'separator' })
} catch (e) {
// ignore
// 避免出错时无法创建托盘菜单
}
}
const contextMenu = [ const contextMenu = [
{ {
id: 'show', id: 'show',
@ -36,7 +81,6 @@ const buildContextMenu = async (): Promise<Menu> => {
await patchControledMihomoConfig({ mode: 'rule' }) await patchControledMihomoConfig({ mode: 'rule' })
await patchMihomoConfig({ mode: 'rule' }) await patchMihomoConfig({ mode: 'rule' })
mainWindow?.webContents.send('controledMihomoConfigUpdated') mainWindow?.webContents.send('controledMihomoConfigUpdated')
await updateTrayMenu()
} }
}, },
{ {
@ -48,7 +92,6 @@ const buildContextMenu = async (): Promise<Menu> => {
await patchControledMihomoConfig({ mode: 'global' }) await patchControledMihomoConfig({ mode: 'global' })
await patchMihomoConfig({ mode: 'global' }) await patchMihomoConfig({ mode: 'global' })
mainWindow?.webContents.send('controledMihomoConfigUpdated') mainWindow?.webContents.send('controledMihomoConfigUpdated')
await updateTrayMenu()
} }
}, },
{ {
@ -60,7 +103,6 @@ const buildContextMenu = async (): Promise<Menu> => {
await patchControledMihomoConfig({ mode: 'direct' }) await patchControledMihomoConfig({ mode: 'direct' })
await patchMihomoConfig({ mode: 'direct' }) await patchMihomoConfig({ mode: 'direct' })
mainWindow?.webContents.send('controledMihomoConfigUpdated') mainWindow?.webContents.send('controledMihomoConfigUpdated')
await updateTrayMenu()
} }
}, },
{ type: 'separator' }, { type: 'separator' },
@ -77,7 +119,6 @@ const buildContextMenu = async (): Promise<Menu> => {
await patchAppConfig({ sysProxy: { enable: !enable } }) await patchAppConfig({ sysProxy: { enable: !enable } })
} finally { } finally {
mainWindow?.webContents.send('appConfigUpdated') mainWindow?.webContents.send('appConfigUpdated')
await updateTrayMenu()
} }
} }
}, },
@ -94,9 +135,9 @@ const buildContextMenu = async (): Promise<Menu> => {
} }
await patchMihomoConfig({ tun: { enable } }) await patchMihomoConfig({ tun: { enable } })
mainWindow?.webContents.send('controledMihomoConfigUpdated') mainWindow?.webContents.send('controledMihomoConfigUpdated')
await updateTrayMenu()
} }
}, },
...groupsMenu,
{ type: 'separator' }, { type: 'separator' },
{ {
type: 'submenu', type: 'submenu',
@ -152,31 +193,22 @@ export async function createTray(): Promise<void> {
if (process.platform === 'win32') { if (process.platform === 'win32') {
tray = new Tray(icoIcon) tray = new Tray(icoIcon)
} }
const menu = await buildContextMenu()
ipcMain.on('controledMihomoConfigUpdated', async () => {
await updateTrayMenu()
})
ipcMain.on('appConfigUpdated', async () => {
await updateTrayMenu()
})
tray?.setToolTip('Mihomo Party') tray?.setToolTip('Mihomo Party')
tray?.setContextMenu(menu)
tray?.setIgnoreDoubleClickEvents(true) tray?.setIgnoreDoubleClickEvents(true)
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
if (!useDockIcon) { if (!useDockIcon) {
app.dock.hide() app.dock.hide()
} else {
app.dock.setMenu(menu)
} }
tray?.addListener('right-click', () => { tray?.addListener('right-click', async () => {
if (mainWindow?.isVisible()) { if (mainWindow?.isVisible()) {
mainWindow?.close() mainWindow?.close()
} else { } else {
showMainWindow() showMainWindow()
} }
}) })
tray?.addListener('click', async () => {
await updateTrayMenu()
})
} else { } else {
tray?.addListener('click', () => { tray?.addListener('click', () => {
if (mainWindow?.isVisible()) { if (mainWindow?.isVisible()) {
@ -185,13 +217,13 @@ export async function createTray(): Promise<void> {
showMainWindow() showMainWindow()
} }
}) })
tray?.addListener('right-click', async () => {
await updateTrayMenu()
})
} }
} }
async function updateTrayMenu(): Promise<void> { async function updateTrayMenu(): Promise<void> {
const menu = await buildContextMenu() const menu = await buildContextMenu()
if (process.platform === 'darwin') { tray?.popUpContextMenu(menu) // 弹出菜单
app.dock.setMenu(menu) // 更新dock菜单
}
tray?.setContextMenu(menu) // 更新菜单
} }

View File

@ -109,11 +109,11 @@ export async function init(): Promise<void> {
await startPacServer() await startPacServer()
const { sysProxy } = await getAppConfig() const { sysProxy } = await getAppConfig()
await triggerSysProxy(sysProxy.enable) await triggerSysProxy(sysProxy.enable)
startCore().then(() => { await startCore()
startMihomoTraffic() await startMihomoTraffic()
setTimeout(async () => { setTimeout(async () => {
await initProfileUpdater() await initProfileUpdater()
}, 60000) }, 60000)
})
initDeeplink() initDeeplink()
} }

View File

@ -2,6 +2,7 @@ export const defaultConfig: IAppConfig = {
core: 'mihomo', core: 'mihomo',
silentStart: false, silentStart: false,
appTheme: 'system', appTheme: 'system',
proxyInTray: true,
proxyDisplayMode: 'simple', proxyDisplayMode: 'simple',
proxyDisplayOrder: 'default', proxyDisplayOrder: 'default',
autoCheckUpdate: true, autoCheckUpdate: true,

View File

@ -18,7 +18,6 @@ export const useAppConfig = (listenUpdate = false): RetuenType => {
alert(e) alert(e)
} finally { } finally {
mutateAppConfig() mutateAppConfig()
window.electron.ipcRenderer.send('appConfigUpdated')
} }
} }

View File

@ -21,7 +21,6 @@ export const useControledMihomoConfig = (listenUpdate = false): RetuenType => {
alert(e) alert(e)
} finally { } finally {
mutateControledMihomoConfig() mutateControledMihomoConfig()
window.electron.ipcRenderer.send('controledMihomoConfigUpdated')
} }
} }

View File

@ -62,6 +62,7 @@ const Proxies: React.FC = () => {
if (autoCloseConnection) { if (autoCloseConnection) {
await mihomoCloseAllConnections() await mihomoCloseAllConnections()
} }
// window.electron.ipcRenderer.send('mihomoGroupsUpdated')
mutate() mutate()
} }

View File

@ -37,6 +37,7 @@ const Settings: React.FC = () => {
controlSniff = true, controlSniff = true,
useDockIcon = true, useDockIcon = true,
showTraffic = true, showTraffic = true,
proxyInTray = true,
delayTestUrl, delayTestUrl,
delayTestTimeout, delayTestTimeout,
autoCheckUpdate, autoCheckUpdate,
@ -194,6 +195,15 @@ const Settings: React.FC = () => {
}} }}
/> />
</SettingItem> </SettingItem>
<SettingItem title="托盘菜单显示节点信息" divider>
<Switch
size="sm"
isSelected={proxyInTray}
onValueChange={(v) => {
patchAppConfig({ proxyInTray: v })
}}
/>
</SettingItem>
{platform === 'darwin' && ( {platform === 'darwin' && (
<> <>
<SettingItem title="显示Dock图标" divider> <SettingItem title="显示Dock图标" divider>

View File

@ -214,6 +214,7 @@ interface IAppConfig {
core: 'mihomo' | 'mihomo-alpha' core: 'mihomo' | 'mihomo-alpha'
proxyDisplayMode: 'simple' | 'full' proxyDisplayMode: 'simple' | 'full'
proxyDisplayOrder: 'default' | 'delay' | 'name' proxyDisplayOrder: 'default' | 'delay' | 'name'
proxyInTray: boolean
siderOrder: string[] siderOrder: string[]
appTheme: AppTheme appTheme: AppTheme
autoCheckUpdate: boolean autoCheckUpdate: boolean