parent
cff7cbb4aa
commit
ae71f5ce84
7 changed files with 193 additions and 18 deletions
29
src/state/queries/nuxs/definitions.ts
Normal file
29
src/state/queries/nuxs/definitions.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import zod from 'zod'
|
||||
|
||||
import {BaseNux} from '#/state/queries/nuxs/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
src/state/queries/nuxs/index.ts
Normal file
83
src/state/queries/nuxs/index.ts
Normal file
|
@ -0,0 +1,83 @@
|
|||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {AppNux, Nux} from '#/state/queries/nuxs/definitions'
|
||||
import {parseAppNux, serializeAppNux} from '#/state/queries/nuxs/util'
|
||||
import {
|
||||
preferencesQueryKey,
|
||||
usePreferencesQuery,
|
||||
} from '#/state/queries/preferences'
|
||||
import {useAgent} from '#/state/session'
|
||||
|
||||
export {Nux} from '#/state/queries/nuxs/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
src/state/queries/nuxs/types.ts
Normal file
9
src/state/queries/nuxs/types.ts
Normal file
|
@ -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
src/state/queries/nuxs/util.ts
Normal file
52
src/state/queries/nuxs/util.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import {AppBskyActorDefs, nuxSchema} from '@atproto/api'
|
||||
|
||||
import {
|
||||
AppNux,
|
||||
Nux,
|
||||
nuxNames,
|
||||
NuxSchemas,
|
||||
} from '#/state/queries/nuxs/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
|
||||
}
|
|
@ -37,5 +37,6 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
|
|||
bskyAppState: {
|
||||
queuedNudges: [],
|
||||
activeProgressGuide: undefined,
|
||||
nuxs: [],
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue