From 7adaf159c13d5c47c04ca37ea214e445eac6b12e Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 12 Aug 2024 14:55:22 -0500 Subject: [PATCH] Add new mutation, handle app view ready and invalidation --- src/state/queries/threadgate/index.ts | 106 +++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/src/state/queries/threadgate/index.ts b/src/state/queries/threadgate/index.ts index 48cf4c4323..1a8c1a2fd2 100644 --- a/src/state/queries/threadgate/index.ts +++ b/src/state/queries/threadgate/index.ts @@ -1,13 +1,22 @@ -import {AppBskyFeedThreadgate, AtUri, BskyAgent} from '@atproto/api' +import { + AppBskyFeedDefs, + AppBskyFeedGetPostThread, + AppBskyFeedThreadgate, + AtUri, + BskyAgent, +} from '@atproto/api' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {networkRetry, retry} from '#/lib/async/retry' +import {until} from '#/lib/async/until' import {STALE} from '#/state/queries' +import {RQKEY_ROOT as postThreadQueryKeyRoot} from '#/state/queries/post-thread' import {ThreadgateAllowUISetting} from '#/state/queries/threadgate/types' import { createThreadgateRecord, mergeThreadgateRecords, threadgateAllowUISettingToAllowRecordValue, + threadgateViewToAllowUISetting, } from '#/state/queries/threadgate/util' import {useAgent} from '#/state/session' @@ -43,6 +52,40 @@ export function useThreadgateRecordQuery({ }) } +export const threadgateViewQueryKeyRoot = 'threadgate-view' +export const createThreadgateViewQueryKey = (uri: string) => [ + threadgateViewQueryKeyRoot, + uri, +] +export function useThreadgateViewQuery({ + postUri, + initialData, +}: { + postUri?: string + initialData?: AppBskyFeedDefs.ThreadgateView +} = {}) { + const agent = useAgent() + + return useQuery({ + enabled: !!postUri, + queryKey: createThreadgateViewQueryKey(postUri || ''), + placeholderData: initialData, + staleTime: STALE.MINUTES.ONE, + async queryFn() { + const {data} = await agent.app.bsky.feed.getPostThread({ + uri: postUri!, + depth: 0, + }) + + if (AppBskyFeedDefs.isThreadViewPost(data.thread)) { + return data.thread.post.threadgate ?? null + } + + return null + }, + }) +} + export async function getThreadgateRecord({ agent, postUri, @@ -178,6 +221,67 @@ export async function updateThreadgateAllow({ }) } +export function useSetThreadgateAllowMutation() { + const agent = useAgent() + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async ({ + postUri, + allow, + }: { + postUri: string + allow: ThreadgateAllowUISetting[] + }) => { + return upsertThreadgate({agent, postUri}, async prev => { + if (prev) { + return { + ...prev, + allow: threadgateAllowUISettingToAllowRecordValue(allow), + } + } else { + return createThreadgateRecord({ + post: postUri, + allow: threadgateAllowUISettingToAllowRecordValue(allow), + }) + } + }) + }, + async onSuccess(_, {postUri, allow}) { + await until( + 5, // 5 tries + 1e3, // 1s delay between tries + (res: AppBskyFeedGetPostThread.Response) => { + const thread = res.data.thread + if (AppBskyFeedDefs.isThreadViewPost(thread)) { + const fetchedSettings = threadgateViewToAllowUISetting( + thread.post.threadgate, + ) + return JSON.stringify(fetchedSettings) === JSON.stringify(allow) + } + return false + }, + () => { + return agent.app.bsky.feed.getPostThread({ + uri: postUri, + depth: 0, + }) + }, + ) + + queryClient.invalidateQueries({ + queryKey: [postThreadQueryKeyRoot], + }) + queryClient.invalidateQueries({ + queryKey: [threadgateRecordQueryKeyRoot], + }) + queryClient.invalidateQueries({ + queryKey: [threadgateViewQueryKeyRoot], + }) + }, + }) +} + export function useToggleReplyVisibilityMutation() { const agent = useAgent() const queryClient = useQueryClient()