Replace createThreadgate handling

This commit is contained in:
Eric Bailey
2024-08-05 10:52:45 -05:00
parent 9be0d49e78
commit 50b8e6c63c
3 changed files with 81 additions and 52 deletions
+7 -34
View File
@@ -3,7 +3,6 @@ import {
AppBskyEmbedImages, AppBskyEmbedImages,
AppBskyEmbedRecord, AppBskyEmbedRecord,
AppBskyEmbedRecordWithMedia, AppBskyEmbedRecordWithMedia,
AppBskyFeedThreadgate,
BskyAgent, BskyAgent,
ComAtprotoLabelDefs, ComAtprotoLabelDefs,
ComAtprotoRepoUploadBlob, ComAtprotoRepoUploadBlob,
@@ -12,7 +11,11 @@ import {
import {AtUri} from '@atproto/api' import {AtUri} from '@atproto/api'
import {logger} from '#/logger' import {logger} from '#/logger'
import {ThreadgateAllowUISetting} from '#/state/queries/threadgate' import {
createThreadgate as upsertThreadgate,
ThreadgateAllowUISetting,
threadgateAllowUISettingToAllowType,
} from '#/state/queries/threadgate'
import {isNetworkError} from 'lib/strings/errors' import {isNetworkError} from 'lib/strings/errors'
import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip' import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip'
import {isNative, isWeb} from 'platform/detection' import {isNative, isWeb} from 'platform/detection'
@@ -279,38 +282,8 @@ export async function createThreadgate(
postUri: string, postUri: string,
threadgate: ThreadgateAllowUISetting[], threadgate: ThreadgateAllowUISetting[],
) { ) {
let allow: ( const allow = threadgateAllowUISettingToAllowType(threadgate)
| AppBskyFeedThreadgate.MentionRule return upsertThreadgate({agent, postUri, threadgate: {allow}})
| AppBskyFeedThreadgate.FollowingRule
| AppBskyFeedThreadgate.ListRule
)[] = []
if (!threadgate.find(v => v.type === 'nobody')) {
for (const rule of threadgate) {
if (rule.type === 'mention') {
allow.push({$type: 'app.bsky.feed.threadgate#mentionRule'})
} else if (rule.type === 'following') {
allow.push({$type: 'app.bsky.feed.threadgate#followingRule'})
} else if (rule.type === 'list') {
allow.push({
$type: 'app.bsky.feed.threadgate#listRule',
list: rule.list,
})
}
}
}
const postUrip = new AtUri(postUri)
await agent.api.com.atproto.repo.putRecord({
repo: agent.session!.did,
collection: 'app.bsky.feed.threadgate',
rkey: postUrip.rkey,
record: {
$type: 'app.bsky.feed.threadgate',
post: postUri,
allow,
createdAt: new Date().toISOString(),
},
})
} }
// helpers // helpers
+70 -14
View File
@@ -1,6 +1,8 @@
import {AppBskyFeedThreadgate, AtUri, BskyAgent} from '@atproto/api' import {AppBskyFeedThreadgate, AtUri, BskyAgent} from '@atproto/api'
import {useQuery} from '@tanstack/react-query' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
import {networkRetry} from '#/lib/async/retry'
import {mergeThreadgateRecords} from '#/state/queries/threadgate/util'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export * from '#/state/queries/threadgate/types' export * from '#/state/queries/threadgate/types'
@@ -45,7 +47,7 @@ export function useThreadgateRecordQuery({
}) })
} }
export function createThreadgate({ export async function createThreadgate({
agent, agent,
postUri, postUri,
threadgate, threadgate,
@@ -54,18 +56,72 @@ export function createThreadgate({
postUri: string postUri: string
threadgate: Partial<AppBskyFeedThreadgate.Record> threadgate: Partial<AppBskyFeedThreadgate.Record>
}) { }) {
const urip = new AtUri(postUri) const postUrip = new AtUri(postUri)
const record = {
...threadgate,
post: postUri,
createdAt: new Date().toISOString(),
}
return agent.api.app.bsky.feed.threadgate.create( const {data} = await networkRetry(2, () =>
{ agent.api.com.atproto.repo.getRecord({
repo: urip.host, repo: agent.session!.did,
rkey: urip.rkey, collection: 'app.bsky.feed.threadgate',
}, rkey: postUrip.rkey,
record, }),
) )
if (data.value && AppBskyFeedThreadgate.isRecord(data.value)) {
// has existing, merge
const prev = data.value
const merged = mergeThreadgateRecords(prev, threadgate)
await networkRetry(2, () =>
agent.api.com.atproto.repo.putRecord({
repo: agent.session!.did,
collection: 'app.bsky.feed.threadgate',
rkey: postUrip.rkey,
record: merged,
}),
)
} else {
// no existing, create new
const record: AppBskyFeedThreadgate.Record = {
$type: 'app.bsky.feed.threadgate',
post: postUri,
allow: threadgate.allow || [],
hiddenReplies: threadgate.hiddenReplies || [],
createdAt: new Date().toISOString(),
}
await networkRetry(2, () =>
agent.api.com.atproto.repo.putRecord({
repo: agent.session!.did,
collection: 'app.bsky.feed.threadgate',
rkey: postUrip.rkey,
record,
}),
)
}
}
export function useCreateThreadgateMutation() {
const agent = useAgent()
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({
postUri,
threadgate,
}: {
postUri: string
threadgate: Partial<AppBskyFeedThreadgate.Record>
}) => {
return createThreadgate({
agent,
postUri,
threadgate,
})
},
onSuccess() {
queryClient.invalidateQueries({
queryKey: [threadgateRecordQueryKeyRoot],
})
},
})
} }
+4 -4
View File
@@ -31,8 +31,8 @@ import {
usePostDeleteMutation, usePostDeleteMutation,
useThreadMuteMutationQueue, useThreadMuteMutationQueue,
} from '#/state/queries/post' } from '#/state/queries/post'
import {createThreadgate} from '#/state/queries/threadgate' import {useCreateThreadgateMutation} from '#/state/queries/threadgate'
import {useAgent, useSession} from '#/state/session' import {useSession} from '#/state/session'
import {getCurrentRoute} from 'lib/routes/helpers' import {getCurrentRoute} from 'lib/routes/helpers'
import {shareUrl} from 'lib/sharing' import {shareUrl} from 'lib/sharing'
import {toShareUrl} from 'lib/strings/url-helpers' import {toShareUrl} from 'lib/strings/url-helpers'
@@ -88,7 +88,6 @@ let PostDropdownBtn = ({
rootPostUri?: string rootPostUri?: string
}): React.ReactNode => { }): React.ReactNode => {
const {hasSession, currentAccount} = useSession() const {hasSession, currentAccount} = useSession()
const agent = useAgent()
const theme = useTheme() const theme = useTheme()
const alf = useAlf() const alf = useAlf()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
@@ -108,6 +107,8 @@ let PostDropdownBtn = ({
const loggedOutWarningPromptControl = useDialogControl() const loggedOutWarningPromptControl = useDialogControl()
const embedPostControl = useDialogControl() const embedPostControl = useDialogControl()
const sendViaChatControl = useDialogControl() const sendViaChatControl = useDialogControl()
const {mutateAsync: createThreadgate} = useCreateThreadgateMutation()
const postUri = post.uri const postUri = post.uri
const postCid = post.cid const postCid = post.cid
const postAuthor = post.author const postAuthor = post.author
@@ -404,7 +405,6 @@ let PostDropdownBtn = ({
label={_(msg`Hide reply`)} label={_(msg`Hide reply`)}
onPress={() => { onPress={() => {
createThreadgate({ createThreadgate({
agent,
postUri: rootPostUri, postUri: rootPostUri,
threadgate: { threadgate: {
hiddenReplies: [postUri], hiddenReplies: [postUri],