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