about summary refs log tree commit diff
path: root/src/view/com/posts/Feed.tsx
diff options
context:
space:
mode:
authorAnsh <anshnanda10@gmail.com>2023-03-02 10:21:33 -0800
committerGitHub <noreply@github.com>2023-03-02 12:21:33 -0600
commitbd9386d81c258d3d3f43666d3e25328f68428689 (patch)
tree8008c5dcfc41f85aac24abac0f6fec08dea6296f /src/view/com/posts/Feed.tsx
parent9b46b2e6a9a8e4e9254fa9031b2eb44a672e287f (diff)
downloadvoidsky-bd9386d81c258d3d3f43666d3e25328f68428689.tar.zst
New onboarding (#241)
* delete old onboarding files and code

* add custom FollowButton component to Post, FeedItem, & ProfileCard

* move building suggested feed into helper lib

* show suggested posts/feed if follower list is empty

* Update tsconfig.json

* add pagination to getting new onboarding

* remove unnecessary console log

* fix naming, add better null check for combinedCursor

* In locally-combined feeds, correctly produce an undefined cursor when out of data

* Minor refactors of the suggested posts lib functions

* Show 'follow button' style of post meta in certain conditions only

* Only show follow btn in posts on the main feed and the discovery feed

* Add a welcome notice to the home feed

* Tune the timing of when the welcome banner shows or hides

* Make the follow button an observer (closes #244)

* Update postmeta to keep the follow btn after press until next render

* A couple of fixes that ensure consistent welcome screen

* Fix lint

* Rework the welcome banner

* Fix cache invalidation of follows model on user switch

* Show welcome banner while loading

* Update the home onboarding feed to get top posts from hardcode recommends

* Drop unused helper function

* Update happy path tests

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/view/com/posts/Feed.tsx')
-rw-r--r--src/view/com/posts/Feed.tsx41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index 7e5d166d2..03a719f16 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -13,16 +13,21 @@ import {EmptyState} from '../util/EmptyState'
 import {ErrorMessage} from '../util/error/ErrorMessage'
 import {FeedModel} from 'state/models/feed-view'
 import {FeedItem} from './FeedItem'
+import {WelcomeBanner} from '../util/WelcomeBanner'
 import {OnScrollCb} from 'lib/hooks/useOnMainScroll'
 import {s} from 'lib/styles'
 import {useAnalytics} from 'lib/analytics'
+import {useStores} from 'state/index'
 
 const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
 const ERROR_FEED_ITEM = {_reactKey: '__error__'}
+const WELCOME_FEED_ITEM = {_reactKey: '__welcome__'}
 
 export const Feed = observer(function Feed({
   feed,
   style,
+  showWelcomeBanner,
+  showPostFollowBtn,
   scrollElRef,
   onPressTryAgain,
   onScroll,
@@ -31,6 +36,8 @@ export const Feed = observer(function Feed({
 }: {
   feed: FeedModel
   style?: StyleProp<ViewStyle>
+  showWelcomeBanner?: boolean
+  showPostFollowBtn?: boolean
   scrollElRef?: MutableRefObject<FlatList<any> | null>
   onPressTryAgain?: () => void
   onScroll?: OnScrollCb
@@ -38,7 +45,9 @@ export const Feed = observer(function Feed({
   headerOffset?: number
 }) {
   const {track} = useAnalytics()
+  const store = useStores()
   const [isRefreshing, setIsRefreshing] = React.useState(false)
+  const [isNewUser, setIsNewUser] = React.useState<boolean>(false)
 
   const data = React.useMemo(() => {
     let feedItems: any[] = []
@@ -46,6 +55,9 @@ export const Feed = observer(function Feed({
       if (feed.hasError) {
         feedItems = feedItems.concat([ERROR_FEED_ITEM])
       }
+      if (showWelcomeBanner && isNewUser) {
+        feedItems = feedItems.concat([WELCOME_FEED_ITEM])
+      }
       if (feed.isEmpty) {
         feedItems = feedItems.concat([EMPTY_FEED_ITEM])
       } else {
@@ -53,21 +65,39 @@ export const Feed = observer(function Feed({
       }
     }
     return feedItems
-  }, [feed.hasError, feed.hasLoaded, feed.isEmpty, feed.feed])
+  }, [
+    feed.hasError,
+    feed.hasLoaded,
+    feed.isEmpty,
+    feed.feed,
+    showWelcomeBanner,
+    isNewUser,
+  ])
 
   // events
   // =
 
+  const checkWelcome = React.useCallback(async () => {
+    if (showWelcomeBanner) {
+      await store.me.follows.fetchIfNeeded()
+      setIsNewUser(store.me.follows.isEmpty)
+    }
+  }, [showWelcomeBanner, store.me.follows])
+  React.useEffect(() => {
+    checkWelcome()
+  }, [checkWelcome])
+
   const onRefresh = React.useCallback(async () => {
     track('Feed:onRefresh')
     setIsRefreshing(true)
+    checkWelcome()
     try {
       await feed.refresh()
     } catch (err) {
       feed.rootStore.log.error('Failed to refresh posts feed', err)
     }
     setIsRefreshing(false)
-  }, [feed, track, setIsRefreshing])
+  }, [feed, track, setIsRefreshing, checkWelcome])
   const onEndReached = React.useCallback(async () => {
     track('Feed:onEndReached')
     try {
@@ -101,10 +131,12 @@ export const Feed = observer(function Feed({
             onPressTryAgain={onPressTryAgain}
           />
         )
+      } else if (item === WELCOME_FEED_ITEM) {
+        return <WelcomeBanner />
       }
-      return <FeedItem item={item} />
+      return <FeedItem item={item} showFollowBtn={showPostFollowBtn} />
     },
-    [feed, onPressTryAgain],
+    [feed, onPressTryAgain, showPostFollowBtn],
   )
 
   const FeedFooter = React.useCallback(
@@ -123,6 +155,7 @@ export const Feed = observer(function Feed({
     <View testID={testID} style={style}>
       {feed.isLoading && data.length === 0 && (
         <CenteredView style={{paddingTop: headerOffset}}>
+          {showWelcomeBanner && isNewUser && <WelcomeBanner />}
           <PostFeedLoadingPlaceholder />
         </CenteredView>
       )}