import type {ReactContext} from 'shared/ReactTypes';
import * as React from 'react';
import {
createContext,
useContext,
useCallback,
useState,
startTransition,
} from 'react';
import {BridgeContext, StoreContext} from '../context';
import type {FrontendBridge} from '../../../bridge';
import type {DevToolsHookSettings} from '../../../backend/types';
import type Store from '../../store';
export type Theme = 'auto' | 'light' | 'dark';
type Context = {
isModalShowing: boolean,
setIsModalShowing: (value: boolean) => void,
environmentNames: null | Promise<Array<string>>,
hookSettings: null | Promise<$ReadOnly<DevToolsHookSettings>>,
};
const SettingsModalContext: ReactContext<Context> = createContext<Context>(
((null: any): Context),
);
SettingsModalContext.displayName = 'SettingsModalContext';
function fetchEnvironmentNames(bridge: FrontendBridge): Promise<Array<string>> {
return new Promise(resolve => {
function onEnvironmentNames(names: Array<string>) {
bridge.removeListener('environmentNames', onEnvironmentNames);
resolve(names);
}
bridge.addListener('environmentNames', onEnvironmentNames);
bridge.send('getEnvironmentNames');
});
}
function fetchHookSettings(
store: Store,
): Promise<$ReadOnly<DevToolsHookSettings>> {
return new Promise(resolve => {
function onHookSettings(settings: $ReadOnly<DevToolsHookSettings>) {
store.removeListener('hookSettings', onHookSettings);
resolve(settings);
}
store.addListener('hookSettings', onHookSettings);
store.getHookSettings();
});
}
function SettingsModalContextController({
children,
}: {
children: React$Node,
}): React.Node {
const bridge = useContext(BridgeContext);
const store = useContext(StoreContext);
const setIsModalShowing: boolean => void = useCallback(
(value: boolean) => {
startTransition(() => {
setContext({
isModalShowing: value,
setIsModalShowing,
environmentNames: value ? fetchEnvironmentNames(bridge) : null,
hookSettings: value ? fetchHookSettings(store) : null,
});
});
},
[bridge, store],
);
const [currentContext, setContext] = useState<Context>({
isModalShowing: false,
setIsModalShowing,
environmentNames: null,
hookSettings: null,
});
return (
<SettingsModalContext.Provider value={currentContext}>
{children}
</SettingsModalContext.Provider>
);
}
export {SettingsModalContext, SettingsModalContextController};