about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/state/events.ts8
-rw-r--r--src/state/queries/post-feed.ts2
-rw-r--r--src/view/com/composer/Composer.tsx45
-rw-r--r--src/view/com/posts/Feed.tsx25
4 files changed, 66 insertions, 14 deletions
diff --git a/src/state/events.ts b/src/state/events.ts
index 5441aafef..f85860823 100644
--- a/src/state/events.ts
+++ b/src/state/events.ts
@@ -36,3 +36,11 @@ export function listenSessionDropped(fn: () => void): UnlistenFn {
   emitter.on('session-dropped', fn)
   return () => emitter.off('session-dropped', fn)
 }
+
+export function emitPostCreated() {
+  emitter.emit('post-created')
+}
+export function listenPostCreated(fn: () => void): UnlistenFn {
+  emitter.on('post-created', fn)
+  return () => emitter.off('post-created', fn)
+}
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index 7589aa346..36e06cfab 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -248,7 +248,7 @@ export function findPostInQueryData(
 export function* findAllPostsInQueryData(
   queryClient: QueryClient,
   uri: string,
-): Generator<AppBskyFeedDefs.PostView, void> {
+): Generator<AppBskyFeedDefs.PostView, undefined> {
   const queryDatas = queryClient.getQueriesData<
     InfiniteData<FeedPageUnselected>
   >({
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 7336f3b95..d8af6d0ce 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -14,7 +14,7 @@ import {
 import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import LinearGradient from 'react-native-linear-gradient'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {RichText} from '@atproto/api'
+import {AppBskyFeedGetPosts, RichText} from '@atproto/api'
 import {useAnalytics} from 'lib/analytics/analytics'
 import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
 import {ExternalEmbed} from './ExternalEmbed'
@@ -59,6 +59,8 @@ import {
 import {useSession, getAgent} from '#/state/session'
 import {useProfileQuery} from '#/state/queries/profile'
 import {useComposerControls} from '#/state/shell/composer'
+import {until} from '#/lib/async/until'
+import {emitPostCreated} from '#/state/events'
 
 type Props = ComposerOpts
 export const ComposePost = observer(function ComposePost({
@@ -208,17 +210,20 @@ export const ComposePost = observer(function ComposePost({
 
     setIsProcessing(true)
 
+    let postUri
     try {
-      await apilib.post(getAgent(), {
-        rawText: richtext.text,
-        replyTo: replyTo?.uri,
-        images: gallery.images,
-        quote,
-        extLink,
-        labels,
-        onStateChange: setProcessingState,
-        langs: toPostLanguages(langPrefs.postLanguage),
-      })
+      postUri = (
+        await apilib.post(getAgent(), {
+          rawText: richtext.text,
+          replyTo: replyTo?.uri,
+          images: gallery.images,
+          quote,
+          extLink,
+          labels,
+          onStateChange: setProcessingState,
+          langs: toPostLanguages(langPrefs.postLanguage),
+        })
+      ).uri
     } catch (e: any) {
       if (extLink) {
         setExtLink({
@@ -236,8 +241,10 @@ export const ComposePost = observer(function ComposePost({
       })
       if (replyTo && replyTo.uri) track('Post:Reply')
     }
-    if (!replyTo) {
-      // TODO onPostCreated
+    if (postUri && !replyTo) {
+      whenAppViewReady(postUri).then(() => {
+        emitPostCreated()
+      })
     }
     setLangPrefs.savePostLanguageToHistory()
     onPost?.()
@@ -533,3 +540,15 @@ const styles = StyleSheet.create({
     borderTopWidth: 1,
   },
 })
+
+async function whenAppViewReady(uri: string) {
+  await until(
+    5, // 5 tries
+    1e3, // 1s delay between tries
+    (res: AppBskyFeedGetPosts.Response) => !!res.data.posts[0],
+    () =>
+      getAgent().getPosts({
+        uris: [uri],
+      }),
+  )
+}
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index ed00561ba..5da04e389 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -8,6 +8,7 @@ import {
   View,
   ViewStyle,
 } from 'react-native'
+import {useQueryClient} from '@tanstack/react-query'
 import {FlatList} from '../util/Views'
 import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
 import {FeedErrorMessage} from './FeedErrorMessage'
@@ -20,6 +21,7 @@ import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIX
 import {useTheme} from 'lib/ThemeContext'
 import {logger} from '#/logger'
 import {
+  RQKEY,
   FeedDescriptor,
   FeedParams,
   usePostFeedQuery,
@@ -27,6 +29,8 @@ import {
 } from '#/state/queries/post-feed'
 import {useModerationOpts} from '#/state/queries/preferences'
 import {isWeb} from '#/platform/detection'
+import {listenPostCreated} from '#/state/events'
+import {useSession} from '#/state/session'
 
 const LOADING_ITEM = {_reactKey: '__loading__'}
 const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
@@ -73,6 +77,8 @@ let Feed = ({
   const pal = usePalette('default')
   const theme = useTheme()
   const {track} = useAnalytics()
+  const queryClient = useQueryClient()
+  const {currentAccount} = useSession()
   const [isPTRing, setIsPTRing] = React.useState(false)
   const checkForNewRef = React.useRef<(() => void) | null>(null)
 
@@ -104,6 +110,25 @@ let Feed = ({
     }
   }, [feed, data, isFetching, onHasNew, enabled])
 
+  const myDid = currentAccount?.did || ''
+  const onPostCreated = React.useCallback(() => {
+    // NOTE
+    // only invalidate if there's 1 page
+    // more than 1 page can trigger some UI freakouts on iOS and android
+    // -prf
+    if (
+      data?.pages.length === 1 &&
+      (feed === 'following' ||
+        feed === 'home' ||
+        feed === `author|${myDid}|posts_no_replies`)
+    ) {
+      queryClient.invalidateQueries({queryKey: RQKEY(feed)})
+    }
+  }, [queryClient, feed, data, myDid])
+  React.useEffect(() => {
+    return listenPostCreated(onPostCreated)
+  }, [onPostCreated])
+
   React.useEffect(() => {
     // we store the interval handler in a ref to avoid needless
     // reassignments of the interval