mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-02-11 12:10:28 +08:00
Compare commits
No commits in common. "30f87b843918c7c8091a0bfa52bd10e5e9173d97" and "19ff003352d149ffa0acc7764167d11855fa914d" have entirely different histories.
30f87b8439
...
19ff003352
@ -4,7 +4,7 @@ import { promisify } from 'util'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import { createWriteStream, existsSync } from 'fs'
|
import { createWriteStream, existsSync } from 'fs'
|
||||||
import chokidar, { FSWatcher } from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
import { app, ipcMain } from 'electron'
|
import { app, ipcMain } from 'electron'
|
||||||
import { mainWindow } from '../window'
|
import { mainWindow } from '../window'
|
||||||
import {
|
import {
|
||||||
@ -69,38 +69,15 @@ export {
|
|||||||
export { getDefaultDevice } from './dns'
|
export { getDefaultDevice } from './dns'
|
||||||
|
|
||||||
const execFilePromise = promisify(execFile)
|
const execFilePromise = promisify(execFile)
|
||||||
const ctlParam = process.platform === 'win32' ? '-ext-ctl-pipe' : '-ext-ctl-unix'
|
|
||||||
|
|
||||||
// 核心进程状态
|
chokidar.watch(path.join(mihomoCoreDir(), 'meta-update'), {}).on('unlinkDir', async () => {
|
||||||
let child: ChildProcess
|
|
||||||
let retry = 10
|
|
||||||
let isRestarting = false
|
|
||||||
|
|
||||||
// 文件监听器
|
|
||||||
let coreWatcher: FSWatcher | null = null
|
|
||||||
|
|
||||||
// 初始化核心文件监听
|
|
||||||
export function initCoreWatcher(): void {
|
|
||||||
if (coreWatcher) return
|
|
||||||
|
|
||||||
coreWatcher = chokidar.watch(path.join(mihomoCoreDir(), 'meta-update'), {})
|
|
||||||
coreWatcher.on('unlinkDir', async () => {
|
|
||||||
try {
|
try {
|
||||||
await stopCore(true)
|
await stopCore(true)
|
||||||
await startCore()
|
await startCore()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
safeShowErrorBox('mihomo.error.coreStartFailed', `${e}`)
|
safeShowErrorBox('mihomo.error.coreStartFailed', `${e}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// 清理核心文件监听
|
|
||||||
export function cleanupCoreWatcher(): void {
|
|
||||||
if (coreWatcher) {
|
|
||||||
coreWatcher.close()
|
|
||||||
coreWatcher = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 动态生成 IPC 路径
|
// 动态生成 IPC 路径
|
||||||
export const getMihomoIpcPath = (): string => {
|
export const getMihomoIpcPath = (): string => {
|
||||||
@ -119,20 +96,14 @@ export const getMihomoIpcPath = (): string => {
|
|||||||
return `/tmp/mihomo-party-${uid}-${processId}.sock`
|
return `/tmp/mihomo-party-${uid}-${processId}.sock`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心配置接口
|
const ctlParam = process.platform === 'win32' ? '-ext-ctl-pipe' : '-ext-ctl-unix'
|
||||||
interface CoreConfig {
|
|
||||||
corePath: string
|
|
||||||
workDir: string
|
|
||||||
ipcPath: string
|
|
||||||
logLevel: LogLevel
|
|
||||||
tunEnabled: boolean
|
|
||||||
autoSetDNS: boolean
|
|
||||||
cpuPriority: string
|
|
||||||
detached: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
// 准备核心配置
|
let child: ChildProcess
|
||||||
async function prepareCore(detached: boolean): Promise<CoreConfig> {
|
let retry = 10
|
||||||
|
let isRestarting = false
|
||||||
|
|
||||||
|
export async function startCore(detached = false): Promise<Promise<void>[]> {
|
||||||
|
// 合并配置读取,避免多次 await
|
||||||
const [appConfig, mihomoConfig] = await Promise.all([
|
const [appConfig, mihomoConfig] = await Promise.all([
|
||||||
getAppConfig(),
|
getAppConfig(),
|
||||||
getControledMihomoConfig()
|
getControledMihomoConfig()
|
||||||
@ -145,7 +116,7 @@ async function prepareCore(detached: boolean): Promise<CoreConfig> {
|
|||||||
mihomoCpuPriority = 'PRIORITY_NORMAL'
|
mihomoCpuPriority = 'PRIORITY_NORMAL'
|
||||||
} = appConfig
|
} = appConfig
|
||||||
|
|
||||||
const { 'log-level': logLevel = 'info' as LogLevel, tun } = mihomoConfig
|
const { 'log-level': logLevel, tun } = mihomoConfig
|
||||||
|
|
||||||
// 清理旧进程
|
// 清理旧进程
|
||||||
const pidPath = path.join(dataDir(), 'core.pid')
|
const pidPath = path.join(dataDir(), 'core.pid')
|
||||||
@ -160,6 +131,8 @@ async function prepareCore(detached: boolean): Promise<CoreConfig> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const corePath = mihomoCorePath(core)
|
||||||
|
|
||||||
// 管理 Smart 内核覆写配置
|
// 管理 Smart 内核覆写配置
|
||||||
await manageSmartOverride()
|
await manageSmartOverride()
|
||||||
|
|
||||||
@ -169,7 +142,6 @@ async function prepareCore(detached: boolean): Promise<CoreConfig> {
|
|||||||
await stopCore()
|
await stopCore()
|
||||||
await cleanupSocketFile()
|
await cleanupSocketFile()
|
||||||
|
|
||||||
// 设置 DNS
|
|
||||||
if (tun?.enable && autoSetDNS) {
|
if (tun?.enable && autoSetDNS) {
|
||||||
try {
|
try {
|
||||||
await setPublicDNS()
|
await setPublicDNS()
|
||||||
@ -179,57 +151,39 @@ async function prepareCore(detached: boolean): Promise<CoreConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取动态 IPC 路径
|
// 获取动态 IPC 路径
|
||||||
const ipcPath = getMihomoIpcPath()
|
const dynamicIpcPath = getMihomoIpcPath()
|
||||||
managerLogger.info(`Using IPC path: ${ipcPath}`)
|
managerLogger.info(`Using IPC path: ${dynamicIpcPath}`)
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
await validateWindowsPipeAccess(ipcPath)
|
await validateWindowsPipeAccess(dynamicIpcPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
// 内核日志输出
|
||||||
corePath: mihomoCorePath(core),
|
|
||||||
workDir: diffWorkDir ? mihomoProfileWorkDir(current) : mihomoWorkDir(),
|
|
||||||
ipcPath,
|
|
||||||
logLevel,
|
|
||||||
tunEnabled: tun?.enable ?? false,
|
|
||||||
autoSetDNS,
|
|
||||||
cpuPriority: mihomoCpuPriority,
|
|
||||||
detached
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 启动核心进程
|
|
||||||
function spawnCoreProcess(config: CoreConfig): ChildProcess {
|
|
||||||
const { corePath, workDir, ipcPath, cpuPriority, detached } = config
|
|
||||||
|
|
||||||
const stdout = createWriteStream(coreLogPath(), { flags: 'a' })
|
const stdout = createWriteStream(coreLogPath(), { flags: 'a' })
|
||||||
const stderr = createWriteStream(coreLogPath(), { flags: 'a' })
|
const stderr = createWriteStream(coreLogPath(), { flags: 'a' })
|
||||||
|
|
||||||
const proc = spawn(corePath, ['-d', workDir, ctlParam, ipcPath], {
|
child = spawn(
|
||||||
|
corePath,
|
||||||
|
['-d', diffWorkDir ? mihomoProfileWorkDir(current) : mihomoWorkDir(), ctlParam, dynamicIpcPath],
|
||||||
|
{
|
||||||
detached,
|
detached,
|
||||||
stdio: detached ? 'ignore' : undefined
|
stdio: detached ? 'ignore' : undefined
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (process.platform === 'win32' && proc.pid) {
|
if (process.platform === 'win32' && child.pid) {
|
||||||
os.setPriority(proc.pid, os.constants.priority[cpuPriority as keyof typeof os.constants.priority])
|
os.setPriority(child.pid, os.constants.priority[mihomoCpuPriority])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!detached) {
|
if (detached) {
|
||||||
proc.stdout?.pipe(stdout)
|
managerLogger.info(
|
||||||
proc.stderr?.pipe(stderr)
|
`Core process detached successfully on ${process.platform}, PID: ${child.pid}`
|
||||||
|
)
|
||||||
|
child.unref()
|
||||||
|
return [new Promise(() => {})]
|
||||||
}
|
}
|
||||||
|
|
||||||
return proc
|
child.on('close', async (code, signal) => {
|
||||||
}
|
|
||||||
|
|
||||||
// 设置核心进程事件监听
|
|
||||||
function setupCoreListeners(
|
|
||||||
proc: ChildProcess,
|
|
||||||
logLevel: LogLevel,
|
|
||||||
resolve: (value: Promise<void>[]) => void,
|
|
||||||
reject: (reason: unknown) => void
|
|
||||||
): void {
|
|
||||||
proc.on('close', async (code, signal) => {
|
|
||||||
managerLogger.info(`Core closed, code: ${code}, signal: ${signal}`)
|
managerLogger.info(`Core closed, code: ${code}, signal: ${signal}`)
|
||||||
|
|
||||||
if (isRestarting) {
|
if (isRestarting) {
|
||||||
@ -246,19 +200,20 @@ function setupCoreListeners(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
proc.stdout?.on('data', async (data) => {
|
child.stdout?.pipe(stdout)
|
||||||
|
child.stderr?.pipe(stderr)
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
child.stdout?.on('data', async (data) => {
|
||||||
const str = data.toString()
|
const str = data.toString()
|
||||||
|
|
||||||
// TUN 权限错误
|
|
||||||
if (str.includes('configure tun interface: operation not permitted')) {
|
if (str.includes('configure tun interface: operation not permitted')) {
|
||||||
patchControledMihomoConfig({ tun: { enable: false } })
|
patchControledMihomoConfig({ tun: { enable: false } })
|
||||||
mainWindow?.webContents.send('controledMihomoConfigUpdated')
|
mainWindow?.webContents.send('controledMihomoConfigUpdated')
|
||||||
ipcMain.emit('updateTrayMenu')
|
ipcMain.emit('updateTrayMenu')
|
||||||
reject(i18next.t('tun.error.tunPermissionDenied'))
|
reject(i18next.t('tun.error.tunPermissionDenied'))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 控制器监听错误
|
|
||||||
const isControllerError =
|
const isControllerError =
|
||||||
(process.platform !== 'win32' && str.includes('External controller unix listen error')) ||
|
(process.platform !== 'win32' && str.includes('External controller unix listen error')) ||
|
||||||
(process.platform === 'win32' && str.includes('External controller pipe listen error'))
|
(process.platform === 'win32' && str.includes('External controller pipe listen error'))
|
||||||
@ -277,10 +232,8 @@ function setupCoreListeners(
|
|||||||
}
|
}
|
||||||
|
|
||||||
reject(i18next.t('mihomo.error.externalControllerListenError'))
|
reject(i18next.t('mihomo.error.externalControllerListenError'))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// API 就绪
|
|
||||||
const isApiReady =
|
const isApiReady =
|
||||||
(process.platform !== 'win32' && str.includes('RESTful API unix listening at')) ||
|
(process.platform !== 'win32' && str.includes('RESTful API unix listening at')) ||
|
||||||
(process.platform === 'win32' && str.includes('RESTful API pipe listening at'))
|
(process.platform === 'win32' && str.includes('RESTful API pipe listening at'))
|
||||||
@ -288,7 +241,7 @@ function setupCoreListeners(
|
|||||||
if (isApiReady) {
|
if (isApiReady) {
|
||||||
resolve([
|
resolve([
|
||||||
new Promise((innerResolve) => {
|
new Promise((innerResolve) => {
|
||||||
proc.stdout?.on('data', async (innerData) => {
|
child.stdout?.on('data', async (innerData) => {
|
||||||
if (
|
if (
|
||||||
innerData.toString().toLowerCase().includes('start initial compatible provider default')
|
innerData.toString().toLowerCase().includes('start initial compatible provider default')
|
||||||
) {
|
) {
|
||||||
@ -315,27 +268,9 @@ function setupCoreListeners(
|
|||||||
retry = 10
|
retry = 10
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// 启动核心
|
|
||||||
export async function startCore(detached = false): Promise<Promise<void>[]> {
|
|
||||||
const config = await prepareCore(detached)
|
|
||||||
child = spawnCoreProcess(config)
|
|
||||||
|
|
||||||
if (detached) {
|
|
||||||
managerLogger.info(
|
|
||||||
`Core process detached successfully on ${process.platform}, PID: ${child.pid}`
|
|
||||||
)
|
|
||||||
child.unref()
|
|
||||||
return [new Promise(() => {})]
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setupCoreListeners(child, config.logLevel, resolve, reject)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 停止核心
|
|
||||||
export async function stopCore(force = false): Promise<void> {
|
export async function stopCore(force = false): Promise<void> {
|
||||||
try {
|
try {
|
||||||
if (!force) {
|
if (!force) {
|
||||||
@ -364,7 +299,6 @@ export async function stopCore(force = false): Promise<void> {
|
|||||||
await cleanupSocketFile()
|
await cleanupSocketFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重启核心
|
|
||||||
export async function restartCore(): Promise<void> {
|
export async function restartCore(): Promise<void> {
|
||||||
if (isRestarting) {
|
if (isRestarting) {
|
||||||
managerLogger.info('Core restart already in progress, skipping duplicate request')
|
managerLogger.info('Core restart already in progress, skipping duplicate request')
|
||||||
@ -382,7 +316,6 @@ export async function restartCore(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保持核心运行
|
|
||||||
export async function keepCoreAlive(): Promise<void> {
|
export async function keepCoreAlive(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await startCore(true)
|
await startCore(true)
|
||||||
@ -394,7 +327,6 @@ export async function keepCoreAlive(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退出但保持核心运行
|
|
||||||
export async function quitWithoutCore(): Promise<void> {
|
export async function quitWithoutCore(): Promise<void> {
|
||||||
managerLogger.info(`Starting lightweight mode on platform: ${process.platform}`)
|
managerLogger.info(`Starting lightweight mode on platform: ${process.platform}`)
|
||||||
|
|
||||||
@ -414,7 +346,6 @@ export async function quitWithoutCore(): Promise<void> {
|
|||||||
app.exit()
|
app.exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查配置文件
|
|
||||||
async function checkProfile(
|
async function checkProfile(
|
||||||
current: string | undefined,
|
current: string | undefined,
|
||||||
core: string = 'mihomo',
|
core: string = 'mihomo',
|
||||||
|
|||||||
@ -10,8 +10,7 @@ import {
|
|||||||
checkHighPrivilegeCore,
|
checkHighPrivilegeCore,
|
||||||
restartAsAdmin,
|
restartAsAdmin,
|
||||||
initAdminStatus,
|
initAdminStatus,
|
||||||
checkAdminPrivileges,
|
checkAdminPrivileges
|
||||||
initCoreWatcher
|
|
||||||
} from './core/manager'
|
} from './core/manager'
|
||||||
import { createTray } from './resolve/tray'
|
import { createTray } from './resolve/tray'
|
||||||
import { init, initBasic, safeShowErrorBox } from './utils/init'
|
import { init, initBasic, safeShowErrorBox } from './utils/init'
|
||||||
@ -150,7 +149,6 @@ app.whenReady().then(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
initCoreWatcher()
|
|
||||||
const [startPromise] = await startCore()
|
const [startPromise] = await startCore()
|
||||||
startPromise.then(async () => {
|
startPromise.then(async () => {
|
||||||
await initProfileUpdater()
|
await initProfileUpdater()
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { promisify } from 'util'
|
|||||||
import { stat } from 'fs/promises'
|
import { stat } from 'fs/promises'
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'fs'
|
||||||
import { app, powerMonitor } from 'electron'
|
import { app, powerMonitor } from 'electron'
|
||||||
import { stopCore, cleanupCoreWatcher } from './core/manager'
|
import { stopCore } from './core/manager'
|
||||||
import { triggerSysProxy } from './sys/sysproxy'
|
import { triggerSysProxy } from './sys/sysproxy'
|
||||||
import { exePath } from './utils/dirs'
|
import { exePath } from './utils/dirs'
|
||||||
|
|
||||||
@ -56,14 +56,12 @@ export function setupPlatformSpecifics(): void {
|
|||||||
export function setupAppLifecycle(): void {
|
export function setupAppLifecycle(): void {
|
||||||
app.on('before-quit', async (e) => {
|
app.on('before-quit', async (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
cleanupCoreWatcher()
|
|
||||||
await triggerSysProxy(false)
|
await triggerSysProxy(false)
|
||||||
await stopCore()
|
await stopCore()
|
||||||
app.exit()
|
app.exit()
|
||||||
})
|
})
|
||||||
|
|
||||||
powerMonitor.on('shutdown', async () => {
|
powerMonitor.on('shutdown', async () => {
|
||||||
cleanupCoreWatcher()
|
|
||||||
triggerSysProxy(false)
|
triggerSysProxy(false)
|
||||||
await stopCore()
|
await stopCore()
|
||||||
app.exit()
|
app.exit()
|
||||||
|
|||||||
@ -12,309 +12,189 @@ async function invoke<T>(channel: string, ...args: unknown[]): Promise<T> {
|
|||||||
return checkIpcError<T>(response)
|
return checkIpcError<T>(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPC API 类型定义
|
// Mihomo API
|
||||||
interface IpcApi {
|
export const mihomoVersion = (): Promise<IMihomoVersion> => invoke('mihomoVersion')
|
||||||
// Mihomo API
|
export const mihomoCloseConnection = (id: string): Promise<void> =>
|
||||||
mihomoVersion: () => Promise<IMihomoVersion>
|
invoke('mihomoCloseConnection', id)
|
||||||
mihomoCloseConnection: (id: string) => Promise<void>
|
export const mihomoCloseAllConnections = (): Promise<void> => invoke('mihomoCloseAllConnections')
|
||||||
mihomoCloseAllConnections: () => Promise<void>
|
export const mihomoRules = (): Promise<IMihomoRulesInfo> => invoke('mihomoRules')
|
||||||
mihomoRules: () => Promise<IMihomoRulesInfo>
|
export const mihomoProxies = (): Promise<IMihomoProxies> => invoke('mihomoProxies')
|
||||||
mihomoProxies: () => Promise<IMihomoProxies>
|
export const mihomoGroups = (): Promise<IMihomoMixedGroup[]> => invoke('mihomoGroups')
|
||||||
mihomoGroups: () => Promise<IMihomoMixedGroup[]>
|
export const mihomoProxyProviders = (): Promise<IMihomoProxyProviders> =>
|
||||||
mihomoProxyProviders: () => Promise<IMihomoProxyProviders>
|
invoke('mihomoProxyProviders')
|
||||||
mihomoUpdateProxyProviders: (name: string) => Promise<void>
|
export const mihomoUpdateProxyProviders = (name: string): Promise<void> =>
|
||||||
mihomoRuleProviders: () => Promise<IMihomoRuleProviders>
|
invoke('mihomoUpdateProxyProviders', name)
|
||||||
mihomoUpdateRuleProviders: (name: string) => Promise<void>
|
export const mihomoRuleProviders = (): Promise<IMihomoRuleProviders> =>
|
||||||
mihomoChangeProxy: (group: string, proxy: string) => Promise<IMihomoProxy>
|
invoke('mihomoRuleProviders')
|
||||||
mihomoUnfixedProxy: (group: string) => Promise<IMihomoProxy>
|
export const mihomoUpdateRuleProviders = (name: string): Promise<void> =>
|
||||||
mihomoUpgradeGeo: () => Promise<void>
|
invoke('mihomoUpdateRuleProviders', name)
|
||||||
mihomoUpgrade: () => Promise<void>
|
export const mihomoChangeProxy = (group: string, proxy: string): Promise<IMihomoProxy> =>
|
||||||
mihomoUpgradeUI: () => Promise<void>
|
invoke('mihomoChangeProxy', group, proxy)
|
||||||
mihomoUpgradeConfig: () => Promise<void>
|
export const mihomoUnfixedProxy = (group: string): Promise<IMihomoProxy> =>
|
||||||
mihomoProxyDelay: (proxy: string, url?: string) => Promise<IMihomoDelay>
|
invoke('mihomoUnfixedProxy', group)
|
||||||
mihomoGroupDelay: (group: string, url?: string) => Promise<IMihomoGroupDelay>
|
export const mihomoUpgradeGeo = (): Promise<void> => invoke('mihomoUpgradeGeo')
|
||||||
patchMihomoConfig: (patch: Partial<IMihomoConfig>) => Promise<void>
|
export const mihomoUpgrade = (): Promise<void> => invoke('mihomoUpgrade')
|
||||||
mihomoSmartGroupWeights: (groupName: string) => Promise<Record<string, number>>
|
export const mihomoUpgradeUI = (): Promise<void> => invoke('mihomoUpgradeUI')
|
||||||
mihomoSmartFlushCache: (configName?: string) => Promise<void>
|
export const mihomoUpgradeConfig = (): Promise<void> => invoke('mihomoUpgradeConfig')
|
||||||
getSmartOverrideContent: () => Promise<string | null>
|
export const mihomoProxyDelay = (proxy: string, url?: string): Promise<IMihomoDelay> =>
|
||||||
// AutoRun
|
invoke('mihomoProxyDelay', proxy, url)
|
||||||
checkAutoRun: () => Promise<boolean>
|
export const mihomoGroupDelay = (group: string, url?: string): Promise<IMihomoGroupDelay> =>
|
||||||
enableAutoRun: () => Promise<void>
|
invoke('mihomoGroupDelay', group, url)
|
||||||
disableAutoRun: () => Promise<void>
|
export const patchMihomoConfig = (patch: Partial<IMihomoConfig>): Promise<void> =>
|
||||||
// Config
|
invoke('patchMihomoConfig', patch)
|
||||||
getAppConfig: (force?: boolean) => Promise<IAppConfig>
|
export const mihomoSmartGroupWeights = (groupName: string): Promise<Record<string, number>> =>
|
||||||
patchAppConfig: (patch: Partial<IAppConfig>) => Promise<void>
|
invoke('mihomoSmartGroupWeights', groupName)
|
||||||
getControledMihomoConfig: (force?: boolean) => Promise<Partial<IMihomoConfig>>
|
export const mihomoSmartFlushCache = (configName?: string): Promise<void> =>
|
||||||
patchControledMihomoConfig: (patch: Partial<IMihomoConfig>) => Promise<void>
|
invoke('mihomoSmartFlushCache', configName)
|
||||||
resetAppConfig: () => Promise<void>
|
export const getSmartOverrideContent = (): Promise<string | null> =>
|
||||||
// Profile
|
invoke('getSmartOverrideContent')
|
||||||
getProfileConfig: (force?: boolean) => Promise<IProfileConfig>
|
|
||||||
setProfileConfig: (config: IProfileConfig) => Promise<void>
|
|
||||||
getCurrentProfileItem: () => Promise<IProfileItem>
|
|
||||||
getProfileItem: (id: string | undefined) => Promise<IProfileItem>
|
|
||||||
getProfileStr: (id: string) => Promise<string>
|
|
||||||
setProfileStr: (id: string, str: string) => Promise<void>
|
|
||||||
addProfileItem: (item: Partial<IProfileItem>) => Promise<void>
|
|
||||||
removeProfileItem: (id: string) => Promise<void>
|
|
||||||
updateProfileItem: (item: IProfileItem) => Promise<void>
|
|
||||||
changeCurrentProfile: (id: string) => Promise<void>
|
|
||||||
addProfileUpdater: (item: IProfileItem) => Promise<void>
|
|
||||||
removeProfileUpdater: (id: string) => Promise<void>
|
|
||||||
// Override
|
|
||||||
getOverrideConfig: (force?: boolean) => Promise<IOverrideConfig>
|
|
||||||
setOverrideConfig: (config: IOverrideConfig) => Promise<void>
|
|
||||||
getOverrideItem: (id: string) => Promise<IOverrideItem | undefined>
|
|
||||||
addOverrideItem: (item: Partial<IOverrideItem>) => Promise<void>
|
|
||||||
removeOverrideItem: (id: string) => Promise<void>
|
|
||||||
updateOverrideItem: (item: IOverrideItem) => Promise<void>
|
|
||||||
getOverride: (id: string, ext: 'js' | 'yaml' | 'log') => Promise<string>
|
|
||||||
setOverride: (id: string, ext: 'js' | 'yaml', str: string) => Promise<void>
|
|
||||||
// File
|
|
||||||
getFileStr: (path: string) => Promise<string>
|
|
||||||
setFileStr: (path: string, str: string) => Promise<void>
|
|
||||||
convertMrsRuleset: (path: string, behavior: string) => Promise<string>
|
|
||||||
getRuntimeConfig: () => Promise<IMihomoConfig>
|
|
||||||
getRuntimeConfigStr: () => Promise<string>
|
|
||||||
getRuleStr: (id: string) => Promise<string>
|
|
||||||
setRuleStr: (id: string, str: string) => Promise<void>
|
|
||||||
getFilePath: (ext: string[]) => Promise<string[] | undefined>
|
|
||||||
readTextFile: (filePath: string) => Promise<string>
|
|
||||||
openFile: (type: 'profile' | 'override', id: string, ext?: 'yaml' | 'js') => Promise<void>
|
|
||||||
// Core
|
|
||||||
restartCore: () => Promise<void>
|
|
||||||
startMonitor: () => Promise<void>
|
|
||||||
quitWithoutCore: () => Promise<void>
|
|
||||||
// System
|
|
||||||
triggerSysProxy: (enable: boolean) => Promise<void>
|
|
||||||
checkTunPermissions: () => Promise<boolean>
|
|
||||||
grantTunPermissions: () => Promise<void>
|
|
||||||
manualGrantCorePermition: () => Promise<void>
|
|
||||||
checkAdminPrivileges: () => Promise<boolean>
|
|
||||||
restartAsAdmin: () => Promise<void>
|
|
||||||
checkMihomoCorePermissions: () => Promise<boolean>
|
|
||||||
checkHighPrivilegeCore: () => Promise<boolean>
|
|
||||||
showTunPermissionDialog: () => Promise<boolean>
|
|
||||||
showErrorDialog: (title: string, message: string) => Promise<void>
|
|
||||||
openUWPTool: () => Promise<void>
|
|
||||||
setupFirewall: () => Promise<void>
|
|
||||||
getInterfaces: () => Promise<Record<string, NetworkInterfaceInfo[]>>
|
|
||||||
setNativeTheme: (theme: 'system' | 'light' | 'dark') => Promise<void>
|
|
||||||
copyEnv: (type: 'bash' | 'cmd' | 'powershell') => Promise<void>
|
|
||||||
// Update
|
|
||||||
checkUpdate: () => Promise<IAppVersion | undefined>
|
|
||||||
downloadAndInstallUpdate: (version: string) => Promise<void>
|
|
||||||
getVersion: () => Promise<string>
|
|
||||||
platform: () => Promise<NodeJS.Platform>
|
|
||||||
fetchMihomoTags: (
|
|
||||||
forceRefresh?: boolean
|
|
||||||
) => Promise<{ name: string; zipball_url: string; tarball_url: string }[]>
|
|
||||||
installSpecificMihomoCore: (version: string) => Promise<void>
|
|
||||||
clearMihomoVersionCache: () => Promise<void>
|
|
||||||
// Backup
|
|
||||||
webdavBackup: () => Promise<boolean>
|
|
||||||
webdavRestore: (filename: string) => Promise<void>
|
|
||||||
listWebdavBackups: () => Promise<string[]>
|
|
||||||
webdavDelete: (filename: string) => Promise<void>
|
|
||||||
reinitWebdavBackupScheduler: () => Promise<void>
|
|
||||||
exportLocalBackup: () => Promise<boolean>
|
|
||||||
importLocalBackup: () => Promise<boolean>
|
|
||||||
// SubStore
|
|
||||||
startSubStoreFrontendServer: () => Promise<void>
|
|
||||||
stopSubStoreFrontendServer: () => Promise<void>
|
|
||||||
startSubStoreBackendServer: () => Promise<void>
|
|
||||||
stopSubStoreBackendServer: () => Promise<void>
|
|
||||||
downloadSubStore: () => Promise<void>
|
|
||||||
subStorePort: () => Promise<number>
|
|
||||||
subStoreFrontendPort: () => Promise<number>
|
|
||||||
subStoreSubs: () => Promise<ISubStoreSub[]>
|
|
||||||
subStoreCollections: () => Promise<ISubStoreSub[]>
|
|
||||||
// Theme
|
|
||||||
resolveThemes: () => Promise<{ key: string; label: string; content: string }[]>
|
|
||||||
fetchThemes: () => Promise<void>
|
|
||||||
importThemes: (files: string[]) => Promise<void>
|
|
||||||
readTheme: (theme: string) => Promise<string>
|
|
||||||
writeTheme: (theme: string, css: string) => Promise<void>
|
|
||||||
// Tray
|
|
||||||
showTrayIcon: () => Promise<void>
|
|
||||||
closeTrayIcon: () => Promise<void>
|
|
||||||
updateTrayIcon: () => Promise<void>
|
|
||||||
// Window
|
|
||||||
showMainWindow: () => Promise<void>
|
|
||||||
closeMainWindow: () => Promise<void>
|
|
||||||
triggerMainWindow: () => Promise<void>
|
|
||||||
showFloatingWindow: () => Promise<void>
|
|
||||||
closeFloatingWindow: () => Promise<void>
|
|
||||||
showContextMenu: () => Promise<void>
|
|
||||||
setAlwaysOnTop: (alwaysOnTop: boolean) => Promise<void>
|
|
||||||
isAlwaysOnTop: () => Promise<boolean>
|
|
||||||
openDevTools: () => Promise<void>
|
|
||||||
createHeapSnapshot: () => Promise<void>
|
|
||||||
// Shortcut
|
|
||||||
registerShortcut: (oldShortcut: string, newShortcut: string, action: string) => Promise<boolean>
|
|
||||||
// Misc
|
|
||||||
getGistUrl: () => Promise<string>
|
|
||||||
getImageDataURL: (url: string) => Promise<string>
|
|
||||||
relaunchApp: () => Promise<void>
|
|
||||||
quitApp: () => Promise<void>
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用 Proxy 自动生成 IPC 调用
|
// AutoRun
|
||||||
const ipc = new Proxy({} as IpcApi, {
|
export const checkAutoRun = (): Promise<boolean> => invoke('checkAutoRun')
|
||||||
get:
|
export const enableAutoRun = (): Promise<void> => invoke('enableAutoRun')
|
||||||
<K extends keyof IpcApi>(_: IpcApi, channel: K) =>
|
export const disableAutoRun = (): Promise<void> => invoke('disableAutoRun')
|
||||||
(...args: Parameters<IpcApi[K]>) =>
|
|
||||||
invoke(channel, ...args)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 导出所有 IPC 方法
|
// Config
|
||||||
export const {
|
export const getAppConfig = (force = false): Promise<IAppConfig> => invoke('getAppConfig', force)
|
||||||
// Mihomo API
|
export const patchAppConfig = (patch: Partial<IAppConfig>): Promise<void> =>
|
||||||
mihomoVersion,
|
invoke('patchAppConfig', patch)
|
||||||
mihomoCloseConnection,
|
export const getControledMihomoConfig = (force = false): Promise<Partial<IMihomoConfig>> =>
|
||||||
mihomoCloseAllConnections,
|
invoke('getControledMihomoConfig', force)
|
||||||
mihomoRules,
|
export const patchControledMihomoConfig = (patch: Partial<IMihomoConfig>): Promise<void> =>
|
||||||
mihomoProxies,
|
invoke('patchControledMihomoConfig', patch)
|
||||||
mihomoGroups,
|
export const resetAppConfig = (): Promise<void> => invoke('resetAppConfig')
|
||||||
mihomoProxyProviders,
|
|
||||||
mihomoUpdateProxyProviders,
|
|
||||||
mihomoRuleProviders,
|
|
||||||
mihomoUpdateRuleProviders,
|
|
||||||
mihomoChangeProxy,
|
|
||||||
mihomoUnfixedProxy,
|
|
||||||
mihomoUpgradeGeo,
|
|
||||||
mihomoUpgrade,
|
|
||||||
mihomoUpgradeUI,
|
|
||||||
mihomoUpgradeConfig,
|
|
||||||
mihomoProxyDelay,
|
|
||||||
mihomoGroupDelay,
|
|
||||||
patchMihomoConfig,
|
|
||||||
mihomoSmartGroupWeights,
|
|
||||||
mihomoSmartFlushCache,
|
|
||||||
getSmartOverrideContent,
|
|
||||||
// AutoRun
|
|
||||||
checkAutoRun,
|
|
||||||
enableAutoRun,
|
|
||||||
disableAutoRun,
|
|
||||||
// Config
|
|
||||||
getAppConfig,
|
|
||||||
patchAppConfig,
|
|
||||||
getControledMihomoConfig,
|
|
||||||
patchControledMihomoConfig,
|
|
||||||
resetAppConfig,
|
|
||||||
// Profile
|
|
||||||
getProfileConfig,
|
|
||||||
setProfileConfig,
|
|
||||||
getCurrentProfileItem,
|
|
||||||
getProfileItem,
|
|
||||||
getProfileStr,
|
|
||||||
setProfileStr,
|
|
||||||
addProfileItem,
|
|
||||||
removeProfileItem,
|
|
||||||
updateProfileItem,
|
|
||||||
changeCurrentProfile,
|
|
||||||
addProfileUpdater,
|
|
||||||
removeProfileUpdater,
|
|
||||||
// Override
|
|
||||||
getOverrideConfig,
|
|
||||||
setOverrideConfig,
|
|
||||||
getOverrideItem,
|
|
||||||
addOverrideItem,
|
|
||||||
removeOverrideItem,
|
|
||||||
updateOverrideItem,
|
|
||||||
getOverride,
|
|
||||||
setOverride,
|
|
||||||
// File
|
|
||||||
getFileStr,
|
|
||||||
setFileStr,
|
|
||||||
convertMrsRuleset,
|
|
||||||
getRuntimeConfig,
|
|
||||||
getRuntimeConfigStr,
|
|
||||||
getRuleStr,
|
|
||||||
setRuleStr,
|
|
||||||
getFilePath,
|
|
||||||
readTextFile,
|
|
||||||
openFile,
|
|
||||||
// Core
|
|
||||||
restartCore,
|
|
||||||
startMonitor,
|
|
||||||
quitWithoutCore,
|
|
||||||
// System
|
|
||||||
triggerSysProxy,
|
|
||||||
checkTunPermissions,
|
|
||||||
grantTunPermissions,
|
|
||||||
manualGrantCorePermition,
|
|
||||||
checkAdminPrivileges,
|
|
||||||
restartAsAdmin,
|
|
||||||
checkMihomoCorePermissions,
|
|
||||||
checkHighPrivilegeCore,
|
|
||||||
showTunPermissionDialog,
|
|
||||||
showErrorDialog,
|
|
||||||
openUWPTool,
|
|
||||||
setupFirewall,
|
|
||||||
getInterfaces,
|
|
||||||
setNativeTheme,
|
|
||||||
copyEnv,
|
|
||||||
// Update
|
|
||||||
checkUpdate,
|
|
||||||
downloadAndInstallUpdate,
|
|
||||||
getVersion,
|
|
||||||
fetchMihomoTags,
|
|
||||||
installSpecificMihomoCore,
|
|
||||||
clearMihomoVersionCache,
|
|
||||||
// Backup
|
|
||||||
webdavBackup,
|
|
||||||
webdavRestore,
|
|
||||||
listWebdavBackups,
|
|
||||||
webdavDelete,
|
|
||||||
reinitWebdavBackupScheduler,
|
|
||||||
exportLocalBackup,
|
|
||||||
importLocalBackup,
|
|
||||||
// SubStore
|
|
||||||
startSubStoreFrontendServer,
|
|
||||||
stopSubStoreFrontendServer,
|
|
||||||
startSubStoreBackendServer,
|
|
||||||
stopSubStoreBackendServer,
|
|
||||||
downloadSubStore,
|
|
||||||
subStorePort,
|
|
||||||
subStoreFrontendPort,
|
|
||||||
subStoreSubs,
|
|
||||||
subStoreCollections,
|
|
||||||
// Theme
|
|
||||||
resolveThemes,
|
|
||||||
fetchThemes,
|
|
||||||
importThemes,
|
|
||||||
readTheme,
|
|
||||||
writeTheme,
|
|
||||||
// Tray
|
|
||||||
showTrayIcon,
|
|
||||||
closeTrayIcon,
|
|
||||||
updateTrayIcon,
|
|
||||||
// Window
|
|
||||||
showMainWindow,
|
|
||||||
closeMainWindow,
|
|
||||||
triggerMainWindow,
|
|
||||||
showFloatingWindow,
|
|
||||||
closeFloatingWindow,
|
|
||||||
showContextMenu,
|
|
||||||
setAlwaysOnTop,
|
|
||||||
isAlwaysOnTop,
|
|
||||||
openDevTools,
|
|
||||||
createHeapSnapshot,
|
|
||||||
// Shortcut
|
|
||||||
registerShortcut,
|
|
||||||
// Misc
|
|
||||||
getGistUrl,
|
|
||||||
getImageDataURL,
|
|
||||||
relaunchApp,
|
|
||||||
quitApp
|
|
||||||
} = ipc
|
|
||||||
|
|
||||||
// platform 需要重命名导出
|
// Profile
|
||||||
export const getPlatform = ipc.platform
|
export const getProfileConfig = (force = false): Promise<IProfileConfig> =>
|
||||||
|
invoke('getProfileConfig', force)
|
||||||
|
export const setProfileConfig = (config: IProfileConfig): Promise<void> =>
|
||||||
|
invoke('setProfileConfig', config)
|
||||||
|
export const getCurrentProfileItem = (): Promise<IProfileItem> => invoke('getCurrentProfileItem')
|
||||||
|
export const getProfileItem = (id: string | undefined): Promise<IProfileItem> =>
|
||||||
|
invoke('getProfileItem', id)
|
||||||
|
export const getProfileStr = (id: string): Promise<string> => invoke('getProfileStr', id)
|
||||||
|
export const setProfileStr = (id: string, str: string): Promise<void> =>
|
||||||
|
invoke('setProfileStr', id, str)
|
||||||
|
export const addProfileItem = (item: Partial<IProfileItem>): Promise<void> =>
|
||||||
|
invoke('addProfileItem', item)
|
||||||
|
export const removeProfileItem = (id: string): Promise<void> => invoke('removeProfileItem', id)
|
||||||
|
export const updateProfileItem = (item: IProfileItem): Promise<void> =>
|
||||||
|
invoke('updateProfileItem', item)
|
||||||
|
export const changeCurrentProfile = (id: string): Promise<void> =>
|
||||||
|
invoke('changeCurrentProfile', id)
|
||||||
|
export const addProfileUpdater = (item: IProfileItem): Promise<void> =>
|
||||||
|
invoke('addProfileUpdater', item)
|
||||||
|
export const removeProfileUpdater = (id: string): Promise<void> =>
|
||||||
|
invoke('removeProfileUpdater', id)
|
||||||
|
|
||||||
// 需要特殊处理的函数
|
// Override
|
||||||
|
export const getOverrideConfig = (force = false): Promise<IOverrideConfig> =>
|
||||||
|
invoke('getOverrideConfig', force)
|
||||||
|
export const setOverrideConfig = (config: IOverrideConfig): Promise<void> =>
|
||||||
|
invoke('setOverrideConfig', config)
|
||||||
|
export const getOverrideItem = (id: string): Promise<IOverrideItem | undefined> =>
|
||||||
|
invoke('getOverrideItem', id)
|
||||||
|
export const addOverrideItem = (item: Partial<IOverrideItem>): Promise<void> =>
|
||||||
|
invoke('addOverrideItem', item)
|
||||||
|
export const removeOverrideItem = (id: string): Promise<void> => invoke('removeOverrideItem', id)
|
||||||
|
export const updateOverrideItem = (item: IOverrideItem): Promise<void> =>
|
||||||
|
invoke('updateOverrideItem', item)
|
||||||
|
export const getOverride = (id: string, ext: 'js' | 'yaml' | 'log'): Promise<string> =>
|
||||||
|
invoke('getOverride', id, ext)
|
||||||
|
export const setOverride = (id: string, ext: 'js' | 'yaml', str: string): Promise<void> =>
|
||||||
|
invoke('setOverride', id, ext, str)
|
||||||
|
|
||||||
|
// File
|
||||||
|
export const getFileStr = (path: string): Promise<string> => invoke('getFileStr', path)
|
||||||
|
export const setFileStr = (path: string, str: string): Promise<void> =>
|
||||||
|
invoke('setFileStr', path, str)
|
||||||
|
export const convertMrsRuleset = (path: string, behavior: string): Promise<string> =>
|
||||||
|
invoke('convertMrsRuleset', path, behavior)
|
||||||
|
export const getRuntimeConfig = (): Promise<IMihomoConfig> => invoke('getRuntimeConfig')
|
||||||
|
export const getRuntimeConfigStr = (): Promise<string> => invoke('getRuntimeConfigStr')
|
||||||
|
export const getRuleStr = (id: string): Promise<string> => invoke('getRuleStr', id)
|
||||||
|
export const setRuleStr = (id: string, str: string): Promise<void> => invoke('setRuleStr', id, str)
|
||||||
|
export const getFilePath = (ext: string[]): Promise<string[] | undefined> =>
|
||||||
|
invoke('getFilePath', ext)
|
||||||
|
export const readTextFile = (filePath: string): Promise<string> => invoke('readTextFile', filePath)
|
||||||
|
export const openFile = (
|
||||||
|
type: 'profile' | 'override',
|
||||||
|
id: string,
|
||||||
|
ext?: 'yaml' | 'js'
|
||||||
|
): Promise<void> => invoke('openFile', type, id, ext)
|
||||||
|
|
||||||
|
// Core
|
||||||
|
export const restartCore = (): Promise<void> => invoke('restartCore')
|
||||||
|
export const startMonitor = (): Promise<void> => invoke('startMonitor')
|
||||||
|
export const quitWithoutCore = (): Promise<void> => invoke('quitWithoutCore')
|
||||||
|
|
||||||
|
// System
|
||||||
|
export const triggerSysProxy = (enable: boolean): Promise<void> => invoke('triggerSysProxy', enable)
|
||||||
|
export const checkTunPermissions = (): Promise<boolean> => invoke('checkTunPermissions')
|
||||||
|
export const grantTunPermissions = (): Promise<void> => invoke('grantTunPermissions')
|
||||||
|
export const manualGrantCorePermition = (): Promise<void> => invoke('manualGrantCorePermition')
|
||||||
|
export const checkAdminPrivileges = (): Promise<boolean> => invoke('checkAdminPrivileges')
|
||||||
|
export const restartAsAdmin = (): Promise<void> => invoke('restartAsAdmin')
|
||||||
|
export const checkMihomoCorePermissions = (): Promise<boolean> =>
|
||||||
|
invoke('checkMihomoCorePermissions')
|
||||||
|
export const checkHighPrivilegeCore = (): Promise<boolean> => invoke('checkHighPrivilegeCore')
|
||||||
|
export const showTunPermissionDialog = (): Promise<boolean> => invoke('showTunPermissionDialog')
|
||||||
|
export const showErrorDialog = (title: string, message: string): Promise<void> =>
|
||||||
|
invoke('showErrorDialog', title, message)
|
||||||
|
export const openUWPTool = (): Promise<void> => invoke('openUWPTool')
|
||||||
|
export const setupFirewall = (): Promise<void> => invoke('setupFirewall')
|
||||||
|
export const getInterfaces = (): Promise<Record<string, NetworkInterfaceInfo[]>> =>
|
||||||
|
invoke('getInterfaces')
|
||||||
|
export const setNativeTheme = (theme: 'system' | 'light' | 'dark'): Promise<void> =>
|
||||||
|
invoke('setNativeTheme', theme)
|
||||||
|
export const copyEnv = (type: 'bash' | 'cmd' | 'powershell'): Promise<void> =>
|
||||||
|
invoke('copyEnv', type)
|
||||||
|
|
||||||
|
// Update
|
||||||
|
export const checkUpdate = (): Promise<IAppVersion | undefined> => invoke('checkUpdate')
|
||||||
|
export const downloadAndInstallUpdate = (version: string): Promise<void> =>
|
||||||
|
invoke('downloadAndInstallUpdate', version)
|
||||||
|
export const getVersion = (): Promise<string> => invoke('getVersion')
|
||||||
|
export const getPlatform = (): Promise<NodeJS.Platform> => invoke('platform')
|
||||||
|
export const fetchMihomoTags = (
|
||||||
|
forceRefresh = false
|
||||||
|
): Promise<{ name: string; zipball_url: string; tarball_url: string }[]> =>
|
||||||
|
invoke('fetchMihomoTags', forceRefresh)
|
||||||
|
export const installSpecificMihomoCore = (version: string): Promise<void> =>
|
||||||
|
invoke('installSpecificMihomoCore', version)
|
||||||
|
export const clearMihomoVersionCache = (): Promise<void> => invoke('clearMihomoVersionCache')
|
||||||
|
|
||||||
|
// Backup
|
||||||
|
export const webdavBackup = (): Promise<boolean> => invoke('webdavBackup')
|
||||||
|
export const webdavRestore = (filename: string): Promise<void> => invoke('webdavRestore', filename)
|
||||||
|
export const listWebdavBackups = (): Promise<string[]> => invoke('listWebdavBackups')
|
||||||
|
export const webdavDelete = (filename: string): Promise<void> => invoke('webdavDelete', filename)
|
||||||
|
export const reinitWebdavBackupScheduler = (): Promise<void> =>
|
||||||
|
invoke('reinitWebdavBackupScheduler')
|
||||||
|
export const exportLocalBackup = (): Promise<boolean> => invoke('exportLocalBackup')
|
||||||
|
export const importLocalBackup = (): Promise<boolean> => invoke('importLocalBackup')
|
||||||
|
|
||||||
|
// SubStore
|
||||||
|
export const startSubStoreFrontendServer = (): Promise<void> =>
|
||||||
|
invoke('startSubStoreFrontendServer')
|
||||||
|
export const stopSubStoreFrontendServer = (): Promise<void> => invoke('stopSubStoreFrontendServer')
|
||||||
|
export const startSubStoreBackendServer = (): Promise<void> => invoke('startSubStoreBackendServer')
|
||||||
|
export const stopSubStoreBackendServer = (): Promise<void> => invoke('stopSubStoreBackendServer')
|
||||||
|
export const downloadSubStore = (): Promise<void> => invoke('downloadSubStore')
|
||||||
|
export const subStorePort = (): Promise<number> => invoke('subStorePort')
|
||||||
|
export const subStoreFrontendPort = (): Promise<number> => invoke('subStoreFrontendPort')
|
||||||
|
export const subStoreSubs = (): Promise<ISubStoreSub[]> => invoke('subStoreSubs')
|
||||||
|
export const subStoreCollections = (): Promise<ISubStoreSub[]> => invoke('subStoreCollections')
|
||||||
|
|
||||||
|
// Theme
|
||||||
|
export const resolveThemes = (): Promise<{ key: string; label: string; content: string }[]> =>
|
||||||
|
invoke('resolveThemes')
|
||||||
|
export const fetchThemes = (): Promise<void> => invoke('fetchThemes')
|
||||||
|
export const importThemes = (files: string[]): Promise<void> => invoke('importThemes', files)
|
||||||
|
export const readTheme = (theme: string): Promise<string> => invoke('readTheme', theme)
|
||||||
|
export const writeTheme = (theme: string, css: string): Promise<void> =>
|
||||||
|
invoke('writeTheme', theme, css)
|
||||||
|
|
||||||
// applyTheme: 防抖处理,避免频繁调用
|
|
||||||
let applyThemeRunning = false
|
let applyThemeRunning = false
|
||||||
let pendingTheme: string | null = null
|
let pendingTheme: string | null = null
|
||||||
|
|
||||||
@ -336,7 +216,21 @@ export async function applyTheme(theme: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTitleBarOverlay: 需要静默处理不支持的平台
|
// Tray
|
||||||
|
export const showTrayIcon = (): Promise<void> => invoke('showTrayIcon')
|
||||||
|
export const closeTrayIcon = (): Promise<void> => invoke('closeTrayIcon')
|
||||||
|
export const updateTrayIcon = (): Promise<void> => invoke('updateTrayIcon')
|
||||||
|
export function updateTrayIconImmediate(sysProxyEnabled: boolean, tunEnabled: boolean): void {
|
||||||
|
window.electron.ipcRenderer.invoke('updateTrayIconImmediate', sysProxyEnabled, tunEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window
|
||||||
|
export const showMainWindow = (): Promise<void> => invoke('showMainWindow')
|
||||||
|
export const closeMainWindow = (): Promise<void> => invoke('closeMainWindow')
|
||||||
|
export const triggerMainWindow = (): Promise<void> => invoke('triggerMainWindow')
|
||||||
|
export const showFloatingWindow = (): Promise<void> => invoke('showFloatingWindow')
|
||||||
|
export const closeFloatingWindow = (): Promise<void> => invoke('closeFloatingWindow')
|
||||||
|
export const showContextMenu = (): Promise<void> => invoke('showContextMenu')
|
||||||
export async function setTitleBarOverlay(overlay: TitleBarOverlayOptions): Promise<void> {
|
export async function setTitleBarOverlay(overlay: TitleBarOverlayOptions): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await invoke<void>('setTitleBarOverlay', overlay)
|
await invoke<void>('setTitleBarOverlay', overlay)
|
||||||
@ -344,8 +238,21 @@ export async function setTitleBarOverlay(overlay: TitleBarOverlayOptions): Promi
|
|||||||
// Not supported on this platform
|
// Not supported on this platform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export const setAlwaysOnTop = (alwaysOnTop: boolean): Promise<void> =>
|
||||||
|
invoke('setAlwaysOnTop', alwaysOnTop)
|
||||||
|
export const isAlwaysOnTop = (): Promise<boolean> => invoke('isAlwaysOnTop')
|
||||||
|
export const openDevTools = (): Promise<void> => invoke('openDevTools')
|
||||||
|
export const createHeapSnapshot = (): Promise<void> => invoke('createHeapSnapshot')
|
||||||
|
|
||||||
// updateTrayIconImmediate: 同步调用,不等待结果
|
// Shortcut
|
||||||
export function updateTrayIconImmediate(sysProxyEnabled: boolean, tunEnabled: boolean): void {
|
export const registerShortcut = (
|
||||||
window.electron.ipcRenderer.invoke('updateTrayIconImmediate', sysProxyEnabled, tunEnabled)
|
oldShortcut: string,
|
||||||
}
|
newShortcut: string,
|
||||||
|
action: string
|
||||||
|
): Promise<boolean> => invoke('registerShortcut', oldShortcut, newShortcut, action)
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
export const getGistUrl = (): Promise<string> => invoke('getGistUrl')
|
||||||
|
export const getImageDataURL = (url: string): Promise<string> => invoke('getImageDataURL', url)
|
||||||
|
export const relaunchApp = (): Promise<void> => invoke('relaunchApp')
|
||||||
|
export const quitApp = (): Promise<void> => invoke('quitApp')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user