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 (