From f89767d16cbcae6042ba71166d0f1decb4c2e2fe Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 25 May 2026 20:33:40 -0500 Subject: [PATCH] Pure reshuffle, no cleanup yet --- src/ageAssurance/index.tsx | 38 ++++++++-------------------------- src/ageAssurance/state.ts | 42 ++++++++++++++++++++++++++------------ src/ageAssurance/types.ts | 8 ++++++++ src/ageAssurance/util.ts | 38 +++++++++++++++++++++++++++++++++- src/state/session/agent.ts | 2 +- 5 files changed, 83 insertions(+), 45 deletions(-) diff --git a/src/ageAssurance/index.tsx b/src/ageAssurance/index.tsx index fdea33d6fa..ef62fba4e7 100644 --- a/src/ageAssurance/index.tsx +++ b/src/ageAssurance/index.tsx @@ -14,13 +14,13 @@ import { } from '#/ageAssurance/state' import { AgeAssuranceAccess, + type AgeAssuranceFlags, type AgeAssuranceState, AgeAssuranceStatus, } from '#/ageAssurance/types' import { - isUnderAge, + computeAgeAssuranceFlags, maybeRestrictChatSettings, - MIN_ACCESS_AGE, useAgeAssuranceRegionConfigWithFallback, } from '#/ageAssurance/util' @@ -38,13 +38,7 @@ const AgeAssuranceStateContext = createContext<{ Access: typeof AgeAssuranceAccess Status: typeof AgeAssuranceStatus state: AgeAssuranceState - flags: { - adultContentDisabled: boolean - chatDisabled: boolean - isUnder18: boolean - isOverRegionMinAccessAge: boolean - isOverAppMinAccessAge: boolean - } + flags: AgeAssuranceFlags }>({ Access: AgeAssuranceAccess, Status: AgeAssuranceStatus, @@ -107,31 +101,15 @@ function InnerProvider({children}: {children: React.ReactNode}) { return ( { - const chatDisabled = state.access !== AgeAssuranceAccess.Full - // Conservative default: if we don't yet know the birthdate, treat as - // under 18 so we don't briefly expose group-chat UI. - const isUnder18 = data?.birthdate - ? isUnderAge(data.birthdate, 18) - : true - const isOverRegionMinAccessAge = data?.birthdate - ? !isUnderAge(data.birthdate, config.minAccessAge) - : false - const isOverAppMinAccessAge = data?.birthdate - ? !isUnderAge(data.birthdate, MIN_ACCESS_AGE) - : false - const adultContentDisabled = - state.access !== AgeAssuranceAccess.Full || isUnder18 return { Access: AgeAssuranceAccess, Status: AgeAssuranceStatus, state, - flags: { - adultContentDisabled, - chatDisabled, - isUnder18, - isOverRegionMinAccessAge, - isOverAppMinAccessAge, - }, + flags: computeAgeAssuranceFlags({ + state, + config, + data, + }), } }, [state, data, config])}> {children} diff --git a/src/ageAssurance/state.ts b/src/ageAssurance/state.ts index 5aac40ef44..92eadafe82 100644 --- a/src/ageAssurance/state.ts +++ b/src/ageAssurance/state.ts @@ -18,7 +18,10 @@ import { parseAccessFromString, parseStatusFromString, } from '#/ageAssurance/types' -import {getAgeAssuranceRegionConfigWithFallback} from '#/ageAssurance/util' +import { + computeAgeAssuranceFlags, + getAgeAssuranceRegionConfigWithFallback, +} from '#/ageAssurance/util' import {type Geolocation, useGeolocation} from '#/geolocation' import {device} from '#/storage' @@ -116,29 +119,42 @@ export function computeAgeAssuranceState({ export function getAndComputeAgeAssuranceState({did}: {did: string}) { const config = getConfigFromCache() const state = getServerStateFromCache({did}) - const data = getOtherRequiredDataFromCache({did}) + const requiredData = getOtherRequiredDataFromCache({did}) const geolocation = device.get(['mergedGeolocation']) - if (!geolocation || !config || !state || !data) { + if (!geolocation || !config || !state || !requiredData) { return { - status: AgeAssuranceStatus.Unknown, - access: AgeAssuranceAccess.Safe, + state: { + status: AgeAssuranceStatus.Unknown, + access: AgeAssuranceAccess.Safe, + }, } } - return computeAgeAssuranceState({ + const region = getAgeAssuranceRegionConfigWithFallback(config, geolocation) + const data = { + accountCreatedAt: state.metadata?.accountCreatedAt, + declaredAge: requiredData?.birthdate + ? getAge(new Date(requiredData.birthdate)) + : undefined, + birthdate: requiredData?.birthdate, + } + const computed = computeAgeAssuranceState({ hasSession: true, config, geolocation, state: state.state, - data: { - accountCreatedAt: state.metadata?.accountCreatedAt, - declaredAge: data?.birthdate - ? getAge(new Date(data.birthdate)) - : undefined, - birthdate: data?.birthdate, - }, + data, }) + + return { + state: computed, + flags: computeAgeAssuranceFlags({ + state: computed, + config: region, + data, + }), + } } export function useAgeAssuranceState(): AgeAssuranceState { diff --git a/src/ageAssurance/types.ts b/src/ageAssurance/types.ts index f34ed10aea..a594c81e64 100644 --- a/src/ageAssurance/types.ts +++ b/src/ageAssurance/types.ts @@ -21,6 +21,14 @@ export type AgeAssuranceState = { error?: 'config' // maybe other specific cases in the future } +export type AgeAssuranceFlags = { + adultContentDisabled: boolean + chatDisabled: boolean + isUnder18: boolean + isOverRegionMinAccessAge: boolean + isOverAppMinAccessAge: boolean +} + export function parseStatusFromString(raw: string) { switch (raw) { case 'unknown': diff --git a/src/ageAssurance/util.ts b/src/ageAssurance/util.ts index 310725db8f..2ff524a5a6 100644 --- a/src/ageAssurance/util.ts +++ b/src/ageAssurance/util.ts @@ -11,11 +11,16 @@ import {getAge} from '#/lib/strings/time' import {restrictChatSettings} from '#/state/queries/messages/restrictChatSettings' import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation' import { + type AgeAssuranceData, getDidFromAgentSession, getOtherRequiredDataFromCache, useAgeAssuranceDataContext, } from '#/ageAssurance/data' -import {AgeAssuranceAccess} from '#/ageAssurance/types' +import { + AgeAssuranceAccess, + type AgeAssuranceFlags, + type AgeAssuranceState, +} from '#/ageAssurance/types' import {type Geolocation, useGeolocation} from '#/geolocation' export const MIN_ACCESS_AGE = 13 @@ -128,3 +133,34 @@ export function maybeRestrictChatSettings({agent}: {agent: AtpAgent}) { if (data?.actorDeclaration?.allowIncoming === 'none') return restrictChatSettings({agent, did}) } + +export function computeAgeAssuranceFlags({ + state, + config, + data, +}: { + state: AgeAssuranceState + config: AppBskyAgeassuranceDefs.ConfigRegion + data: AgeAssuranceData['data'] +}): AgeAssuranceFlags { + const chatDisabled = state.access !== AgeAssuranceAccess.Full + // Conservative default: if we don't yet know the birthdate, treat as + // under 18 so we don't briefly expose group-chat UI. + const isUnder18 = data?.birthdate ? isUnderAge(data.birthdate, 18) : true + const isOverRegionMinAccessAge = data?.birthdate + ? !isUnderAge(data.birthdate, config.minAccessAge) + : false + const isOverAppMinAccessAge = data?.birthdate + ? !isUnderAge(data.birthdate, MIN_ACCESS_AGE) + : false + const adultContentDisabled = + state.access !== AgeAssuranceAccess.Full || isUnder18 + + return { + adultContentDisabled, + chatDisabled, + isUnder18, + isOverRegionMinAccessAge, + isOverAppMinAccessAge, + } +} diff --git a/src/state/session/agent.ts b/src/state/session/agent.ts index ff57002566..ab6ed397eb 100644 --- a/src/state/session/agent.ts +++ b/src/state/session/agent.ts @@ -223,7 +223,7 @@ export async function createAgentAndCreateAccount( }), // wait for AA data to load first, then check state aa.then(async () => { - const state = getAndComputeAgeAssuranceState({did: account.did}) + const {state} = getAndComputeAgeAssuranceState({did: account.did}) if (state.access !== AgeAssuranceAccess.Full) { restrictChatSettings({agent, did: account.did}) }