Align group invite settings with eligibility logic (#10748)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-06-05 18:10:14 +03:00
committed by GitHub
parent 7d4d7642fd
commit 67ed59fbcd
4 changed files with 41 additions and 10 deletions
+16
View File
@@ -47,6 +47,22 @@ export function canBeAddedToGroup(profile: bsky.profile.AnyProfileView) {
}
}
/**
* Resolves the effective `allowGroupInvites` value for a chat declaration.
* When unset, group invites follow the general DM preference
* (`allowIncoming`), which itself defaults to `following`. This mirrors the
* `undefined` fallthrough in canBeAddedToGroup, and is the single source of
* truth for both displaying and persisting the setting.
*/
export function resolveAllowGroupInvites(
chat: {allowIncoming?: string; allowGroupInvites?: string} | undefined,
): 'all' | 'none' | 'following' {
return (chat?.allowGroupInvites ?? chat?.allowIncoming ?? 'following') as
| 'all'
| 'none'
| 'following'
}
export function localDateString(date: Date) {
// can't use toISOString because it should be in local time
const mm = date.getMonth()
+2 -4
View File
@@ -13,6 +13,7 @@ import {AgeRestrictedScreen} from '#/components/ageAssurance/AgeRestrictedScreen
import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy'
import * as Dialog from '#/components/Dialog'
import {Divider} from '#/components/Divider'
import {resolveAllowGroupInvites} from '#/components/dms/util'
import * as Toggle from '#/components/forms/Toggle'
import {Bell_Stroke2_Corner0_Rounded as BellIcon} from '#/components/icons/Bell'
import {Car_Stroke2_Corner2_Rounded as CarIcon} from '#/components/icons/Car'
@@ -199,10 +200,7 @@ export function MessagesSettingsScreenInner({}: Props) {
<Toggle.Group
label={l`Allow group chat invites from`}
type="radio"
values={[
(profile?.associated?.chat
?.allowGroupInvites as AllowIncoming) ?? 'following',
]}
values={[resolveAllowGroupInvites(profile?.associated?.chat)]}
onChange={onSelectGroupInvitesFrom}>
<View>
{allowGroupInvitesFromOptions.map(option => (
@@ -483,7 +483,7 @@ function BaseChatItem({
to={`/messages/${convo.view.id}`}
// In split view, this list stays mounted alongside the open convo,
// so push would stack duplicate routes on repeated clicks.
action={isWithinSplitView ? 'navigate' : 'push'}
action={isWithinLeftPanel ? 'navigate' : 'push'}
label={title}
accessibilityHint={accessibilityHint}
accessibilityActions={
@@ -7,6 +7,7 @@ import {useMutation, useQueryClient} from '@tanstack/react-query'
import {logger} from '#/logger'
import {useAgent, useSession} from '#/state/session'
import {resolveAllowGroupInvites} from '#/components/dms/util'
import {RQKEY as PROFILE_RKEY} from '../profile'
export function useUpdateActorDeclaration({
@@ -34,8 +35,12 @@ export function useUpdateActorDeclaration({
update.allowIncoming ??
current?.associated?.chat?.allowIncoming ??
'following'
const allowGroupInvites =
update.allowGroupInvites ?? current?.associated?.chat?.allowGroupInvites
const allowGroupInvites = resolveAllowGroupInvites({
allowIncoming,
allowGroupInvites:
update.allowGroupInvites ??
current?.associated?.chat?.allowGroupInvites,
})
const result = await agent.com.atproto.repo.putRecord({
repo: currentAccount.did,
collection: 'chat.bsky.actor.declaration',
@@ -43,7 +48,7 @@ export function useUpdateActorDeclaration({
record: {
$type: 'chat.bsky.actor.declaration',
allowIncoming,
...(allowGroupInvites && {allowGroupInvites}),
allowGroupInvites,
},
})
return result
@@ -54,14 +59,26 @@ export function useUpdateActorDeclaration({
PROFILE_RKEY(currentAccount?.did),
(old?: AppBskyActorDefs.ProfileViewDetailed) => {
if (!old) return old
const allowIncoming =
update.allowIncoming ??
old.associated?.chat?.allowIncoming ??
'following'
// resolve the same concrete value the server will receive, so
// optimistic cache and persisted record stay aligned
const allowGroupInvites = resolveAllowGroupInvites({
allowIncoming,
allowGroupInvites:
update.allowGroupInvites ??
old.associated?.chat?.allowGroupInvites,
})
return {
...old,
associated: {
...old.associated,
chat: {
allowIncoming: 'following',
...old.associated?.chat,
...update,
allowIncoming,
allowGroupInvites,
},
},
} satisfies AppBskyActorDefs.ProfileViewDetailed