diff --git a/src/state/queries/usePostThread/queryCache.ts b/src/state/queries/usePostThread/queryCache.ts index 17cec359d1..88180d2318 100644 --- a/src/state/queries/usePostThread/queryCache.ts +++ b/src/state/queries/usePostThread/queryCache.ts @@ -33,7 +33,7 @@ export function createCacheMutator({ }) { return { insertReplies( - parent: AppBskyUnspeccedGetPostThreadV2.ThreadItem, + parentUri: string, replies: AppBskyUnspeccedGetPostThreadV2.ThreadItem[], ) { queryClient.setQueryData( @@ -51,16 +51,14 @@ export function createCacheMutator({ ) ) continue - if (!AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(parent.value)) - continue - if (existingParent.uri !== parent.uri) continue + if (existingParent.uri !== parentUri) continue /* * Update parent data */ existingParent.value.post = { ...existingParent.value.post, - replyCount: parent.value.post.replyCount, + replyCount: (existingParent.value.post.replyCount || 0) + 1, } const opDid = getRootPostAtUri(existingParent.value.post)?.host diff --git a/src/state/shell/composer/index.tsx b/src/state/shell/composer/index.tsx index bdbf873e5e..b317942480 100644 --- a/src/state/shell/composer/index.tsx +++ b/src/state/shell/composer/index.tsx @@ -27,14 +27,9 @@ export interface ComposerOptsPostRef { export type OnPostSuccessData = | { - type: 'post' + replyToUri?: string posts: AppBskyUnspeccedGetPostThreadV2.ThreadItem[] } - | { - type: 'reply' - parent: AppBskyUnspeccedGetPostThreadV2.ThreadItem - replies: AppBskyUnspeccedGetPostThreadV2.ThreadItem[] - } | undefined export interface ComposerOpts { diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index ebc4d7ce0f..67e6c08437 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -45,6 +45,7 @@ import {type ImagePickerAsset} from 'expo-image-picker' import { AppBskyFeedDefs, type AppBskyFeedGetPostThread, + AppBskyUnspeccedGetPostThreadV2, type BskyAgent, type RichText, } from '@atproto/api' @@ -393,6 +394,7 @@ export const ComposePost = ({ let postUri: string | undefined let postSuccessData: OnPostSuccessData try { + logger.info(`composer: posting...`) postUri = ( await apilib.post(agent, queryClient, { thread, @@ -401,47 +403,48 @@ export const ComposePost = ({ langs: toPostLanguages(langPrefs.postLanguage), }) ).uris[0] + + /* + * Wait for app view to have received the post(s). If this fails, it's + * ok, because the post _was_ actually published above. + */ try { if (postUri) { - const [maybeParent, maybeReply, ...posts] = await retry( + logger.info(`composer: waiting for app view`) + + const posts = await retry( 5, _e => true, async () => { const res = await agent.app.bsky.unspecced.getPostThreadV2({ - uri: postUri!, - above: 1, + anchor: postUri!, + above: false, below: thread.posts.length - 1, - nestedBranchingFactor: 1, + branchingFactor: 1, }) - const parent = res.data.thread.at(0) - if (!parent) { - throw new Error(`Not ready`) + if (res.data.thread.length !== thread.posts.length) { + throw new Error(`composer: app view is not ready`) } - if (res.data.thread.length !== thread.posts.length + 1) { - throw new Error(`Not ready`) + if ( + !res.data.thread.every(p => + AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(p.value), + ) + ) { + throw new Error(`composer: app view returned non-post items`) } return res.data.thread }, 1e3, ) - if (maybeReply && maybeReply.uri === postUri) { - postSuccessData = { - type: 'reply', - parent: maybeParent, - replies: [maybeReply, ...posts], - } - } else { - postSuccessData = { - type: 'post', - posts: [maybeParent, maybeReply, ...posts].filter(Boolean), - } + postSuccessData = { + replyToUri: replyTo?.uri, + posts, } } } catch (waitErr: any) { - logger.error(waitErr, { - message: `Waiting for app view failed`, + logger.info(`composer: waiting for app view failed`, { + safeMessage: waitErr, }) - // Keep going because the post *was* published. } } catch (e: any) { logger.error(e, { diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx index b8debaa929..1e90169f2a 100644 --- a/src/view/screens/PostThread.tsx +++ b/src/view/screens/PostThread.tsx @@ -151,10 +151,10 @@ export function Inner({uri}: {uri: string | undefined}) { }) const optimisticOnPostReply = (data: OnPostSuccessData) => { - if (data && data.type === 'reply') { - const {parent, replies} = data - if (parent && replies.length) { - insertReplies(parent, replies) + if (data) { + const {replyToUri, posts} = data + if (replyToUri && posts.length) { + insertReplies(replyToUri, posts) } } }