From 247362a4a9fced65667728b9a37a860721419f5d Mon Sep 17 00:00:00 2001 From: Marcos Rios Date: Sun, 18 Feb 2024 01:23:53 -0300 Subject: [PATCH 1/3] Add preview theme functionality to SettingsPage --- src/pages/Settings.tsx | 20 +++++++++++++++++--- src/pages/layouts/SubPageLayout.tsx | 4 ++-- src/pages/parts/settings/ThemePart.tsx | 15 ++++++++------- src/stores/theme/index.tsx | 21 ++++++++++++++++++++- 4 files changed, 47 insertions(+), 13 deletions(-) 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 (
From 3522f6c038fda8d31e6d74f22e6666b3474f7338 Mon Sep 17 00:00:00 2001 From: Marcos Rios Date: Sun, 18 Feb 2024 02:54:53 -0300 Subject: [PATCH 2/3] Fix theme preview not being reset after leaving settings --- src/hooks/useSettingsState.ts | 7 +++++++ src/pages/Settings.tsx | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/hooks/useSettingsState.ts b/src/hooks/useSettingsState.ts index d0946deb..8e540a19 100644 --- a/src/hooks/useSettingsState.ts +++ b/src/hooks/useSettingsState.ts @@ -9,6 +9,7 @@ import { } from "react"; import { SubtitleStyling } from "@/stores/subtitles"; +import { usePreviewThemeStore } from "@/stores/theme"; export function useDerived( initial: T, @@ -56,6 +57,11 @@ export function useSettingsState( const [backendUrlState, setBackendUrl, resetBackendUrl, backendUrlChanged] = useDerived(backendUrl); const [themeState, setTheme, resetTheme, themeChanged] = useDerived(theme); + const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); + const resetPreviewTheme = useCallback( + () => setPreviewTheme(theme), + [setPreviewTheme, theme], + ); const [ appLanguageState, setAppLanguage, @@ -81,6 +87,7 @@ export function useSettingsState( function reset() { resetTheme(); + resetPreviewTheme(); resetAppLanguage(); resetSubStyling(); resetProxyUrls(); diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 5744e90f..d4ee5292 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -1,5 +1,5 @@ import classNames from "classnames"; -import { useCallback, useEffect, useMemo } from "react"; +import { useCallback, useEffect, useMemo, useRef } from "react"; import { useTranslation } from "react-i18next"; import { useAsyncFn } from "react-use"; @@ -105,6 +105,8 @@ export function SettingsPage() { const setTheme = useThemeStore((s) => s.setTheme); const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); + const activeThemeRef = useRef(activeTheme); + activeThemeRef.current = activeTheme; const appLanguage = useLanguageStore((s) => s.language); const setAppLanguage = useLanguageStore((s) => s.setLanguage); @@ -145,6 +147,15 @@ export function SettingsPage() { enableThumbnails, ); + useEffect( + () => () => { + setPreviewTheme( + activeThemeRef.current === "default" ? null : activeThemeRef.current, + ); + }, + [setPreviewTheme], + ); + const setThemeWithPreview = useCallback( (v: string | null) => { state.theme.set(v === "default" ? null : v); From ac9d347a26fc4df55dbb04ddf6d6d5ec89889543 Mon Sep 17 00:00:00 2001 From: Marcos Rios Date: Thu, 22 Feb 2024 23:55:07 -0300 Subject: [PATCH 3/3] Remove nonsense ref --- src/pages/Settings.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index d4ee5292..d56e4815 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -105,8 +105,6 @@ export function SettingsPage() { const setTheme = useThemeStore((s) => s.setTheme); const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); - const activeThemeRef = useRef(activeTheme); - activeThemeRef.current = activeTheme; const appLanguage = useLanguageStore((s) => s.language); const setAppLanguage = useLanguageStore((s) => s.setLanguage); @@ -147,11 +145,10 @@ export function SettingsPage() { enableThumbnails, ); + // Reset the preview theme when the settings page is unmounted useEffect( () => () => { - setPreviewTheme( - activeThemeRef.current === "default" ? null : activeThemeRef.current, - ); + setPreviewTheme(null); }, [setPreviewTheme], );