Refactor appearance settings for reuse

This commit is contained in:
Eric Bailey
2024-09-18 14:05:24 -05:00
parent 0bdfaf3905
commit 77167d0b51
+124 -124
View File
@@ -16,6 +16,7 @@ import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
import {ScrollView} from '#/view/com/util/Views' import {ScrollView} from '#/view/com/util/Views'
import {atoms as a, native, useAlf, useTheme} from '#/alf' import {atoms as a, native, useAlf, useTheme} from '#/alf'
import * as ToggleButton from '#/components/forms/ToggleButton' import * as ToggleButton from '#/components/forms/ToggleButton'
import {Props as SVGIconProps} from '#/components/icons/common'
import {Moon_Stroke2_Corner0_Rounded as MoonIcon} from '#/components/icons/Moon' import {Moon_Stroke2_Corner0_Rounded as MoonIcon} from '#/components/icons/Moon'
import {Phone_Stroke2_Corner0_Rounded as PhoneIcon} from '#/components/icons/Phone' import {Phone_Stroke2_Corner0_Rounded as PhoneIcon} from '#/components/icons/Phone'
import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize' import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize'
@@ -32,9 +33,6 @@ export function AppearanceSettingsScreen({}: Props) {
const {colorMode, darkTheme} = useThemePrefs() const {colorMode, darkTheme} = useThemePrefs()
const {setColorMode, setDarkTheme} = useSetThemePrefs() const {setColorMode, setDarkTheme} = useSetThemePrefs()
const [fontFamily, setFontFamily] = React.useState(fonts.family)
const [fontScale, setFontScale] = React.useState(() => fonts.scale)
const onChangeAppearance = useCallback( const onChangeAppearance = useCallback(
(keys: string[]) => { (keys: string[]) => {
const appearance = keys.find(key => key !== colorMode) as const appearance = keys.find(key => key !== colorMode) as
@@ -63,19 +61,17 @@ export function AppearanceSettingsScreen({}: Props) {
const onChangeFontFamily = useCallback( const onChangeFontFamily = useCallback(
(values: string[]) => { (values: string[]) => {
const next = values[0] === 'system' ? 'system' : 'theme' const next = values[0] === 'system' ? 'system' : 'theme'
setFontFamily(next)
fonts.setFontFamily(next) fonts.setFontFamily(next)
}, },
[setFontFamily, fonts], [fonts],
) )
const onChangeFontScale = useCallback( const onChangeFontScale = useCallback(
(values: string[]) => { (values: string[]) => {
const next = values[0] || ('0' as any) const next = values[0] || ('0' as any)
setFontScale(next)
fonts.setFontScale(next) fonts.setFontScale(next)
}, },
[setFontScale, fonts], [fonts],
) )
return ( return (
@@ -97,133 +93,90 @@ export function AppearanceSettingsScreen({}: Props) {
<View style={[a.gap_3xl, a.pt_xl, a.px_xl]}> <View style={[a.gap_3xl, a.pt_xl, a.px_xl]}>
<View style={[a.gap_lg]}> <View style={[a.gap_lg]}>
<View style={[a.gap_md]}> <AppearanceToggleButtonGroup
<View style={[a.flex_row, a.align_center, a.gap_md]}> title={_(msg`Color mode`)}
<PhoneIcon style={t.atoms.text} /> icon={PhoneIcon}
<Text style={[a.text_md, a.font_bold]}> items={[
<Trans>Mode</Trans> {
</Text> label: _(msg`System`),
</View> name: 'system',
<ToggleButton.Group },
label={_(msg`Dark mode`)} {
label: _(msg`Light`),
name: 'light',
},
{
label: _(msg`Dark`),
name: 'dark',
},
]}
values={[colorMode]} values={[colorMode]}
onChange={onChangeAppearance}> onChange={onChangeAppearance}
<ToggleButton.Button label={_(msg`System`)} name="system"> />
<ToggleButton.ButtonText>
<Trans>System</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button label={_(msg`Light`)} name="light">
<ToggleButton.ButtonText>
<Trans>Light</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button label={_(msg`Dark`)} name="dark">
<ToggleButton.ButtonText>
<Trans>Dark</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>
</View>
{colorMode !== 'light' && ( {colorMode !== 'light' && (
<Animated.View <Animated.View
entering={native(FadeInDown)} entering={native(FadeInDown)}
exiting={native(FadeOutDown)} exiting={native(FadeOutDown)}>
style={[a.gap_md]}> <AppearanceToggleButtonGroup
<View style={[a.flex_row, a.align_center, a.gap_md]}> title={_(msg`Dark theme`)}
<MoonIcon style={t.atoms.text} /> icon={MoonIcon}
<Text style={[a.text_md, a.font_bold]}> items={[
<Trans>Dark theme</Trans> {
</Text> label: _(msg`Dim`),
</View> name: 'dim',
},
<ToggleButton.Group {
label={_(msg`Dark theme`)} label: _(msg`Dark`),
name: 'dark',
},
]}
values={[darkTheme ?? 'dim']} values={[darkTheme ?? 'dim']}
onChange={onChangeDarkTheme}> onChange={onChangeDarkTheme}
<ToggleButton.Button label={_(msg`Dim`)} name="dim"> />
<ToggleButton.ButtonText>
<Trans>Dim</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button label={_(msg`Dark`)} name="dark">
<ToggleButton.ButtonText>
<Trans>Dark</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>
</Animated.View> </Animated.View>
)} )}
<View style={[a.gap_md]}> <AppearanceToggleButtonGroup
<View style={[a.gap_xs]}> title={_(msg`Font`)}
<View style={[a.flex_row, a.align_center, a.gap_md]}> description={_(
<Aa style={t.atoms.text} /> msg`For the best experience, we recommend using the theme font.`,
<Text style={[a.text_md, a.font_bold]}> )}
<Trans>Font</Trans> icon={Aa}
</Text> items={[
</View> {
<Text label: _(msg`System`),
style={[ name: 'system',
a.text_sm, },
a.leading_snug, {
t.atoms.text_contrast_medium, label: _(msg`Theme`),
]}> name: 'theme',
<Trans> },
For the best experience, we recommend using the theme ]}
font. values={[fonts.family]}
</Trans> onChange={onChangeFontFamily}
</Text> />
</View>
<ToggleButton.Group
label={_(msg`Font`)}
values={[fontFamily]}
onChange={onChangeFontFamily}>
<ToggleButton.Button label={_(msg`System`)} name="system">
<ToggleButton.ButtonText>
<Trans>System</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button label={_(msg`Theme`)} name="theme">
<ToggleButton.ButtonText>
<Trans>Theme</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>
</View>
<View style={[a.gap_md]}> <AppearanceToggleButtonGroup
<View style={[a.gap_xs]}> title={_(msg`Font size`)}
<View style={[a.flex_row, a.align_center, a.gap_md]}> icon={TextSize}
<TextSize style={t.atoms.text} /> items={[
<Text style={[a.text_md, a.font_bold]}> {
<Trans>Font size</Trans> label: _(msg`Smaller`),
</Text> name: '-1',
</View> },
</View> {
label: _(msg`Default`),
<ToggleButton.Group name: '0',
label={_(msg`Font`)} },
values={[fontScale]} {
onChange={onChangeFontScale}> label: _(msg`Larger`),
<ToggleButton.Button label={_(msg`Small`)} name="-1"> name: '1',
<ToggleButton.ButtonText> },
<Trans>Smaller</Trans> ]}
</ToggleButton.ButtonText> values={[fonts.scale]}
</ToggleButton.Button> onChange={onChangeFontScale}
<ToggleButton.Button label={_(msg`Default`)} name="0"> />
<ToggleButton.ButtonText>
<Trans>Default</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button label={_(msg`Large`)} name="1">
<ToggleButton.ButtonText>
<Trans>Larger</Trans>
</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>
</View>
</View> </View>
</View> </View>
</ScrollView> </ScrollView>
@@ -231,3 +184,50 @@ export function AppearanceSettingsScreen({}: Props) {
</LayoutAnimationConfig> </LayoutAnimationConfig>
) )
} }
export function AppearanceToggleButtonGroup({
title,
description,
icon: Icon,
items,
values,
onChange,
}: {
title: string
description?: string
icon: React.ComponentType<SVGIconProps>
items: {
label: string
name: string
}[]
values: string[]
onChange: (values: string[]) => void
}) {
const t = useTheme()
return (
<View style={[a.gap_md]}>
<View style={[a.gap_xs]}>
<View style={[a.flex_row, a.align_center, a.gap_md]}>
<Icon style={t.atoms.text} />
<Text style={[a.text_md, a.font_bold]}>{title}</Text>
</View>
{description && (
<Text
style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}>
{description}
</Text>
)}
</View>
<ToggleButton.Group label={title} values={values} onChange={onChange}>
{items.map(item => (
<ToggleButton.Button
key={item.name}
label={item.label}
name={item.name}>
<ToggleButton.ButtonText>{item.label}</ToggleButton.ButtonText>
</ToggleButton.Button>
))}
</ToggleButton.Group>
</View>
)
}