Ensure theme remains on load and syncs to account

This commit is contained in:
WardPearce
2026-04-09 00:46:45 +12:00
parent 2f0b106264
commit a0885cc09d
8 changed files with 81 additions and 59 deletions
@@ -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({});
}
</script>
@@ -126,7 +133,7 @@
bind:checked={$interfaceAmoledTheme}
onclick={async () => {
interfaceAmoledTheme.set(!$interfaceAmoledTheme);
currentThemeColors = await getDynamicTheme();
await setThemeColors();
}}
role="switch"
/>
+1 -1
View File
@@ -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%;
@@ -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<T> = {
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<any>[] = [
{
@@ -270,6 +278,12 @@ export const persistedStores: PersistedStore<any>[] = [
name: 'filterContentUrlAutoUpdate',
store: filterContentUrlAutoUpdateStore,
schema: zBoolean
},
{
name: 'advancedTheming',
store: interfaceAdvancedThemingStore,
schema: zThemeColors,
serialize: JSON.stringify
}
];
+38
View File
@@ -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;
-39
View File
@@ -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());
@@ -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;
+14 -6
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import {
darkModeStore,
interfaceAdvancedThemingStore,
interfaceAmoledTheme,
invidiousAuthStore,
isAndroidTvStore,
@@ -15,7 +16,7 @@
import 'beercss';
import 'material-dynamic-colors';
import { setAmoledTheme, setStatusBarColor, setTheme } from '$lib/theme';
import { setAmoledTheme, setStatusBarColor, setTheme, setThemeColors } from '$lib/theme';
import { pwaInfo } from 'virtual:pwa-info';
import { onMount } from 'svelte';
@@ -30,8 +31,18 @@
let { children } = $props();
themeColorStore.subscribe(async (hex) => {
if (!hex || Object.keys($interfaceAdvancedThemingStore).length > 0) return;
await ui('theme', hex);
});
interfaceAdvancedThemingStore.subscribe((colors) => {
setThemeColors(colors);
});
interfaceAmoledTheme.subscribe(async () => {
setAmoledTheme();
setThemeColors($interfaceAdvancedThemingStore);
await setStatusBarColor();
});
@@ -40,6 +51,8 @@
setTheme();
setAmoledTheme();
setThemeColors($interfaceAdvancedThemingStore);
await setStatusBarColor();
});
@@ -114,11 +127,6 @@
// Should always be loaded after env settings
// So user preferences overwrite instance preferences.
bookmarkletLoadFromUrl();
await setStatusBarColor();
setTheme();
setAmoledTheme();
});
let syncToSettingsInitialized = false;
@@ -25,7 +25,7 @@ export async function DELETE({ locals, params }) {
}
const zUpdateKeyStore = z.object({
valueCipher: z.string().max(1000),
valueCipher: z.string().max(3000),
valueNonce: z.string().max(255)
});