diff --git a/materialious/src/lib/components/settings/Theme.svelte b/materialious/src/lib/components/settings/Theme.svelte index b2dd2c10..0575255c 100644 --- a/materialious/src/lib/components/settings/Theme.svelte +++ b/materialious/src/lib/components/settings/Theme.svelte @@ -29,6 +29,13 @@ currentThemeColors = await getDynamicTheme(); }); + async function setThemeColors() { + await tick(); + + currentThemeColors = await getDynamicTheme(); + interfaceAdvancedThemingStore.set(currentThemeColors); + } + async function colorOnInput( color: { hsv: HsvaColor | null; @@ -43,10 +50,7 @@ colorPickerDebounce = setTimeout(async () => { if (!color.hex) return; setThemeColor(propetyKey, color.hex); - await tick(); - currentThemeColors = await getDynamicTheme(); - - interfaceAdvancedThemingStore.set(currentThemeColors); + await setThemeColors(); }, 100); } @@ -62,8 +66,10 @@ colorPickerDebounce = setTimeout(async () => { themeColorStore.set(color.hex); await tick(); + setAmoledTheme(); currentThemeColors = await getDynamicTheme(); + interfaceAdvancedThemingStore.set({}); }, 100); } @@ -79,6 +85,7 @@ } currentThemeColors = await getDynamicTheme(); + interfaceAdvancedThemingStore.set({}); } @@ -126,7 +133,7 @@ bind:checked={$interfaceAmoledTheme} onclick={async () => { interfaceAmoledTheme.set(!$interfaceAmoledTheme); - currentThemeColors = await getDynamicTheme(); + await setThemeColors(); }} role="switch" /> diff --git a/materialious/src/lib/css/global.css b/materialious/src/lib/css/global.css index aa68c71a..10757630 100644 --- a/materialious/src/lib/css/global.css +++ b/materialious/src/lib/css/global.css @@ -183,7 +183,7 @@ menu.player-settings { .player-slider [data-melt-slider-thumb] { position: absolute; - border-radius: 1rem; + border-radius: var(--player-border-radius); background: var(--primary); left: var(--percentage); top: 50%; diff --git a/materialious/src/lib/externalSettings/settings.ts b/materialious/src/lib/externalSettings/settings.ts index 61c7fd6f..6014e74d 100644 --- a/materialious/src/lib/externalSettings/settings.ts +++ b/materialious/src/lib/externalSettings/settings.ts @@ -53,9 +53,11 @@ import { playerPreferredVolumeStore, watchHistoryEnabledStore, filterContentUrlStore, - filterContentUrlAutoUpdateStore + filterContentUrlAutoUpdateStore, + interfaceAdvancedThemingStore } from '$lib/store'; import { isOwnBackend } from '$lib/shared'; +import { SUPPORTED_THEME_KEYS } from '$lib/shared/theme'; type PersistedStore = { name: string; @@ -77,6 +79,12 @@ const zAuth = z.object({ username: z.string(), token: z.string() }); +const zThemeColors = z.record( + z.string().refine((val) => SUPPORTED_THEME_KEYS.includes(val), { + message: 'CSS property not allowed' + }), + z.string().regex(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) +); export const persistedStores: PersistedStore[] = [ { @@ -270,6 +278,12 @@ export const persistedStores: PersistedStore[] = [ name: 'filterContentUrlAutoUpdate', store: filterContentUrlAutoUpdateStore, schema: zBoolean + }, + { + name: 'advancedTheming', + store: interfaceAdvancedThemingStore, + schema: zThemeColors, + serialize: JSON.stringify } ]; diff --git a/materialious/src/lib/shared/theme.ts b/materialious/src/lib/shared/theme.ts new file mode 100644 index 00000000..48204be0 --- /dev/null +++ b/materialious/src/lib/shared/theme.ts @@ -0,0 +1,38 @@ +export const SUPPORTED_THEME_KEYS: string[] = [ + '--primary', + '--on-primary', + '--primary-container', + '--on-primary-container', + '--secondary', + '--on-secondary', + '--secondary-container', + '--on-secondary-container', + '--tertiary', + '--on-tertiary', + '--tertiary-container', + '--on-tertiary-container', + '--error', + '--on-error', + '--error-container', + '--on-error-container', + '--background', + '--on-background', + '--surface', + '--on-surface', + '--surface-variant', + '--on-surface-variant', + '--outline', + '--outline-variant', + '--shadow', + '--scrim', + '--inverse-surface', + '--inverse-on-surface', + '--inverse-primary', + '--surface-dim', + '--surface-bright', + '--surface-container-lowest', + '--surface-container-low', + '--surface-container', + '--surface-container-high', + '--surface-container-highest' +] as const; diff --git a/materialious/src/lib/theme.ts b/materialious/src/lib/theme.ts index 4ac0f303..fb7cf1f4 100644 --- a/materialious/src/lib/theme.ts +++ b/materialious/src/lib/theme.ts @@ -116,45 +116,6 @@ export function setTheme() { } } -export const SUPPORTED_THEME_KEYS: ThemeKey[] = [ - '--primary', - '--on-primary', - '--primary-container', - '--on-primary-container', - '--secondary', - '--on-secondary', - '--secondary-container', - '--on-secondary-container', - '--tertiary', - '--on-tertiary', - '--tertiary-container', - '--on-tertiary-container', - '--error', - '--on-error', - '--error-container', - '--on-error-container', - '--background', - '--on-background', - '--surface', - '--on-surface', - '--surface-variant', - '--on-surface-variant', - '--outline', - '--outline-variant', - '--shadow', - '--scrim', - '--inverse-surface', - '--inverse-on-surface', - '--inverse-primary', - '--surface-dim', - '--surface-bright', - '--surface-container-lowest', - '--surface-container-low', - '--surface-container', - '--surface-container-high', - '--surface-container-highest' -] as const; - export function setThemeColors(theme: ThemeColors) { for (const [themeKey, themeValue] of Object.entries(theme)) { setThemeColor(themeKey as ThemeKey, themeValue.trim()); diff --git a/materialious/src/routes/(app)/+layout.svelte b/materialious/src/routes/(app)/+layout.svelte index 9be4c6c6..b00e8408 100644 --- a/materialious/src/routes/(app)/+layout.svelte +++ b/materialious/src/routes/(app)/+layout.svelte @@ -20,7 +20,6 @@ playerState, playerTheatreModeIsActive, rawMasterKeyStore, - themeColorStore, backendInUseStore, hideSearchStore } from '$lib/store'; @@ -126,11 +125,6 @@ notifications = feed.notifications; } - themeColorStore.subscribe(async (hex) => { - if (!hex) return; - await ui('theme', hex); - }); - function resetScroll() { const main = document.querySelector('main.root'); if (main) main.scrollTop = 0; diff --git a/materialious/src/routes/+layout.svelte b/materialious/src/routes/+layout.svelte index fa41b4f6..a30bd759 100644 --- a/materialious/src/routes/+layout.svelte +++ b/materialious/src/routes/+layout.svelte @@ -1,6 +1,7 @@