Clean up onPostSuccess
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user