[Chat] Prevent reactions when unavailable (#10615)
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import {useCallback, useRef, useState} from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type ChatBskyConvoDefs, type ModerationOpts} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
import {useSession} from '#/state/session'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
@@ -12,19 +13,21 @@ import {EmojiSmile_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components
|
||||
import * as Toast from '#/components/Toast'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {EmojiReactionPicker} from './EmojiReactionPicker'
|
||||
import {hasReachedReactionLimit} from './util'
|
||||
import {canReact, hasReachedReactionLimit} from './util'
|
||||
|
||||
export function ActionsWrapper({
|
||||
message,
|
||||
hasReactions,
|
||||
isFromSelf,
|
||||
senderProfile,
|
||||
moderationOpts,
|
||||
children,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
hasReactions?: boolean
|
||||
isFromSelf: boolean
|
||||
senderProfile?: bsky.profile.AnyProfileView
|
||||
moderationOpts: ModerationOpts | undefined
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const viewRef = useRef(null)
|
||||
@@ -32,6 +35,12 @@ export function ActionsWrapper({
|
||||
const {t: l} = useLingui()
|
||||
const convo = useConvoActive()
|
||||
const {currentAccount} = useSession()
|
||||
const primaryMember = useMaybeProfileShadow(convo.convo.primaryMember)
|
||||
const reactionsAvailable = canReact({
|
||||
convoState: convo,
|
||||
primaryMember,
|
||||
moderationOpts,
|
||||
})
|
||||
|
||||
const [showActions, setShowActions] = useState(false)
|
||||
|
||||
@@ -93,29 +102,34 @@ export function ActionsWrapper({
|
||||
: [a.ml_xs, {marginRight: 'auto'}],
|
||||
hasReactions ? [a.mb_2xl] : undefined,
|
||||
]}>
|
||||
<EmojiReactionPicker message={message} onEmojiSelect={onEmojiSelect}>
|
||||
{({props, state, IS_NATIVE, control}) => {
|
||||
// always false, file is platform split
|
||||
if (IS_NATIVE) return null
|
||||
const showMenuTrigger = showActions || control.isOpen ? 1 : 0
|
||||
return (
|
||||
<Pressable
|
||||
{...props}
|
||||
style={[
|
||||
{opacity: showMenuTrigger},
|
||||
a.p_xs,
|
||||
a.rounded_full,
|
||||
(state.hovered || state.pressed) && t.atoms.bg_contrast_25,
|
||||
]}>
|
||||
<EmojiSmileIcon
|
||||
size="md"
|
||||
style={t.atoms.text_contrast_medium}
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
}}
|
||||
</EmojiReactionPicker>
|
||||
<MessageContextMenu message={message} senderProfile={senderProfile}>
|
||||
{reactionsAvailable && (
|
||||
<EmojiReactionPicker message={message} onEmojiSelect={onEmojiSelect}>
|
||||
{({props, state, IS_NATIVE, control}) => {
|
||||
// always false, file is platform split
|
||||
if (IS_NATIVE) return null
|
||||
const showMenuTrigger = showActions || control.isOpen ? 1 : 0
|
||||
return (
|
||||
<Pressable
|
||||
{...props}
|
||||
style={[
|
||||
{opacity: showMenuTrigger},
|
||||
a.p_xs,
|
||||
a.rounded_full,
|
||||
(state.hovered || state.pressed) && t.atoms.bg_contrast_25,
|
||||
]}>
|
||||
<EmojiSmileIcon
|
||||
size="md"
|
||||
style={t.atoms.text_contrast_medium}
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
}}
|
||||
</EmojiReactionPicker>
|
||||
)}
|
||||
<MessageContextMenu
|
||||
message={message}
|
||||
senderProfile={senderProfile}
|
||||
moderationOpts={moderationOpts}>
|
||||
{({props, state, IS_NATIVE, control}) => {
|
||||
// always false, file is platform split
|
||||
if (IS_NATIVE) return null
|
||||
|
||||
Reference in New Issue
Block a user