simplify into a single call

This commit is contained in:
Samuel Newman
2026-06-04 16:45:30 +03:00
parent 07d89287cd
commit f412de521d
7 changed files with 58 additions and 77 deletions
-11
View File
@@ -19,11 +19,6 @@
"count": 1
}
},
"src/ageAssurance/util.ts": {
"@typescript-eslint/no-floating-promises": {
"count": 1
}
},
"src/alf/util/flatten.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
@@ -1942,12 +1937,6 @@
"src/state/session/agent.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
},
"@typescript-eslint/no-floating-promises": {
"count": 1
},
"@typescript-eslint/require-await": {
"count": 1
}
},
"src/state/shell/color-mode.tsx": {
+1 -1
View File
@@ -93,7 +93,7 @@ function InnerProvider({children}: {children: React.ReactNode}) {
const isAgeRestricted = s.access !== AgeAssuranceAccess.Full
if (isAgeRestricted) {
void getAndRegisterPushToken({isAgeRestricted})
maybeRestrictChatSettings({agent})
void maybeRestrictChatSettings({agent})
}
},
[agent, getAndRegisterPushToken],
+2 -5
View File
@@ -12,7 +12,6 @@ import {restrictChatSettings} from '#/state/queries/messages/restrictChatSetting
import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation'
import {
getDidFromAgentSession,
getOtherRequiredDataFromCache,
useAgeAssuranceDataContext,
} from '#/ageAssurance/data'
import {AgeAssuranceAccess} from '#/ageAssurance/types'
@@ -123,8 +122,6 @@ export const makeAgeRestrictedModerationPrefs = (
export function maybeRestrictChatSettings({agent}: {agent: AtpAgent}) {
const did = getDidFromAgentSession(agent)
if (!did) return
const data = getOtherRequiredDataFromCache({did})
// ...update the chat setting record if allowIncoming is not already 'none'.
if (data?.actorDeclaration?.allowIncoming === 'none') return
restrictChatSettings({agent, did})
// restrictChatSettings is a no-op if allowIncoming is already 'none'.
return restrictChatSettings({agent, did, restrictIncoming: true})
}
+8 -4
View File
@@ -1,11 +1,11 @@
import {useMemo} from 'react'
import {useMutation, useQueryClient} from '@tanstack/react-query'
import {restrictGroupChatSettings} from '#/state/queries/messages/restrictChatSettings'
import {restrictChatSettings} from '#/state/queries/messages/restrictChatSettings'
import {preferencesQueryKey} from '#/state/queries/preferences'
import {useAgent, useSession} from '#/state/session'
import {usePatchAgeAssuranceOtherRequiredData} from '#/ageAssurance'
import {isUnderAge, maybeRestrictChatSettings} from '#/ageAssurance/util'
import {isUnderAge} from '#/ageAssurance/util'
import {IS_DEV} from '#/env'
import {account} from '#/storage'
@@ -67,10 +67,14 @@ export function useBirthdateMutation() {
})
if (isUnderAge(birthDate.toISOString(), 18)) {
maybeRestrictChatSettings({agent})
const did = agent.sessionManager.did
if (did) {
await restrictGroupChatSettings({agent, did})
await restrictChatSettings({
agent,
did,
restrictIncoming: true,
restrictGroupInvites: true,
})
}
}
@@ -14,13 +14,13 @@ import {
} from '@tanstack/react-query'
import throttle from 'lodash.throttle'
import {useAgeAssurance} from '#/ageAssurance'
import {DM_SERVICE_HEADERS} from '#/lib/constants'
import {useCurrentConvoId} from '#/state/messages/current-convo-id'
import {useMessagesEventBus} from '#/state/messages/events'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useAgent, useSession} from '#/state/session'
import {parseConvoView} from '#/components/dms/util'
import {useAgeAssurance} from '#/ageAssurance'
import * as bsky from '#/types/bsky'
import {RQKEY as CONVO_KEY} from './conversation'
import {useLeftConvos} from './leave-conversation'
@@ -9,20 +9,51 @@ import {
} from '#/ageAssurance/data'
/**
* Helper to update the chat settings record.
* Updates the chat actor declaration record to restrict who can contact the
* user. Both restrictions write to the same record (`rkey: 'self'`), so this
* is a single helper to avoid two concurrent `putRecord` calls racing each
* other and clobbering one another's changes.
*
* - `restrictIncoming`: sets `allowIncoming: 'none'` (used when a user isn't
* age-assured).
* - `restrictGroupInvites`: sets `allowGroupInvites: 'none'` (used for under-18
* users, who per spec cannot participate in group chats).
*
* Dimensions that aren't being restricted preserve their cached value, falling
* back to the lexicon defaults when the cache is empty.
*/
export async function restrictChatSettings({
agent,
did,
restrictIncoming = false,
restrictGroupInvites = false,
}: {
agent: AtpAgent
did: string
restrictIncoming?: boolean
restrictGroupInvites?: boolean
}): Promise<void> {
const cached = getOtherRequiredDataFromCache({did})?.actorDeclaration
const record: ChatBskyActorDeclaration.Main = {
$type: 'chat.bsky.actor.declaration',
allowIncoming: restrictIncoming
? 'none'
: (cached?.allowIncoming ?? 'following'),
allowGroupInvites: restrictGroupInvites
? 'none'
: cached?.allowGroupInvites,
}
// Nothing to do if the record already reflects the desired restrictions.
if (
cached?.allowIncoming === record.allowIncoming &&
cached?.allowGroupInvites === record.allowGroupInvites
) {
return
}
try {
const record: ChatBskyActorDeclaration.Main = {
$type: 'chat.bsky.actor.declaration',
allowIncoming: 'none',
}
await networkRetry(3, () =>
agent.com.atproto.repo.putRecord({
repo: did,
@@ -40,44 +71,3 @@ export async function restrictChatSettings({
logger.error(`restrictChatSettings: failed to set chat declaration`)
}
}
/**
* Locks the user out of being added to group chats by setting
* `allowGroupInvites: 'none'` on the chat actor declaration. Used for under-18
* users, who per spec cannot participate in group chats.
*
* Preserves the existing `allowIncoming` value if one is cached, otherwise
* defaults to 'following' (the lexicon default) since the field is required.
*/
export async function restrictGroupChatSettings({
agent,
did,
}: {
agent: AtpAgent
did: string
}): Promise<void> {
const cached = getOtherRequiredDataFromCache({did})?.actorDeclaration
if (cached?.allowGroupInvites === 'none') return
try {
const record: ChatBskyActorDeclaration.Main = {
$type: 'chat.bsky.actor.declaration',
allowIncoming: cached?.allowIncoming ?? 'following',
allowGroupInvites: 'none',
}
await networkRetry(3, () =>
agent.com.atproto.repo.putRecord({
repo: did,
collection: 'chat.bsky.actor.declaration',
rkey: 'self',
record,
}),
)
setOtherRequiredDataActorDeclarationCache({
did,
actorDeclaration: record,
})
} catch {
logger.error(`restrictGroupChatSettings: failed to set chat declaration`)
}
}
+10 -9
View File
@@ -22,10 +22,7 @@ import {
import {getAge} from '#/lib/strings/time'
import {logger} from '#/logger'
import {snoozeBirthdateUpdateAllowedForDid} from '#/state/birthdate'
import {
restrictChatSettings,
restrictGroupChatSettings,
} from '#/state/queries/messages/restrictChatSettings'
import {restrictChatSettings} from '#/state/queries/messages/restrictChatSettings'
import {snoozeEmailConfirmationPrompt} from '#/state/shell/reminders'
import {
prefetchAgeAssuranceData,
@@ -224,11 +221,15 @@ export async function createAgentAndCreateAccount(
// wait for AA data to load first, then check state
aa.then(async () => {
const state = getAndComputeAgeAssuranceState({did: account.did})
if (state.access !== AgeAssuranceAccess.Full) {
restrictChatSettings({agent, did: account.did})
}
if (getAge(birthDate) < 18) {
restrictGroupChatSettings({agent, did: account.did})
const restrictIncoming = state.access !== AgeAssuranceAccess.Full
const restrictGroupInvites = getAge(birthDate) < 18
if (restrictIncoming || restrictGroupInvites) {
await restrictChatSettings({
agent,
did: account.did,
restrictIncoming,
restrictGroupInvites,
})
}
}),
]).then(promises => {