forked from Shiloh/remnantchat
feat: persist color theme setting
This commit is contained in:
parent
82673d54fd
commit
7fb46bfe27
@ -52,6 +52,7 @@ test('persists user settings if none were already persisted', async () => {
|
||||
})
|
||||
|
||||
expect(mockSetItem).toHaveBeenCalledWith(PersistedStorageKeys.USER_SETTINGS, {
|
||||
colorMode: 'dark',
|
||||
userId: 'abc123',
|
||||
})
|
||||
})
|
||||
|
@ -3,6 +3,7 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import localforage from 'localforage'
|
||||
|
||||
import { SettingsContext } from 'contexts/SettingsContext'
|
||||
import { Home } from 'pages/Home/'
|
||||
import { PublicRoom } from 'pages/PublicRoom/'
|
||||
import { UserSettings } from 'models/settings'
|
||||
@ -22,8 +23,11 @@ function Bootstrap({
|
||||
getUuid = uuid,
|
||||
}: BootstrapProps) {
|
||||
const [hasLoadedSettings, setHasLoadedSettings] = useState(false)
|
||||
const [settings, setSettings] = useState({ userId: getUuid() })
|
||||
const { userId } = settings
|
||||
const [userSettings, setUserSettings] = useState<UserSettings>({
|
||||
userId: getUuid(),
|
||||
colorMode: 'dark',
|
||||
})
|
||||
const { userId } = userSettings
|
||||
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
@ -35,20 +39,38 @@ function Bootstrap({
|
||||
)
|
||||
|
||||
if (persistedUserSettings) {
|
||||
setSettings(persistedUserSettings)
|
||||
setUserSettings(persistedUserSettings)
|
||||
} else {
|
||||
await persistedStorage.setItem(
|
||||
PersistedStorageKeys.USER_SETTINGS,
|
||||
settings
|
||||
userSettings
|
||||
)
|
||||
}
|
||||
|
||||
setHasLoadedSettings(true)
|
||||
})()
|
||||
}, [hasLoadedSettings, persistedStorage, settings, userId])
|
||||
}, [hasLoadedSettings, persistedStorage, userSettings, userId])
|
||||
|
||||
const settingsContextValue = {
|
||||
updateUserSettings: async (changedSettings: Partial<UserSettings>) => {
|
||||
const newSettings = {
|
||||
...userSettings,
|
||||
...changedSettings,
|
||||
}
|
||||
|
||||
await persistedStorage.setItem(
|
||||
PersistedStorageKeys.USER_SETTINGS,
|
||||
newSettings
|
||||
)
|
||||
|
||||
setUserSettings(newSettings)
|
||||
},
|
||||
getUserSettings: () => ({ ...userSettings }),
|
||||
}
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<SettingsContext.Provider value={settingsContextValue}>
|
||||
<Shell userPeerId={userId}>
|
||||
{hasLoadedSettings ? (
|
||||
<Routes>
|
||||
@ -64,6 +86,7 @@ function Bootstrap({
|
||||
<></>
|
||||
)}
|
||||
</Shell>
|
||||
</SettingsContext.Provider>
|
||||
</Router>
|
||||
)
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import {
|
||||
forwardRef,
|
||||
PropsWithChildren,
|
||||
SyntheticEvent,
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
SyntheticEvent,
|
||||
} from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import CssBaseline from '@mui/material/CssBaseline'
|
||||
@ -34,6 +35,7 @@ import Brightness4Icon from '@mui/icons-material/Brightness4'
|
||||
import Brightness7Icon from '@mui/icons-material/Brightness7'
|
||||
|
||||
import { ShellContext } from 'contexts/ShellContext'
|
||||
import { SettingsContext } from 'contexts/SettingsContext'
|
||||
import { AlertOptions } from 'models/shell'
|
||||
import { PeerNameDisplay } from 'components/PeerNameDisplay'
|
||||
|
||||
@ -98,6 +100,7 @@ const DrawerHeader = styled('div')(({ theme }) => ({
|
||||
}))
|
||||
|
||||
export const Shell = ({ children, userPeerId }: ShellProps) => {
|
||||
const settingsContext = useContext(SettingsContext)
|
||||
const [isAlertShowing, setIsAlertShowing] = useState(false)
|
||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
|
||||
const [doShowPeers, setDoShowPeers] = useState(false)
|
||||
@ -125,20 +128,21 @@ export const Shell = ({ children, userPeerId }: ShellProps) => {
|
||||
[numberOfPeers, setDoShowPeers, setNumberOfPeers, setTitle, showAlert]
|
||||
)
|
||||
|
||||
const [mode, setMode] = useState<'light' | 'dark'>('dark')
|
||||
const colorMode = settingsContext.getUserSettings().colorMode
|
||||
|
||||
const handleColorModeToggleClick = () => {
|
||||
setMode(prevMode => (prevMode === 'light' ? 'dark' : 'light'))
|
||||
const newMode = colorMode === 'light' ? 'dark' : 'light'
|
||||
settingsContext.updateUserSettings({ colorMode: newMode })
|
||||
}
|
||||
|
||||
const theme = useMemo(
|
||||
() =>
|
||||
createTheme({
|
||||
palette: {
|
||||
mode,
|
||||
mode: colorMode,
|
||||
},
|
||||
}),
|
||||
[mode]
|
||||
[colorMode]
|
||||
)
|
||||
|
||||
const handleAlertClose = (
|
||||
|
16
src/contexts/SettingsContext.ts
Normal file
16
src/contexts/SettingsContext.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { createContext } from 'react'
|
||||
|
||||
import { UserSettings } from 'models/settings'
|
||||
|
||||
interface SettingsContextProps {
|
||||
updateUserSettings: (settings: Partial<UserSettings>) => Promise<void>
|
||||
getUserSettings: () => UserSettings
|
||||
}
|
||||
|
||||
export const SettingsContext = createContext<SettingsContextProps>({
|
||||
updateUserSettings: () => Promise.resolve(),
|
||||
getUserSettings: () => ({
|
||||
userId: '',
|
||||
colorMode: 'dark',
|
||||
}),
|
||||
})
|
@ -1,3 +1,4 @@
|
||||
export interface UserSettings {
|
||||
colorMode: 'dark' | 'light'
|
||||
userId: string
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user