diff options
author | Hailey <me@haileyok.com> | 2024-02-06 11:43:51 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-06 11:43:51 -0800 |
commit | ec86282403ea34704d0faab7b04ca033bd3a0650 (patch) | |
tree | ca5881ada59d7ad634bd799efe3c751a4c5509d2 /src/state | |
parent | 856f80fc6df731b1dbe9efa289ad6a4f728d4e0d (diff) | |
download | voidsky-ec86282403ea34704d0faab7b04ca033bd3a0650.tar.zst |
Options for selecting dark theme, fix some white flashes when in dark mode (#2722)
* add dark theme selection to settings/schema * use `useThemePrefs` where needed * adjust theme providers to support various themes * update storybook * handle web themes * better themeing for web * dont show dark theme prefs when color mode is light * drop the inverted text change on oled theme * get the color mode inside of `useColorModeTheme` * use `ThemeName` type everywhere * typo * use dim/dark instead of dark/oled * prevent any fickers on web * fix styles * use `dim` for dark default * more cleanup * 🤔 * set system background color * ts
Diffstat (limited to 'src/state')
-rw-r--r-- | src/state/persisted/legacy.ts | 1 | ||||
-rw-r--r-- | src/state/persisted/schema.ts | 2 | ||||
-rw-r--r-- | src/state/shell/color-mode.tsx | 70 | ||||
-rw-r--r-- | src/state/shell/index.tsx | 2 |
4 files changed, 43 insertions, 32 deletions
diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts index 6bb75ae86..767faf48f 100644 --- a/src/state/persisted/legacy.ts +++ b/src/state/persisted/legacy.ts @@ -69,6 +69,7 @@ const DEPRECATED_ROOT_STATE_STORAGE_KEY = 'root' export function transform(legacy: Partial<LegacySchema>): Schema { return { colorMode: legacy.shell?.colorMode || defaults.colorMode, + darkTheme: defaults.darkTheme, session: { accounts: legacy.session?.accounts || defaults.session.accounts, currentAccount: diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index 870e14aaf..ade97ef74 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -18,6 +18,7 @@ export type PersistedAccount = z.infer<typeof accountSchema> export const schema = z.object({ colorMode: z.enum(['system', 'light', 'dark']), + darkTheme: z.enum(['dim', 'dark']).optional(), session: z.object({ accounts: z.array(accountSchema), currentAccount: accountSchema.optional(), @@ -60,6 +61,7 @@ export type Schema = z.infer<typeof schema> export const defaults: Schema = { colorMode: 'system', + darkTheme: 'dim', session: { accounts: [], currentAccount: undefined, diff --git a/src/state/shell/color-mode.tsx b/src/state/shell/color-mode.tsx index 192b88314..4f0391aa6 100644 --- a/src/state/shell/color-mode.tsx +++ b/src/state/shell/color-mode.tsx @@ -1,57 +1,65 @@ import React from 'react' -import {isWeb} from '#/platform/detection' import * as persisted from '#/state/persisted' -type StateContext = persisted.Schema['colorMode'] -type SetContext = (v: persisted.Schema['colorMode']) => void +type StateContext = { + colorMode: persisted.Schema['colorMode'] + darkTheme: persisted.Schema['darkTheme'] +} +type SetContext = { + setColorMode: (v: persisted.Schema['colorMode']) => void + setDarkTheme: (v: persisted.Schema['darkTheme']) => void +} -const stateContext = React.createContext<StateContext>('system') -const setContext = React.createContext<SetContext>( - (_: persisted.Schema['colorMode']) => {}, -) +const stateContext = React.createContext<StateContext>({ + colorMode: 'system', + darkTheme: 'dark', +}) +const setContext = React.createContext<SetContext>({} as SetContext) export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(persisted.get('colorMode')) + const [colorMode, setColorMode] = React.useState(persisted.get('colorMode')) + const [darkTheme, setDarkTheme] = React.useState(persisted.get('darkTheme')) - const setStateWrapped = React.useCallback( - (colorMode: persisted.Schema['colorMode']) => { - setState(colorMode) - persisted.write('colorMode', colorMode) - updateDocument(colorMode) + const setColorModeWrapped = React.useCallback( + (_colorMode: persisted.Schema['colorMode']) => { + setColorMode(_colorMode) + persisted.write('colorMode', _colorMode) }, - [setState], + [setColorMode], + ) + + const setDarkThemeWrapped = React.useCallback( + (_darkTheme: persisted.Schema['darkTheme']) => { + setDarkTheme(_darkTheme) + persisted.write('darkTheme', _darkTheme) + }, + [setDarkTheme], ) React.useEffect(() => { - updateDocument(persisted.get('colorMode')) // set on load return persisted.onUpdate(() => { - setState(persisted.get('colorMode')) - updateDocument(persisted.get('colorMode')) + setColorModeWrapped(persisted.get('colorMode')) + setDarkThemeWrapped(persisted.get('darkTheme')) }) - }, [setState]) + }, [setColorModeWrapped, setDarkThemeWrapped]) return ( - <stateContext.Provider value={state}> - <setContext.Provider value={setStateWrapped}> + <stateContext.Provider value={{colorMode, darkTheme}}> + <setContext.Provider + value={{ + setDarkTheme: setDarkThemeWrapped, + setColorMode: setColorModeWrapped, + }}> {children} </setContext.Provider> </stateContext.Provider> ) } -export function useColorMode() { +export function useThemePrefs() { return React.useContext(stateContext) } -export function useSetColorMode() { +export function useSetThemePrefs() { return React.useContext(setContext) } - -function updateDocument(colorMode: string) { - if (isWeb && typeof window !== 'undefined') { - const html = window.document.documentElement - // remove any other color mode classes - html.className = html.className.replace(/colorMode--\w+/g, '') - html.classList.add(`colorMode--${colorMode}`) - } -} diff --git a/src/state/shell/index.tsx b/src/state/shell/index.tsx index 53f05055c..07909c000 100644 --- a/src/state/shell/index.tsx +++ b/src/state/shell/index.tsx @@ -14,7 +14,7 @@ export { useSetDrawerSwipeDisabled, } from './drawer-swipe-disabled' export {useMinimalShellMode, useSetMinimalShellMode} from './minimal-mode' -export {useColorMode, useSetColorMode} from './color-mode' +export {useThemePrefs, useSetThemePrefs} from './color-mode' export {useOnboardingState, useOnboardingDispatch} from './onboarding' export {useComposerState, useComposerControls} from './composer' export {useTickEveryMinute} from './tick-every-minute' |