From da0ed7e002c926f2a3a342d8d420304b10aa8663 Mon Sep 17 00:00:00 2001 From: Jaz Date: Tue, 16 May 2023 21:36:43 -0700 Subject: [PATCH] Feat: Use system default color mode, but allow user override --- src/App.native.tsx | 2 +- src/App.web.tsx | 2 +- src/lib/ThemeContext.tsx | 7 +++-- src/state/models/ui/shell.ts | 12 ++++----- src/view/shell/Drawer.tsx | 29 +++++++++++++------- src/view/shell/desktop/RightNav.tsx | 42 ++++++++++++++++++----------- 6 files changed, 59 insertions(+), 35 deletions(-) diff --git a/src/App.native.tsx b/src/App.native.tsx index 66722dc1..afab8236 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -51,7 +51,7 @@ const App = observer(() => { return null } return ( - + diff --git a/src/App.web.tsx b/src/App.web.tsx index 42932827..7570db44 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -30,7 +30,7 @@ const App = observer(() => { } return ( - + diff --git a/src/lib/ThemeContext.tsx b/src/lib/ThemeContext.tsx index ef17c1e7..251e04e5 100644 --- a/src/lib/ThemeContext.tsx +++ b/src/lib/ThemeContext.tsx @@ -89,10 +89,13 @@ export const ThemeProvider: React.FC = ({ theme, children, }) => { - const colorScheme = useColorScheme() + const colorSchemeFromRN = useColorScheme() + + // if theme is 'system', use the device's configured color scheme + let colorScheme = theme === 'system' ? colorSchemeFromRN : theme const value = useMemo( - () => ((theme || colorScheme) === 'dark' ? darkTheme : defaultTheme), + () => (colorScheme === 'dark' ? darkTheme : defaultTheme), [colorScheme, theme], ) diff --git a/src/state/models/ui/shell.ts b/src/state/models/ui/shell.ts index 9b9a176b..187342ec 100644 --- a/src/state/models/ui/shell.ts +++ b/src/state/models/ui/shell.ts @@ -189,7 +189,7 @@ export interface ComposerOpts { } export class ShellUiModel { - darkMode = false + colorMode = 'system' minimalShellMode = false isDrawerOpen = false isDrawerSwipeDisabled = false @@ -210,20 +210,20 @@ export class ShellUiModel { serialize(): unknown { return { - darkMode: this.darkMode, + colorMode: this.colorMode, } } hydrate(v: unknown) { if (isObj(v)) { - if (hasProp(v, 'darkMode') && typeof v.darkMode === 'boolean') { - this.darkMode = v.darkMode + if (hasProp(v, 'colorMode') && typeof v.colorMode === 'string') { + this.colorMode = v.colorMode } } } - setDarkMode(v: boolean) { - this.darkMode = v + setColorMode(mode: string) { + this.colorMode = mode } setMinimalShellMode(v: boolean) { diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index d595bc52..ea215378 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -53,6 +53,19 @@ export const DrawerContent = observer(() => { const {notifications} = store.me + const colorModes = ['light', 'dark', 'system'] + const modeAccessibilityText = { + light: 'Sets display to light mode', + dark: 'Sets display to dark mode', + system: 'Sets display to system default', + } + + const nextColorMode = () => { + return colorModes[ + (colorModes.indexOf(store.shell.colorMode) + 1) % colorModes.length + ] + } + // events // = @@ -112,9 +125,9 @@ export const DrawerContent = observer(() => { Linking.openURL(FEEDBACK_FORM_URL) }, [track]) - const onDarkmodePress = React.useCallback(() => { - track('Menu:ItemClicked', {url: '#darkmode'}) - store.shell.setDarkMode(!store.shell.darkMode) + const onColorModePress = React.useCallback(() => { + track('Menu:ItemClicked', {url: '#cycleColorMode'}) + store.shell.setColorMode(nextColorMode()) }, [track, store]) // rendering @@ -280,13 +293,9 @@ export const DrawerContent = observer(() => { {!isWeb && ( { - store.shell.setDarkMode(!store.shell.darkMode) + const nextColorMode = () => { + return colorModes[ + (colorModes.indexOf(store.shell.colorMode) + 1) % colorModes.length + ] + } + + const onModePress = React.useCallback(() => { + store.shell.setColorMode(nextColorMode()) }, [store]) return ( @@ -61,20 +77,16 @@ export const DesktopRightNav = observer(function DesktopRightNav() { - + accessibilityLabel="Cycle color mode" + accessibilityHint={modeAccessibilityText[nextColorMode()]}> + - {mode} mode + {modeHelpText[store.shell.colorMode]} @@ -148,13 +160,13 @@ const styles = StyleSheet.create({ marginRight: 6, }, - darkModeToggle: { + cycleColorModeToggle: { flexDirection: 'row', alignItems: 'center', gap: 8, marginHorizontal: 12, }, - darkModeToggleIcon: { + cycleColorModeToggleIcon: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center',