Files
AstralRinth/apps/frontend/src/composables/featureFlags.ts
Prospector c39bb78e38 App redesign (#2946)
* Start of app redesign

* format

* continue progress

* Content page nearly done

* Fix recursion issues with content page

* Fix update all alignment

* Discover page progress

* Settings progress

* Removed unlocked-size hack that breaks web

* Revamp project page, refactor web project page to share code with app, fixed loading bar, misc UI/UX enhancements, update ko-fi logo, update arrow icons, fix web issues caused by floating-vue migration, fix tooltip issues, update web tooltips, clean up web hydration issues

* Ads + run prettier

* Begin auth refactor, move common messages to ui lib, add i18n extraction to all apps, begin Library refactor

* fix ads not hiding when plus log in

* rev lockfile changes/conflicts

* Fix sign in page

* Add generated

* (mostly) Data driven search

* Fix search mobile issue

* profile fixes

* Project versions page, fix typescript on UI lib and misc fixes

* Remove unused gallery component

* Fix linkfunction err

* Search filter controls at top, localization for locked filters

* Fix provided filter names

* Fix navigating from instance browse to main browse

* Friends frontend (#2995)

* Friends system frontend

* (almost) finish frontend

* finish friends, fix lint

* Fix lint

---------

Signed-off-by: Geometrically <18202329+Geometrically@users.noreply.github.com>

* Refresh macOS app icon

* Update web search UI more

* Fix link opens

* Fix frontend build

---------

Signed-off-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
Co-authored-by: Jai A <jaiagr+gpg@pm.me>
Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
2024-12-11 19:54:18 -08:00

103 lines
2.8 KiB
TypeScript

import type { CookieOptions } from "#app";
export type ProjectDisplayMode = "list" | "grid" | "gallery";
export type DarkColorTheme = "dark" | "oled" | "retro";
export interface NumberFlag {
min: number;
max: number;
}
export type BooleanFlag = boolean;
export type RadioFlag = ProjectDisplayMode | DarkColorTheme;
export type FlagValue = BooleanFlag; /* | NumberFlag | RadioFlag */
const validateValues = <K extends PropertyKey>(flags: Record<K, FlagValue>) => flags;
export const DEFAULT_FEATURE_FLAGS = validateValues({
// Developer flags
developerMode: false,
showVersionFilesInTable: false,
showAdsWithPlus: false,
// Feature toggles
projectTypesPrimaryNav: false,
hidePlusPromoInUserMenu: false,
oldProjectCards: true,
newProjectCards: false,
projectBackground: false,
searchBackground: false,
// advancedRendering: true,
// externalLinksNewTab: true,
// notUsingBlockers: false,
// hideModrinthAppPromos: false,
// preferredDarkTheme: 'dark',
// hideStagingBanner: false,
// Project display modes
// modSearchDisplayMode: 'list',
// pluginSearchDisplayMode: 'list',
// resourcePackSearchDisplayMode: 'gallery',
// modpackSearchDisplayMode: 'list',
// shaderSearchDisplayMode: 'gallery',
// dataPackSearchDisplayMode: 'list',
// userProjectDisplayMode: 'list',
// collectionProjectDisplayMode: 'list',
} as const);
export type FeatureFlag = keyof typeof DEFAULT_FEATURE_FLAGS;
export type AllFeatureFlags = {
[key in FeatureFlag]: (typeof DEFAULT_FEATURE_FLAGS)[key];
};
export type PartialFeatureFlags = Partial<AllFeatureFlags>;
const COOKIE_OPTIONS = {
maxAge: 60 * 60 * 24 * 365 * 10,
sameSite: "lax",
secure: true,
httpOnly: false,
path: "/",
} satisfies CookieOptions<PartialFeatureFlags>;
export const useFeatureFlags = () =>
useState<AllFeatureFlags>("featureFlags", () => {
const config = useRuntimeConfig();
const savedFlags = useCookie<PartialFeatureFlags>("featureFlags", COOKIE_OPTIONS);
if (!savedFlags.value) {
savedFlags.value = {};
}
const flags: AllFeatureFlags = JSON.parse(JSON.stringify(DEFAULT_FEATURE_FLAGS));
const overrides = config.public.featureFlagOverrides as PartialFeatureFlags;
for (const key in overrides) {
if (key in flags) {
const flag = key as FeatureFlag;
const value = overrides[flag] as (typeof flags)[FeatureFlag];
flags[flag] = value;
}
}
for (const key in savedFlags.value) {
if (key in flags) {
const flag = key as FeatureFlag;
const value = savedFlags.value[flag] as (typeof flags)[FeatureFlag];
flags[flag] = value;
}
}
return flags;
});
export const saveFeatureFlags = () => {
const flags = useFeatureFlags();
const cookie = useCookie<PartialFeatureFlags>("featureFlags", COOKIE_OPTIONS);
cookie.value = flags.value;
};