diff --git a/src/renderer/src/hooks/use-profile-config.tsx b/src/renderer/src/hooks/use-profile-config.tsx index 315257d..a6d0cb7 100644 --- a/src/renderer/src/hooks/use-profile-config.tsx +++ b/src/renderer/src/hooks/use-profile-config.tsx @@ -1,12 +1,12 @@ -import React, { createContext, useContext, ReactNode } from 'react' +import React, { createContext, ReactNode, useContext } from 'react' import useSWR from 'swr' import { - getProfileConfig, - setProfileConfig as set, addProfileItem as add, + changeCurrentProfile as change, + getProfileConfig, removeProfileItem as remove, - updateProfileItem as update, - changeCurrentProfile as change + setProfileConfig as set, + updateProfileItem as update } from '@renderer/utils/ipc' interface ProfileConfigContextType { @@ -25,7 +25,8 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child const { data: profileConfig, mutate: mutateProfileConfig } = useSWR('getProfileConfig', () => getProfileConfig() ) - const [targetProfileId, setTargetProfileId] = React.useState(null) + const targetProfileId = React.useRef(null) + const pendingTask = React.useRef | null>(null) const setProfileConfig = async (config: IProfileConfig): Promise => { try { @@ -72,12 +73,10 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child } const changeCurrentProfile = async (id: string): Promise => { - if (targetProfileId === id) { + if (targetProfileId.current === id) { return } - setTargetProfileId(id) - // 立即更新 UI 状态和托盘菜单,提供即时反馈 if (profileConfig) { const optimisticUpdate = { ...profileConfig, current: id } @@ -85,17 +84,24 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child window.electron.ipcRenderer.send('updateTrayMenu') } - // 异步执行后台切换,不阻塞 UI - try { - await change(id) + targetProfileId.current = id + await processChange() + } - if (targetProfileId === id) { - mutateProfileConfig() - setTargetProfileId(null) - } else { - } - } catch (e) { - if (targetProfileId === id) { + 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) { const errorMsg = (e as any)?.message || String(e) // 处理 IPC 超时错误 if (errorMsg.includes('reply was never sent')) { @@ -104,7 +110,8 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child alert(`切换 Profile 失败: ${errorMsg}`) mutateProfileConfig() } - setTargetProfileId(null) + } finally { + pendingTask.current = null } } }