mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 21:20:29 +08:00
optimized rule page performance
This commit is contained in:
parent
704a322c25
commit
449597f941
@ -2,10 +2,6 @@
|
||||
|
||||
- 1.2.x YAML覆写语法有所变动,请更新后参考文档进行修改
|
||||
|
||||
### New Features
|
||||
### Performance Improvements
|
||||
|
||||
- 支持使用外部编辑器打开文件
|
||||
- 支持新建订阅/覆写
|
||||
- 添加窗口置顶按钮
|
||||
- 允许禁用系统标题栏
|
||||
- 重写连接页面
|
||||
- 优化规则/代理页面性能
|
||||
|
||||
@ -8,17 +8,22 @@ import {
|
||||
} from '../config'
|
||||
import { mihomoWorkConfigPath, overridePath } from '../utils/dirs'
|
||||
import yaml from 'yaml'
|
||||
import { readFile, writeFile } from 'fs/promises'
|
||||
import { writeFile } from 'fs/promises'
|
||||
import { deepMerge } from '../utils/merge'
|
||||
import vm from 'vm'
|
||||
import { writeFileSync } from 'fs'
|
||||
|
||||
let runtimeConfigStr: string
|
||||
let runtimeConfig: IMihomoConfig
|
||||
|
||||
export async function generateProfile(): Promise<void> {
|
||||
const { current } = await getProfileConfig()
|
||||
const currentProfile = await overrideProfile(current, await getProfile(current))
|
||||
const controledMihomoConfig = await getControledMihomoConfig()
|
||||
const profile = deepMerge(currentProfile, controledMihomoConfig)
|
||||
await writeFile(mihomoWorkConfigPath(), yaml.stringify(profile))
|
||||
runtimeConfig = profile
|
||||
runtimeConfigStr = yaml.stringify(profile)
|
||||
await writeFile(mihomoWorkConfigPath(), runtimeConfigStr)
|
||||
}
|
||||
|
||||
async function overrideProfile(
|
||||
@ -87,9 +92,9 @@ function runOverrideScript(
|
||||
}
|
||||
|
||||
export async function getRuntimeConfigStr(): Promise<string> {
|
||||
return await readFile(mihomoWorkConfigPath(), 'utf8')
|
||||
return runtimeConfigStr
|
||||
}
|
||||
|
||||
export async function getRuntimeConfig(): Promise<IMihomoConfig> {
|
||||
return yaml.parse(await getRuntimeConfigStr())
|
||||
return runtimeConfig
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ export async function startCore(): Promise<void> {
|
||||
}
|
||||
if (data.toString().includes('RESTful API listening at')) {
|
||||
await startMihomoTraffic()
|
||||
mainWindow?.webContents.send('coreRestart')
|
||||
retry = 10
|
||||
resolve()
|
||||
}
|
||||
|
||||
@ -71,8 +71,11 @@ export const mihomoRules = async (): Promise<IMihomoRulesInfo> => {
|
||||
|
||||
export const mihomoProxies = async (): Promise<IMihomoProxies> => {
|
||||
const instance = await getAxios()
|
||||
|
||||
return await instance.get('/proxies')
|
||||
const proxies = (await instance.get('/proxies')) as IMihomoProxies
|
||||
if (!proxies.proxies['GLOBAL']) {
|
||||
throw new Error('GLOBAL proxy not found')
|
||||
}
|
||||
return proxies
|
||||
}
|
||||
|
||||
export const mihomoGroups = async (): Promise<IMihomoMixedGroup[]> => {
|
||||
|
||||
@ -3,14 +3,13 @@ import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { LuGroup } from 'react-icons/lu'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import useSWR from 'swr'
|
||||
import { mihomoGroups } from '@renderer/utils/ipc'
|
||||
import { useGroups } from '@renderer/hooks/use-groups'
|
||||
|
||||
const ProxyCard: React.FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const match = location.pathname.includes('/proxies')
|
||||
const { data: groups = [] } = useSWR('mihomoGroups', mihomoGroups)
|
||||
const { groups = [] } = useGroups()
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
import { Button, Card, CardBody, CardFooter, Chip } from '@nextui-org/react'
|
||||
import { mihomoRules } from '@renderer/utils/ipc'
|
||||
import { MdOutlineAltRoute } from 'react-icons/md'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import useSWR from 'swr'
|
||||
import { useRules } from '@renderer/hooks/use-rules'
|
||||
|
||||
const RuleCard: React.FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const match = location.pathname.includes('/rules')
|
||||
const { data: rules } = useSWR<IMihomoRulesInfo>('mihomoRules', mihomoRules)
|
||||
const { rules } = useRules()
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
|
||||
36
src/renderer/src/hooks/use-groups.tsx
Normal file
36
src/renderer/src/hooks/use-groups.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import { mihomoGroups } from '@renderer/utils/ipc'
|
||||
|
||||
interface GroupsContextType {
|
||||
groups: IMihomoMixedGroup[] | undefined
|
||||
mutate: () => void
|
||||
}
|
||||
|
||||
const GroupsContext = createContext<GroupsContextType | undefined>(undefined)
|
||||
|
||||
export const GroupsProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
const { data: groups, mutate } = useSWR<IMihomoMixedGroup[]>('mihomoGroups', mihomoGroups, {
|
||||
errorRetryInterval: 200,
|
||||
errorRetryCount: 10
|
||||
})
|
||||
|
||||
React.useEffect(() => {
|
||||
window.electron.ipcRenderer.on('coreRestart', () => {
|
||||
mutate()
|
||||
})
|
||||
return (): void => {
|
||||
window.electron.ipcRenderer.removeAllListeners('coreRestart')
|
||||
}
|
||||
}, [])
|
||||
|
||||
return <GroupsContext.Provider value={{ groups, mutate }}>{children}</GroupsContext.Provider>
|
||||
}
|
||||
|
||||
export const useGroups = (): GroupsContextType => {
|
||||
const context = useContext(GroupsContext)
|
||||
if (context === undefined) {
|
||||
throw new Error('useGroups must be used within an GroupsProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
47
src/renderer/src/hooks/use-rules.tsx
Normal file
47
src/renderer/src/hooks/use-rules.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import { mihomoRules } from '@renderer/utils/ipc'
|
||||
|
||||
interface RulesContextType {
|
||||
rules: IMihomoRulesInfo | undefined
|
||||
mutate: () => void
|
||||
}
|
||||
|
||||
const RulesContext = createContext<RulesContextType | undefined>(undefined)
|
||||
let emptyRetry = 10
|
||||
|
||||
export const RulesProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
const { data: rules, mutate } = useSWR<IMihomoRulesInfo>('mihomoRules', mihomoRules, {
|
||||
errorRetryInterval: 200,
|
||||
errorRetryCount: 10,
|
||||
onSuccess: (data) => {
|
||||
if (data.rules.length === 0 && emptyRetry) {
|
||||
emptyRetry--
|
||||
setTimeout(() => {
|
||||
mutate()
|
||||
}, 200)
|
||||
} else {
|
||||
emptyRetry = 10
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
React.useEffect(() => {
|
||||
window.electron.ipcRenderer.on('coreRestart', () => {
|
||||
mutate()
|
||||
})
|
||||
return (): void => {
|
||||
window.electron.ipcRenderer.removeAllListeners('coreRestart')
|
||||
}
|
||||
}, [])
|
||||
|
||||
return <RulesContext.Provider value={{ rules, mutate }}>{children}</RulesContext.Provider>
|
||||
}
|
||||
|
||||
export const useRules = (): RulesContextType => {
|
||||
const context = useContext(RulesContext)
|
||||
if (context === undefined) {
|
||||
throw new Error('useRules must be used within an RulesProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
@ -12,6 +12,8 @@ import { AppConfigProvider } from './hooks/use-app-config'
|
||||
import { ControledMihomoConfigProvider } from './hooks/use-controled-mihomo-config'
|
||||
import { OverrideConfigProvider } from './hooks/use-override-config'
|
||||
import { ProfileConfigProvider } from './hooks/use-profile-config'
|
||||
import { RulesProvider } from './hooks/use-rules'
|
||||
import { GroupsProvider } from './hooks/use-groups'
|
||||
|
||||
init().then(() => {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
@ -53,7 +55,11 @@ init().then(() => {
|
||||
<ControledMihomoConfigProvider>
|
||||
<ProfileConfigProvider>
|
||||
<OverrideConfigProvider>
|
||||
<GroupsProvider>
|
||||
<RulesProvider>
|
||||
<App />
|
||||
</RulesProvider>
|
||||
</GroupsProvider>
|
||||
</OverrideConfigProvider>
|
||||
</ProfileConfigProvider>
|
||||
</ControledMihomoConfigProvider>
|
||||
|
||||
@ -5,7 +5,6 @@ import {
|
||||
mihomoChangeProxy,
|
||||
mihomoCloseAllConnections,
|
||||
mihomoGroupDelay,
|
||||
mihomoGroups,
|
||||
mihomoProxyDelay
|
||||
} from '@renderer/utils/ipc'
|
||||
import { CgDetailsLess, CgDetailsMore } from 'react-icons/cg'
|
||||
@ -14,14 +13,14 @@ import { TbCircleLetterD } from 'react-icons/tb'
|
||||
import { FaLocationCrosshairs } from 'react-icons/fa6'
|
||||
import { RxLetterCaseCapitalize } from 'react-icons/rx'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import { GroupedVirtuoso, GroupedVirtuosoHandle } from 'react-virtuoso'
|
||||
import ProxyItem from '@renderer/components/proxies/proxy-item'
|
||||
import { IoIosArrowBack } from 'react-icons/io'
|
||||
import { MdOutlineSpeed } from 'react-icons/md'
|
||||
import { useGroups } from '@renderer/hooks/use-groups'
|
||||
|
||||
const Proxies: React.FC = () => {
|
||||
const { data: groups = [], mutate } = useSWR('mihomoGroups', mihomoGroups)
|
||||
const { groups = [], mutate } = useGroups()
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
const {
|
||||
proxyDisplayMode = 'simple',
|
||||
@ -190,7 +189,6 @@ const Proxies: React.FC = () => {
|
||||
canvas.height = img.height
|
||||
ctx?.drawImage(img, 0, 0)
|
||||
const data = canvas.toDataURL('image/png')
|
||||
console.log('set')
|
||||
localStorage.setItem(groups[index].icon, data)
|
||||
}
|
||||
img.src = groups[index].icon
|
||||
|
||||
@ -3,11 +3,10 @@ import RuleItem from '@renderer/components/rules/rule-item'
|
||||
import { Virtuoso } from 'react-virtuoso'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Divider, Input } from '@nextui-org/react'
|
||||
import useSWR from 'swr'
|
||||
import { mihomoRules } from '@renderer/utils/ipc'
|
||||
import { useRules } from '@renderer/hooks/use-rules'
|
||||
|
||||
const Rules: React.FC = () => {
|
||||
const { data: rules } = useSWR<IMihomoRulesInfo>('mihomoRules', mihomoRules)
|
||||
const { rules } = useRules()
|
||||
const [filter, setFilter] = useState('')
|
||||
|
||||
const filteredRules = useMemo(() => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user