Added system theming and fixed particles background to match theme.
This commit is contained in:
parent
60f62df55a
commit
da07c882a5
@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React, { useState, useEffect, useMemo, useCallback } from 'react'
|
import React, { useState, useEffect, useMemo, useCallback } from 'react'
|
||||||
import Particles, { initParticlesEngine } from '@tsparticles/react'
|
import Particles, { initParticlesEngine } from '@tsparticles/react'
|
||||||
import { loadSlim } from '@tsparticles/slim'
|
import { loadSlim } from '@tsparticles/slim'
|
||||||
|
import { useThemeContext } from '../Dashboard/context/ThemeContext'
|
||||||
|
|
||||||
const ParticlesComponent = React.memo(({ options, particlesLoaded }) => {
|
const ParticlesComponent = React.memo(({ options, particlesLoaded }) => {
|
||||||
return (
|
return (
|
||||||
@ -17,6 +18,7 @@ ParticlesComponent.displayName = 'ParticlesComponent'
|
|||||||
|
|
||||||
const AppParticles = () => {
|
const AppParticles = () => {
|
||||||
const [init, setInit] = useState(false)
|
const [init, setInit] = useState(false)
|
||||||
|
const { isDarkMode } = useThemeContext()
|
||||||
|
|
||||||
// this should be run only once per application lifetime
|
// this should be run only once per application lifetime
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -35,7 +37,7 @@ const AppParticles = () => {
|
|||||||
() => ({
|
() => ({
|
||||||
background: {
|
background: {
|
||||||
color: {
|
color: {
|
||||||
value: '#141414'
|
value: isDarkMode ? '#000000' : '#ffffff'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fpsLimit: 120,
|
fpsLimit: 120,
|
||||||
@ -62,10 +64,10 @@ const AppParticles = () => {
|
|||||||
},
|
},
|
||||||
particles: {
|
particles: {
|
||||||
color: {
|
color: {
|
||||||
value: '#ffffff'
|
value: isDarkMode ? 'rgb(66, 66, 66)' : 'rgb(217, 217, 217)'
|
||||||
},
|
},
|
||||||
links: {
|
links: {
|
||||||
color: '#ffffff',
|
color: isDarkMode ? 'rgb(66, 66, 66)' : 'rgb(217, 217, 217)',
|
||||||
distance: 150,
|
distance: 150,
|
||||||
enable: true,
|
enable: true,
|
||||||
opacity: 0.5,
|
opacity: 0.5,
|
||||||
@ -99,7 +101,7 @@ const AppParticles = () => {
|
|||||||
},
|
},
|
||||||
detectRetina: true
|
detectRetina: true
|
||||||
}),
|
}),
|
||||||
[]
|
[isDarkMode]
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -8,17 +8,30 @@ const { Title } = Typography
|
|||||||
const { Option } = Select
|
const { Option } = Select
|
||||||
|
|
||||||
const Settings = () => {
|
const Settings = () => {
|
||||||
const { isDarkMode, toggleTheme, isCompact, toggleCompact } =
|
const {
|
||||||
useThemeContext()
|
isDarkMode,
|
||||||
|
toggleTheme,
|
||||||
|
isCompact,
|
||||||
|
toggleCompact,
|
||||||
|
isSystem,
|
||||||
|
toggleSystem
|
||||||
|
} = useThemeContext()
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('Settings', {
|
const [collapseState, updateCollapseState] = useCollapseState('Settings', {
|
||||||
appearance: true
|
appearance: true
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleThemeChange = (value) => {
|
const handleThemeChange = (value) => {
|
||||||
if (value === 'dark' && !isDarkMode) {
|
if (value === 'system') {
|
||||||
toggleTheme()
|
toggleSystem()
|
||||||
} else if (value === 'light' && isDarkMode) {
|
} else {
|
||||||
toggleTheme()
|
if (isSystem) {
|
||||||
|
toggleSystem()
|
||||||
|
}
|
||||||
|
if (value === 'dark' && !isDarkMode) {
|
||||||
|
toggleTheme()
|
||||||
|
} else if (value === 'light' && isDarkMode) {
|
||||||
|
toggleTheme()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +43,11 @@ const Settings = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getCurrentThemeValue = () => {
|
||||||
|
if (isSystem) return 'system'
|
||||||
|
return isDarkMode ? 'dark' : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ height: '100%', minHeight: 0, overflowY: 'auto' }}>
|
<div style={{ height: '100%', minHeight: 0, overflowY: 'auto' }}>
|
||||||
<Collapse
|
<Collapse
|
||||||
@ -71,12 +89,13 @@ const Settings = () => {
|
|||||||
>
|
>
|
||||||
<Descriptions.Item label='Theme'>
|
<Descriptions.Item label='Theme'>
|
||||||
<Select
|
<Select
|
||||||
value={isDarkMode ? 'dark' : 'light'}
|
value={getCurrentThemeValue()}
|
||||||
onChange={handleThemeChange}
|
onChange={handleThemeChange}
|
||||||
style={{ width: '200px' }}
|
style={{ width: '200px' }}
|
||||||
>
|
>
|
||||||
<Option value='light'>Light</Option>
|
<Option value='light'>Light</Option>
|
||||||
<Option value='dark'>Dark</Option>
|
<Option value='dark'>Dark</Option>
|
||||||
|
<Option value='system'>System</Option>
|
||||||
</Select>
|
</Select>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label='UI Density'>
|
<Descriptions.Item label='UI Density'>
|
||||||
|
|||||||
@ -1,17 +1,73 @@
|
|||||||
import React, { createContext, useContext, useState } from 'react'
|
import React, { createContext, useContext, useState, useEffect } from 'react'
|
||||||
import { theme } from 'antd'
|
import { theme } from 'antd'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
const ThemeContext = createContext()
|
const ThemeContext = createContext()
|
||||||
|
|
||||||
export const ThemeProvider = ({ children }) => {
|
export const ThemeProvider = ({ children }) => {
|
||||||
const [isDarkMode, setIsDarkMode] = useState(true)
|
const [isSystem, setIsSystem] = useState(() => {
|
||||||
const [isCompact, setIsCompact] = useState(false)
|
const savedSystem = sessionStorage.getItem('isSystem')
|
||||||
|
return savedSystem ? JSON.parse(savedSystem) : true
|
||||||
|
})
|
||||||
|
const [isDarkMode, setIsDarkMode] = useState(() => {
|
||||||
|
const savedTheme = sessionStorage.getItem('isDarkMode')
|
||||||
|
return savedTheme ? JSON.parse(savedTheme) : true
|
||||||
|
})
|
||||||
|
const [isCompact, setIsCompact] = useState(() => {
|
||||||
|
const savedCompact = sessionStorage.getItem('isCompact')
|
||||||
|
return savedCompact ? JSON.parse(savedCompact) : false
|
||||||
|
})
|
||||||
|
|
||||||
|
// System theme detection
|
||||||
|
useEffect(() => {
|
||||||
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
|
||||||
|
const handleSystemThemeChange = (e) => {
|
||||||
|
if (isSystem) {
|
||||||
|
setIsDarkMode(e.matches)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial value
|
||||||
|
if (isSystem) {
|
||||||
|
setIsDarkMode(mediaQuery.matches)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add listener
|
||||||
|
mediaQuery.addEventListener('change', handleSystemThemeChange)
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
return () =>
|
||||||
|
mediaQuery.removeEventListener('change', handleSystemThemeChange)
|
||||||
|
}, [isSystem])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
sessionStorage.setItem('isSystem', JSON.stringify(isSystem))
|
||||||
|
}, [isSystem])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
sessionStorage.setItem('isDarkMode', JSON.stringify(isDarkMode))
|
||||||
|
}, [isDarkMode])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
sessionStorage.setItem('isCompact', JSON.stringify(isCompact))
|
||||||
|
}, [isCompact])
|
||||||
|
|
||||||
const toggleTheme = () => {
|
const toggleTheme = () => {
|
||||||
|
if (isSystem) {
|
||||||
|
setIsSystem(false)
|
||||||
|
}
|
||||||
setIsDarkMode(!isDarkMode)
|
setIsDarkMode(!isDarkMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleSystem = () => {
|
||||||
|
setIsSystem(!isSystem)
|
||||||
|
if (!isSystem) {
|
||||||
|
// When enabling system theme, update to match system preference
|
||||||
|
setIsDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const toggleCompact = () => {
|
const toggleCompact = () => {
|
||||||
setIsCompact(!isCompact)
|
setIsCompact(!isCompact)
|
||||||
}
|
}
|
||||||
@ -50,6 +106,8 @@ export const ThemeProvider = ({ children }) => {
|
|||||||
toggleTheme,
|
toggleTheme,
|
||||||
isCompact,
|
isCompact,
|
||||||
toggleCompact,
|
toggleCompact,
|
||||||
|
isSystem,
|
||||||
|
toggleSystem,
|
||||||
themeConfig
|
themeConfig
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user