Fix Android thread number alignment across font scales (#11667)
This commit is contained in:
@@ -2,13 +2,35 @@ import {Text, View} from 'react-native'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {atoms as a, ios, platform, useTheme} from '#/alf'
|
||||
import {useNativeFontScale} from '#/alf/util/dimensions'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
/**
|
||||
* How far the inline badge is nudged below the text baseline. Android's
|
||||
* Map of Android font scale values to inline offsets.
|
||||
*/
|
||||
const ANDROID_INLINE_OFFSETS = [
|
||||
[0.85, 2],
|
||||
[1, 4],
|
||||
[1.15, 6],
|
||||
[1.3, 8],
|
||||
[1.5, 10],
|
||||
[1.8, 12],
|
||||
[2, 14],
|
||||
] as const
|
||||
|
||||
/**
|
||||
* Max amount the inline badge is nudged below the text baseline. Android's
|
||||
* containing `RichText` reserves matching room via `suffixOffset`.
|
||||
*/
|
||||
export const POST_NUMBER_INLINE_OFFSET = 6
|
||||
export const POST_NUMBER_INLINE_OFFSET = 14
|
||||
|
||||
function getAndroidInlineOffset(fontScale: number) {
|
||||
return ANDROID_INLINE_OFFSETS.reduce((nearest, candidate) =>
|
||||
Math.abs(candidate[0] - fontScale) < Math.abs(nearest[0] - fontScale)
|
||||
? candidate
|
||||
: nearest,
|
||||
)[1]
|
||||
}
|
||||
|
||||
export type ThreadItemPostNumbering = Pick<
|
||||
app.bsky.unspecced.defs.ThreadItemPost,
|
||||
@@ -39,6 +61,7 @@ export function ThreadItemPostNumber({
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {t: l} = useLingui()
|
||||
const nativeFontScale = useNativeFontScale()
|
||||
const shouldRender = useHasThreadItemPostNumber(value)
|
||||
const index = value?.opThreadPostIndex
|
||||
const count = value?.opThreadPostCount
|
||||
@@ -61,11 +84,27 @@ export function ThreadItemPostNumber({
|
||||
},
|
||||
inline
|
||||
? platform({
|
||||
android: {transform: [{translateY: POST_NUMBER_INLINE_OFFSET}]},
|
||||
ios: {transform: [{translateY: a.py_2xs.paddingBottom}]},
|
||||
android: {
|
||||
/*
|
||||
* Android aligns the inline view's bottom to the surrounding
|
||||
* text baseline.
|
||||
* We want it to align the inline view's child/text baseline.
|
||||
*/
|
||||
transform: [
|
||||
{translateY: getAndroidInlineOffset(nativeFontScale)},
|
||||
],
|
||||
},
|
||||
ios: {
|
||||
/*
|
||||
* For iOS, we just need to offset the padding we applied.
|
||||
*/
|
||||
transform: [{translateY: a.py_2xs.paddingBottom}],
|
||||
},
|
||||
web: {
|
||||
// Inline views inherit the surrounding line height on web. Keep
|
||||
// the badge at its usual size when emoji-only text enlarges it.
|
||||
/*
|
||||
* Inline views inherit the surrounding line height on web. Keep
|
||||
* the badge at its usual size when emoji-only text enlarges it.
|
||||
*/
|
||||
lineHeight: a.text_xs.fontSize * a.leading_normal.lineHeight,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user