diff --git a/src/main/config/controledMihomo.ts b/src/main/config/controledMihomo.ts index 46bed81..0bf638a 100644 --- a/src/main/config/controledMihomo.ts +++ b/src/main/config/controledMihomo.ts @@ -2,6 +2,7 @@ import { controledMihomoConfigPath } from '../utils/dirs' import yaml from 'yaml' import fs from 'fs' import { getAxios, startMihomoMemory, startMihomoTraffic } from '../core/mihomoApi' +import { generateProfile } from '../resolve/factory' export let controledMihomoConfig: Partial // mihomo.yaml @@ -34,5 +35,6 @@ export function setControledMihomoConfig(patch: Partial): void { startMihomoMemory() startMihomoTraffic() } + generateProfile() fs.writeFileSync(controledMihomoConfigPath(), yaml.stringify(controledMihomoConfig)) } diff --git a/src/main/config/index.ts b/src/main/config/index.ts index 89223e2..e74b4c2 100644 --- a/src/main/config/index.ts +++ b/src/main/config/index.ts @@ -1,7 +1,7 @@ export { getAppConfig, setAppConfig } from './app' export { getControledMihomoConfig, setControledMihomoConfig } from './controledMihomo' export { - getCurrentProfile, + getProfile, getCurrentProfileItem, getProfileItem, getProfileConfig, diff --git a/src/main/config/profile.ts b/src/main/config/profile.ts index dde07ac..23cb8fb 100644 --- a/src/main/config/profile.ts +++ b/src/main/config/profile.ts @@ -10,7 +10,6 @@ import { dialog } from 'electron' import { addProfileUpdater } from '../core/profileUpdater' let profileConfig: IProfileConfig // profile.yaml -let currentProfile: Partial // profiles/xxx.yaml export function getProfileConfig(force = false): IProfileConfig { if (force || !profileConfig) { @@ -27,12 +26,10 @@ export function getProfileItem(id: string | undefined): IProfileItem { export async function changeCurrentProfile(id: string): Promise { const oldId = getProfileConfig().current profileConfig.current = id - getCurrentProfile(true) try { await startCore() } catch (e) { profileConfig.current = oldId - getCurrentProfile(true) } finally { window?.webContents.send('profileConfigUpdated') fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig)) @@ -180,19 +177,10 @@ export function getProfileStr(id: string): string { export async function setProfileStr(id: string, content: string): Promise { fs.writeFileSync(profilePath(id), content, 'utf-8') if (id === getProfileConfig().current) { - getCurrentProfile(true) await startCore() } } -export function getCurrentProfile(force = false): Partial { - if (force || !currentProfile) { - const current = getProfileConfig().current - if (current) { - currentProfile = yaml.parse(getProfileStr(current)) - } else { - currentProfile = yaml.parse(getProfileStr('default')) - } - } - return currentProfile +export function getProfile(id: string): IMihomoConfig { + return yaml.parse(getProfileStr(id)) } diff --git a/src/main/core/mihomoApi.ts b/src/main/core/mihomoApi.ts index 23c18aa..4a29538 100644 --- a/src/main/core/mihomoApi.ts +++ b/src/main/core/mihomoApi.ts @@ -33,13 +33,6 @@ export async function mihomoVersion(): Promise { })) as IMihomoVersion } -export const mihomoConfig = async (): Promise => { - const instance = await getAxios() - return (await instance.get('/configs').catch(() => { - return {} - })) as IMihomoConfig -} - export const patchMihomoConfig = async (patch: Partial): Promise => { const instance = await getAxios() return (await instance.patch('/configs', patch).catch((e) => { diff --git a/src/main/resolve/factory.ts b/src/main/resolve/factory.ts index fa00ea1..ec4b6a3 100644 --- a/src/main/resolve/factory.ts +++ b/src/main/resolve/factory.ts @@ -1,10 +1,12 @@ -import { getControledMihomoConfig, getCurrentProfile } from '../config' +import { getControledMihomoConfig, getProfileConfig, getProfile } from '../config' import { mihomoWorkConfigPath } from '../utils/dirs' import yaml from 'yaml' import fs from 'fs' export function generateProfile(): void { - const currentProfile = getCurrentProfile() + const current = getProfileConfig().current + if (!current) return + const currentProfile = getProfile(current) const controledMihomoConfig = getControledMihomoConfig() const { tun: profileTun = {} } = currentProfile const { tun: controledTun } = controledMihomoConfig diff --git a/src/main/utils/ipc.ts b/src/main/utils/ipc.ts index aa06f14..984c556 100644 --- a/src/main/utils/ipc.ts +++ b/src/main/utils/ipc.ts @@ -3,7 +3,6 @@ import { mihomoChangeProxy, mihomoCloseAllConnections, mihomoCloseConnection, - mihomoConfig, mihomoProxies, mihomoProxyDelay, mihomoRules, @@ -33,13 +32,12 @@ import { import { isEncryptionAvailable, startCore } from '../core/manager' import { triggerSysProxy } from '../resolve/sysproxy' import { checkUpdate } from '../resolve/autoUpdater' -import { exePath, mihomoCorePath } from './dirs' +import { exePath, mihomoCorePath, mihomoWorkConfigPath } from './dirs' import { execSync } from 'child_process' import fs from 'fs' export function registerIpcMainHandlers(): void { ipcMain.handle('mihomoVersion', mihomoVersion) - ipcMain.handle('mihomoConfig', mihomoConfig) ipcMain.handle('mihomoCloseConnection', (_e, id) => mihomoCloseConnection(id)) ipcMain.handle('mihomoCloseAllConnections', mihomoCloseAllConnections) ipcMain.handle('mihomoRules', mihomoRules) @@ -73,6 +71,7 @@ export function registerIpcMainHandlers(): void { ipcMain.handle('encryptString', (_e, str) => safeStorage.encryptString(str)) ipcMain.handle('getFilePath', getFilePath) ipcMain.handle('readTextFile', (_e, filePath) => readTextFile(filePath)) + ipcMain.handle('getRuntimeConfig', getRuntimeConfig) ipcMain.handle('checkUpdate', () => checkUpdate()) ipcMain.handle('getVersion', () => app.getVersion()) ipcMain.handle('platform', () => process.platform) @@ -92,6 +91,10 @@ function readTextFile(filePath: string): string { return fs.readFileSync(filePath, 'utf8') } +function getRuntimeConfig(): string { + return fs.readFileSync(mihomoWorkConfigPath(), 'utf8') +} + async function setupFirewall(): Promise { return new Promise((resolve, reject) => { const removeCommand = ` diff --git a/src/renderer/src/components/sider/config-viewer.tsx b/src/renderer/src/components/sider/config-viewer.tsx new file mode 100644 index 0000000..e77e836 --- /dev/null +++ b/src/renderer/src/components/sider/config-viewer.tsx @@ -0,0 +1,67 @@ +import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from '@nextui-org/react' +import React, { useEffect, useState } from 'react' +import MonacoEditor, { monaco } from 'react-monaco-editor' +import { useTheme } from 'next-themes' +import { getRuntimeConfig } from '@renderer/utils/ipc' +interface Props { + onClose: () => void +} +const ConfigViewer: React.FC = (props) => { + const { onClose } = props + const [currData, setCurrData] = useState('') + const { theme } = useTheme() + + const editorDidMount = (editor: monaco.editor.IStandaloneCodeEditor): void => { + window.electron.ipcRenderer.on('resize', () => { + editor.layout() + }) + } + + const editorWillUnmount = (editor: monaco.editor.IStandaloneCodeEditor): void => { + window.electron.ipcRenderer.removeAllListeners('resize') + editor.dispose() + } + + const getContent = async (): Promise => { + setCurrData(await getRuntimeConfig()) + } + + useEffect(() => { + getContent() + }, []) + + return ( + + + 当前运行时配置 + + + + + + + + + ) +} + +export default ConfigViewer diff --git a/src/renderer/src/components/sider/profile-card.tsx b/src/renderer/src/components/sider/profile-card.tsx index e5bc7f7..9d3cdd1 100644 --- a/src/renderer/src/components/sider/profile-card.tsx +++ b/src/renderer/src/components/sider/profile-card.tsx @@ -2,11 +2,13 @@ import { Button, Card, CardBody, CardFooter, Chip, Progress } from '@nextui-org/ import { useProfileConfig } from '@renderer/hooks/use-profile-config' import { useLocation, useNavigate } from 'react-router-dom' import { calcTraffic, calcPercent } from '@renderer/utils/calc' +import { LiaGripfire } from 'react-icons/lia' import { IoMdRefresh } from 'react-icons/io' import relativeTime from 'dayjs/plugin/relativeTime' import 'dayjs/locale/zh-cn' import dayjs from 'dayjs' import { useState } from 'react' +import ConfigViewer from './config-viewer' dayjs.extend(relativeTime) dayjs.locale('zh-cn') @@ -16,6 +18,7 @@ const ProfileCard: React.FC = () => { const location = useLocation() const match = location.pathname.includes('/profiles') const [updating, setUpdating] = useState(false) + const [showRuntimeConfig, setShowRuntimeConfig] = useState(false) const { profileConfig, addProfileItem } = useProfileConfig() const { current, items } = profileConfig ?? {} const info = items?.find((item) => item.id === current) ?? { @@ -35,6 +38,7 @@ const ProfileCard: React.FC = () => { isPressable onPress={() => navigate('/profiles')} > + {showRuntimeConfig && setShowRuntimeConfig(false)} />}

{ > {info?.name}

- {info.type === 'remote' && ( +
- )} + {info.type === 'remote' && ( + + )} +
{info.type === 'remote' && (
{ return await window.electron.ipcRenderer.invoke('mihomoVersion') } -export async function mihomoConfig(): Promise { - return await window.electron.ipcRenderer.invoke('mihomoConfig') -} - export async function mihomoCloseConnection(id: string): Promise { return await window.electron.ipcRenderer.invoke('mihomoCloseConnection', id) } @@ -139,6 +135,10 @@ export async function readTextFile(filePath: string): Promise { return await window.electron.ipcRenderer.invoke('readTextFile', filePath) } +export async function getRuntimeConfig(): Promise { + return await window.electron.ipcRenderer.invoke('getRuntimeConfig') +} + export async function checkUpdate(): Promise { return await window.electron.ipcRenderer.invoke('checkUpdate') }