11import { clsx } from 'clsx'
22import { useCallback , useEffect , useState } from 'react'
3- import { BsFillBookmarksFill , BsFillGearFill , BsMoonFill } from 'react-icons/bs'
3+ import { BsFillBookmarksFill , BsFillGearFill } from 'react-icons/bs'
44import { CgTab } from 'react-icons/cg'
55import { FaCrown } from 'react-icons/fa'
6- import { IoMdSunny } from 'react-icons/io'
76import { MdDoDisturbOff } from 'react-icons/md'
87import { RiDashboardHorizontalFill } from 'react-icons/ri'
98import { TfiLayoutColumn4Alt } from 'react-icons/tfi'
@@ -15,12 +14,7 @@ import { UserTags } from 'src/components/Elements/UserTags'
1514import { useAuth } from 'src/features/auth'
1615import { Changelog } from 'src/features/changelog'
1716import { useRemoteConfigStore } from 'src/features/remoteConfig'
18- import {
19- identifyUserTheme ,
20- trackDNDDisable ,
21- trackDisplayTypeChange ,
22- trackThemeSelect ,
23- } from 'src/lib/analytics'
17+ import { trackDNDDisable , trackDisplayTypeChange } from 'src/lib/analytics'
2418import { useUserPreferences } from 'src/stores/preferences'
2519import { lazyImport } from 'src/utils/lazyImport'
2620import { Button , CircleButton } from '../Elements'
@@ -30,36 +24,32 @@ const { DonateModal } = lazyImport(() => import('src/features/donate'), 'DonateM
3024export const Header = ( ) => {
3125 const { openAuthModal, user, isConnected, isConnecting } = useAuth ( )
3226
33- const [ themeIcon , setThemeIcon ] = useState ( < BsMoonFill /> )
3427 const [ openDonateModal , setOpenDonateModal ] = useState ( false )
3528 const { paywall } = useRemoteConfigStore ( )
36- const { theme, setTheme, setDNDDuration, isDNDModeActive, layout, setLayout } =
37- useUserPreferences ( )
29+ const { theme, setDNDDuration, isDNDModeActive, layout, setLayout } = useUserPreferences ( )
3830 const navigate = useNavigate ( )
3931 const location = useLocation ( )
4032
4133 useEffect ( ( ) => {
42- document . documentElement . classList . add ( theme )
43- // eslint-disable-next-line react-hooks/exhaustive-deps
44- } , [ ] )
34+ const applyResolvedTheme = ( resolved : 'dark' | 'light' ) => {
35+ document . documentElement . classList . remove ( 'dark' , 'light' )
36+ document . documentElement . classList . add ( resolved )
37+ }
4538
46- useEffect ( ( ) => {
47- if ( theme === 'light' ) {
48- document . documentElement . classList . replace ( 'dark' , theme )
49- setThemeIcon ( < BsMoonFill /> )
50- } else if ( theme === 'dark' ) {
51- document . documentElement . classList . replace ( 'light' , theme )
52- setThemeIcon ( < IoMdSunny /> )
39+ if ( theme === 'system' ) {
40+ const mq = window . matchMedia ( '(prefers-color-scheme: dark)' )
41+ const updateSystemTheme = ( matches : boolean ) => {
42+ applyResolvedTheme ( matches ? 'dark' : 'light' )
43+ }
44+ updateSystemTheme ( mq . matches )
45+ const handler = ( e : MediaQueryListEvent ) => updateSystemTheme ( e . matches )
46+ mq . addEventListener ( 'change' , handler )
47+ return ( ) => mq . removeEventListener ( 'change' , handler )
48+ } else {
49+ applyResolvedTheme ( theme )
5350 }
5451 } , [ theme ] )
5552
56- const onThemeChange = useCallback ( ( ) => {
57- const newTheme = theme === 'dark' ? 'light' : 'dark'
58- setTheme ( newTheme )
59- trackThemeSelect ( newTheme )
60- identifyUserTheme ( newTheme )
61- } , [ theme , setTheme ] )
62-
6353 const onLayoutChange = useCallback ( ( ) => {
6454 const newLayout = layout === 'cards' ? 'grid' : 'cards'
6555 trackDisplayTypeChange ( newLayout )
@@ -111,9 +101,6 @@ export const Header = () => {
111101 < CircleButton onClick = { onLayoutChange } >
112102 { layout === 'cards' ? < RiDashboardHorizontalFill /> : < TfiLayoutColumn4Alt /> }
113103 </ CircleButton >
114- < CircleButton onClick = { onThemeChange } variant = "darkfocus" >
115- { themeIcon }
116- </ CircleButton >
117104 < CircleButton onClick = { ( ) => navigate ( '/settings/bookmarks' ) } >
118105 < BsFillBookmarksFill />
119106 </ CircleButton >
0 commit comments