Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
1import {useMemo} from 'react'
2import {useMutation, useQueryClient} from '@tanstack/react-query'
3
4import {preferencesQueryKey} from '#/state/queries/preferences'
5import {useAgent, useSession} from '#/state/session'
6import {usePatchAgeAssuranceOtherRequiredData} from '#/ageAssurance'
7import {IS_DEV} from '#/env'
8import {account} from '#/storage'
9
10// 6s in dev, 48h in prod
11const BIRTHDATE_DELAY_HOURS = IS_DEV ? 0.001 : 48
12
13/**
14 * Stores the timestamp of the birthday update locally. This is used to
15 * debounce birthday updates globally.
16 *
17 * Use {@link useIsBirthDateUpdateAllowed} to check if an update is allowed.
18 */
19export function snoozeBirthdateUpdateAllowedForDid(did: string) {
20 account.set([did, 'birthdateLastUpdatedAt'], new Date().toISOString())
21}
22
23/**
24 * Checks if we've already snoozed bday updates. In some cases, if one is
25 * present, we don't need to set another, such as in AA when reading initial
26 * data on load.
27 */
28export function hasSnoozedBirthdateUpdateForDid(did: string) {
29 return !!account.get([did, 'birthdateLastUpdatedAt'])
30}
31
32/**
33 * Returns whether a birthdate update is currently allowed, based on the
34 * last update timestamp stored locally.
35 */
36export function useIsBirthdateUpdateAllowed() {
37 const {currentAccount} = useSession()
38 return useMemo(() => {
39 if (!currentAccount) return false
40 const lastUpdated = account.get([
41 currentAccount.did,
42 'birthdateLastUpdatedAt',
43 ])
44 if (!lastUpdated) return true
45 const lastUpdatedDate = new Date(lastUpdated)
46 const diffMs = Date.now() - lastUpdatedDate.getTime()
47 const diffHours = diffMs / (1000 * 60 * 60)
48 return diffHours >= BIRTHDATE_DELAY_HOURS
49 }, [currentAccount])
50}
51
52export function useBirthdateMutation() {
53 const queryClient = useQueryClient()
54 const agent = useAgent()
55 const patchOtherRequiredData = usePatchAgeAssuranceOtherRequiredData()
56
57 return useMutation<void, unknown, {birthDate: Date}>({
58 mutationFn: async ({birthDate}: {birthDate: Date}) => {
59 const bday = birthDate.toISOString()
60 await agent.setPersonalDetails({birthDate: bday})
61 // triggers a refetch
62 await queryClient.invalidateQueries({
63 queryKey: preferencesQueryKey,
64 })
65 /**
66 * Also patch the age assurance other required data with the new
67 * birthdate, which may change the user's age assurance access level.
68 */
69 patchOtherRequiredData({birthdate: bday})
70 snoozeBirthdateUpdateAllowedForDid(agent.sessionManager.did!)
71 },
72 })
73}