55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, PropsWithChildren, useCallback, useContext, useMemo, useState } from "react";
|
|
|
|
type DevFlags = {
|
|
opsPopup: boolean;
|
|
eventDebug: boolean;
|
|
abBanner: boolean;
|
|
};
|
|
|
|
type DevFlagsContextValue = {
|
|
flags: DevFlags;
|
|
setFlag: (key: keyof DevFlags, value: boolean) => void;
|
|
};
|
|
|
|
const STORAGE_KEY = "download_nova_dev_flags";
|
|
|
|
const defaultFlags: DevFlags = {
|
|
opsPopup: false,
|
|
eventDebug: false,
|
|
abBanner: false,
|
|
};
|
|
|
|
const DevFlagsContext = createContext<DevFlagsContextValue | null>(null);
|
|
|
|
function readFlags(): DevFlags {
|
|
if (typeof window === "undefined") return defaultFlags;
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) return defaultFlags;
|
|
try {
|
|
return { ...defaultFlags, ...(JSON.parse(raw) as Partial<DevFlags>) };
|
|
} catch {
|
|
return defaultFlags;
|
|
}
|
|
}
|
|
|
|
export function DeveloperFlagsProvider({ children }: PropsWithChildren) {
|
|
const [flags, setFlags] = useState<DevFlags>(() => readFlags());
|
|
|
|
const setFlag = useCallback((key: keyof DevFlags, value: boolean) => {
|
|
const next = { ...flags, [key]: value };
|
|
setFlags(next);
|
|
if (typeof window !== "undefined") localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
}, [flags]);
|
|
|
|
const value = useMemo(() => ({ flags, setFlag }), [flags, setFlag]);
|
|
return <DevFlagsContext.Provider value={value}>{children}</DevFlagsContext.Provider>;
|
|
}
|
|
|
|
export function useDeveloperFlags() {
|
|
const ctx = useContext(DevFlagsContext);
|
|
if (!ctx) throw new Error("useDeveloperFlags must be used within DeveloperFlagsProvider");
|
|
return ctx;
|
|
}
|