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);
}
}