From 09253457f941522fa1a904370146bd1db594a152 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Tue, 19 May 2026 21:47:54 +0300 Subject: [PATCH] Gate group chat invites on allowGroupInvites (#10546) Co-authored-by: Claude Opus 4.7 (1M context) --- src/components/dms/AddMembersFlow.tsx | 10 +++++++--- src/components/dms/InitiateChatFlow.tsx | 12 +++++++----- .../dms/components/GroupChatProfileCard.tsx | 6 +++--- src/components/dms/util.ts | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/components/dms/AddMembersFlow.tsx b/src/components/dms/AddMembersFlow.tsx index 68f48bcd45..1601594dab 100644 --- a/src/components/dms/AddMembersFlow.tsx +++ b/src/components/dms/AddMembersFlow.tsx @@ -18,7 +18,7 @@ import {type ListMethods} from '#/view/com/util/List' import {android, atoms as a, native, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' -import {canBeMessaged, type ConvoWithDetails} from '#/components/dms/util' +import {canBeAddedToGroup, type ConvoWithDetails} from '#/components/dms/util' import * as Toggle from '#/components/forms/Toggle' import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeftIcon} from '#/components/icons/Arrow' import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' @@ -190,7 +190,9 @@ export function AddMembersFlow({ } _items.sort(item => { - return item.type === 'profile' && canBeMessaged(item.profile) ? -1 : 1 + return item.type === 'profile' && canBeAddedToGroup(item.profile) + ? -1 + : 1 }) } } else { @@ -206,7 +208,9 @@ export function AddMembersFlow({ } _items.sort(item => { - return item.type === 'profile' && canBeMessaged(item.profile) ? -1 : 1 + return item.type === 'profile' && canBeAddedToGroup(item.profile) + ? -1 + : 1 }) } else { for (let i = 0; i < 10; i++) { diff --git a/src/components/dms/InitiateChatFlow.tsx b/src/components/dms/InitiateChatFlow.tsx index bc4824f47c..fdf37be24b 100644 --- a/src/components/dms/InitiateChatFlow.tsx +++ b/src/components/dms/InitiateChatFlow.tsx @@ -20,7 +20,7 @@ import {type ListMethods} from '#/view/com/util/List' import {android, atoms as a, native, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' -import {canBeMessaged} from '#/components/dms/util' +import {canBeAddedToGroup, canBeMessaged} from '#/components/dms/util' import * as TextField from '#/components/forms/TextField' import * as Toggle from '#/components/forms/Toggle' import { @@ -246,6 +246,8 @@ export function InitiateChatFlow({ const items = useMemo(() => { let _items: Item[] = [] + const checker = + chatState === ChatState.NEW_GROUP_CHAT ? canBeAddedToGroup : canBeMessaged if (isError) { _items.push({ @@ -276,7 +278,7 @@ export function InitiateChatFlow({ } _items = _items.sort(item => { - return item.type === 'profile' && canBeMessaged(item.profile) ? -1 : 1 + return item.type === 'profile' && checker(item.profile) ? -1 : 1 }) } } else { @@ -299,7 +301,7 @@ export function InitiateChatFlow({ } _items = _items.sort(item => { - return item.type === 'profile' && canBeMessaged(item.profile) ? -1 : 1 + return item.type === 'profile' && checker(item.profile) ? -1 : 1 }) } else { _items.push(...placeholders) @@ -825,7 +827,7 @@ function GroupChatMemberProfileCard({ moderationOpts: ModerationOpts }) { const t = useTheme() - const enabled = canBeMessaged(profile) + const enabled = canBeAddedToGroup(profile) const handle = sanitizeHandle(profile.handle, '@') return ( @@ -845,7 +847,7 @@ function GroupChatMemberProfileCard({ - {handle} can’t be messaged + {handle} can’t be added )} diff --git a/src/components/dms/components/GroupChatProfileCard.tsx b/src/components/dms/components/GroupChatProfileCard.tsx index 49ef5cc5b0..c5438464e8 100644 --- a/src/components/dms/components/GroupChatProfileCard.tsx +++ b/src/components/dms/components/GroupChatProfileCard.tsx @@ -5,7 +5,7 @@ import {Trans} from '@lingui/react/macro' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import {atoms as a, useTheme} from '#/alf' -import {canBeMessaged} from '#/components/dms/util' +import {canBeAddedToGroup} from '#/components/dms/util' import * as Toggle from '#/components/forms/Toggle' import * as ProfileCard from '#/components/ProfileCard' import {Text} from '#/components/Typography' @@ -19,7 +19,7 @@ export function GroupChatProfileCard({ moderationOpts: ModerationOpts }) { const t = useTheme() - const enabled = canBeMessaged(profile) + const enabled = canBeAddedToGroup(profile) const moderation = moderateProfile(profile, moderationOpts) const handle = sanitizeHandle(profile.handle, '@') const displayName = sanitizeDisplayName( @@ -53,7 +53,7 @@ export function GroupChatProfileCard({ - {handle} can’t be messaged + {handle} can’t be added )} diff --git a/src/components/dms/util.ts b/src/components/dms/util.ts index 0fc11d0d5e..6f11a5c973 100644 --- a/src/components/dms/util.ts +++ b/src/components/dms/util.ts @@ -24,6 +24,20 @@ export function canBeMessaged(profile: bsky.profile.AnyProfileView) { } } +export function canBeAddedToGroup(profile: bsky.profile.AnyProfileView) { + switch (profile.associated?.chat?.allowGroupInvites) { + case 'none': + return false + case 'all': + return true + case 'following': + case undefined: + return Boolean(profile.viewer?.followedBy) + default: + return false + } +} + export function localDateString(date: Date) { // can't use toISOString because it should be in local time const mm = date.getMonth()