This commit is contained in:
Eric Bailey
2024-09-15 12:39:48 -05:00
parent bf509eb6d5
commit 4a0f65c144
7 changed files with 134 additions and 39 deletions
+19
View File
@@ -1,5 +1,24 @@
import {useFonts as defaultUseFonts} from 'expo-font'
import {Device, device} from '#/storage'
export function getFontScale() {
const fontScale = device.get(['fontScale']) || 1
return fontScale
}
export function setFontScale(fontScale: Device['fontScale']) {
device.set(['fontScale'], fontScale)
}
export function getFontFamily() {
return device.get(['fontFamily']) || 'system'
}
export function setFontFamily(fontFamily: Device['fontFamily']) {
device.set(['fontFamily'], fontFamily)
}
export function useFonts() {
return defaultUseFonts({
'Inter-Thin': require('../../assets/fonts/inter/Inter-Thin.otf'),
+57 -20
View File
@@ -2,10 +2,16 @@ import React from 'react'
import {useMediaQuery} from 'react-responsive'
import {useGate} from '#/lib/statsig/statsig'
import {
getFontFamily,
getFontScale,
setFontFamily as persistFontFamily,
setFontScale as persistFontScale,
} from '#/alf/fonts'
import {createThemes, defaultTheme} from '#/alf/themes'
import {Theme, ThemeName} from '#/alf/types'
import {BLUE_HUE, GREEN_HUE, RED_HUE} from '#/alf/util/colorGeneration'
import * as fontScaling from '#/alf/util/fontScaling'
import {Device} from '#/storage'
export {atoms} from '#/alf/atoms'
export * from '#/alf/fonts'
@@ -19,8 +25,12 @@ export type Alf = {
themeName: ThemeName
theme: Theme
themes: ReturnType<typeof createThemes>
fontScale: number
setFontScale: (fontScale: number) => void
fonts: {
scale: Exclude<Device['fontScale'], undefined>
family: Device['fontFamily']
setFontScale: (fontScale: Exclude<Device['fontScale'], undefined>) => void
setFontFamily: (fontFamily: Device['fontFamily']) => void
}
flags: {
neue: boolean
}
@@ -39,8 +49,12 @@ export const Context = React.createContext<Alf>({
positive: GREEN_HUE,
},
}),
fontScale: fontScaling.get(),
setFontScale: () => {},
fonts: {
scale: getFontScale(),
family: getFontFamily(),
setFontScale: () => {},
setFontFamily: () => {},
},
flags: {
neue: false,
},
@@ -52,17 +66,33 @@ export function ThemeProvider({
}: React.PropsWithChildren<{theme: ThemeName}>) {
const gate = useGate()
const [neue] = React.useState(() => gate('typography_neue'))
const [fontScale, setFontScale] = React.useState(() => {
if (!neue) return 1
return fontScaling.get()
})
const setFontScaleAndPersist = React.useCallback(
(fontScale: number) => {
const [fontScale, setFontScale] = React.useState<Alf['fonts']['scale']>(
() => {
if (!neue) return 1
return getFontScale()
},
)
const setFontScaleAndPersist = React.useCallback<
Alf['fonts']['setFontScale']
>(
fontScale => {
setFontScale(fontScale)
fontScaling.set(fontScale)
persistFontScale(fontScale)
},
[setFontScale],
)
const [fontFamily, setFontFamily] = React.useState<Alf['fonts']['family']>(
() => getFontFamily(),
)
const setFontFamilyAndPersist = React.useCallback<
Alf['fonts']['setFontFamily']
>(
fontFamily => {
setFontFamily(fontFamily)
persistFontFamily(fontFamily)
},
[setFontFamily],
)
const themes = React.useMemo(() => {
return createThemes({
hues: {
@@ -80,13 +110,25 @@ export function ThemeProvider({
themes,
themeName: themeName,
theme: themes[themeName],
fontScale,
setFontScale: setFontScaleAndPersist,
fonts: {
scale: fontScale,
family: fontFamily,
setFontScale: setFontScaleAndPersist,
setFontFamily: setFontFamilyAndPersist,
},
flags: {
neue,
},
}),
[themeName, themes, fontScale, setFontScaleAndPersist, neue],
[
themeName,
themes,
neue,
fontScale,
setFontScaleAndPersist,
fontFamily,
setFontFamilyAndPersist,
],
)}>
{children}
</Context.Provider>
@@ -97,11 +139,6 @@ export function useAlf() {
return React.useContext(Context)
}
export function useFontScale() {
const {fontScale, setFontScale} = useAlf()
return {fontScale, setFontScale}
}
export function useTheme(theme?: ThemeName) {
const alf = useAlf()
return React.useMemo(() => {
+14 -5
View File
@@ -3,7 +3,7 @@ import {StyleProp, TextProps as RNTextProps, TextStyle} from 'react-native'
import {UITextView} from 'react-native-uitextview'
import {isNative} from '#/platform/detection'
import {applyFonts, atoms, flatten, useAlf, useTheme, web} from '#/alf'
import {Alf, applyFonts, atoms, flatten, useAlf, useTheme, web} from '#/alf'
export type TextProps = RNTextProps & {
/**
@@ -36,7 +36,15 @@ export function leading<
*/
export function normalizeTextStyles(
styles: StyleProp<TextStyle>,
{fontScale, flags}: {fontScale: number; flags: {neue: boolean}},
{
fontScale,
fontFamily,
flags,
}: {
fontScale: number
fontFamily: Alf['fonts']['family']
flags: {neue: boolean}
},
) {
const s = flatten(styles)
// should always be defined on these components
@@ -50,7 +58,7 @@ export function normalizeTextStyles(
s.lineHeight = s.fontSize
}
if (flags.neue) {
if (flags.neue && fontFamily === 'theme') {
applyFonts(s)
}
@@ -61,10 +69,11 @@ export function normalizeTextStyles(
* Our main text component. Use this most of the time.
*/
export function Text({style, selectable, ...rest}: TextProps) {
const {fontScale, flags} = useAlf()
const {fonts, flags} = useAlf()
const t = useTheme()
const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, flatten(style)], {
fontScale,
fontScale: fonts.scale,
fontFamily: fonts.family,
flags,
})
+40 -2
View File
@@ -10,11 +10,13 @@ import {useLingui} from '@lingui/react'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {s} from '#/lib/styles'
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, useTheme} from '#/alf'
import {atoms as a, native, useAlf, useTheme} from '#/alf'
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'
@@ -22,13 +24,21 @@ import {Text} from '#/components/Typography'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppearanceSettings'>
export function AppearanceSettingsScreen({}: Props) {
const {_} = useLingui()
const t = useTheme()
const {_} = useLingui()
const gate = useGate()
const [neue] = React.useState(() => gate('typography_neue'))
const {isTabletOrMobile} = useWebMediaQueries()
const {fonts} = useAlf()
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 onChangeAppearance = useCallback(
(keys: string[]) => {
const appearance = keys.find(key => key !== colorMode) as
@@ -128,6 +138,34 @@ export function AppearanceSettingsScreen({}: Props) {
</Animated.View>
)}
</View>
{neue && (
<View style={[a.p_xl, a.gap_lg]}>
<Text>Neue options</Text>
<Toggle.Item
name="Font scale"
label="Font scale"
value={fontScale}
onChange={checked => {
setFontScale(checked)
fonts.setFontScale(checked ? 0.9375 : 1)
}}>
<Toggle.LabelText>Enable new font scale</Toggle.LabelText>
<Toggle.Switch />
</Toggle.Item>
<Toggle.Item
name="Font family"
label="Font family"
value={fontFamily}
onChange={checked => {
setFontFamily(checked)
fonts.setFontFamily(checked ? 'theme' : 'system')
}}>
<Toggle.LabelText>Use theme font</Toggle.LabelText>
<Toggle.Switch />
</Toggle.Item>
</View>
)}
</ScrollView>
</View>
</LayoutAnimationConfig>
+2
View File
@@ -2,6 +2,8 @@ import {MMKV} from 'react-native-mmkv'
import {Device} from '#/storage/schema'
export * from '#/storage/schema'
/**
* Generic storage class. DO NOT use this directly. Instead, use the exported
* storage instances below.
+1
View File
@@ -3,5 +3,6 @@
*/
export type Device = {
fontScale: number | undefined
fontFamily: 'system' | 'theme'
lastNuxDialog: string | undefined
}
+1 -12
View File
@@ -54,7 +54,7 @@ import * as Toast from 'view/com/util/Toast'
import {UserAvatar} from 'view/com/util/UserAvatar'
import {ScrollView} from 'view/com/util/Views'
import {DeactivateAccountDialog} from '#/screens/Settings/components/DeactivateAccountDialog'
import {atoms as a, useAlf, useTheme} from '#/alf'
import {atoms as a, useTheme} from '#/alf'
import {useDialogControl} from '#/components/Dialog'
import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings'
import {Email2FAToggle} from './Email2FAToggle'
@@ -133,7 +133,6 @@ function SettingsAccountCard({
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
export function SettingsScreen({}: Props) {
const {setFontScale} = useAlf()
const queryClient = useQueryClient()
const pal = usePalette('default')
const {_} = useLingui()
@@ -820,16 +819,6 @@ export function SettingsScreen({}: Props) {
</TouchableOpacity>
{__DEV__ ? (
<>
<TouchableOpacity
style={[pal.view, styles.linkCardNoIcon]}
onPress={() => setFontScale(0.9375)}
accessibilityRole="button"
accessibilityLabel={_(msg`Set test font scale`)}
accessibilityHint={_(msg`Set test font scale`)}>
<Text type="lg" style={pal.text}>
<Trans>Enable neue font scale</Trans>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[pal.view, styles.linkCardNoIcon]}
onPress={onPressStorybook}