mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-28 05:30:29 +08:00
fix: inconsistent applied profile when rapidly switching profiles (#1268)
This commit is contained in:
parent
d8fdbebc4b
commit
6429e93adf
@ -1,12 +1,12 @@
|
|||||||
import React, { createContext, useContext, ReactNode } from 'react'
|
import React, { createContext, ReactNode, useContext } from 'react'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
import {
|
import {
|
||||||
getProfileConfig,
|
|
||||||
setProfileConfig as set,
|
|
||||||
addProfileItem as add,
|
addProfileItem as add,
|
||||||
|
changeCurrentProfile as change,
|
||||||
|
getProfileConfig,
|
||||||
removeProfileItem as remove,
|
removeProfileItem as remove,
|
||||||
updateProfileItem as update,
|
setProfileConfig as set,
|
||||||
changeCurrentProfile as change
|
updateProfileItem as update
|
||||||
} from '@renderer/utils/ipc'
|
} from '@renderer/utils/ipc'
|
||||||
|
|
||||||
interface ProfileConfigContextType {
|
interface ProfileConfigContextType {
|
||||||
@ -25,7 +25,8 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
const { data: profileConfig, mutate: mutateProfileConfig } = useSWR('getProfileConfig', () =>
|
const { data: profileConfig, mutate: mutateProfileConfig } = useSWR('getProfileConfig', () =>
|
||||||
getProfileConfig()
|
getProfileConfig()
|
||||||
)
|
)
|
||||||
const [targetProfileId, setTargetProfileId] = React.useState<string | null>(null)
|
const targetProfileId = React.useRef<string | null>(null)
|
||||||
|
const pendingTask = React.useRef<Promise<void> | null>(null)
|
||||||
|
|
||||||
const setProfileConfig = async (config: IProfileConfig): Promise<void> => {
|
const setProfileConfig = async (config: IProfileConfig): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
@ -72,12 +73,10 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
}
|
}
|
||||||
|
|
||||||
const changeCurrentProfile = async (id: string): Promise<void> => {
|
const changeCurrentProfile = async (id: string): Promise<void> => {
|
||||||
if (targetProfileId === id) {
|
if (targetProfileId.current === id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setTargetProfileId(id)
|
|
||||||
|
|
||||||
// 立即更新 UI 状态和托盘菜单,提供即时反馈
|
// 立即更新 UI 状态和托盘菜单,提供即时反馈
|
||||||
if (profileConfig) {
|
if (profileConfig) {
|
||||||
const optimisticUpdate = { ...profileConfig, current: id }
|
const optimisticUpdate = { ...profileConfig, current: id }
|
||||||
@ -85,17 +84,24 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
window.electron.ipcRenderer.send('updateTrayMenu')
|
window.electron.ipcRenderer.send('updateTrayMenu')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步执行后台切换,不阻塞 UI
|
targetProfileId.current = id
|
||||||
try {
|
await processChange()
|
||||||
await change(id)
|
|
||||||
|
|
||||||
if (targetProfileId === id) {
|
|
||||||
mutateProfileConfig()
|
|
||||||
setTargetProfileId(null)
|
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const processChange = async () => {
|
||||||
|
if (pendingTask.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
while (targetProfileId.current) {
|
||||||
|
const targetId = targetProfileId.current
|
||||||
|
targetProfileId.current = null
|
||||||
|
|
||||||
|
pendingTask.current = change(targetId)
|
||||||
|
try {
|
||||||
|
// 异步执行后台切换,不阻塞 UI
|
||||||
|
await pendingTask.current
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (targetProfileId === id) {
|
|
||||||
const errorMsg = (e as any)?.message || String(e)
|
const errorMsg = (e as any)?.message || String(e)
|
||||||
// 处理 IPC 超时错误
|
// 处理 IPC 超时错误
|
||||||
if (errorMsg.includes('reply was never sent')) {
|
if (errorMsg.includes('reply was never sent')) {
|
||||||
@ -104,7 +110,8 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
alert(`切换 Profile 失败: ${errorMsg}`)
|
alert(`切换 Profile 失败: ${errorMsg}`)
|
||||||
mutateProfileConfig()
|
mutateProfileConfig()
|
||||||
}
|
}
|
||||||
setTargetProfileId(null)
|
} finally {
|
||||||
|
pendingTask.current = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user