use context provider

This commit is contained in:
pompurin404 2024-08-29 12:07:08 +08:00
parent a049b2ab7f
commit 1c924bcc89
No known key found for this signature in database
6 changed files with 110 additions and 54 deletions

View File

@ -4,7 +4,6 @@ import { addProfileUpdater } from '../core/profileUpdater'
import { readFile, rm, writeFile } from 'fs/promises' import { readFile, rm, writeFile } from 'fs/promises'
import { restartCore } from '../core/manager' import { restartCore } from '../core/manager'
import { getAppConfig } from './app' import { getAppConfig } from './app'
import { mainWindow } from '..'
import { existsSync } from 'fs' import { existsSync } from 'fs'
import axios from 'axios' import axios from 'axios'
import yaml from 'yaml' import yaml from 'yaml'
@ -22,7 +21,6 @@ export async function getProfileConfig(force = false): Promise<IProfileConfig> {
export async function setProfileConfig(config: IProfileConfig): Promise<void> { export async function setProfileConfig(config: IProfileConfig): Promise<void> {
profileConfig = config profileConfig = config
mainWindow?.webContents.send('profileConfigUpdated')
await writeFile(profileConfigPath(), yaml.stringify(config), 'utf-8') await writeFile(profileConfigPath(), yaml.stringify(config), 'utf-8')
} }

View File

@ -1,14 +1,16 @@
import React, { createContext, useContext, ReactNode } from 'react'
import useSWR from 'swr' import useSWR from 'swr'
import { getAppConfig, patchAppConfig as patch } from '@renderer/utils/ipc' import { getAppConfig, patchAppConfig as patch } from '@renderer/utils/ipc'
import { useEffect } from 'react'
interface RetuenType { interface AppConfigContextType {
appConfig: IAppConfig | undefined appConfig: IAppConfig | undefined
mutateAppConfig: () => void mutateAppConfig: () => void
patchAppConfig: (value: Partial<IAppConfig>) => Promise<void> patchAppConfig: (value: Partial<IAppConfig>) => Promise<void>
} }
export const useAppConfig = (listenUpdate = false): RetuenType => { const AppConfigContext = createContext<AppConfigContextType | undefined>(undefined)
export const AppConfigProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { data: appConfig, mutate: mutateAppConfig } = useSWR('getConfig', () => getAppConfig()) const { data: appConfig, mutate: mutateAppConfig } = useSWR('getConfig', () => getAppConfig())
const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => { const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => {
@ -21,8 +23,7 @@ export const useAppConfig = (listenUpdate = false): RetuenType => {
} }
} }
useEffect(() => { React.useEffect(() => {
if (!listenUpdate) return
window.electron.ipcRenderer.on('appConfigUpdated', () => { window.electron.ipcRenderer.on('appConfigUpdated', () => {
mutateAppConfig() mutateAppConfig()
}) })
@ -31,9 +32,17 @@ export const useAppConfig = (listenUpdate = false): RetuenType => {
} }
}, []) }, [])
return { return (
appConfig, <AppConfigContext.Provider value={{ appConfig, mutateAppConfig, patchAppConfig }}>
mutateAppConfig, {children}
patchAppConfig </AppConfigContext.Provider>
} )
}
export const useAppConfig = (): AppConfigContextType => {
const context = useContext(AppConfigContext)
if (context === undefined) {
throw new Error('useAppConfig must be used within an AppConfigProvider')
}
return context
} }

View File

@ -1,14 +1,18 @@
import React, { createContext, useContext, ReactNode } from 'react'
import useSWR from 'swr' import useSWR from 'swr'
import { getControledMihomoConfig, patchControledMihomoConfig as patch } from '@renderer/utils/ipc' import { getControledMihomoConfig, patchControledMihomoConfig as patch } from '@renderer/utils/ipc'
import { useEffect } from 'react'
interface RetuenType { interface ControledMihomoConfigContextType {
controledMihomoConfig: Partial<IMihomoConfig> | undefined controledMihomoConfig: Partial<IMihomoConfig> | undefined
mutateControledMihomoConfig: () => void mutateControledMihomoConfig: () => void
patchControledMihomoConfig: (value: Partial<IMihomoConfig>) => Promise<void> patchControledMihomoConfig: (value: Partial<IMihomoConfig>) => Promise<void>
} }
export const useControledMihomoConfig = (listenUpdate = false): RetuenType => { const ControledMihomoConfigContext = createContext<ControledMihomoConfigContextType | undefined>(
undefined
)
export const ControledMihomoConfigProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { data: controledMihomoConfig, mutate: mutateControledMihomoConfig } = useSWR( const { data: controledMihomoConfig, mutate: mutateControledMihomoConfig } = useSWR(
'getControledMihomoConfig', 'getControledMihomoConfig',
() => getControledMihomoConfig() () => getControledMihomoConfig()
@ -24,8 +28,7 @@ export const useControledMihomoConfig = (listenUpdate = false): RetuenType => {
} }
} }
useEffect(() => { React.useEffect(() => {
if (!listenUpdate) return
window.electron.ipcRenderer.on('controledMihomoConfigUpdated', () => { window.electron.ipcRenderer.on('controledMihomoConfigUpdated', () => {
mutateControledMihomoConfig() mutateControledMihomoConfig()
}) })
@ -34,9 +37,19 @@ export const useControledMihomoConfig = (listenUpdate = false): RetuenType => {
} }
}, []) }, [])
return { return (
controledMihomoConfig, <ControledMihomoConfigContext.Provider
mutateControledMihomoConfig, value={{ controledMihomoConfig, mutateControledMihomoConfig, patchControledMihomoConfig }}
patchControledMihomoConfig >
} {children}
</ControledMihomoConfigContext.Provider>
)
}
export const useControledMihomoConfig = (): ControledMihomoConfigContextType => {
const context = useContext(ControledMihomoConfigContext)
if (context === undefined) {
throw new Error('useControledMihomoConfig must be used within a ControledMihomoConfigProvider')
}
return context
} }

View File

@ -1,3 +1,4 @@
import React, { createContext, useContext, ReactNode } from 'react'
import useSWR from 'swr' import useSWR from 'swr'
import { import {
getOverrideConfig, getOverrideConfig,
@ -7,7 +8,7 @@ import {
updateOverrideItem as update updateOverrideItem as update
} from '@renderer/utils/ipc' } from '@renderer/utils/ipc'
interface RetuenType { interface OverrideConfigContextType {
overrideConfig: IOverrideConfig | undefined overrideConfig: IOverrideConfig | undefined
setOverrideConfig: (config: IOverrideConfig) => Promise<void> setOverrideConfig: (config: IOverrideConfig) => Promise<void>
mutateOverrideConfig: () => void mutateOverrideConfig: () => void
@ -16,7 +17,9 @@ interface RetuenType {
removeOverrideItem: (id: string) => Promise<void> removeOverrideItem: (id: string) => Promise<void>
} }
export const useOverrideConfig = (): RetuenType => { const OverrideConfigContext = createContext<OverrideConfigContextType | undefined>(undefined)
export const OverrideConfigProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { data: overrideConfig, mutate: mutateOverrideConfig } = useSWR('getOverrideConfig', () => const { data: overrideConfig, mutate: mutateOverrideConfig } = useSWR('getOverrideConfig', () =>
getOverrideConfig() getOverrideConfig()
) )
@ -61,12 +64,26 @@ export const useOverrideConfig = (): RetuenType => {
} }
} }
return { return (
overrideConfig, <OverrideConfigContext.Provider
setOverrideConfig, value={{
mutateOverrideConfig, overrideConfig,
addOverrideItem, setOverrideConfig,
removeOverrideItem, mutateOverrideConfig,
updateOverrideItem addOverrideItem,
} removeOverrideItem,
updateOverrideItem
}}
>
{children}
</OverrideConfigContext.Provider>
)
}
export const useOverrideConfig = (): OverrideConfigContextType => {
const context = useContext(OverrideConfigContext)
if (context === undefined) {
throw new Error('useOverrideConfig must be used within an OverrideConfigProvider')
}
return context
} }

View File

@ -1,3 +1,4 @@
import React, { createContext, useContext, ReactNode } from 'react'
import useSWR from 'swr' import useSWR from 'swr'
import { import {
getProfileConfig, getProfileConfig,
@ -7,9 +8,8 @@ import {
updateProfileItem as update, updateProfileItem as update,
changeCurrentProfile as change changeCurrentProfile as change
} from '@renderer/utils/ipc' } from '@renderer/utils/ipc'
import { useEffect } from 'react'
interface RetuenType { interface ProfileConfigContextType {
profileConfig: IProfileConfig | undefined profileConfig: IProfileConfig | undefined
setProfileConfig: (config: IProfileConfig) => Promise<void> setProfileConfig: (config: IProfileConfig) => Promise<void>
mutateProfileConfig: () => void mutateProfileConfig: () => void
@ -19,7 +19,9 @@ interface RetuenType {
changeCurrentProfile: (id: string) => Promise<void> changeCurrentProfile: (id: string) => Promise<void>
} }
export const useProfileConfig = (): RetuenType => { const ProfileConfigContext = createContext<ProfileConfigContextType | undefined>(undefined)
export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { data: profileConfig, mutate: mutateProfileConfig } = useSWR('getProfileConfig', () => const { data: profileConfig, mutate: mutateProfileConfig } = useSWR('getProfileConfig', () =>
getProfileConfig() getProfileConfig()
) )
@ -74,22 +76,27 @@ export const useProfileConfig = (): RetuenType => {
} }
} }
useEffect(() => { return (
window.electron.ipcRenderer.on('profileConfigUpdated', () => { <ProfileConfigContext.Provider
mutateProfileConfig() value={{
}) profileConfig,
return (): void => { setProfileConfig,
window.electron.ipcRenderer.removeAllListeners('profileConfigUpdated') mutateProfileConfig,
} addProfileItem,
}, []) removeProfileItem,
updateProfileItem,
return { changeCurrentProfile
profileConfig, }}
setProfileConfig, >
mutateProfileConfig, {children}
addProfileItem, </ProfileConfigContext.Provider>
removeProfileItem, )
updateProfileItem, }
changeCurrentProfile
} export const useProfileConfig = (): ProfileConfigContextType => {
const context = useContext(ProfileConfigContext)
if (context === undefined) {
throw new Error('useProfileConfig must be used within a ProfileConfigProvider')
}
return context
} }

View File

@ -8,6 +8,10 @@ import '@renderer/assets/main.css'
import App from '@renderer/App' import App from '@renderer/App'
import BaseErrorBoundary from './components/base/base-error-boundary' import BaseErrorBoundary from './components/base/base-error-boundary'
import { quitApp } from './utils/ipc' import { quitApp } from './utils/ipc'
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'
init().then(() => { init().then(() => {
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', (e) => {
@ -45,7 +49,15 @@ init().then(() => {
> >
<BaseErrorBoundary> <BaseErrorBoundary>
<HashRouter> <HashRouter>
<App /> <AppConfigProvider>
<ControledMihomoConfigProvider>
<ProfileConfigProvider>
<OverrideConfigProvider>
<App />
</OverrideConfigProvider>
</ProfileConfigProvider>
</ControledMihomoConfigProvider>
</AppConfigProvider>
</HashRouter> </HashRouter>
</BaseErrorBoundary> </BaseErrorBoundary>
</NextThemesProvider> </NextThemesProvider>