diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 18b755ca..5744e90f 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -33,7 +33,7 @@ import { AccountWithToken, useAuthStore } from "@/stores/auth"; import { useLanguageStore } from "@/stores/language"; import { usePreferencesStore } from "@/stores/preferences"; import { useSubtitleStore } from "@/stores/subtitles"; -import { useThemeStore } from "@/stores/theme"; +import { usePreviewThemeStore, useThemeStore } from "@/stores/theme"; import { SubPageLayout } from "./layouts/SubPageLayout"; import { PreferencesPart } from "./parts/settings/PreferencesPart"; @@ -101,8 +101,10 @@ export function AccountSettings(props: { export function SettingsPage() { const { t } = useTranslation(); - const activeTheme = useThemeStore((s) => s.theme); + const activeTheme = useThemeStore((s) => s.theme) ?? "default"; const setTheme = useThemeStore((s) => s.setTheme); + const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; + const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); const appLanguage = useLanguageStore((s) => s.language); const setAppLanguage = useLanguageStore((s) => s.setLanguage); @@ -143,6 +145,14 @@ export function SettingsPage() { enableThumbnails, ); + const setThemeWithPreview = useCallback( + (v: string | null) => { + state.theme.set(v === "default" ? null : v); + setPreviewTheme(v); + }, + [state.theme, setPreviewTheme], + ); + const saveChanges = useCallback(async () => { if (account) { if ( @@ -241,7 +251,11 @@ export function SettingsPage() { />
- +
diff --git a/src/pages/parts/settings/ThemePart.tsx b/src/pages/parts/settings/ThemePart.tsx index 264c5b40..f4972eaf 100644 --- a/src/pages/parts/settings/ThemePart.tsx +++ b/src/pages/parts/settings/ThemePart.tsx @@ -5,6 +5,10 @@ import { Icon, Icons } from "@/components/Icon"; import { Heading1 } from "@/components/utils/Text"; const availableThemes = [ + { + id: "default", + key: "settings.appearance.themes.default", + }, { id: "blue", key: "settings.appearance.themes.blue", @@ -26,6 +30,7 @@ const availableThemes = [ function ThemePreview(props: { selector?: string; active?: boolean; + inUse?: boolean; name: string; onClick?: () => void; }) { @@ -105,7 +110,7 @@ function ThemePreview(props: { {t("settings.appearance.activeTheme")} @@ -117,6 +122,7 @@ function ThemePreview(props: { export function ThemePart(props: { active: string | null; + inUse: string | null; setTheme: (theme: string | null) => void; }) { const { t } = useTranslation(); @@ -126,16 +132,11 @@ export function ThemePart(props: { {t("settings.appearance.title")}
{/* default theme */} - props.setTheme(null)} - /> {availableThemes.map((v) => ( props.setTheme(v.id)} diff --git a/src/stores/theme/index.tsx b/src/stores/theme/index.tsx index c43ec414..a644c626 100644 --- a/src/stores/theme/index.tsx +++ b/src/stores/theme/index.tsx @@ -25,12 +25,31 @@ export const useThemeStore = create( ), ); +export interface PreviewThemeStore { + previewTheme: string | null; + setPreviewTheme(v: string | null): void; +} + +export const usePreviewThemeStore = create( + immer((set) => ({ + previewTheme: null, + setPreviewTheme(v) { + set((s) => { + s.previewTheme = v; + }); + }, + })), +); + export function ThemeProvider(props: { children?: ReactNode; applyGlobal?: boolean; }) { + const previewTheme = usePreviewThemeStore((s) => s.previewTheme); const theme = useThemeStore((s) => s.theme); - const themeSelector = theme ? `theme-${theme}` : undefined; + + const themeToDisplay = previewTheme ?? theme; + const themeSelector = themeToDisplay ? `theme-${themeToDisplay}` : undefined; return (