``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
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<FeatureFlagContextType>(null!);
|
|
|
|
interface ProviderProps {
|
|
defaultOverrides?: Partial<FeatureFlags>;
|
|
}
|
|
|
|
export const FeatureFlagProvider: FC<ProviderProps> = ({
|
|
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 (
|
|
<FeatureFlagContext.Provider value={{ ...featureFlags, featureFlags }}>
|
|
{children}
|
|
</FeatureFlagContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useFeatureFlags = () => {
|
|
return useContext(FeatureFlagContext);
|
|
};
|