[Chat] Prevent reactions when unavailable (#10615)
This commit is contained in:
@@ -1,7 +1,15 @@
|
||||
import {type $Typed, ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {
|
||||
type $Typed,
|
||||
ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
moderateProfile,
|
||||
type ModerationOpts,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {type Shadow} from '#/state/cache/profile-shadow'
|
||||
import {type ConvoState, ConvoStatus} from '#/state/messages/convo/types'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
export const MESSAGE_GAP_THRESHOLD_MS = 60 * 60 * 1000
|
||||
@@ -31,8 +39,9 @@ export function canBeAddedToGroup(profile: bsky.profile.AnyProfileView) {
|
||||
case 'all':
|
||||
return true
|
||||
case 'following':
|
||||
case undefined:
|
||||
return Boolean(profile.viewer?.followedBy)
|
||||
case undefined:
|
||||
return canBeMessaged(profile)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -73,6 +82,55 @@ export function hasReachedReactionLimit(
|
||||
return myReactions.length >= EMOJI_REACTION_LIMIT
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the active conversation accepts emoji reactions. Reactions are
|
||||
* unavailable when:
|
||||
* - the convo is in the disabled state
|
||||
* - a group convo is locked or permanently locked
|
||||
* - 1-1: the other user is blocked or is blocking us
|
||||
* - group: we are blocking the primary member (the owner)
|
||||
*/
|
||||
export function canReact({
|
||||
convoState,
|
||||
primaryMember,
|
||||
moderationOpts,
|
||||
}: {
|
||||
convoState: ConvoState
|
||||
primaryMember: Shadow<bsky.profile.AnyProfileView> | undefined
|
||||
moderationOpts: ModerationOpts | undefined
|
||||
}): boolean {
|
||||
if (convoState.status === ConvoStatus.Disabled) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!convoState.convo) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (convoState.convo.kind === 'group') {
|
||||
const {lockStatus} = convoState.convo.details
|
||||
if (lockStatus === 'locked' || lockStatus === 'locked-permanently') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (primaryMember && moderationOpts) {
|
||||
const moderation = moderateProfile(primaryMember, moderationOpts)
|
||||
if (convoState.convo.kind === 'direct') {
|
||||
// Either direction (blocking or blocked-by) hides reactions in 1-1s
|
||||
if (moderation.blocked) return false
|
||||
} else {
|
||||
// In groups, only "we are blocking" the owner hides reactions
|
||||
const isBlockingPrimary = moderation
|
||||
.ui('profileView')
|
||||
.alerts.some(alert => alert.type === 'blocking')
|
||||
if (isBlockingPrimary) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export type GroupConvoMember = ChatBskyActorDefs.ProfileViewBasic & {
|
||||
// can be missing if account deleted
|
||||
kind?: $Typed<ChatBskyActorDefs.GroupConvoMember>
|
||||
|
||||
Reference in New Issue
Block a user