import { defineStore } from 'pinia' let systemThemeMq: MediaQueryList | null = null export const DEFAULT_FEATURE_FLAGS = { project_background: false, page_path: false, worlds_tab: false, worlds_in_home: true, server_project_qa: false, server_ram_as_bytes_always_on: false, always_show_app_controls: false, skip_non_essential_warnings: false, skip_unknown_pack_warning: false, pride_fundraiser: true, i18n_debug: false, show_instance_play_time: true, } export const THEME_OPTIONS = ['dark', 'light', 'oled', 'system'] as const export type FeatureFlag = keyof typeof DEFAULT_FEATURE_FLAGS export type FeatureFlags = Record export type ColorTheme = (typeof THEME_OPTIONS)[number] export type ThemeStore = { selectedTheme: ColorTheme advancedRendering: boolean hideNametagSkinsPage: boolean toggleSidebar: boolean devMode: boolean featureFlags: FeatureFlags } export const DEFAULT_THEME_STORE: ThemeStore = { selectedTheme: 'dark', advancedRendering: true, hideNametagSkinsPage: false, toggleSidebar: false, devMode: false, featureFlags: DEFAULT_FEATURE_FLAGS, } export const useTheming = defineStore('themeStore', { state: () => DEFAULT_THEME_STORE, actions: { setThemeState(newTheme: ColorTheme) { if (THEME_OPTIONS.includes(newTheme)) { this.selectedTheme = newTheme } else { console.warn('Selected theme is not present. Check themeOptions.') } this.setThemeClass() }, setThemeClass() { const html = document.getElementsByTagName('html')[0] for (const theme of THEME_OPTIONS) { html.classList.remove(`${theme}-mode`) } systemThemeMq?.removeEventListener('change', this.setThemeClass) systemThemeMq = null let theme = this.selectedTheme if (this.selectedTheme === 'system') { systemThemeMq = window.matchMedia('(prefers-color-scheme: dark)') systemThemeMq.addEventListener('change', this.setThemeClass) theme = systemThemeMq.matches ? 'dark' : 'light' } html.classList.add(`${theme}-mode`) }, getFeatureFlag(key: FeatureFlag) { return this.featureFlags[key] ?? DEFAULT_FEATURE_FLAGS[key] }, getThemeOptions() { return THEME_OPTIONS }, }, })