Skip to content

Commit

Permalink
Set up nux API
Browse files Browse the repository at this point in the history
  • Loading branch information
estrattonbailey committed Sep 11, 2024
1 parent 580b67b commit b1f88b3
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/state/queries/nux/definitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import zod from 'zod'

import {BaseNux} from '#/state/queries/nux/types'

export enum Nux {
One = 'one',
Two = 'two',
}

export const nuxNames = new Set(Object.values(Nux))

export type AppNux =
| BaseNux<{
id: Nux.One
data: {
likes: number
}
}>
| BaseNux<{
id: Nux.Two
data: undefined
}>

export const NuxSchemas = {
[Nux.One]: zod.object({
likes: zod.number(),
}),
[Nux.Two]: undefined,
}
83 changes: 83 additions & 0 deletions src/state/queries/nux/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {useMutation, useQueryClient} from '@tanstack/react-query'

import {AppNux, Nux} from '#/state/queries/nux/definitions'
import {parseAppNux, serializeAppNux} from '#/state/queries/nux/util'
import {
preferencesQueryKey,
usePreferencesQuery,
} from '#/state/queries/preferences'
import {useAgent} from '#/state/session'

export {Nux} from '#/state/queries/nux/definitions'

export function useNuxs() {
const {data, ...rest} = usePreferencesQuery()

if (data && rest.isSuccess) {
const nuxs = data.bskyAppState.nuxs
?.map(parseAppNux)
?.filter(Boolean) as AppNux[]

if (nuxs) {
return {
nuxs,
...rest,
}
}
}

return {
nuxs: undefined,
...rest,
}
}

export function useNux<T extends Nux>(id: T) {
const {nuxs, ...rest} = useNuxs()

if (nuxs && rest.isSuccess) {
const nux = nuxs.find(nux => nux.id === id)

if (nux) {
return {
nux: nux as Extract<AppNux, {id: T}>,
...rest,
}
}
}

return {
nux: undefined,
...rest,
}
}

export function useUpsertNuxMutation() {
const queryClient = useQueryClient()
const agent = useAgent()

return useMutation({
mutationFn: async (nux: AppNux) => {
await agent.bskyAppUpsertNux(serializeAppNux(nux))
// triggers a refetch
await queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
})
},
})
}

export function useRemoveNuxsMutation() {
const queryClient = useQueryClient()
const agent = useAgent()

return useMutation({
mutationFn: async (ids: string[]) => {
await agent.bskyAppRemoveNuxs(ids)
// triggers a refetch
await queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
})
},
})
}
9 changes: 9 additions & 0 deletions src/state/queries/nux/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {AppBskyActorDefs} from '@atproto/api'

export type Data = Record<string, unknown> | undefined

export type BaseNux<
T extends Pick<AppBskyActorDefs.Nux, 'id' | 'expiresAt'> & {data: Data},
> = T & {
completed: boolean
}
52 changes: 52 additions & 0 deletions src/state/queries/nux/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {AppBskyActorDefs, nuxSchema} from '@atproto/api'

import {
AppNux,
Nux,
nuxNames,
NuxSchemas,
} from '#/state/queries/nux/definitions'

export function parseAppNux(nux: AppBskyActorDefs.Nux): AppNux | undefined {
if (!nuxNames.has(nux.id as Nux)) return
if (!nuxSchema.safeParse(nux).success) return

const {data, ...rest} = nux

const schema = NuxSchemas[nux.id as Nux]

if (schema && data) {
const parsedData = JSON.parse(data)

if (!schema.safeParse(parsedData).success) return

return {
...rest,
data: parsedData,
} as AppNux
}

return {
...rest,
data: undefined,
} as AppNux
}

export function serializeAppNux(nux: AppNux): AppBskyActorDefs.Nux {
const {data, ...rest} = nux
const schema = NuxSchemas[nux.id as Nux]

const result: AppBskyActorDefs.Nux = {
...rest,
data: undefined,
}

if (schema) {
schema.parse(data)
result.data = JSON.stringify(data)
}

nuxSchema.parse(result)

return result
}
1 change: 1 addition & 0 deletions src/state/queries/preferences/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
bskyAppState: {
queuedNudges: [],
activeProgressGuide: undefined,
nuxs: [],
},
}

0 comments on commit b1f88b3

Please sign in to comment.