diff --git a/src/App.native.tsx b/src/App.native.tsx index 66722dc15c..afab823686 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 4293282769..7570db44e9 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 ef17c1e7a1..251e04e501 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 95b6662433..a77ffbdfb7 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/screens/Settings.tsx b/src/view/screens/Settings.tsx index 1b90cbb8af..4288223396 100644 --- a/src/view/screens/Settings.tsx +++ b/src/view/screens/Settings.tsx @@ -1,6 +1,7 @@ import React from 'react' import { ActivityIndicator, + Pressable, StyleSheet, TextStyle, TouchableOpacity, @@ -287,6 +288,34 @@ export const SettingsScreen = withAuthRequired( + + + Appearance + + + + store.shell.setColorMode(v)} + /> + store.shell.setColorMode(v)} + /> + store.shell.setColorMode(v)} + /> + + @@ -442,6 +471,45 @@ function AccountDropdownBtn({handle}: {handle: string}) { ) } +interface SelectableBtnProps { + current: string + value: string + label: string + left?: boolean + right?: boolean + onChange: (v: string) => void +} + +function SelectableBtn({ + current, + value, + label, + left, + right, + onChange, +}: SelectableBtnProps) { + const pal = usePalette('default') + const palPrimary = usePalette('inverted') + return ( + onChange(value)} + accessibilityRole="button" + accessibilityLabel={value} + accessibilityHint={`Set color theme to ${value}`}> + + {label} + + + ) +} + const styles = StyleSheet.create({ dimmed: { opacity: 0.5, @@ -493,4 +561,45 @@ const styles = StyleSheet.create({ paddingVertical: 8, paddingHorizontal: 18, }, + + colorModeText: { + marginLeft: 10, + marginBottom: 6, + }, + + selectableBtns: { + flexDirection: 'row', + }, + selectableBtn: { + flex: isDesktopWeb ? undefined : 1, + width: isDesktopWeb ? 100 : undefined, + flexDirection: 'row', + justifyContent: 'center', + borderWidth: 1, + borderLeftWidth: 0, + paddingHorizontal: 10, + paddingVertical: 10, + }, + selectableBtnLeft: { + borderTopLeftRadius: 8, + borderBottomLeftRadius: 8, + borderLeftWidth: 1, + }, + selectableBtnRight: { + borderTopRightRadius: 8, + borderBottomRightRadius: 8, + }, + + btn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + width: '100%', + borderRadius: 32, + padding: 14, + backgroundColor: colors.gray1, + }, + toggleBtn: { + paddingHorizontal: 0, + }, }) diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 57f4ee696a..cf86393382 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -27,7 +27,6 @@ import { CogIcon, MagnifyingGlassIcon2, MagnifyingGlassIcon2Solid, - MoonIcon, UserIconSolid, SatelliteDishIcon, SatelliteDishIconSolid, @@ -119,12 +118,6 @@ export const DrawerContent = observer(() => { track('Menu:FeedbackClicked') Linking.openURL(FEEDBACK_FORM_URL) }, [track]) - - const onDarkmodePress = React.useCallback(() => { - track('Menu:ItemClicked', {url: '#darkmode'}) - store.shell.setDarkMode(!store.shell.darkMode) - }, [track, store]) - // rendering // = @@ -303,29 +296,6 @@ export const DrawerContent = observer(() => { - {!isWeb && ( - - } - strokeWidth={2} - /> - - )} { - store.shell.setDarkMode(!store.shell.darkMode) - }, [store]) return ( @@ -60,29 +52,6 @@ export const DesktopRightNav = observer(function DesktopRightNav() { - - - - {mode === 'Dark' ? ( - - ) : ( - - )} - - - {otherMode} mode - - - ) }) @@ -152,20 +121,4 @@ const styles = StyleSheet.create({ inviteCodesIcon: { marginRight: 6, }, - - darkModeToggle: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, - marginHorizontal: 12, - marginTop: 8, - }, - darkModeToggleIcon: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - width: 26, - height: 26, - borderRadius: 15, - }, })