about summary refs log tree commit diff
path: root/src/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/Search/Explore.tsx14
-rw-r--r--src/screens/Search/modules/ExploreFeedPreviews.tsx264
2 files changed, 9 insertions, 269 deletions
diff --git a/src/screens/Search/Explore.tsx b/src/screens/Search/Explore.tsx
index 33d8d343c..b8fc644e1 100644
--- a/src/screens/Search/Explore.tsx
+++ b/src/screens/Search/Explore.tsx
@@ -15,6 +15,10 @@ import {logger} from '#/logger'
 import {type MetricEvents} from '#/logger/metrics'
 import {useModerationOpts} from '#/state/preferences/moderation-opts'
 import {useActorSearchPaginated} from '#/state/queries/actor-search'
+import {
+  type FeedPreviewItem,
+  useFeedPreviews,
+} from '#/state/queries/explore-feed-previews'
 import {useGetPopularFeedsQuery} from '#/state/queries/feed'
 import {usePreferencesQuery} from '#/state/queries/preferences'
 import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
@@ -48,10 +52,6 @@ import * as ProfileCard from '#/components/ProfileCard'
 import {Text} from '#/components/Typography'
 import * as ModuleHeader from './components/ModuleHeader'
 import {
-  type FeedPreviewItem,
-  useFeedPreviews,
-} from './modules/ExploreFeedPreviews'
-import {
   SuggestedAccountsTabBar,
   SuggestedProfileCard,
   useLoadEnoughProfiles,
@@ -900,7 +900,7 @@ export function Explore({
     <List
       data={items}
       renderItem={renderItem}
-      keyExtractor={item => item.key}
+      keyExtractor={keyExtractor}
       desktopFixedHeight
       contentContainerStyle={{paddingBottom: 100}}
       keyboardShouldPersistTaps="handled"
@@ -914,6 +914,10 @@ export function Explore({
   )
 }
 
+function keyExtractor(item: FeedPreviewItem) {
+  return item.key
+}
+
 const viewabilityConfig: ViewabilityConfig = {
   itemVisiblePercentThreshold: 100,
 }
diff --git a/src/screens/Search/modules/ExploreFeedPreviews.tsx b/src/screens/Search/modules/ExploreFeedPreviews.tsx
deleted file mode 100644
index 30aa00a3f..000000000
--- a/src/screens/Search/modules/ExploreFeedPreviews.tsx
+++ /dev/null
@@ -1,264 +0,0 @@
-import {useMemo} from 'react'
-import {type AppBskyFeedDefs, moderatePost} from '@atproto/api'
-import {msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useInfiniteQuery} from '@tanstack/react-query'
-
-import {CustomFeedAPI} from '#/lib/api/feed/custom'
-import {aggregateUserInterests} from '#/lib/api/feed/utils'
-import {FeedTuner} from '#/lib/api/feed-manip'
-import {cleanError} from '#/lib/strings/errors'
-import {useModerationOpts} from '#/state/preferences/moderation-opts'
-import {
-  type FeedPostSlice,
-  type FeedPostSliceItem,
-} from '#/state/queries/post-feed'
-import {usePreferencesQuery} from '#/state/queries/preferences'
-import {useAgent} from '#/state/session'
-
-const RQKEY_ROOT = 'feed-previews'
-const RQKEY = (feeds: string[]) => [RQKEY_ROOT, feeds]
-
-const LIMIT = 8 // sliced to 6, overfetch to account for moderation
-
-export type FeedPreviewItem =
-  | {
-      type: 'topBorder'
-      key: string
-    }
-  | {
-      type: 'preview:loading'
-      key: string
-    }
-  | {
-      type: 'preview:error'
-      key: string
-      message: string
-      error: string
-    }
-  | {
-      type: 'preview:loadMoreError'
-      key: string
-    }
-  | {
-      type: 'preview:empty'
-      key: string
-    }
-  | {
-      type: 'preview:header'
-      key: string
-      feed: AppBskyFeedDefs.GeneratorView
-    }
-  | {
-      type: 'preview:footer'
-      key: string
-    }
-  // copied from PostFeed.tsx
-  | {
-      type: 'preview:sliceItem'
-      key: string
-      slice: FeedPostSlice
-      indexInSlice: number
-      showReplyTo: boolean
-      hideTopBorder: boolean
-    }
-  | {
-      type: 'preview:sliceViewFullThread'
-      key: string
-      uri: string
-    }
-
-export function useFeedPreviews(feeds: AppBskyFeedDefs.GeneratorView[]) {
-  const uris = feeds.map(feed => feed.uri)
-  const {_} = useLingui()
-  const agent = useAgent()
-  const {data: preferences} = usePreferencesQuery()
-  const userInterests = aggregateUserInterests(preferences)
-  const moderationOpts = useModerationOpts()
-  const enabled = feeds.length > 0
-
-  const query = useInfiniteQuery({
-    enabled,
-    queryKey: RQKEY(uris),
-    queryFn: async ({pageParam}) => {
-      const feed = feeds[pageParam]
-      const api = new CustomFeedAPI({
-        agent,
-        feedParams: {feed: feed.uri},
-        userInterests,
-      })
-      const data = await api.fetch({cursor: undefined, limit: LIMIT})
-      return {
-        feed,
-        posts: data.feed,
-      }
-    },
-    initialPageParam: 0,
-    getNextPageParam: (_p, _a, count) =>
-      count < feeds.length ? count + 1 : undefined,
-  })
-
-  const {data, isFetched, isError, isPending, error} = query
-
-  return {
-    query,
-    data: useMemo<FeedPreviewItem[]>(() => {
-      const items: FeedPreviewItem[] = []
-
-      if (!enabled) return items
-
-      const isEmpty =
-        !isPending && !data?.pages?.some(page => page.posts.length)
-
-      if (isFetched) {
-        if (isError && isEmpty) {
-          items.push({
-            type: 'preview:error',
-            key: 'error',
-            message: _(msg`An error occurred while fetching the feed.`),
-            error: cleanError(error),
-          })
-        } else if (isEmpty) {
-          items.push({
-            type: 'preview:empty',
-            key: 'empty',
-          })
-        } else if (data) {
-          for (let pageIndex = 0; pageIndex < data.pages.length; pageIndex++) {
-            const page = data.pages[pageIndex]
-            // default feed tuner - we just want it to slice up the feed
-            const tuner = new FeedTuner([])
-            const slices: FeedPreviewItem[] = []
-
-            let rowIndex = 0
-            for (const item of tuner.tune(page.posts)) {
-              if (item.isFallbackMarker) continue
-
-              const moderations = item.items.map(item =>
-                moderatePost(item.post, moderationOpts!),
-              )
-
-              // apply moderation filters
-              item.items = item.items.filter((_, i) => {
-                return !moderations[i]?.ui('contentList').filter
-              })
-
-              const slice = {
-                _reactKey: item._reactKey,
-                _isFeedPostSlice: true,
-                isFallbackMarker: false,
-                isIncompleteThread: item.isIncompleteThread,
-                feedContext: item.feedContext,
-                reason: item.reason,
-                feedPostUri: item.feedPostUri,
-                items: item.items.slice(0, 6).map((subItem, i) => {
-                  const feedPostSliceItem: FeedPostSliceItem = {
-                    _reactKey: `${item._reactKey}-${i}-${subItem.post.uri}`,
-                    uri: subItem.post.uri,
-                    post: subItem.post,
-                    record: subItem.record,
-                    moderation: moderations[i],
-                    parentAuthor: subItem.parentAuthor,
-                    isParentBlocked: subItem.isParentBlocked,
-                    isParentNotFound: subItem.isParentNotFound,
-                  }
-                  return feedPostSliceItem
-                }),
-              }
-              if (slice.isIncompleteThread && slice.items.length >= 3) {
-                const beforeLast = slice.items.length - 2
-                const last = slice.items.length - 1
-                slices.push({
-                  type: 'preview:sliceItem',
-                  key: slice.items[0]._reactKey,
-                  slice: slice,
-                  indexInSlice: 0,
-                  showReplyTo: false,
-                  hideTopBorder: rowIndex === 0,
-                })
-                slices.push({
-                  type: 'preview:sliceViewFullThread',
-                  key: slice._reactKey + '-viewFullThread',
-                  uri: slice.items[0].uri,
-                })
-                slices.push({
-                  type: 'preview:sliceItem',
-                  key: slice.items[beforeLast]._reactKey,
-                  slice: slice,
-                  indexInSlice: beforeLast,
-                  showReplyTo:
-                    slice.items[beforeLast].parentAuthor?.did !==
-                    slice.items[beforeLast].post.author.did,
-                  hideTopBorder: false,
-                })
-                slices.push({
-                  type: 'preview:sliceItem',
-                  key: slice.items[last]._reactKey,
-                  slice: slice,
-                  indexInSlice: last,
-                  showReplyTo: false,
-                  hideTopBorder: false,
-                })
-              } else {
-                for (let i = 0; i < slice.items.length; i++) {
-                  slices.push({
-                    type: 'preview:sliceItem',
-                    key: slice.items[i]._reactKey,
-                    slice: slice,
-                    indexInSlice: i,
-                    showReplyTo: i === 0,
-                    hideTopBorder: i === 0 && rowIndex === 0,
-                  })
-                }
-              }
-
-              rowIndex++
-            }
-
-            if (slices.length > 0) {
-              if (pageIndex > 0) {
-                items.push({
-                  type: 'topBorder',
-                  key: `topBorder-${page.feed.uri}`,
-                })
-              }
-              items.push(
-                {
-                  type: 'preview:footer',
-                  key: `footer-${page.feed.uri}`,
-                },
-                {
-                  type: 'preview:header',
-                  key: `header-${page.feed.uri}`,
-                  feed: page.feed,
-                },
-                ...slices,
-              )
-            }
-          }
-        } else if (isError && !isEmpty) {
-          items.push({
-            type: 'preview:loadMoreError',
-            key: 'loadMoreError',
-          })
-        }
-      } else {
-        items.push({
-          type: 'preview:loading',
-          key: 'loading',
-        })
-      }
-
-      return items
-    }, [
-      enabled,
-      data,
-      isFetched,
-      isError,
-      isPending,
-      moderationOpts,
-      _,
-      error,
-    ]),
-  }
-}