From f2f6edcd63accb0da67e6e75052da3605e4a6a5f Mon Sep 17 00:00:00 2001 From: William Martin Date: Fri, 19 Dec 2025 11:18:22 -0500 Subject: [PATCH] wip --- apps/browser/src/popup/app.component.html | 2 +- apps/browser/src/popup/app.component.ts | 13 +++++-- apps/browser/src/popup/main.ts | 38 +++++++++++++++++++ .../platform/theming/theme-state.service.ts | 1 + 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/apps/browser/src/popup/app.component.html b/apps/browser/src/popup/app.component.html index 3a5c8021e17..05c4f8829f8 100644 --- a/apps/browser/src/popup/app.component.html +++ b/apps/browser/src/popup/app.component.html @@ -1,4 +1,4 @@ -@if (showSdkWarning | async) { +@if (showSdkWarning()) {
{{ "wasmNotSupported" | i18n }} diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index 8f00569b720..1e5ed6d01d9 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -9,7 +9,7 @@ import { OnDestroy, OnInit, } from "@angular/core"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { takeUntilDestroyed, toSignal } from "@angular/core/rxjs-interop"; import { NavigationEnd, Router, RouterOutlet } from "@angular/router"; import { catchError, @@ -88,9 +88,14 @@ export class AppComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); // Show a warning if the SDK is not available. - protected showSdkWarning = this.sdkService.client$.pipe( - map(() => false), - catchError(() => of(true)), + protected readonly showSdkWarning = toSignal( + this.sdkService.client$.pipe( + map(() => false), + catchError(() => of(true)), + ), + { + initialValue: false, + }, ); constructor( diff --git a/apps/browser/src/popup/main.ts b/apps/browser/src/popup/main.ts index fa6a07d031a..46d33c71a10 100644 --- a/apps/browser/src/popup/main.ts +++ b/apps/browser/src/popup/main.ts @@ -15,6 +15,44 @@ if (BrowserPlatformUtilsService.shouldApplySafariHeightFix(window)) { document.documentElement.classList.add("safari_height_fix"); } +/** + * Set theme on page load based on (in order of priority): + * 1. the user's preferred theme from the theme state provider + * 2. the user's system theme + * 3. default to light theme (theoretically should never happen, but we need some kind of default) + * + * This is done outside the Angular app to avoid a flash of unthemed content before it loads. + */ +const setTheme = () => { + /** + * If we cannot find a system preference or any other indication of what theme to apply, + * then we will default to light. `theme_light` is hardcoded as the default in the web app's + * index.html file. + */ + const defaultTheme = "light"; + const htmlEl = document.documentElement; + let theme = defaultTheme; + + const themeFromState = window.localStorage.getItem("global_theming_selection"); + + if (themeFromState) { + if (themeFromState.indexOf("system") > -1) { + theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + } else if (themeFromState.indexOf("dark") > -1) { + theme = "dark"; + } + } else { + theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + } + + if (!htmlEl.classList.contains("theme_" + theme)) { + htmlEl.classList.remove("theme_" + defaultTheme); + htmlEl.classList.add("theme_" + theme); + } +}; + +setTheme(); + if (process.env.ENV === "production") { enableProdMode(); } diff --git a/libs/common/src/platform/theming/theme-state.service.ts b/libs/common/src/platform/theming/theme-state.service.ts index a02400b5b3a..36e2129bf13 100644 --- a/libs/common/src/platform/theming/theme-state.service.ts +++ b/libs/common/src/platform/theming/theme-state.service.ts @@ -44,5 +44,6 @@ export class DefaultThemeStateService implements ThemeStateService { await this.selectedThemeState.update(() => theme, { shouldUpdate: (currentTheme) => currentTheme !== theme, }); + // globalThis?.localStorage?.setItem("theme", theme); } }