Potentially fix disappearing chat emoji on some devices (#11113)

This commit is contained in:
DS Boyce
2026-07-10 02:40:54 -07:00
committed by GitHub
parent 5e6b693294
commit f1b2bcd638
+27 -8
View File
@@ -246,6 +246,8 @@ let MessageItem = ({
const rt = new RichTextAPI({text: message.text, facets: message.facets}) const rt = new RichTextAPI({text: message.text, facets: message.facets})
const isEmojiOnly = isOnlyEmoji(message.text)
const hasEmbed = const hasEmbed =
AppBskyEmbedRecord.isView(message.embed) || AppBskyEmbedRecord.isView(message.embed) ||
ChatBskyEmbedJoinLink.isView(message.embed) ChatBskyEmbedJoinLink.isView(message.embed)
@@ -261,16 +263,33 @@ let MessageItem = ({
const topRadiusSV = useSharedValue(targetTopRadius) const topRadiusSV = useSharedValue(targetTopRadius)
const showDisplayName = const showDisplayName =
isGroupChat && !isFromSelf && isFirstInCluster && !isOnlyEmoji(message.text) isGroupChat && !isFromSelf && isFirstInCluster && !isEmojiOnly
const showAvatar = isGroupChat && !isFromSelf && isLastInCluster const showAvatar = isGroupChat && !isFromSelf && isLastInCluster
/*
* Emoji-only messages have no bubble background (see the `!isOnlyEmoji` gate
* on the bubble styling below), so the corner-radius animation is invisible
* overhead for them. Worse, on Android the resulting re-layout of the parent
* Animated.View re-measures the enlarged emoji `<Text>` and some Android
* device's text stack drops the trailing glyph on that second pass (while
* keeping its reserved width). Set the radii directly for emoji-only messages
* so nothing re-lays-out the glyph after its initial paint.
*/
useEffect(() => { useEffect(() => {
bottomRadiusSV.set(withTiming(targetBottomRadius, {duration: 300})) bottomRadiusSV.set(
}, [targetBottomRadius, bottomRadiusSV]) isEmojiOnly
? targetBottomRadius
: withTiming(targetBottomRadius, {duration: 300}),
)
}, [targetBottomRadius, bottomRadiusSV, isEmojiOnly])
useEffect(() => { useEffect(() => {
topRadiusSV.set(withTiming(targetTopRadius, {duration: 300})) topRadiusSV.set(
}, [targetTopRadius, topRadiusSV]) isEmojiOnly
? targetTopRadius
: withTiming(targetTopRadius, {duration: 300}),
)
}, [targetTopRadius, topRadiusSV, isEmojiOnly])
// Flash the message background when it's been scrolled to (e.g. by tapping a // Flash the message background when it's been scrolled to (e.g. by tapping a
// reply that quotes it), so it's easy to spot. Keyed on the highlight `key` // reply that quotes it), so it's easy to spot. Keyed on the highlight `key`
@@ -521,7 +540,7 @@ let MessageItem = ({
accessibilityHint={l`Double tap or long press the message to add a reaction`} accessibilityHint={l`Double tap or long press the message to add a reaction`}
style={[ style={[
!isFromSelf && isGroupChat && a.ml_sm, !isFromSelf && isGroupChat && a.ml_sm,
!isOnlyEmoji(message.text) && [ !isEmojiOnly && [
a.rounded_xl, a.rounded_xl,
a.py_sm, a.py_sm,
a.px_md, a.px_md,
@@ -536,7 +555,7 @@ let MessageItem = ({
highlightStyle, highlightStyle,
], ],
]}> ]}>
{replyTo && !isOnlyEmoji(message.text) ? ( {replyTo && !isEmojiOnly ? (
<ReplyQuote <ReplyQuote
replyTo={replyTo} replyTo={replyTo}
isFromSelf={isFromSelf} isFromSelf={isFromSelf}
@@ -553,7 +572,7 @@ let MessageItem = ({
// glyph, then pull the bottom up by the same amount so // glyph, then pull the bottom up by the same amount so
// the glyph bottom-aligns with the avatar instead of // the glyph bottom-aligns with the avatar instead of
// sitting above its line-box baseline. // sitting above its line-box baseline.
isOnlyEmoji(message.text) && [ isEmojiOnly && [
a.leading_tight, a.leading_tight,
// Visually align bottom of the emoji with the avatar // Visually align bottom of the emoji with the avatar
!isFromSelf && !isFromSelf &&