diff options
-rw-r--r-- | src/view/com/util/Link.tsx | 9 | ||||
-rw-r--r-- | src/view/shell/Drawer.tsx | 135 | ||||
-rw-r--r-- | src/view/shell/desktop/RightNav.tsx | 144 |
3 files changed, 227 insertions, 61 deletions
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index f753f01cc..e47354428 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -229,14 +229,19 @@ function onPressInner( } else if ( !e.defaultPrevented && // onPress prevented default // @ts-ignore Web only -prf - !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys + !(e.metaKey || e.altKey || e.shiftKey) && // ignore clicks with modifier keys // @ts-ignore Web only -prf (e.button == null || e.button === 0) && // ignore everything but left clicks // @ts-ignore Web only -prf [undefined, null, '', 'self'].includes(e.currentTarget?.target) // let browser handle "target=_blank" etc. ) { e.preventDefault() - shouldHandle = true + if (e.ctrlKey && Platform.OS === 'web') { + shouldHandle = false + window.open(href, '_blank') + } else { + shouldHandle = true + } } if (shouldHandle) { diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index ea2153789..2c7c65247 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -1,6 +1,7 @@ import React, {ComponentProps} from 'react' import { Linking, + Pressable, SafeAreaView, StyleProp, StyleSheet, @@ -125,10 +126,13 @@ export const DrawerContent = observer(() => { Linking.openURL(FEEDBACK_FORM_URL) }, [track]) - const onColorModePress = React.useCallback(() => { - track('Menu:ItemClicked', {url: '#cycleColorMode'}) - store.shell.setColorMode(nextColorMode()) - }, [track, store]) + const onColorModePress = React.useCallback( + (mode: string) => { + track('Menu:ItemClicked', {url: '#cycleColorMode'}) + store.shell.setColorMode(mode) + }, + [track, store], + ) // rendering // = @@ -291,23 +295,33 @@ export const DrawerContent = observer(() => { <View style={s.flex1} /> <View style={styles.footer}> {!isWeb && ( - <TouchableOpacity - accessibilityRole="button" - accessibilityLabel="Cycle color mode" - accessibilityHint={modeAccessibilityText[store.shell.colorMode]} - onPress={onColorModePress} - style={[ - styles.footerBtn, - theme.colorScheme === 'light' - ? pal.btn - : styles.footerBtnDarkMode, - ]}> - <MoonIcon - size={22} - style={pal.text as StyleProp<ViewStyle>} - strokeWidth={2} - /> - </TouchableOpacity> + <View> + <Text type="sm" style={[pal.textLight, styles.colorModeText]}> + Set color theme + </Text> + <View style={styles.selectableBtns}> + <SelectableBtn + current={store.shell.colorMode} + value="system" + label="System" + left + onChange={onColorModePress} + /> + <SelectableBtn + current={store.shell.colorMode} + value="light" + label="Light" + onChange={onColorModePress} + /> + <SelectableBtn + current={store.shell.colorMode} + value="dark" + label="Dark" + right + onChange={onColorModePress} + /> + </View> + </View> )} <TouchableOpacity accessibilityRole="link" @@ -428,6 +442,45 @@ const InviteCodes = observer(() => { ) }) +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 ( + <Pressable + style={[ + styles.selectableBtn, + left && styles.selectableBtnLeft, + right && styles.selectableBtnRight, + pal.border, + current === value ? palPrimary.view : pal.view, + ]} + onPress={() => onChange(value)} + accessibilityRole="button" + accessibilityLabel={value} + accessibilityHint={`Set color theme to ${value}`}> + <Text style={current === value ? palPrimary.text : pal.text}> + {label} + </Text> + </Pressable> + ) +} + const styles = StyleSheet.create({ view: { flex: 1, @@ -502,6 +555,46 @@ const styles = StyleSheet.create({ marginRight: 6, }, + colorModeText: { + marginLeft: 10, + marginBottom: 6, + }, + + selectableBtns: { + flexDirection: 'row', + marginLeft: 10, + }, + selectableBtn: { + 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, + }, + footer: { flexDirection: 'row', justifyContent: 'space-between', diff --git a/src/view/shell/desktop/RightNav.tsx b/src/view/shell/desktop/RightNav.tsx index 084e95607..f81c218cd 100644 --- a/src/view/shell/desktop/RightNav.tsx +++ b/src/view/shell/desktop/RightNav.tsx @@ -1,43 +1,20 @@ import React from 'react' import {observer} from 'mobx-react-lite' -import {StyleSheet, TouchableOpacity, View} from 'react-native' +import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {usePalette} from 'lib/hooks/usePalette' import {DesktopSearch} from './Search' import {Text} from 'view/com/util/text/Text' import {TextLink} from 'view/com/util/Link' import {FEEDBACK_FORM_URL} from 'lib/constants' -import {s} from 'lib/styles' +import {colors, s} from 'lib/styles' import {useStores} from 'state/index' import {pluralize} from 'lib/strings/helpers' -import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle' -import {MoonIcon} from 'lib/icons' import {formatCount} from 'view/com/util/numeric/format' export const DesktopRightNav = observer(function DesktopRightNav() { const store = useStores() const pal = usePalette('default') - 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 modeHelpText = { - light: 'Light Theme', - dark: 'Dark Theme', - system: 'System Default Theme', - } - - const nextColorMode = () => { - return colorModes[ - (colorModes.indexOf(store.shell.colorMode) + 1) % colorModes.length - ] - } - - const onModePress = React.useCallback(() => { - store.shell.setColorMode(nextColorMode()) - }, [store]) return ( <View style={[styles.rightNav, pal.view]}> @@ -76,19 +53,31 @@ export const DesktopRightNav = observer(function DesktopRightNav() { </View> <InviteCodes /> <View> - <TouchableOpacity - style={[styles.cycleColorModeToggle]} - onPress={onModePress} - accessibilityRole="button" - accessibilityLabel="Cycle color mode" - accessibilityHint={modeAccessibilityText[nextColorMode()]}> - <View style={[pal.viewLight, styles.cycleColorModeToggleIcon]}> - <MoonIcon size={18} style={pal.textLight} /> - </View> - <Text type="sm" style={pal.textLight}> - {modeHelpText[store.shell.colorMode]} - </Text> - </TouchableOpacity> + <Text type="sm" style={[pal.textLight, styles.colorModeText]}> + Set color theme + </Text> + <View style={styles.selectableBtns}> + <SelectableBtn + current={store.shell.colorMode} + value="system" + label="System" + left + onChange={(v: string) => store.shell.setColorMode(v)} + /> + <SelectableBtn + current={store.shell.colorMode} + value="light" + label="Light" + onChange={(v: string) => store.shell.setColorMode(v)} + /> + <SelectableBtn + current={store.shell.colorMode} + value="dark" + label="Dark" + right + onChange={(v: string) => store.shell.setColorMode(v)} + /> + </View> </View> </View> ) @@ -132,6 +121,45 @@ const InviteCodes = observer(() => { ) }) +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 ( + <Pressable + style={[ + styles.selectableBtn, + left && styles.selectableBtnLeft, + right && styles.selectableBtnRight, + pal.border, + current === value ? palPrimary.view : pal.view, + ]} + onPress={() => onChange(value)} + accessibilityRole="button" + accessibilityLabel={value} + accessibilityHint={`Set color theme to ${value}`}> + <Text style={current === value ? palPrimary.text : pal.text}> + {label} + </Text> + </Pressable> + ) +} + const styles = StyleSheet.create({ rightNav: { position: 'absolute', @@ -174,4 +202,44 @@ const styles = StyleSheet.create({ height: 26, borderRadius: 15, }, + + colorModeText: { + marginLeft: 10, + marginBottom: 6, + }, + + selectableBtns: { + flexDirection: 'row', + marginLeft: 10, + }, + selectableBtn: { + 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, + }, }) |