about summary refs log tree commit diff
path: root/src/state/queries/invites.ts
blob: fdccac8cbdfc9fac359e9d9146a047abb52fac77 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import {ComAtprotoServerDefs} from '@atproto/api'
import {useQuery} from '@tanstack/react-query'

import {cleanError} from '#/lib/strings/errors'
import {STALE} from '#/state/queries'
import {useAgent} from '#/state/session'

function isInviteAvailable(invite: ComAtprotoServerDefs.InviteCode): boolean {
  return invite.available - invite.uses.length > 0 && !invite.disabled
}

const inviteCodesQueryKeyRoot = 'inviteCodes'

export type InviteCodesQueryResponse = Exclude<
  ReturnType<typeof useInviteCodesQuery>['data'],
  undefined
>
export function useInviteCodesQuery() {
  const agent = useAgent()
  return useQuery({
    staleTime: STALE.MINUTES.FIVE,
    queryKey: [inviteCodesQueryKeyRoot],
    queryFn: async () => {
      const res = await agent.com.atproto.server
        .getAccountInviteCodes({})
        .catch(e => {
          if (cleanError(e) === 'Bad token scope') {
            return null
          } else {
            throw e
          }
        })

      if (res === null) {
        return {
          disabled: true,
          all: [],
          available: [],
          used: [],
        }
      }

      if (!res.data?.codes) {
        throw new Error(`useInviteCodesQuery: no codes returned`)
      }

      const available = res.data.codes.filter(isInviteAvailable)
      const used = res.data.codes
        .filter(code => !isInviteAvailable(code))
        .sort((a, b) => {
          return (
            new Date(b.uses[0].usedAt).getTime() -
            new Date(a.uses[0].usedAt).getTime()
          )
        })

      return {
        disabled: false,
        all: [...available, ...used],
        available,
        used,
      }
    },
  })
}