diff --git a/src/RootApp.tsx b/src/RootApp.tsx index 0159b155ab..a44e25d565 100644 --- a/src/RootApp.tsx +++ b/src/RootApp.tsx @@ -5,6 +5,7 @@ import React from 'react'; import StableApp from './apps/stable/App'; import { HistoryRouter } from './components/router/HistoryRouter'; import { ApiProvider } from './hooks/useApi'; +import { WebConfigProvider } from './hooks/useWebConfig'; const ExperimentalApp = loadable(() => import('./apps/experimental/App')); @@ -13,13 +14,15 @@ const RootApp = ({ history }: { history: History }) => { return ( - - { - layoutMode === 'experimental' ? - : - - } - + + + { + layoutMode === 'experimental' ? + : + + } + + ); }; diff --git a/src/hooks/useWebConfig.tsx b/src/hooks/useWebConfig.tsx new file mode 100644 index 0000000000..528afcee0f --- /dev/null +++ b/src/hooks/useWebConfig.tsx @@ -0,0 +1,40 @@ +import React, { createContext, FC, useContext, useEffect, useState } from 'react'; + +import type { WebConfig } from '../types/webConfig'; +import defaultConfig from '../config.json'; +import fetchLocal from '../utils/fetchLocal'; + +export const WebConfigContext = createContext(defaultConfig); +export const useWebConfig = () => useContext(WebConfigContext); + +export const WebConfigProvider: FC = ({ children }) => { + const [ config, setConfig ] = useState(defaultConfig); + + useEffect(() => { + const fetchConfig = async () => { + try { + const response = await fetchLocal('config.json', { cache: 'no-cache' }); + + if (!response.ok) { + throw new Error('network response was not ok'); + } + + const configData = await response.json(); + setConfig(configData); + } catch (err) { + console.warn('[WebConfigProvider] failed to fetch config file', err); + } + }; + + fetchConfig() + .catch(() => { + // This should never happen since fetchConfig catches errors internally + }); + }, [ setConfig ]); + + return ( + + {children} + + ); +}; diff --git a/src/types/webConfig.ts b/src/types/webConfig.ts new file mode 100644 index 0000000000..5ef164c247 --- /dev/null +++ b/src/types/webConfig.ts @@ -0,0 +1,20 @@ +interface Theme { + name: string + id: string + color: string +} + +interface MenuLink { + name: string + icon?: string + url: string +} + +export interface WebConfig { + includeCorsCredentials?: boolean + multiserver?: boolean + themes?: Theme[] + menuLinks?: MenuLink[] + servers?: string[] + plugins?: string[] +}