From b42ca9434ae187c2c162ea0a02789bc3ff46eea5 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 24 Feb 2026 20:56:17 -0600 Subject: [PATCH] Add 'system' theme option that follows OS prefers-color-scheme --- public/theme.js | 8 +++- src/components/AppProvider.tsx | 38 ++++++++++------ src/components/InitialSyncGate.tsx | 22 +++++++--- src/components/LeftSidebar.tsx | 3 +- src/components/MobileDrawer.tsx | 3 +- src/components/ThemeSelector.tsx | 69 ++++++++++++++++++++++++++++++ src/contexts/AppContext.ts | 6 ++- src/lib/schemas.ts | 2 +- src/themes.ts | 12 +++++- 9 files changed, 136 insertions(+), 27 deletions(-) diff --git a/public/theme.js b/public/theme.js index 67f76e9a..7eb9289c 100644 --- a/public/theme.js +++ b/public/theme.js @@ -11,9 +11,13 @@ var theme = 'dark'; try { var cfg = JSON.parse(localStorage.getItem('nostr:app-config') || '{}'); - if (cfg.theme && themes[cfg.theme]) theme = cfg.theme; + if (cfg.theme && (themes[cfg.theme] || cfg.theme === 'system')) theme = cfg.theme; } catch (e) {} - var t = themes[theme]; + // Resolve "system" to light or dark based on OS preference + if (theme === 'system') { + theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } + var t = themes[theme] || themes.dark; document.documentElement.className = theme; document.body.style.background = t.bg; var p = document.getElementById('preloader'); diff --git a/src/components/AppProvider.tsx b/src/components/AppProvider.tsx index 88f0b28f..69970f45 100644 --- a/src/components/AppProvider.tsx +++ b/src/components/AppProvider.tsx @@ -2,7 +2,7 @@ import { ReactNode, useEffect } from 'react'; import { z } from 'zod'; import { useLocalStorage } from '@/hooks/useLocalStorage'; import { AppContext, type AppConfig, type AppContextType, type Theme, type RelayMetadata } from '@/contexts/AppContext'; -import { themes, buildThemeCss } from '@/themes'; +import { themes, buildThemeCss, resolveTheme } from '@/themes'; import { ThemeSchema, FeedSettingsSchema, ContentWarningPolicySchema } from '@/lib/schemas'; interface AppProviderProps { @@ -101,21 +101,35 @@ export function AppProvider(props: AppProviderProps) { /** * Hook to apply theme changes to the document root via an injected