about summary refs log tree commit diff
path: root/src/lib/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/api')
-rw-r--r--src/lib/api/index.ts119
1 files changed, 66 insertions, 53 deletions
diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts
index db5c9c247..a08d7ae5b 100644
--- a/src/lib/api/index.ts
+++ b/src/lib/api/index.ts
@@ -4,13 +4,17 @@ import {
   AppBskyEmbedRecord,
   AppBskyEmbedRecordWithMedia,
   AppBskyEmbedVideo,
+  AppBskyFeedPost,
+  AppBskyFeedPostgate,
   AtUri,
   BlobRef,
   BskyAgent,
   ComAtprotoLabelDefs,
+  ComAtprotoRepoApplyWrites,
   ComAtprotoRepoStrongRef,
   RichText,
 } from '@atproto/api'
+import {TID} from '@atproto/common-web'
 import {t} from '@lingui/macro'
 import {QueryClient} from '@tanstack/react-query'
 
@@ -18,7 +22,6 @@ import {isNetworkError} from '#/lib/strings/errors'
 import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip'
 import {logger} from '#/logger'
 import {compressImage} from '#/state/gallery'
-import {writePostgateRecord} from '#/state/queries/postgate'
 import {
   fetchResolveGifQuery,
   fetchResolveLinkQuery,
@@ -26,7 +29,6 @@ import {
 import {
   createThreadgateRecord,
   threadgateAllowUISettingToAllowRecordValue,
-  writeThreadgateRecord,
 } from '#/state/queries/threadgate'
 import {ComposerDraft, EmbedDraft} from '#/view/com/composer/state/composer'
 import {createGIFDescription} from '../gif-alt-text'
@@ -101,78 +103,89 @@ export async function post(
     langs = opts.langs.slice(0, 3)
   }
 
-  let res
-  try {
-    opts.onStateChange?.(t`Posting...`)
-    res = await agent.post({
+  const rkey = TID.nextStr()
+  const uri = `at://${agent.assertDid}/app.bsky.feed.post/${rkey}`
+  const date = new Date().toISOString()
+
+  const writes: ComAtprotoRepoApplyWrites.Create[] = []
+
+  // Create post record
+  {
+    const record: AppBskyFeedPost.Record = {
+      $type: 'app.bsky.feed.post',
+      createdAt: date,
       text: rt.text,
       facets: rt.facets,
       reply,
       embed,
       langs,
       labels,
-    })
-  } catch (e: any) {
-    logger.error(`Failed to create post`, {
-      safeMessage: e.message,
-    })
-    if (isNetworkError(e)) {
-      throw new Error(
-        t`Post failed to upload. Please check your Internet connection and try again.`,
-      )
-    } else {
-      throw e
     }
+
+    writes.push({
+      $type: 'com.atproto.repo.applyWrites#create',
+      collection: 'app.bsky.feed.post',
+      rkey: rkey,
+      value: record,
+    })
   }
 
+  // Create threadgate record
   if (draft.threadgate.some(tg => tg.type !== 'everybody')) {
-    try {
-      // TODO: this needs to be batch-created with the post!
-      await writeThreadgateRecord({
-        agent,
-        postUri: res.uri,
-        threadgate: createThreadgateRecord({
-          post: res.uri,
-          allow: threadgateAllowUISettingToAllowRecordValue(draft.threadgate),
-        }),
-      })
-    } catch (e: any) {
-      logger.error(`Failed to create threadgate`, {
-        context: 'composer',
-        safeMessage: e.message,
-      })
-      throw new Error(
-        t`Failed to save post interaction settings. Your post was created but users may be able to interact with it.`,
-      )
-    }
+    const record = createThreadgateRecord({
+      createdAt: date,
+      post: uri,
+      allow: threadgateAllowUISettingToAllowRecordValue(draft.threadgate),
+    })
+
+    writes.push({
+      $type: 'com.atproto.repo.applyWrites#create',
+      collection: 'app.bsky.feed.threadgate',
+      rkey: rkey,
+      value: record,
+    })
   }
 
+  // Create postgate record
   if (
     draft.postgate.embeddingRules?.length ||
     draft.postgate.detachedEmbeddingUris?.length
   ) {
-    try {
-      // TODO: this needs to be batch-created with the post!
-      await writePostgateRecord({
-        agent,
-        postUri: res.uri,
-        postgate: {
-          ...draft.postgate,
-          post: res.uri,
-        },
-      })
-    } catch (e: any) {
-      logger.error(`Failed to create postgate`, {
-        context: 'composer',
-        safeMessage: e.message,
-      })
+    const record: AppBskyFeedPostgate.Record = {
+      ...draft.postgate,
+      $type: 'app.bsky.feed.postgate',
+      createdAt: date,
+      post: uri,
+    }
+
+    writes.push({
+      $type: 'com.atproto.repo.applyWrites#create',
+      collection: 'app.bsky.feed.postgate',
+      rkey: rkey,
+      value: record,
+    })
+  }
+
+  try {
+    await agent.com.atproto.repo.applyWrites({
+      repo: agent.assertDid,
+      writes: writes,
+      validate: true,
+    })
+  } catch (e: any) {
+    logger.error(`Failed to create post`, {
+      safeMessage: e.message,
+    })
+    if (isNetworkError(e)) {
       throw new Error(
-        t`Failed to save post interaction settings. Your post was created but users may be able to interact with it.`,
+        t`Post failed to upload. Please check your Internet connection and try again.`,
       )
+    } else {
+      throw e
     }
   }
 
-  return res
+  return {uri}
 }
 
 async function resolveEmbed(