From 6fc31eeb48daadfcaf2553a40e942d6ebf307c11 Mon Sep 17 00:00:00 2001 From: DS Boyce <260543580+ds-boyce@users.noreply.github.com> Date: Thu, 23 Apr 2026 09:30:50 -0700 Subject: [PATCH] Clean up minor issues in MessgeItem (#10338) --- src/components/dms/MessageItem.tsx | 150 +++++++++++++---------------- 1 file changed, 69 insertions(+), 81 deletions(-) diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx index 223390b996..afbd4bfcd2 100644 --- a/src/components/dms/MessageItem.tsx +++ b/src/components/dms/MessageItem.tsx @@ -1,4 +1,4 @@ -import {memo, useCallback, useEffect, useMemo, useRef} from 'react' +import {memo, useEffect, useMemo, useRef} from 'react' import { type GestureResponderEvent, LayoutAnimation, @@ -28,9 +28,8 @@ import {plural} from '@lingui/core/macro' import {Trans, useLingui} from '@lingui/react/macro' import {useQueryClient} from '@tanstack/react-query' +import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' import {makeProfileLink} from '#/lib/routes/links' -import {sanitizeDisplayName} from '#/lib/strings/display-names' -import {sanitizeHandle} from '#/lib/strings/handles' import {useConvoActive} from '#/state/messages/convo' import {type ConvoItem} from '#/state/messages/convo/types' import {useModerationOpts} from '#/state/preferences/moderation-opts' @@ -59,7 +58,9 @@ const DISPLAY_NAME_INSET = 22 const CLUSTERED_MESSAGE_THRESHOLD_MS = 5 * 60 * 1000 const MESSAGE_GAP_THRESHOLD_MS = 60 * 60 * 1000 -function isWithinCluster({ +const TAP_AND_DRAG_DELAY_MS = 100 + +function isWithinClusterBoundary({ isPending, adjacentMessage, isFromSameSender, @@ -111,43 +112,38 @@ let MessageItem = ({ const {message, nextMessage, prevMessage} = item const isPending = item.type === 'pending-message' - const displayName = sanitizeDisplayName( - profile?.displayName || sanitizeHandle(profile?.handle ?? ''), - ) + const displayName = profile ? createSanitizedDisplayName(profile) : null - const isFromSelf = message.sender?.did === currentAccount?.did + const isFromSelf = + message.sender?.did != null && message.sender.did === currentAccount?.did const prevIsMessage = ChatBskyConvoDefs.isMessageView(prevMessage) const nextIsMessage = ChatBskyConvoDefs.isMessageView(nextMessage) const isPrevFromSameSender = - prevIsMessage && prevMessage.sender?.did === message.sender?.did + prevIsMessage && + prevMessage.sender?.did === message.sender?.did && + message.sender?.did != null const isNextFromSameSender = - nextIsMessage && nextMessage.sender?.did === message.sender?.did + nextIsMessage && + nextMessage.sender?.did === message.sender?.did && + message.sender?.did != null - const isFirstInCluster = useMemo( - () => - isWithinCluster({ - isPending, - adjacentMessage: prevMessage, - isFromSameSender: isPrevFromSameSender, - currentSentAt: message.sentAt, - direction: 'prev', - }), - [isPending, prevMessage, isPrevFromSameSender, message.sentAt], - ) + const isFirstInCluster = isWithinClusterBoundary({ + isPending, + adjacentMessage: prevMessage, + isFromSameSender: isPrevFromSameSender, + currentSentAt: message.sentAt, + direction: 'prev', + }) - const isLastInCluster = useMemo( - () => - isWithinCluster({ - isPending, - adjacentMessage: nextMessage, - isFromSameSender: isNextFromSameSender, - currentSentAt: message.sentAt, - direction: 'next', - }), - [isPending, nextMessage, isNextFromSameSender, message.sentAt], - ) + const isLastInCluster = isWithinClusterBoundary({ + isPending, + adjacentMessage: nextMessage, + isFromSameSender: isNextFromSameSender, + currentSentAt: message.sentAt, + direction: 'next', + }) const hasLargeGapFromPrev = !ChatBskyConvoDefs.isMessageView(prevMessage) || @@ -159,7 +155,6 @@ let MessageItem = ({ const isDateDividerToggled = isDividerToggled(message.id) const isNextDateDividerToggled = nextMessage != null && isDividerToggled(nextMessage.id) - const showDateDivider = hasLargeGapFromPrev const effectiveFirstInCluster = isFirstInCluster || isDateDividerToggled const effectiveLastInCluster = isLastInCluster || isNextDateDividerToggled @@ -169,9 +164,7 @@ let MessageItem = ({ const hasReactions = message.reactions && message.reactions.length > 0 const prevHasReactions = - prevIsMessage && - prevMessage.reactions != null && - prevMessage.reactions.length > 0 + prevIsMessage && prevMessage.reactions && prevMessage.reactions.length > 0 const squaredBottomCorner = !hasReactions && isInCluster && @@ -183,9 +176,7 @@ let MessageItem = ({ const pendingColor = t.palette.primary_300 - const rt = useMemo(() => { - return new RichTextAPI({text: message.text, facets: message.facets}) - }, [message.text, message.facets]) + const rt = new RichTextAPI({text: message.text, facets: message.facets}) const hasEmbedAndText = AppBskyEmbedRecord.isView(message.embed) && rt.text.length > 0 @@ -225,27 +216,26 @@ let MessageItem = ({ }, ) - const avatar = profile ? ( - unstableCacheProfileView(queryClient, profile)}> - - - ) : ( - - ) + const avatar = + profile && moderationOpts ? ( + unstableCacheProfileView(queryClient, profile)}> + + + ) : ( + + ) const groupedReactions = useMemo(() => { const reactions = message.reactions ?? [] @@ -287,11 +277,11 @@ let MessageItem = ({ return l`You reacted ${reaction.value}` } else { const senderDid = reaction.sender.did - const sender = convo.members.find(member => member.did === senderDid) - if (sender) { - return l`${sanitizeDisplayName( - sender.displayName || sender.handle, - )} reacted ${reaction.value}` + const memberSender = convo.members.find( + member => member.did === senderDid, + ) + if (memberSender) { + return l`${createSanitizedDisplayName(memberSender)} reacted ${reaction.value}` } return l`Someone reacted ${reaction.value}` } @@ -343,14 +333,16 @@ let MessageItem = ({ // Include a delay here to account for tap-and-drag before release. setTimeout(() => { reactionTapRef.current = false - }, 100) + }, TAP_AND_DRAG_DELAY_MS) }} - onPress={() => (isGroupChat ? reactionsControl.open() : undefined)}> + onPress={isGroupChat ? reactionsControl.open : undefined}> {groupedReactions.map(group => ( 1 && native(ZoomOut.delay(200)) + groupedReactions.length > 1 + ? native(ZoomOut.delay(200)) + : undefined } layout={native(LinearTransition.delay(300))} key={group.value} @@ -399,7 +391,7 @@ let MessageItem = ({ return ( <> - {(showDateDivider || isDateDividerToggled) && ( + {(hasLargeGapFromPrev || isDateDividerToggled) && ( @@ -424,7 +416,7 @@ let MessageItem = ({ a.flex_grow, !isFromSelf && isGroupChat && {paddingLeft: AVATAR_SIZE}, ]}> - {showDisplayName ? ( + {displayName && showDisplayName ? ( { - if (item.type === 'pending-message' && item.retry) { - e.preventDefault() - item.retry() - return false - } - }, - [item], - ) + const handleRetry = (e: GestureResponderEvent) => { + if (item.type === 'pending-message' && item.retry) { + e.preventDefault() + item.retry() + return false + } + } const errorColor = t.palette.negative_400