import { FC, createContext, useContext, useEffect, useState } from "react"; import { toCamelCase } from "~/helpers/casing"; import { getFeatureFlagsFromCharacterService } from "~/helpers/characterServiceApi"; const featureFlagsToGet = [ "release-gate-ims", "release-gate-gfs-blessings-ui", "release-gate-character-sheet-tour", "release-gate-premade-characters", ]; export const defaultFlags = { imsFlag: false, gfsBlessingsUiFlag: false, characterSheetTourFlag: false, premadeCharactersFlag: false, }; export type FeatureFlags = typeof defaultFlags; export interface FeatureFlagContextType extends FeatureFlags { featureFlags: FeatureFlags; } export const FeatureFlagContext = createContext(null!); interface ProviderProps { defaultOverrides?: Partial; } export const FeatureFlagProvider: FC = ({ children, defaultOverrides, }) => { const [featureFlags, setFeatureFlags] = useState({ ...defaultFlags, ...defaultOverrides, }); const convertFlagsToKeys = (flags: Object) => { return Object.keys(flags).reduce((acc, flag) => { // Perform any manipulations to remove unwanted characters const formattedFlag = flag // Remove `character-app` from the flag name .replace(/character-app\./i, "") // Remove `release-gate` from the flag name .replace(/release-gate\W/i, "") // Remove `character-sheet` from flag name if not the tour flag .replace(/character-sheet\W(?!tour)/i, "") // Change `2d` to `tactical` since var can't start with number .replace(/2d/i, "tactical"); const key = toCamelCase(`${formattedFlag}Flag`); return { ...acc, [key]: flags[flag] }; }, {}); }; const getFeatureFlags = async () => { try { const req = await getFeatureFlagsFromCharacterService(featureFlagsToGet); const res = await req.json(); const flags = convertFlagsToKeys(res.data) as FeatureFlags; setFeatureFlags(flags); } catch (err) { console.error(err); } }; useEffect(() => { if (!defaultOverrides) getFeatureFlags(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultOverrides]); return ( {children} ); }; export const useFeatureFlags = () => { return useContext(FeatureFlagContext); };