Refactor settings and fontScale values
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M9 5a1 1 0 0 1 1-1h12a1 1 0 1 1 0 2h-5v14a1 1 0 1 1-2 0V6h-5a1 1 0 0 1-1-1Zm-3.073 7v8a1 1 0 1 0 2 0v-8H12a1 1 0 1 0 0-2H6.971a1.015 1.015 0 0 0-.089 0H2a1 1 0 1 0 0 2h3.927Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 317 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3.65 17.247c-.242.832-.632 1.178-1.325 1.178-.814 0-1.325-.476-1.325-1.23 0-.216.06-.51.173-.831L4.586 7.07c.364-1.014.979-1.482 1.966-1.482 1.022 0 1.629.45 2.001 1.473l3.43 9.303c.121.337.165.571.165.831 0 .72-.546 1.23-1.308 1.23-.736 0-1.126-.338-1.36-1.152l-.658-1.975H4.309l-.658 1.95ZM6.5 8.152l-1.62 5.12h3.335l-1.654-5.12H6.5Zm13.005 8.688c-.52.988-1.68 1.568-2.84 1.568-1.768 0-3.11-1.144-3.11-2.815 0-1.69 1.299-2.668 3.62-2.807l2.34-.138v-.615c0-.867-.607-1.369-1.56-1.369-.771 0-1.239.251-1.802.979-.277.312-.597.468-1.004.468-.615 0-1.057-.399-1.057-.97 0-.2.043-.382.13-.572.433-1.109 1.923-1.793 3.845-1.793 2.383 0 3.933 1.23 3.933 3.1v5.293c0 .84-.511 1.273-1.23 1.273-.684 0-1.16-.38-1.213-1.126v-.476h-.052Zm-3.43-1.386c0 .693.572 1.126 1.42 1.126 1.11 0 2.02-.719 2.02-1.723v-.676l-1.959.121c-.944.07-1.48.494-1.48 1.152Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 986 B |
+14
-1
@@ -2,8 +2,21 @@ import {useFonts as defaultUseFonts} from 'expo-font'
|
||||
|
||||
import {Device, device} from '#/storage'
|
||||
|
||||
const factor = 0.0625 // 1 - (15/16)
|
||||
const fontScaleMultipliers: Record<Device['fontScale'], number> = {
|
||||
'-2': 1 - factor * 3,
|
||||
'-1': 1 - factor * 2,
|
||||
'0': 1 - factor * 1, // default
|
||||
'1': 1,
|
||||
'2': 1 + factor * 1,
|
||||
}
|
||||
|
||||
export function computeFontScaleMultiplier(scale: Device['fontScale']) {
|
||||
return fontScaleMultipliers[scale]
|
||||
}
|
||||
|
||||
export function getFontScale() {
|
||||
return device.get(['fontScale']) || 1
|
||||
return device.get(['fontScale']) || '0'
|
||||
}
|
||||
|
||||
export function setFontScale(fontScale: Device['fontScale']) {
|
||||
|
||||
+11
-5
@@ -3,6 +3,7 @@ import {useMediaQuery} from 'react-responsive'
|
||||
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {
|
||||
computeFontScaleMultiplier,
|
||||
getFontFamily,
|
||||
getFontScale,
|
||||
setFontFamily as persistFontFamily,
|
||||
@@ -27,6 +28,7 @@ export type Alf = {
|
||||
themes: ReturnType<typeof createThemes>
|
||||
fonts: {
|
||||
scale: Exclude<Device['fontScale'], undefined>
|
||||
scaleMultiplier: number
|
||||
family: Device['fontFamily']
|
||||
setFontScale: (fontScale: Exclude<Device['fontScale'], undefined>) => void
|
||||
setFontFamily: (fontFamily: Device['fontFamily']) => void
|
||||
@@ -51,6 +53,7 @@ export const Context = React.createContext<Alf>({
|
||||
}),
|
||||
fonts: {
|
||||
scale: getFontScale(),
|
||||
scaleMultiplier: computeFontScaleMultiplier(getFontScale()),
|
||||
family: getFontFamily(),
|
||||
setFontScale: () => {},
|
||||
setFontFamily: () => {},
|
||||
@@ -66,11 +69,11 @@ export function ThemeProvider({
|
||||
}: React.PropsWithChildren<{theme: ThemeName}>) {
|
||||
const gate = useGate()
|
||||
const [neue] = React.useState(() => gate('typography_neue'))
|
||||
const [fontScale, setFontScale] = React.useState<Alf['fonts']['scale']>(
|
||||
() => {
|
||||
if (!neue) return 1
|
||||
return getFontScale()
|
||||
},
|
||||
const [fontScale, setFontScale] = React.useState<Alf['fonts']['scale']>(() =>
|
||||
getFontScale(),
|
||||
)
|
||||
const [fontScaleMultiplier, setFontScaleMultiplier] = React.useState(() =>
|
||||
computeFontScaleMultiplier(fontScale),
|
||||
)
|
||||
const setFontScaleAndPersist = React.useCallback<
|
||||
Alf['fonts']['setFontScale']
|
||||
@@ -78,6 +81,7 @@ export function ThemeProvider({
|
||||
fontScale => {
|
||||
setFontScale(fontScale)
|
||||
persistFontScale(fontScale)
|
||||
setFontScaleMultiplier(computeFontScaleMultiplier(fontScale))
|
||||
},
|
||||
[setFontScale],
|
||||
)
|
||||
@@ -112,6 +116,7 @@ export function ThemeProvider({
|
||||
theme: themes[themeName],
|
||||
fonts: {
|
||||
scale: fontScale,
|
||||
scaleMultiplier: fontScaleMultiplier,
|
||||
family: fontFamily,
|
||||
setFontScale: setFontScaleAndPersist,
|
||||
setFontFamily: setFontFamilyAndPersist,
|
||||
@@ -128,6 +133,7 @@ export function ThemeProvider({
|
||||
setFontScaleAndPersist,
|
||||
fontFamily,
|
||||
setFontFamilyAndPersist,
|
||||
fontScaleMultiplier,
|
||||
],
|
||||
)}>
|
||||
{children}
|
||||
|
||||
@@ -72,7 +72,7 @@ export function Text({style, selectable, ...rest}: TextProps) {
|
||||
const {fonts, flags} = useAlf()
|
||||
const t = useTheme()
|
||||
const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, flatten(style)], {
|
||||
fontScale: fonts.scale,
|
||||
fontScale: fonts.scaleMultiplier,
|
||||
fontFamily: fonts.family,
|
||||
flags,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import {createSinglePathSVG} from './TEMPLATE'
|
||||
|
||||
export const TextSize_Stroke2_Corner0_Rounded = createSinglePathSVG({
|
||||
path: 'M9 5a1 1 0 0 1 1-1h12a1 1 0 1 1 0 2h-5v14a1 1 0 1 1-2 0V6h-5a1 1 0 0 1-1-1Zm-3.073 7v8a1 1 0 1 0 2 0v-8H12a1 1 0 1 0 0-2H6.971a1.015 1.015 0 0 0-.089 0H2a1 1 0 1 0 0 2h3.927Z',
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
import {createSinglePathSVG} from './TEMPLATE'
|
||||
|
||||
export const TitleCase_Stroke2_Corner0_Rounded = createSinglePathSVG({
|
||||
path: 'M3.65 17.247c-.242.832-.632 1.178-1.325 1.178-.814 0-1.325-.476-1.325-1.23 0-.216.06-.51.173-.831L4.586 7.07c.364-1.014.979-1.482 1.966-1.482 1.022 0 1.629.45 2.001 1.473l3.43 9.303c.121.337.165.571.165.831 0 .72-.546 1.23-1.308 1.23-.736 0-1.126-.338-1.36-1.152l-.658-1.975H4.309l-.658 1.95ZM6.5 8.152l-1.62 5.12h3.335l-1.654-5.12H6.5Zm13.005 8.688c-.52.988-1.68 1.568-2.84 1.568-1.768 0-3.11-1.144-3.11-2.815 0-1.69 1.299-2.668 3.62-2.807l2.34-.138v-.615c0-.867-.607-1.369-1.56-1.369-.771 0-1.239.251-1.802.979-.277.312-.597.468-1.004.468-.615 0-1.057-.399-1.057-.97 0-.2.043-.382.13-.572.433-1.109 1.923-1.793 3.845-1.793 2.383 0 3.933 1.23 3.933 3.1v5.293c0 .84-.511 1.273-1.23 1.273-.684 0-1.16-.38-1.213-1.126v-.476h-.052Zm-3.43-1.386c0 .693.572 1.126 1.42 1.126 1.11 0 2.02-.719 2.02-1.723v-.676l-1.959.121c-.944.07-1.48.494-1.48 1.152Z',
|
||||
})
|
||||
@@ -16,11 +16,11 @@ import {useSetThemePrefs, useThemePrefs} from '#/state/shell'
|
||||
import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
|
||||
import {ScrollView} from '#/view/com/util/Views'
|
||||
import {atoms as a, native, useAlf, useTheme} from '#/alf'
|
||||
import {Divider} from '#/components/Divider'
|
||||
import * as Toggle from '#/components/forms/Toggle'
|
||||
import * as ToggleButton from '#/components/forms/ToggleButton'
|
||||
import {Moon_Stroke2_Corner0_Rounded as MoonIcon} from '#/components/icons/Moon'
|
||||
import {Phone_Stroke2_Corner0_Rounded as PhoneIcon} from '#/components/icons/Phone'
|
||||
import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize'
|
||||
import {TitleCase_Stroke2_Corner0_Rounded as Aa} from '#/components/icons/TitleCase'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppearanceSettings'>
|
||||
@@ -35,10 +35,8 @@ export function AppearanceSettingsScreen({}: Props) {
|
||||
const {colorMode, darkTheme} = useThemePrefs()
|
||||
const {setColorMode, setDarkTheme} = useSetThemePrefs()
|
||||
|
||||
const [fontScale, setFontScale] = React.useState(() => fonts.scale !== 1)
|
||||
const [fontFamily, setFontFamily] = React.useState(
|
||||
() => fonts.family === 'theme',
|
||||
)
|
||||
const [fontFamily, setFontFamily] = React.useState(fonts.family)
|
||||
const [fontScale, setFontScale] = React.useState(() => fonts.scale)
|
||||
|
||||
const onChangeAppearance = useCallback(
|
||||
(keys: string[]) => {
|
||||
@@ -65,6 +63,24 @@ export function AppearanceSettingsScreen({}: Props) {
|
||||
[setDarkTheme, darkTheme],
|
||||
)
|
||||
|
||||
const onChangeFontFamily = useCallback(
|
||||
(values: string[]) => {
|
||||
const next = values[0] === 'system' ? 'system' : 'theme'
|
||||
setFontFamily(next)
|
||||
fonts.setFontFamily(next)
|
||||
},
|
||||
[setFontFamily, fonts],
|
||||
)
|
||||
|
||||
const onChangeFontScale = useCallback(
|
||||
(values: string[]) => {
|
||||
const next = values[0] || ('0' as any)
|
||||
setFontScale(next)
|
||||
fonts.setFontScale(next)
|
||||
},
|
||||
[setFontScale, fonts],
|
||||
)
|
||||
|
||||
return (
|
||||
<LayoutAnimationConfig skipExiting skipEntering>
|
||||
<View testID="preferencesThreadsScreen" style={s.hContentRegion}>
|
||||
@@ -87,7 +103,7 @@ export function AppearanceSettingsScreen({}: Props) {
|
||||
<View style={[a.gap_md]}>
|
||||
<View style={[a.flex_row, a.align_center, a.gap_md]}>
|
||||
<PhoneIcon style={t.atoms.text} />
|
||||
<Text style={a.text_md}>
|
||||
<Text style={[a.text_md, a.font_bold]}>
|
||||
<Trans>Mode</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
@@ -120,7 +136,7 @@ export function AppearanceSettingsScreen({}: Props) {
|
||||
style={[a.gap_md]}>
|
||||
<View style={[a.flex_row, a.align_center, a.gap_md]}>
|
||||
<MoonIcon style={t.atoms.text} />
|
||||
<Text style={a.text_md}>
|
||||
<Text style={[a.text_md, a.font_bold]}>
|
||||
<Trans>Dark theme</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
@@ -142,105 +158,80 @@ export function AppearanceSettingsScreen({}: Props) {
|
||||
</ToggleButton.Group>
|
||||
</Animated.View>
|
||||
)}
|
||||
|
||||
{neue && (
|
||||
<>
|
||||
<View style={[a.gap_md]}>
|
||||
<View style={[a.gap_xs]}>
|
||||
<View style={[a.flex_row, a.align_center, a.gap_md]}>
|
||||
<Aa style={t.atoms.text} />
|
||||
<Text style={[a.text_md, a.font_bold]}>
|
||||
<Trans>Font</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={[
|
||||
a.text_sm,
|
||||
a.leading_snug,
|
||||
t.atoms.text_contrast_medium,
|
||||
]}>
|
||||
<Trans>
|
||||
For the best experience, we recommend using the theme
|
||||
font.
|
||||
</Trans>
|
||||
</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]}>
|
||||
<View style={[a.gap_xs]}>
|
||||
<View style={[a.flex_row, a.align_center, a.gap_md]}>
|
||||
<TextSize style={t.atoms.text} />
|
||||
<Text style={[a.text_md, a.font_bold]}>
|
||||
<Trans>Font size</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<ToggleButton.Group
|
||||
label={_(msg`Font`)}
|
||||
values={[fontScale]}
|
||||
onChange={onChangeFontScale}>
|
||||
<ToggleButton.Button label={_(msg`Small`)} name="-1">
|
||||
<ToggleButton.ButtonText>
|
||||
<Trans>Smaller</Trans>
|
||||
</ToggleButton.ButtonText>
|
||||
</ToggleButton.Button>
|
||||
<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>
|
||||
|
||||
{neue && (
|
||||
<View style={[a.gap_lg]}>
|
||||
<Text style={[a.text_lg, a.font_bold]}>Typography</Text>
|
||||
|
||||
<Divider />
|
||||
|
||||
<View
|
||||
style={[
|
||||
a.flex_row,
|
||||
a.align_start,
|
||||
a.justify_between,
|
||||
a.gap_xl,
|
||||
]}>
|
||||
<View style={[a.flex_1, a.gap_xs, {maxWidth: 360}]}>
|
||||
<Text style={[a.text_sm, a.font_bold, a.leading_snug]}>
|
||||
<Trans>Theme font</Trans>
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
a.text_sm,
|
||||
a.leading_snug,
|
||||
t.atoms.text_contrast_medium,
|
||||
]}>
|
||||
<Trans>
|
||||
Enables a consistent typeface for a clean user
|
||||
experience across devices. To use your default system
|
||||
font, disable this.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Toggle.Item
|
||||
name="font"
|
||||
label={_(msg`Use theme font`)}
|
||||
value={fontFamily}
|
||||
onChange={checked => {
|
||||
setFontFamily(checked)
|
||||
fonts.setFontFamily(checked ? 'theme' : 'system')
|
||||
}}>
|
||||
<Toggle.LabelText>
|
||||
{fontFamily ? (
|
||||
<Trans>Enabled</Trans>
|
||||
) : (
|
||||
<Trans>Disabled</Trans>
|
||||
)}
|
||||
</Toggle.LabelText>
|
||||
<Toggle.Switch />
|
||||
</Toggle.Item>
|
||||
</View>
|
||||
|
||||
<Divider />
|
||||
|
||||
<View
|
||||
style={[
|
||||
a.flex_row,
|
||||
a.align_start,
|
||||
a.justify_between,
|
||||
a.gap_xl,
|
||||
]}>
|
||||
<View style={[a.flex_1, a.gap_xs, {maxWidth: 360}]}>
|
||||
<Text style={[a.text_sm, a.font_bold, a.leading_snug]}>
|
||||
<Trans>Theme font size</Trans>
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
a.text_sm,
|
||||
a.leading_snug,
|
||||
t.atoms.text_contrast_medium,
|
||||
]}>
|
||||
<Trans>
|
||||
Subtly scales the type size for a clean user experience
|
||||
across devices. To use the font size defined by your
|
||||
operating system, disable this.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Toggle.Item
|
||||
name="fontScale"
|
||||
label={_(msg`Enable new font scale`)}
|
||||
value={fontScale}
|
||||
onChange={checked => {
|
||||
setFontScale(checked)
|
||||
fonts.setFontScale(checked ? 0.9375 : 1)
|
||||
}}>
|
||||
<Toggle.LabelText>
|
||||
{fontScale ? (
|
||||
<Trans>Enabled</Trans>
|
||||
) : (
|
||||
<Trans>Disabled</Trans>
|
||||
)}
|
||||
</Toggle.LabelText>
|
||||
<Toggle.Switch />
|
||||
</Toggle.Item>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Device data that's specific to the device and does not vary based account
|
||||
*/
|
||||
export type Device = {
|
||||
fontScale: number
|
||||
fontScale: '-2' | '-1' | '0' | '1' | '2'
|
||||
fontFamily: 'system' | 'theme'
|
||||
lastNuxDialog: string | undefined
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ export function Text({
|
||||
// @ts-ignore
|
||||
if (flattened.fontSize) {
|
||||
// @ts-ignore
|
||||
flattened.fontSize = flattened.fontSize * fonts.scale
|
||||
flattened.fontSize = flattened.fontSize * fonts.scaleMultiplier
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -81,7 +81,7 @@ export function Text({
|
||||
// @ts-ignore
|
||||
if (flattened.fontSize) {
|
||||
// @ts-ignore
|
||||
flattened.fontSize = flattened.fontSize * fonts.scale
|
||||
flattened.fontSize = flattened.fontSize * fonts.scaleMultiplier
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user