diff options
author | Samuel Newman <mozzius@protonmail.com> | 2025-03-28 16:34:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-28 07:34:07 -0700 |
commit | 152bc3c1ec74fadc687efe97361ae7b1b5bd73c3 (patch) | |
tree | 14ed8a0bc97a040cc24ea685dad56205a8beca30 /src/components/dms/MessageItem.tsx | |
parent | 55a40c2436b68dea850e54a65c5dd197132c08e4 (diff) | |
download | voidsky-152bc3c1ec74fadc687efe97361ae7b1b5bd73c3.tar.zst |
[DMs] Reactions - link up API (attempt 2) (#8074)
* update package * wire up APIs * get reactions to display * allow removing emoji * handle limits better * listen to reactions in log * update convo list with reactions * tweaks to reaction display * Handle empty message fallback case * update package * shift reacts up by 2px --------- Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/components/dms/MessageItem.tsx')
-rw-r--r-- | src/components/dms/MessageItem.tsx | 93 |
1 files changed, 88 insertions, 5 deletions
diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx index 675b6a5ee..60b0b5ed6 100644 --- a/src/components/dms/MessageItem.tsx +++ b/src/components/dms/MessageItem.tsx @@ -1,23 +1,36 @@ import React, {useCallback, useMemo} from 'react' -import {GestureResponderEvent, StyleProp, TextStyle, View} from 'react-native' +import { + type GestureResponderEvent, + type StyleProp, + type TextStyle, + View, +} from 'react-native' +import Animated, { + LayoutAnimationConfig, + LinearTransition, + ZoomIn, + ZoomOut, +} from 'react-native-reanimated' import { AppBskyEmbedRecord, ChatBskyConvoDefs, RichText as RichTextAPI, } from '@atproto/api' -import {I18n} from '@lingui/core' +import {type I18n} from '@lingui/core' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {ConvoItem} from '#/state/messages/convo/types' +import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {useConvoActive} from '#/state/messages/convo' +import {type ConvoItem} from '#/state/messages/convo/types' import {useSession} from '#/state/session' import {TimeElapsed} from '#/view/com/util/TimeElapsed' -import {atoms as a, useTheme} from '#/alf' +import {atoms as a, native, useTheme} from '#/alf' import {isOnlyEmoji} from '#/alf/typography' import {ActionsWrapper} from '#/components/dms/ActionsWrapper' import {InlineLinkText} from '#/components/Link' +import {RichText} from '#/components/RichText' import {Text} from '#/components/Typography' -import {RichText} from '../RichText' import {DateDivider} from './DateDivider' import {MessageItemEmbed} from './MessageItemEmbed' import {localDateString} from './util' @@ -29,6 +42,8 @@ let MessageItem = ({ }): React.ReactNode => { const t = useTheme() const {currentAccount} = useSession() + const {_} = useLingui() + const {convo} = useConvoActive() const {message, nextMessage, prevMessage} = item const isPending = item.type === 'pending-message' @@ -134,6 +149,74 @@ let MessageItem = ({ )} </ActionsWrapper> + <LayoutAnimationConfig skipEntering skipExiting> + {message.reactions && message.reactions.length > 0 && ( + <View + style={[ + isFromSelf ? a.align_end : a.align_start, + a.px_xs, + a.pb_2xs, + ]}> + <View + style={[ + a.flex_row, + a.gap_2xs, + a.py_xs, + a.px_xs, + a.justify_center, + isFromSelf ? a.justify_end : a.justify_start, + a.flex_wrap, + a.pb_xs, + t.atoms.bg, + a.rounded_lg, + a.border, + t.atoms.border_contrast_low, + {marginTop: -6}, + ]}> + {message.reactions.map((reaction, _i, reactions) => { + let label + if (reaction.sender.did === currentAccount?.did) { + label = _(msg`You reacted ${reaction.value}`) + } else { + const senderDid = reaction.sender.did + const sender = convo.members.find( + member => member.did === senderDid, + ) + if (sender) { + label = _( + msg`${sanitizeDisplayName( + sender.displayName || sender.handle, + )} reacted ${reaction.value}`, + ) + } else { + label = _(msg`Someone reacted ${reaction.value}`) + } + } + return ( + <Animated.View + entering={native(ZoomIn.springify(200).delay(400))} + exiting={ + reactions.length > 1 && native(ZoomOut.delay(200)) + } + layout={native(LinearTransition.delay(300))} + key={reaction.sender.did + reaction.value} + style={[a.p_2xs]} + accessible={true} + accessibilityLabel={label} + accessibilityHint={_( + msg`Double tap or long press the message to add a reaction`, + )}> + <Text emoji style={[a.text_sm]}> + {reaction.value} + </Text> + </Animated.View> + ) + })} + </View> + </View> + )} + </LayoutAnimationConfig> + {isLastInGroup && ( <MessageItemMetadata item={item} |