Compare commits

...

3 Commits

Author SHA1 Message Date
Samuel Newman 4c652cf4e2 fix comment 2026-06-05 16:37:03 +03:00
Samuel Newman 9b1c5eb428 fix nested text 2026-06-05 16:36:19 +03:00
Samuel Newman ce7ad9b6fa disable font scaling on fixed-height chat invite cards
thread a hasFixedHeight flag through ChatInvite.Root and its context so
the card, join button, and profile badges disable font scaling when they
live in a fixed-height container, preventing text from overflowing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 14:41:10 +03:00
10 changed files with 46 additions and 24 deletions
@@ -23,7 +23,7 @@ export function ChatInviteEmbed({
style?: StyleProp<ViewStyle>
}) {
return (
<ChatInvite.Root code={code}>
<ChatInvite.Root code={code} hasFixedHeight>
<ChatInviteEmbedBody link={link} onOpen={onOpen} style={style} />
</ChatInvite.Root>
)
@@ -31,7 +31,10 @@ export function JoinRequestEmbed({
if (!resolvedCode) return null
return (
<ChatInvite.Root code={resolvedCode} initialPreview={preview}>
<ChatInvite.Root
code={resolvedCode}
initialPreview={preview}
hasFixedHeight>
<JoinRequestEmbedBody style={style} onOpen={onOpen} />
</ChatInvite.Root>
)
+8 -4
View File
@@ -31,10 +31,12 @@ export function ProfileBadges({
interactive = false,
size,
style,
allowFontScaling = true,
}: ViewStyleProp & {
profile: bsky.profile.AnyProfileView
interactive?: boolean
size: Size
allowFontScaling?: boolean
}) {
const shadowed = useProfileShadow(profile)
const verification = useSimpleVerificationState({profile})
@@ -48,10 +50,12 @@ export function ProfileBadges({
const isOnTheSmallSide = size === 'xs' || size === 'sm'
const verificationIconWidth =
verificationIconSizes[size] * nativeScaleMultiplier * alfScaleMultiplier
const botIconWidth =
botIconSizes[size] * nativeScaleMultiplier * alfScaleMultiplier
const scaleMultiplier = allowFontScaling
? nativeScaleMultiplier * alfScaleMultiplier
: 1
const verificationIconWidth = verificationIconSizes[size] * scaleMultiplier
const botIconWidth = botIconSizes[size] * scaleMultiplier
return (
<View
+3 -1
View File
@@ -23,6 +23,7 @@ export function Text({
title,
dataSet,
numberOfLines,
allowFontScaling = true,
...rest
}: TextProps) {
const {fonts, flags} = useAlf()
@@ -36,7 +37,7 @@ export function Text({
style,
],
{
fontScale: fonts.scaleMultiplier,
fontScale: allowFontScaling ? fonts.scaleMultiplier : 1,
fontFamily: fonts.family,
flags,
},
@@ -57,6 +58,7 @@ export function Text({
numberOfLines,
style: s,
dataSet: Object.assign({tooltip: title}, dataSet || {}),
allowFontScaling,
...rest,
}
+20 -12
View File
@@ -16,7 +16,7 @@ import {useChatInvite} from './Context'
*/
export function Card({size}: {size: 'large' | 'small'}) {
const t = useTheme()
const {preview} = useChatInvite()
const {preview, hasFixedHeight} = useChatInvite()
if (!preview) return null
@@ -31,14 +31,15 @@ export function Card({size}: {size: 'large' | 'small'}) {
<Text
emoji
style={[size === 'large' ? a.text_lg : a.text_md, a.font_bold]}
numberOfLines={1}>
numberOfLines={1}
allowFontScaling={!hasFixedHeight}>
{preview.name}
</Text>
<View style={[a.flex_row, a.align_center, a.gap_sm]}>
<Text
style={[a.text_2xs, a.font_medium, t.atoms.text_contrast_high]}
allowFontScaling
numberOfLines={1}>
numberOfLines={1}
allowFontScaling={!hasFixedHeight}>
<Trans>Group chat</Trans>
</Text>
<Text
@@ -48,8 +49,8 @@ export function Card({size}: {size: 'large' | 'small'}) {
a.font_medium,
t.atoms.text_contrast_high,
]}
allowFontScaling
numberOfLines={1}>
numberOfLines={1}
allowFontScaling={!hasFixedHeight}>
<Trans comment="The number of members in a group chat, in the format '{members}/{total} members'.">
{preview.memberCount}/{preview.memberLimit}{' '}
<Plural
@@ -70,17 +71,24 @@ export function Card({size}: {size: 'large' | 'small'}) {
<Text
emoji
style={[a.flex_shrink, a.text_sm, a.font_medium]}
allowFontScaling
numberOfLines={1}>
numberOfLines={1}
allowFontScaling={!hasFixedHeight}>
<Trans comment="The group chat creator, in the format 'By {displayName}'.">
By <Text style={[a.font_medium]}>{ownerDisplayName}</Text>
By{' '}
<Text style={[a.font_medium]} allowFontScaling={!hasFixedHeight}>
{ownerDisplayName}
</Text>
</Trans>
</Text>
<ProfileBadges profile={preview.owner} size="sm" />
<ProfileBadges
profile={preview.owner}
size="sm"
allowFontScaling={!hasFixedHeight}
/>
<Text
style={[a.flex_shrink, t.atoms.text_contrast_medium]}
allowFontScaling
numberOfLines={1}>
numberOfLines={1}
allowFontScaling={!hasFixedHeight}>
{ownerHandle}
</Text>
</View>
@@ -32,6 +32,8 @@ export type ChatInviteContextValue = {
* preview to act on.
*/
action: ChatInviteAction | undefined
/** Whether the invite is rendered inside a fixed-height container; when true, text inside disables font scaling so the card doesn't overflow. */
hasFixedHeight: boolean
}
const ChatInviteContext = createContext<ChatInviteContextValue | null>(null)
+2 -2
View File
@@ -17,7 +17,7 @@ export function JoinButton({
onPress?: () => void
style?: StyleProp<ViewStyle>
}) {
const {action} = useChatInvite()
const {action, hasFixedHeight} = useChatInvite()
if (!action) return null
@@ -35,7 +35,7 @@ export function JoinButton({
disabled={action.disabled}
style={[a.w_full, style]}>
{action.side === 'left' && <ButtonIcon icon={action.icon} />}
<ButtonText>{action.label}</ButtonText>
<ButtonText allowFontScaling={!hasFixedHeight}>{action.label}</ButtonText>
{action.side === 'right' && <ButtonIcon icon={action.icon} />}
</Button>
)
+3 -1
View File
@@ -30,6 +30,7 @@ export function Root({
code,
initialPreview,
currentConvoId,
hasFixedHeight,
children,
}: {
code: string
@@ -40,6 +41,7 @@ export function Root({
* open/join (you're already here).
*/
currentConvoId?: string
hasFixedHeight: boolean
children: React.ReactNode
}) {
const {hasSession} = useSession()
@@ -137,7 +139,7 @@ export function Root({
return (
<ChatInviteProvider
value={{code, loading, error: !!error, preview, action}}>
value={{code, loading, error: !!error, preview, action, hasFixedHeight}}>
{children}
</ChatInviteProvider>
)
@@ -74,7 +74,8 @@ let MessageItemInviteEmbed = ({
<ChatInvite.Root
code={embed.joinLinkPreview.code}
initialPreview={embed.joinLinkPreview}
currentConvoId={convo.convo.view.id}>
currentConvoId={convo.convo.view.id}
hasFixedHeight={false}>
<ChatInvite.Card size="small" />
<ChatInvite.JoinButton />
</ChatInvite.Root>
@@ -273,7 +273,7 @@ function MessageInputInviteEmbed({
const {t: l} = useLingui()
return (
<ChatInvite.Root code={code}>
<ChatInvite.Root code={code} hasFixedHeight={false}>
<View
style={[
a.flex_1,