mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 05:00:30 +08:00
opt: tray icon updating
This commit is contained in:
parent
4dbf054334
commit
78ec7f9822
@ -375,9 +375,7 @@ export const TunStatus = async (): Promise<boolean> => {
|
||||
return config?.tun?.enable === true
|
||||
}
|
||||
|
||||
export async function getTrayIconStatus(): Promise<'white' | 'blue' | 'green' | 'red'> {
|
||||
const [sysProxyEnabled, tunEnabled] = await Promise.all([SysProxyStatus(), TunStatus()])
|
||||
|
||||
export function calculateTrayIconStatus(sysProxyEnabled: boolean, tunEnabled: boolean): 'white' | 'blue' | 'green' | 'red' {
|
||||
if (sysProxyEnabled && tunEnabled) {
|
||||
return 'red' // 系统代理 + TUN 同时启用(警告状态)
|
||||
} else if (sysProxyEnabled) {
|
||||
@ -388,3 +386,8 @@ export async function getTrayIconStatus(): Promise<'white' | 'blue' | 'green' |
|
||||
return 'white' // 全关
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTrayIconStatus(): Promise<'white' | 'blue' | 'green' | 'red'> {
|
||||
const [sysProxyEnabled, tunEnabled] = await Promise.all([SysProxyStatus(), TunStatus()])
|
||||
return calculateTrayIconStatus(sysProxyEnabled, tunEnabled)
|
||||
}
|
||||
@ -15,7 +15,7 @@ import pngIconBlue from '../../../resources/icon_blue.png?asset'
|
||||
import pngIconRed from '../../../resources/icon_red.png?asset'
|
||||
import pngIconGreen from '../../../resources/icon_green.png?asset'
|
||||
import templateIcon from '../../../resources/iconTemplate.png?asset'
|
||||
import { mihomoChangeProxy, mihomoCloseAllConnections, mihomoGroups, patchMihomoConfig, getTrayIconStatus } from '../core/mihomoApi'
|
||||
import { mihomoChangeProxy, mihomoCloseAllConnections, mihomoGroups, patchMihomoConfig, getTrayIconStatus, calculateTrayIconStatus } from '../core/mihomoApi'
|
||||
import { mainWindow, showMainWindow, triggerMainWindow } from '..'
|
||||
import { app, clipboard, ipcMain, Menu, nativeImage, shell, Tray } from 'electron'
|
||||
import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from '../utils/dirs'
|
||||
@ -458,6 +458,27 @@ const getIconPaths = () => {
|
||||
}
|
||||
}
|
||||
|
||||
export function updateTrayIconImmediate(sysProxyEnabled: boolean, tunEnabled: boolean): void {
|
||||
if (!tray) return
|
||||
|
||||
const status = calculateTrayIconStatus(sysProxyEnabled, tunEnabled)
|
||||
const iconPaths = getIconPaths()
|
||||
const iconPath = iconPaths[status]
|
||||
|
||||
try {
|
||||
if (process.platform === 'darwin') {
|
||||
const icon = nativeImage.createFromPath(iconPath).resize({ height: 16 })
|
||||
tray.setImage(icon)
|
||||
} else if (process.platform === 'win32') {
|
||||
tray.setImage(iconPath)
|
||||
} else if (process.platform === 'linux') {
|
||||
tray.setImage(iconPath)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新托盘图标失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateTrayIcon(): Promise<void> {
|
||||
if (!tray) return
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ import {
|
||||
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
|
||||
import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '../resolve/backup'
|
||||
import { getInterfaces } from '../sys/interface'
|
||||
import { closeTrayIcon, copyEnv, showTrayIcon, updateTrayIcon } from '../resolve/tray'
|
||||
import { closeTrayIcon, copyEnv, showTrayIcon, updateTrayIcon, updateTrayIconImmediate } from '../resolve/tray'
|
||||
import { registerShortcut } from '../resolve/shortcut'
|
||||
import { closeMainWindow, mainWindow, showMainWindow, triggerMainWindow } from '..'
|
||||
import {
|
||||
@ -260,6 +260,9 @@ export function registerIpcMainHandlers(): void {
|
||||
ipcMain.handle('showTrayIcon', () => ipcErrorWrapper(showTrayIcon)())
|
||||
ipcMain.handle('closeTrayIcon', () => ipcErrorWrapper(closeTrayIcon)())
|
||||
ipcMain.handle('updateTrayIcon', () => ipcErrorWrapper(updateTrayIcon)())
|
||||
ipcMain.handle('updateTrayIconImmediate', (_e, sysProxyEnabled, tunEnabled) => {
|
||||
updateTrayIconImmediate(sysProxyEnabled, tunEnabled)
|
||||
})
|
||||
ipcMain.handle('showMainWindow', showMainWindow)
|
||||
ipcMain.handle('closeMainWindow', closeMainWindow)
|
||||
ipcMain.handle('triggerMainWindow', triggerMainWindow)
|
||||
|
||||
@ -2,7 +2,8 @@ import { Button, Card, CardBody, CardFooter, Tooltip } from '@heroui/react'
|
||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import { triggerSysProxy, updateTrayIcon } from '@renderer/utils/ipc'
|
||||
import { triggerSysProxy, updateTrayIcon, updateTrayIconImmediate } from '@renderer/utils/ipc'
|
||||
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||
import { AiOutlineGlobal } from 'react-icons/ai'
|
||||
import React from 'react'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
@ -20,7 +21,9 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/sysproxy')
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
const { controledMihomoConfig } = useControledMihomoConfig()
|
||||
const { sysProxy, sysproxyCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const { tun } = controledMihomoConfig || {}
|
||||
const { enable } = sysProxy || {}
|
||||
const {
|
||||
attributes,
|
||||
@ -35,8 +38,11 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
const onChange = async (enable: boolean): Promise<void> => {
|
||||
const previousState = !enable
|
||||
const tunEnabled = tun?.enable ?? false
|
||||
|
||||
// 立即更新图标
|
||||
updateTrayIconImmediate(enable, tunEnabled)
|
||||
|
||||
// 立即更新UI
|
||||
try {
|
||||
await patchAppConfig({ sysProxy: { enable } })
|
||||
await triggerSysProxy(enable)
|
||||
@ -46,6 +52,8 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
|
||||
await updateTrayIcon()
|
||||
} catch (e) {
|
||||
await patchAppConfig({ sysProxy: { enable: previousState } })
|
||||
// 回滚图标
|
||||
updateTrayIconImmediate(previousState, tunEnabled)
|
||||
alert(e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-c
|
||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||
import { TbDeviceIpadHorizontalBolt } from 'react-icons/tb'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { restartCore, updateTrayIcon } from '@renderer/utils/ipc'
|
||||
import { restartCore, updateTrayIcon, updateTrayIconImmediate } from '@renderer/utils/ipc'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import React from 'react'
|
||||
@ -22,6 +22,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
|
||||
const match = location.pathname.includes('/tun') || false
|
||||
const { appConfig } = useAppConfig()
|
||||
const { tunCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const sysProxyEnabled = appConfig?.sysProxy?.enable ?? false
|
||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||
const { tun } = controledMihomoConfig || {}
|
||||
const { enable } = tun || {}
|
||||
@ -37,6 +38,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
|
||||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
const onChange = async (enable: boolean): Promise<void> => {
|
||||
updateTrayIconImmediate(sysProxyEnabled, enable)
|
||||
if (enable) {
|
||||
try {
|
||||
// 检查内核权限
|
||||
@ -54,9 +56,11 @@ const TunSwitcher: React.FC<Props> = (props) => {
|
||||
} catch (error) {
|
||||
console.error('Failed to restart as admin:', error)
|
||||
await window.electron.ipcRenderer.invoke('showErrorDialog', t('tun.permissions.failed'), String(error))
|
||||
updateTrayIconImmediate(sysProxyEnabled, false)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
updateTrayIconImmediate(sysProxyEnabled, false)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -66,6 +70,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
|
||||
} catch (error) {
|
||||
console.warn('Permission grant failed:', error)
|
||||
await window.electron.ipcRenderer.invoke('showErrorDialog', t('tun.permissions.failed'), String(error))
|
||||
updateTrayIconImmediate(sysProxyEnabled, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -406,6 +406,10 @@ export async function updateTrayIcon(): Promise<void> {
|
||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('updateTrayIcon'))
|
||||
}
|
||||
|
||||
export function updateTrayIconImmediate(sysProxyEnabled: boolean, tunEnabled: boolean): void {
|
||||
window.electron.ipcRenderer.invoke('updateTrayIconImmediate', sysProxyEnabled, tunEnabled)
|
||||
}
|
||||
|
||||
export async function showMainWindow(): Promise<void> {
|
||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('showMainWindow'))
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user