WIP
This commit is contained in:
@@ -126,6 +126,7 @@ module.exports = function (_config) {
|
||||
'com.apple.security.application-groups': 'group.app.bsky',
|
||||
'com.apple.developer.usernotifications.communication': true,
|
||||
// 'com.apple.developer.device-information.user-assigned-device-name': true,
|
||||
'com.apple.developer.declared-age-range': true,
|
||||
},
|
||||
privacyManifests: {
|
||||
NSPrivacyCollectedDataTypes: [
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
"emoji-regex": "^10.4.0",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"expo": "54.0.34",
|
||||
"expo-age-range": "^0.2.0",
|
||||
"expo-application": "~7.0.8",
|
||||
"expo-blur": "~15.0.8",
|
||||
"expo-build-properties": "~1.0.10",
|
||||
|
||||
@@ -4,6 +4,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import * as AgeRange from 'expo-age-range'
|
||||
|
||||
import {
|
||||
SupportCode,
|
||||
@@ -348,7 +349,18 @@ function AccessSection() {
|
||||
label={_(msg`Verify now`)}
|
||||
size="large"
|
||||
color={hasInitiated ? 'secondary' : 'primary'}
|
||||
onPress={() => {
|
||||
onPress={async () => {
|
||||
try {
|
||||
const ageRange = await AgeRange.requestAgeRangeAsync({
|
||||
threshold1: 10,
|
||||
threshold2: 13,
|
||||
threshold3: 18,
|
||||
});
|
||||
console.log(ageRange)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return
|
||||
control.open()
|
||||
ax.metric('ageAssurance:initDialogOpen', {
|
||||
hasInitiatedPreviously: hasInitiated,
|
||||
|
||||
@@ -11,6 +11,7 @@ import {createAsyncStoragePersister} from '@tanstack/query-async-storage-persist
|
||||
import {focusManager, QueryClient, useQuery} from '@tanstack/react-query'
|
||||
import {persistQueryClient} from '@tanstack/react-query-persist-client'
|
||||
import debounce from 'lodash.debounce'
|
||||
import * as AgeRange from 'expo-age-range';
|
||||
|
||||
import {networkRetry} from '#/lib/async/retry'
|
||||
import {PUBLIC_BSKY_SERVICE} from '#/lib/constants'
|
||||
@@ -485,6 +486,99 @@ export function useOtherRequiredDataQuery() {
|
||||
)
|
||||
}
|
||||
|
||||
export function createDeviceSignalsQueryKey({did}: {did: string}) {
|
||||
return ['device-signals', did]
|
||||
}
|
||||
export async function getDeviceSignals(): Promise<AgeRange.AgeRangeResponse | undefined> {
|
||||
if (debug.enabled) return debug.resolve(debug.deviceSignals)
|
||||
try {
|
||||
return AgeRange.requestAgeRangeAsync({
|
||||
threshold1: 13,
|
||||
threshold2: 16,
|
||||
threshold3: 18,
|
||||
});
|
||||
} catch (e: any) {
|
||||
logger.error(`getDeviceSignals: failed to get device signals`, {
|
||||
safeMessage: e.message,
|
||||
})
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
export function getDeviceSignalsFromCache({
|
||||
did,
|
||||
}: {
|
||||
did: string
|
||||
}):
|
||||
| AgeRange.AgeRangeResponse
|
||||
| undefined {
|
||||
return qc.getQueryData<AgeRange.AgeRangeResponse>(
|
||||
createDeviceSignalsQueryKey({did}),
|
||||
)
|
||||
}
|
||||
let deviceSignalsPrefetchPromise: Promise<void> | undefined
|
||||
export async function prefetchDeviceSignals({
|
||||
agent,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
}) {
|
||||
const did = getDidFromAgentSession(agent)
|
||||
if (!did) return
|
||||
|
||||
/**
|
||||
* If we don't have a cache, it's possible the user hasn't granted access.
|
||||
* We don't want to do this during the prefetch phase, so just exit early,
|
||||
* the user can potentially enable it later.
|
||||
*/
|
||||
const cached = getDeviceSignalsFromCache({did})
|
||||
if (!cached) return
|
||||
|
||||
if (deviceSignalsPrefetchPromise) {
|
||||
logger.debug(`prefetchDeviceSignals: already in progress`)
|
||||
return
|
||||
}
|
||||
|
||||
deviceSignalsPrefetchPromise = new Promise(async resolve => {
|
||||
await cacheHydrationPromise
|
||||
const cached = getDeviceSignalsFromCache({did})
|
||||
|
||||
if (cached) {
|
||||
logger.debug(`prefetchDeviceSignals: using cache`)
|
||||
resolve()
|
||||
} else {
|
||||
try {
|
||||
logger.debug(`prefetchDeviceSignals: resolving...`)
|
||||
const res = await getDeviceSignals()
|
||||
qc.setQueryData<AgeRange.AgeRangeResponse>(
|
||||
createDeviceSignalsQueryKey({did}),
|
||||
res,
|
||||
)
|
||||
} catch (e: any) {
|
||||
logger.warn(`prefetchDeviceSignals: failed`, {
|
||||
safeMessage: e.message,
|
||||
})
|
||||
} finally {
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
export function useDeviceSignalsQuery() {
|
||||
const agent = useAgent()
|
||||
const did = getDidFromAgentSession(agent)
|
||||
return useQuery(
|
||||
{
|
||||
enabled: !!did,
|
||||
initialData: getDeviceSignalsFromCache({did: did!}),
|
||||
queryKey: createDeviceSignalsQueryKey({did: did!}),
|
||||
async queryFn() {
|
||||
logger.debug(`useDeviceSignalsQuery: fetching device signals`)
|
||||
return getDeviceSignals()
|
||||
},
|
||||
},
|
||||
qc,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to prefetch all age assurance data from the server.
|
||||
*/
|
||||
@@ -494,6 +588,7 @@ export function prefetchAgeAssuranceServerData({agent}: {agent: AtpAgent}) {
|
||||
configPrefetchPromise,
|
||||
prefetchServerState({agent}),
|
||||
prefetchOtherRequiredData({agent}),
|
||||
prefetchDeviceSignals({agent}),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@ import {
|
||||
type AppBskyAgeassuranceDefs,
|
||||
type AppBskyAgeassuranceGetState,
|
||||
} from '@atproto/api'
|
||||
import * as AgeRange from 'expo-age-range'
|
||||
|
||||
import {type OtherRequiredData} from '#/ageAssurance/data'
|
||||
import {IS_DEV, IS_E2E} from '#/env'
|
||||
import {type Geolocation} from '#/geolocation'
|
||||
|
||||
export const enabled = (IS_DEV && false) || IS_E2E
|
||||
export const enabled = (IS_DEV && true) || IS_E2E
|
||||
|
||||
export const geolocation: Geolocation | undefined = enabled
|
||||
? {
|
||||
@@ -35,9 +36,9 @@ export const serverState: AppBskyAgeassuranceGetState.OutputSchema | undefined =
|
||||
serverStateEnabled
|
||||
? {
|
||||
state: {
|
||||
lastInitiatedAt: new Date(2025, 1, 1).toISOString(),
|
||||
status: 'assured',
|
||||
access: 'full',
|
||||
lastInitiatedAt: undefined, // new Date(2025, 1, 1).toISOString(),
|
||||
status: 'unknown',
|
||||
access: 'unknown',
|
||||
},
|
||||
metadata: {
|
||||
accountCreatedAt: new Date(2023, 1, 1).toISOString(),
|
||||
@@ -257,6 +258,10 @@ export const config: AppBskyAgeassuranceDefs.Config = {
|
||||
],
|
||||
}
|
||||
|
||||
const deviceSignalsEnabled = true
|
||||
export const deviceSignals: AgeRange.AgeRangeResponse | undefined =
|
||||
deviceSignalsEnabled ? {} : undefined
|
||||
|
||||
export async function resolve<T>(data: T) {
|
||||
await new Promise(y => setTimeout(y, 500)) // simulate network
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user