Compare commits

..

3 Commits

Author SHA1 Message Date
Memory
9681f77e20
feat: connection card pure number display 2025-09-30 00:05:32 +08:00
Memory
f488cc3643
perf: reload config without kernel restart 2025-09-29 23:42:40 +08:00
Memory
6832db788a
feat: switch triggerMainWindow behavior 2025-09-29 23:16:06 +08:00
11 changed files with 107 additions and 11 deletions

View File

@ -11,6 +11,7 @@ import { defaultProfile } from '../utils/template'
import { subStorePort } from '../resolve/server' import { subStorePort } from '../resolve/server'
import { join } from 'path' import { join } from 'path'
import { app } from 'electron' import { app } from 'electron'
import { mihomoUpgradeConfig } from '../core/mihomoApi'
let profileConfig: IProfileConfig // profile.yaml let profileConfig: IProfileConfig // profile.yaml
// 最终选中订阅ID // 最终选中订阅ID
@ -221,7 +222,25 @@ export async function setProfileStr(id: string, content: string): Promise<void>
// 读取最新的配置 // 读取最新的配置
const { current } = await getProfileConfig(true) const { current } = await getProfileConfig(true)
await writeFile(profilePath(id), content, 'utf-8') await writeFile(profilePath(id), content, 'utf-8')
if (current === id) await restartCore() if (current === id) {
try {
const { generateProfile } = await import('../core/factory')
await generateProfile()
await mihomoUpgradeConfig()
console.log('[Profile] Config reloaded successfully using mihomoUpgradeConfig')
} catch (error) {
console.error('[Profile] Failed to reload config with mihomoUpgradeConfig:', error)
try {
console.log('[Profile] Falling back to restart core')
const { restartCore } = await import('../core/manager')
await restartCore()
console.log('[Profile] Core restarted successfully')
} catch (restartError) {
console.error('[Profile] Failed to restart core:', restartError)
throw restartError
}
}
}
} }
export async function getProfile(id: string | undefined): Promise<IMihomoConfig> { export async function getProfile(id: string | undefined): Promise<IMihomoConfig> {

View File

@ -188,6 +188,33 @@ export const mihomoUpgradeUI = async (): Promise<void> => {
return await instance.post('/upgrade/ui') return await instance.post('/upgrade/ui')
} }
export const mihomoUpgradeConfig = async (): Promise<void> => {
console.log('[mihomoApi] mihomoUpgradeConfig called')
try {
const instance = await getAxios()
console.log('[mihomoApi] axios instance obtained')
const { diffWorkDir = false } = await getAppConfig()
const { current } = await import('../config').then(mod => mod.getProfileConfig(true))
const { mihomoWorkConfigPath } = await import('../utils/dirs')
const configPath = diffWorkDir ? mihomoWorkConfigPath(current) : mihomoWorkConfigPath('work')
console.log('[mihomoApi] config path:', configPath)
const { existsSync } = await import('fs')
if (!existsSync(configPath)) {
console.log('[mihomoApi] config file does not exist, generating...')
const { generateProfile } = await import('./factory')
await generateProfile()
}
const response = await instance.put('/configs?force=true', {
path: configPath
})
console.log('[mihomoApi] config upgrade request completed', response?.status || 'no status')
} catch (error) {
console.error('[mihomoApi] Failed to upgrade config:', error)
throw error
}
}
// Smart 内核 API // Smart 内核 API
export const mihomoSmartGroupWeights = async ( export const mihomoSmartGroupWeights = async (
groupName: string groupName: string

View File

@ -434,10 +434,16 @@ export async function createWindow(): Promise<void> {
} }
export function triggerMainWindow(): void { export function triggerMainWindow(): void {
if (mainWindow?.isVisible()) { if (mainWindow) {
closeMainWindow() getAppConfig()
} else { .then(({ triggerMainWindowBehavior = 'show' }) => {
showMainWindow() if (triggerMainWindowBehavior === 'toggle' && mainWindow?.isVisible()) {
closeMainWindow()
} else {
showMainWindow()
}
})
.catch(showMainWindow)
} }
} }

View File

@ -16,6 +16,7 @@ import {
mihomoUpgrade, mihomoUpgrade,
mihomoUpgradeGeo, mihomoUpgradeGeo,
mihomoUpgradeUI, mihomoUpgradeUI,
mihomoUpgradeConfig,
mihomoVersion, mihomoVersion,
patchMihomoConfig, patchMihomoConfig,
mihomoSmartGroupWeights, mihomoSmartGroupWeights,
@ -169,6 +170,7 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('mihomoUpgradeGeo', ipcErrorWrapper(mihomoUpgradeGeo)) ipcMain.handle('mihomoUpgradeGeo', ipcErrorWrapper(mihomoUpgradeGeo))
ipcMain.handle('mihomoUpgrade', ipcErrorWrapper(mihomoUpgrade)) ipcMain.handle('mihomoUpgrade', ipcErrorWrapper(mihomoUpgrade))
ipcMain.handle('mihomoUpgradeUI', ipcErrorWrapper(mihomoUpgradeUI)) ipcMain.handle('mihomoUpgradeUI', ipcErrorWrapper(mihomoUpgradeUI))
ipcMain.handle('mihomoUpgradeConfig', ipcErrorWrapper(mihomoUpgradeConfig))
ipcMain.handle('mihomoProxyDelay', (_e, proxy, url) => ipcMain.handle('mihomoProxyDelay', (_e, proxy, url) =>
ipcErrorWrapper(mihomoProxyDelay)(proxy, url) ipcErrorWrapper(mihomoProxyDelay)(proxy, url)
) )

View File

@ -26,6 +26,7 @@ export const defaultConfig: IAppConfig = {
floatingWindowCompatMode: true, floatingWindowCompatMode: true,
disableHardwareAcceleration: false, disableHardwareAcceleration: false,
disableLoopbackDetector: false, disableLoopbackDetector: false,
hideConnectionCardWave: false,
disableEmbedCA: false, disableEmbedCA: false,
disableSystemCA: false, disableSystemCA: false,
skipSafePathCheck: false, skipSafePathCheck: false,
@ -46,7 +47,8 @@ export const defaultConfig: IAppConfig = {
'substore' 'substore'
], ],
siderWidth: 250, siderWidth: 250,
sysProxy: { enable: false, mode: 'manual' } sysProxy: { enable: false, mode: 'manual' },
triggerMainWindowBehavior: 'show' // 添加默认值
} }
export const defaultControledMihomoConfig: Partial<IMihomoConfig> = { export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {

View File

@ -63,7 +63,9 @@ const GeneralConfig: React.FC = () => {
envType = [platform === 'win32' ? 'powershell' : 'bash'], envType = [platform === 'win32' ? 'powershell' : 'bash'],
autoCheckUpdate, autoCheckUpdate,
appTheme = 'system', appTheme = 'system',
language = 'zh-CN' language = 'zh-CN',
triggerMainWindowBehavior = 'show',
hideConnectionCardWave = false
} = appConfig || {} } = appConfig || {}
useEffect(() => { useEffect(() => {
@ -398,6 +400,28 @@ const GeneralConfig: React.FC = () => {
}} }}
/> />
</SettingItem> </SettingItem>
<SettingItem title={t('settings.triggerMainWindowBehavior')} divider>
<Tabs
size="sm"
color="primary"
selectedKey={triggerMainWindowBehavior}
onSelectionChange={(key) => {
patchAppConfig({ triggerMainWindowBehavior: key as 'show' | 'toggle' })
}}
>
<Tab key="show" title={t('settings.triggerMainWindowBehaviorShow')} />
<Tab key="toggle" title={t('settings.triggerMainWindowBehaviorToggle')} />
</Tabs>
</SettingItem>
<SettingItem title={t('settings.hideConnectionCardWave')} divider>
<Switch
size="sm"
isSelected={hideConnectionCardWave}
onValueChange={async (v) => {
await patchAppConfig({ hideConnectionCardWave: v })
}}
/>
</SettingItem>
<SettingItem <SettingItem
title={t('settings.disableHardwareAcceleration')} title={t('settings.disableHardwareAcceleration')}
actions={ actions={

View File

@ -36,7 +36,7 @@ interface Props {
const ConnCard: React.FC<Props> = (props) => { const ConnCard: React.FC<Props> = (props) => {
const { iconOnly } = props const { iconOnly } = props
const { appConfig } = useAppConfig() const { appConfig } = useAppConfig()
const { showTraffic = false, connectionCardStatus = 'col-span-2', disableAnimations = false } = appConfig || {} const { showTraffic = false, connectionCardStatus = 'col-span-2', disableAnimations = false, hideConnectionCardWave = false } = appConfig || {}
const location = useLocation() const location = useLocation()
const navigate = useNavigate() const navigate = useNavigate()
const match = location.pathname.includes('/connections') const match = location.pathname.includes('/connections')
@ -224,9 +224,11 @@ const ConnCard: React.FC<Props> = (props) => {
</h3> </h3>
</CardFooter> </CardFooter>
</Card> </Card>
<div className="w-full h-full absolute top-0 left-0 pointer-events-none overflow-hidden rounded-[14px]"> {!hideConnectionCardWave && (
<Line data={chartData} options={chartOptions} /> <div className="w-full h-full absolute top-0 left-0 pointer-events-none overflow-hidden rounded-[14px]">
</div> <Line data={chartData} options={chartOptions} />
</div>
)}
</> </>
) : ( ) : (
<Card <Card

View File

@ -69,8 +69,12 @@
"settings.disableAnimations": "Disable Animation Effects", "settings.disableAnimations": "Disable Animation Effects",
"settings.showTraffic_windows": "Show Network Speed in Taskbar", "settings.showTraffic_windows": "Show Network Speed in Taskbar",
"settings.showTraffic_mac": "Show Network Speed in Status Bar", "settings.showTraffic_mac": "Show Network Speed in Status Bar",
"settings.hideConnectionCardWave": "Connection Card Pure Number Display",
"settings.showDockIcon": "Show Dock Icon", "settings.showDockIcon": "Show Dock Icon",
"settings.useWindowFrame": "Use System Title Bar", "settings.useWindowFrame": "Use System Title Bar",
"settings.triggerMainWindowBehavior": "Window Trigger Behavior",
"settings.triggerMainWindowBehaviorShow": "Always Show",
"settings.triggerMainWindowBehaviorToggle": "Toggle Show/Hide",
"settings.disableHardwareAcceleration": "Disable Hardware Acceleration", "settings.disableHardwareAcceleration": "Disable Hardware Acceleration",
"settings.disableHardwareAccelerationTooltip": "Disabling hardware acceleration can resolve rendering issues or crashes caused by graphics driver problems, but may reduce performance. Requires app restart to take effect", "settings.disableHardwareAccelerationTooltip": "Disabling hardware acceleration can resolve rendering issues or crashes caused by graphics driver problems, but may reduce performance. Requires app restart to take effect",
"settings.hardwareAcceleration.confirm.title": "Confirm App Restart", "settings.hardwareAcceleration.confirm.title": "Confirm App Restart",

View File

@ -69,8 +69,12 @@
"settings.disableAnimations": "禁用动画效果", "settings.disableAnimations": "禁用动画效果",
"settings.showTraffic_windows": "在任务栏显示网速", "settings.showTraffic_windows": "在任务栏显示网速",
"settings.showTraffic_mac": "在状态栏显示网速", "settings.showTraffic_mac": "在状态栏显示网速",
"settings.hideConnectionCardWave": "连接卡片纯数字显示",
"settings.showDockIcon": "显示 Dock 图标", "settings.showDockIcon": "显示 Dock 图标",
"settings.useWindowFrame": "使用系统标题栏", "settings.useWindowFrame": "使用系统标题栏",
"settings.triggerMainWindowBehavior": "窗口触发行为",
"settings.triggerMainWindowBehaviorShow": "总是显示",
"settings.triggerMainWindowBehaviorToggle": "切换显示/隐藏",
"settings.disableHardwareAcceleration": "禁用硬件加速", "settings.disableHardwareAcceleration": "禁用硬件加速",
"settings.disableHardwareAccelerationTooltip": "禁用硬件加速可以解决某些显卡驱动问题导致的渲染异常或崩溃,但可能会降低性能。修改后需要重启应用生效", "settings.disableHardwareAccelerationTooltip": "禁用硬件加速可以解决某些显卡驱动问题导致的渲染异常或崩溃,但可能会降低性能。修改后需要重启应用生效",
"settings.hardwareAcceleration.confirm.title": "确认重启应用", "settings.hardwareAcceleration.confirm.title": "确认重启应用",

View File

@ -88,6 +88,10 @@ export async function mihomoUpgradeUI(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoUpgradeUI')) return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoUpgradeUI'))
} }
export async function mihomoUpgradeConfig(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoUpgradeConfig'))
}
export async function mihomoProxyDelay(proxy: string, url?: string): Promise<IMihomoDelay> { export async function mihomoProxyDelay(proxy: string, url?: string): Promise<IMihomoDelay> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoProxyDelay', proxy, url)) return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoProxyDelay', proxy, url))
} }

View File

@ -242,6 +242,7 @@ interface IAppConfig {
connectionCardStatus?: CardStatus connectionCardStatus?: CardStatus
dnsCardStatus?: CardStatus dnsCardStatus?: CardStatus
logCardStatus?: CardStatus logCardStatus?: CardStatus
hideConnectionCardWave?: boolean
pauseSSID?: string[] pauseSSID?: string[]
mihomoCoreCardStatus?: CardStatus mihomoCoreCardStatus?: CardStatus
overrideCardStatus?: CardStatus overrideCardStatus?: CardStatus
@ -309,6 +310,7 @@ interface IAppConfig {
restartAppShortcut?: string restartAppShortcut?: string
quitWithoutCoreShortcut?: string quitWithoutCoreShortcut?: string
language?: 'zh-CN' | 'en-US' | 'ru-RU' | 'fa-IR' language?: 'zh-CN' | 'en-US' | 'ru-RU' | 'fa-IR'
triggerMainWindowBehavior?: 'show' | 'toggle'
} }
interface IMihomoTunConfig { interface IMihomoTunConfig {