Refactor appearance settings for reuse
This commit is contained in:
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user