Clean up onPostSuccess

This commit is contained in:
Eric Bailey
2025-05-21 17:15:26 -05:00
parent 6dd71ebae2
commit a16f5ecbff
7 changed files with 50 additions and 22 deletions
+14
View File
@@ -2,6 +2,7 @@ import React from 'react'
import { import {
type AppBskyActorDefs, type AppBskyActorDefs,
type AppBskyFeedDefs, type AppBskyFeedDefs,
type AppBskyUnspeccedGetPostThreadV2,
type ModerationDecision, type ModerationDecision,
} from '@atproto/api' } from '@atproto/api'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
@@ -24,9 +25,22 @@ export interface ComposerOptsPostRef {
moderation?: ModerationDecision moderation?: ModerationDecision
} }
export type OnPostSuccessData =
| {
type: 'post'
posts: AppBskyUnspeccedGetPostThreadV2.ThreadItem[]
}
| {
type: 'reply'
parent: AppBskyUnspeccedGetPostThreadV2.ThreadItem
replies: AppBskyUnspeccedGetPostThreadV2.ThreadItem[]
}
| undefined
export interface ComposerOpts { export interface ComposerOpts {
replyTo?: ComposerOptsPostRef replyTo?: ComposerOptsPostRef
onPost?: (postUri: string | undefined) => void onPost?: (postUri: string | undefined) => void
onPostSuccess?: (data: OnPostSuccessData) => void
quote?: AppBskyFeedDefs.PostView quote?: AppBskyFeedDefs.PostView
mention?: string // handle of user to mention mention?: string // handle of user to mention
openEmojiPicker?: (pos: EmojiPickerPosition | undefined) => void openEmojiPicker?: (pos: EmojiPickerPosition | undefined) => void
+20 -10
View File
@@ -45,7 +45,6 @@ import {type ImagePickerAsset} from 'expo-image-picker'
import { import {
AppBskyFeedDefs, AppBskyFeedDefs,
type AppBskyFeedGetPostThread, type AppBskyFeedGetPostThread,
type AppBskyUnspeccedGetPostThreadV2,
type BskyAgent, type BskyAgent,
type RichText, type RichText,
} from '@atproto/api' } from '@atproto/api'
@@ -89,7 +88,7 @@ import {useProfileQuery} from '#/state/queries/profile'
import {type Gif} from '#/state/queries/tenor' import {type Gif} from '#/state/queries/tenor'
import {useAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
import {useComposerControls} from '#/state/shell/composer' import {useComposerControls} from '#/state/shell/composer'
import {type ComposerOpts} from '#/state/shell/composer' import {type ComposerOpts, type OnPostSuccessData} from '#/state/shell/composer'
import {CharProgress} from '#/view/com/composer/char-progress/CharProgress' import {CharProgress} from '#/view/com/composer/char-progress/CharProgress'
import {ComposerReplyTo} from '#/view/com/composer/ComposerReplyTo' import {ComposerReplyTo} from '#/view/com/composer/ComposerReplyTo'
import { import {
@@ -154,6 +153,7 @@ type Props = ComposerOpts
export const ComposePost = ({ export const ComposePost = ({
replyTo, replyTo,
onPost, onPost,
onPostSuccess,
quote: initQuote, quote: initQuote,
mention: initMention, mention: initMention,
openEmojiPicker, openEmojiPicker,
@@ -391,7 +391,7 @@ export const ComposePost = ({
setIsPublishing(true) setIsPublishing(true)
let postUri: string | undefined let postUri: string | undefined
let posts: AppBskyUnspeccedGetPostThreadV2.OutputSchema['thread'] = [] let postSuccessData: OnPostSuccessData
try { try {
postUri = ( postUri = (
await apilib.post(agent, queryClient, { await apilib.post(agent, queryClient, {
@@ -403,7 +403,7 @@ export const ComposePost = ({
).uris[0] ).uris[0]
try { try {
if (postUri) { if (postUri) {
posts = await retry( const [maybeParent, maybeReply, ...posts] = await retry(
5, 5,
_e => true, _e => true,
async () => { async () => {
@@ -424,12 +424,19 @@ export const ComposePost = ({
}, },
1e3, 1e3,
) )
if (maybeReply && maybeReply.uri === postUri) {
postSuccessData = {
type: 'reply',
parent: maybeParent,
replies: [maybeReply, ...posts],
}
} else {
postSuccessData = {
type: 'post',
posts: [maybeParent, maybeReply, ...posts].filter(Boolean),
}
}
} }
await whenAppViewReady(agent, postUri, res => {
const postedThread = res?.data?.thread
return AppBskyFeedDefs.isThreadViewPost(postedThread)
})
} catch (waitErr: any) { } catch (waitErr: any) {
logger.error(waitErr, { logger.error(waitErr, {
message: `Waiting for app view failed`, message: `Waiting for app view failed`,
@@ -492,12 +499,14 @@ export const ComposePost = ({
quotedThread.post.quoteCount !== initQuote.quoteCount quotedThread.post.quoteCount !== initQuote.quoteCount
) { ) {
onPost?.(postUri) onPost?.(postUri)
onPostSuccess?.(postSuccessData)
return true return true
} }
return false return false
}) })
} else { } else {
onPost?.(postUri, posts) onPost?.(postUri)
onPostSuccess?.(postSuccessData)
} }
onClose() onClose()
Toast.show( Toast.show(
@@ -516,6 +525,7 @@ export const ComposePost = ({
langPrefs.postLanguage, langPrefs.postLanguage,
onClose, onClose,
onPost, onPost,
onPostSuccess,
initQuote, initQuote,
replyTo, replyTo,
setLangPrefs, setLangPrefs,
@@ -39,6 +39,7 @@ import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import {type ThreadPost} from '#/state/queries/post-thread' import {type ThreadPost} from '#/state/queries/post-thread'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {type OnPostSuccessData} from '#/state/shell/composer'
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
import {useUnstablePostSource} from '#/state/unstable-post-source' import {useUnstablePostSource} from '#/state/unstable-post-source'
import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn' import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn'
@@ -85,6 +86,7 @@ export function PostThreadItem({
hasPrecedingItem, hasPrecedingItem,
overrideBlur, overrideBlur,
onPostReply, onPostReply,
onPostSuccess,
hideTopBorder, hideTopBorder,
threadgateRecord, threadgateRecord,
}: { }: {
@@ -102,6 +104,7 @@ export function PostThreadItem({
hasPrecedingItem: boolean hasPrecedingItem: boolean
overrideBlur: boolean overrideBlur: boolean
onPostReply: (postUri: string | undefined) => void onPostReply: (postUri: string | undefined) => void
onPostSuccess?: (data: OnPostSuccessData) => void
hideTopBorder?: boolean hideTopBorder?: boolean
threadgateRecord?: AppBskyFeedThreadgate.Record threadgateRecord?: AppBskyFeedThreadgate.Record
}) { }) {
@@ -137,6 +140,7 @@ export function PostThreadItem({
hasPrecedingItem={hasPrecedingItem} hasPrecedingItem={hasPrecedingItem}
overrideBlur={overrideBlur} overrideBlur={overrideBlur}
onPostReply={onPostReply} onPostReply={onPostReply}
onPostSuccess={onPostSuccess}
hideTopBorder={hideTopBorder} hideTopBorder={hideTopBorder}
threadgateRecord={threadgateRecord} threadgateRecord={threadgateRecord}
/> />
@@ -182,6 +186,7 @@ let PostThreadItemLoaded = ({
hasPrecedingItem, hasPrecedingItem,
overrideBlur, overrideBlur,
onPostReply, onPostReply,
onPostSuccess,
hideTopBorder, hideTopBorder,
threadgateRecord, threadgateRecord,
}: { }: {
@@ -200,6 +205,7 @@ let PostThreadItemLoaded = ({
hasPrecedingItem: boolean hasPrecedingItem: boolean
overrideBlur: boolean overrideBlur: boolean
onPostReply: (postUri: string | undefined) => void onPostReply: (postUri: string | undefined) => void
onPostSuccess?: (data: OnPostSuccessData) => void
hideTopBorder?: boolean hideTopBorder?: boolean
threadgateRecord?: AppBskyFeedThreadgate.Record threadgateRecord?: AppBskyFeedThreadgate.Record
}): React.ReactNode => { }): React.ReactNode => {
@@ -294,6 +300,7 @@ let PostThreadItemLoaded = ({
moderation, moderation,
}, },
onPost: onPostReply, onPost: onPostReply,
onPostSuccess: onPostSuccess,
}) })
} }
+6 -12
View File
@@ -1,6 +1,5 @@
import {useCallback, useMemo, useRef, useState} from 'react' import {useCallback, useMemo, useRef, useState} from 'react'
import {useWindowDimensions, View} from 'react-native' import {useWindowDimensions, View} from 'react-native'
import {type AppBskyUnspeccedGetPostThreadV2} from '@atproto/api'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useFocusEffect} from '@react-navigation/native' import {useFocusEffect} from '@react-navigation/native'
@@ -26,6 +25,7 @@ import {
type Slice, type Slice,
usePostThread, usePostThread,
} from '#/state/queries/usePostThread' } from '#/state/queries/usePostThread'
import {type OnPostSuccessData} from '#/state/shell/composer'
import {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt' import {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt'
import {PostThreadItem} from '#/view/com/post-thread/PostThreadItem' import {PostThreadItem} from '#/view/com/post-thread/PostThreadItem'
import {PostThreadShowHiddenReplies} from '#/view/com/post-thread/PostThreadShowHiddenReplies' import {PostThreadShowHiddenReplies} from '#/view/com/post-thread/PostThreadShowHiddenReplies'
@@ -155,13 +155,9 @@ export function Inner({uri}: {uri: string | undefined}) {
}, },
}) })
const optimisticOnPostReply = ( const optimisticOnPostReply = (data: OnPostSuccessData) => {
_: any, if (data && data.type === 'reply') {
posts: AppBskyUnspeccedGetPostThreadV2.ThreadItem[], const {parent, replies} = data
) => {
if (posts.length) {
const parent = posts.at(0)
const replies = posts.slice(1)
if (parent && replies.length) { if (parent && replies.length) {
insertReplies(parent, replies) insertReplies(parent, replies)
} }
@@ -186,8 +182,7 @@ export function Inner({uri}: {uri: string | undefined}) {
embed: post.embed, embed: post.embed,
moderation: anchorPost.moderation, moderation: anchorPost.moderation,
}, },
// @ts-expect-error TODO onPostSuccess: optimisticOnPostReply,
onPost: optimisticOnPostReply,
}) })
} }
@@ -248,8 +243,7 @@ export function Inner({uri}: {uri: string | undefined}) {
overrideBlur={ overrideBlur={
shownHiddenReplyKinds.has(HiddenReplyKind.Muted) && item.depth > 0 shownHiddenReplyKinds.has(HiddenReplyKind.Muted) && item.depth > 0
} }
// @ts-expect-error TODO onPostSuccess={optimisticOnPostReply}
onPostReply={optimisticOnPostReply}
hideTopBorder={index === 0} // && !item.isParentLoading} // TODO hideTopBorder={index === 0} // && !item.isParentLoading} // TODO
/> />
</View> </View>
+1
View File
@@ -37,6 +37,7 @@ export function Composer({}: {winHeight: number}) {
cancelRef={ref} cancelRef={ref}
replyTo={state?.replyTo} replyTo={state?.replyTo}
onPost={state?.onPost} onPost={state?.onPost}
onPostSuccess={state?.onPostSuccess}
quote={state?.quote} quote={state?.quote}
mention={state?.mention} mention={state?.mention}
text={state?.text} text={state?.text}
+1
View File
@@ -49,6 +49,7 @@ export function Composer({winHeight}: {winHeight: number}) {
<ComposePost <ComposePost
replyTo={state.replyTo} replyTo={state.replyTo}
onPost={state.onPost} onPost={state.onPost}
onPostSuccess={state.onPostSuccess}
quote={state.quote} quote={state.quote}
mention={state.mention} mention={state.mention}
text={state.text} text={state.text}
+1
View File
@@ -105,6 +105,7 @@ function Inner({state}: {state: ComposerOpts}) {
replyTo={state.replyTo} replyTo={state.replyTo}
quote={state.quote} quote={state.quote}
onPost={state.onPost} onPost={state.onPost}
onPostSuccess={state.onPostSuccess}
mention={state.mention} mention={state.mention}
openEmojiPicker={onOpenPicker} openEmojiPicker={onOpenPicker}
text={state.text} text={state.text}