about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-05-17 23:32:19 -0500
committerPaul Frazee <pfrazee@gmail.com>2023-05-17 23:32:19 -0500
commit129fc42e95605617e4dd6509a0458a2b66527ad0 (patch)
treead440b075879540cd739bcf960471a82d30e6a91 /src
parentbec94ed82c47f9a5275cbc5fc740dd97dda10183 (diff)
downloadvoidsky-129fc42e95605617e4dd6509a0458a2b66527ad0.tar.zst
Improve pinned feed management
Diffstat (limited to 'src')
-rw-r--r--src/state/models/ui/saved-feeds.ts2
-rw-r--r--src/view/com/pager/Pager.tsx125
-rw-r--r--src/view/screens/Home.tsx23
3 files changed, 79 insertions, 71 deletions
diff --git a/src/state/models/ui/saved-feeds.ts b/src/state/models/ui/saved-feeds.ts
index 50bb1b871..d68664c2d 100644
--- a/src/state/models/ui/saved-feeds.ts
+++ b/src/state/models/ui/saved-feeds.ts
@@ -81,7 +81,7 @@ export class SavedFeedsModel {
 
   togglePinnedFeed(feed: CustomFeedModel) {
     if (!this.isPinned(feed)) {
-      this.pinned.push(feed)
+      this.pinned = [...this.pinned, feed]
     } else {
       this.removePinnedFeed(feed.data.uri)
     }
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index 34747db6d..e2c8bf6d2 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -1,16 +1,17 @@
-import React from 'react'
+import React, {forwardRef} from 'react'
 import {Animated, View} from 'react-native'
 import PagerView, {PagerViewOnPageSelectedEvent} from 'react-native-pager-view'
-import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
 import {s} from 'lib/styles'
 
 export type PageSelectedEvent = PagerViewOnPageSelectedEvent
 const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
 
+export interface PagerRef {
+  setPage: (index: number) => void
+}
+
 export interface RenderTabBarFnProps {
   selectedPage: number
-  position: Animated.Value
-  offset: Animated.Value
   onSelect?: (index: number) => void
 }
 export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
@@ -22,68 +23,60 @@ interface Props {
   onPageSelected?: (index: number) => void
   testID?: string
 }
-export const Pager = ({
-  children,
-  tabBarPosition = 'top',
-  initialPage = 0,
-  renderTabBar,
-  onPageSelected,
-  testID,
-}: React.PropsWithChildren<Props>) => {
-  const [selectedPage, setSelectedPage] = React.useState(0)
-  const position = useAnimatedValue(0)
-  const offset = useAnimatedValue(0)
-  const pagerView = React.useRef<PagerView>()
+export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
+  (
+    {
+      children,
+      tabBarPosition = 'top',
+      initialPage = 0,
+      renderTabBar,
+      onPageSelected,
+      testID,
+    }: React.PropsWithChildren<Props>,
+    ref,
+  ) => {
+    const [selectedPage, setSelectedPage] = React.useState(0)
+    const pagerView = React.useRef<PagerView>()
 
-  const onPageSelectedInner = React.useCallback(
-    (e: PageSelectedEvent) => {
-      setSelectedPage(e.nativeEvent.position)
-      onPageSelected?.(e.nativeEvent.position)
-    },
-    [setSelectedPage, onPageSelected],
-  )
+    React.useImperativeHandle(ref, () => ({
+      setPage: (index: number) => pagerView.current?.setPage(index),
+    }))
 
-  const onTabBarSelect = React.useCallback(
-    (index: number) => {
-      pagerView.current?.setPage(index)
-    },
-    [pagerView],
-  )
+    const onPageSelectedInner = React.useCallback(
+      (e: PageSelectedEvent) => {
+        setSelectedPage(e.nativeEvent.position)
+        onPageSelected?.(e.nativeEvent.position)
+      },
+      [setSelectedPage, onPageSelected],
+    )
 
-  return (
-    <View testID={testID}>
-      {tabBarPosition === 'top' &&
-        renderTabBar({
-          selectedPage,
-          position,
-          offset,
-          onSelect: onTabBarSelect,
-        })}
-      <AnimatedPagerView
-        ref={pagerView}
-        style={s.h100pct}
-        initialPage={initialPage}
-        onPageSelected={onPageSelectedInner}
-        onPageScroll={Animated.event(
-          [
-            {
-              nativeEvent: {
-                position: position,
-                offset: offset,
-              },
-            },
-          ],
-          {useNativeDriver: true},
-        )}>
-        {children}
-      </AnimatedPagerView>
-      {tabBarPosition === 'bottom' &&
-        renderTabBar({
-          selectedPage,
-          position,
-          offset,
-          onSelect: onTabBarSelect,
-        })}
-    </View>
-  )
-}
+    const onTabBarSelect = React.useCallback(
+      (index: number) => {
+        pagerView.current?.setPage(index)
+      },
+      [pagerView],
+    )
+
+    return (
+      <View testID={testID}>
+        {tabBarPosition === 'top' &&
+          renderTabBar({
+            selectedPage,
+            onSelect: onTabBarSelect,
+          })}
+        <AnimatedPagerView
+          ref={pagerView}
+          style={s.h100pct}
+          initialPage={initialPage}
+          onPageSelected={onPageSelectedInner}>
+          {children}
+        </AnimatedPagerView>
+        {tabBarPosition === 'bottom' &&
+          renderTabBar({
+            selectedPage,
+            onSelect: onTabBarSelect,
+          })}
+      </View>
+    )
+  },
+)
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 9be4a4794..644182126 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -1,6 +1,7 @@
 import React from 'react'
 import {FlatList, View} from 'react-native'
 import {useFocusEffect, useIsFocused} from '@react-navigation/native'
+import {AppBskyFeedGetFeed as GetCustomFeed} from '@atproto/api'
 import {observer} from 'mobx-react-lite'
 import useAppState from 'react-native-appstate-hook'
 import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
@@ -12,7 +13,7 @@ import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
 import {WhatsHotEmptyState} from 'view/com/posts/WhatsHotEmptyState'
 import {LoadLatestBtn} from '../com/util/load-latest/LoadLatestBtn'
 import {FeedsTabBar} from '../com/pager/FeedsTabBar'
-import {Pager, RenderTabBarFnProps} from 'view/com/pager/Pager'
+import {Pager, PagerRef, RenderTabBarFnProps} from 'view/com/pager/Pager'
 import {FAB} from '../com/util/fab/FAB'
 import {SavedFeeds} from 'view/com/feeds/SavedFeeds'
 import {useStores} from 'state/index'
@@ -29,7 +30,9 @@ type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
 export const HomeScreen = withAuthRequired(
   observer((_opts: Props) => {
     const store = useStores()
+    const pagerRef = React.useRef<PagerRef>(null)
     const [selectedPage, setSelectedPage] = React.useState(0)
+    const [customFeeds, setCustomFeeds] = React.useState<PostsFeedModel[]>([])
     const [initialLanguages] = React.useState(
       store.preferences.contentLanguages,
     )
@@ -41,6 +44,17 @@ export const HomeScreen = withAuthRequired(
     }, [store])
 
     React.useEffect(() => {
+      const feeds = []
+      for (const feed of store.me.savedFeeds.pinned) {
+        const model = new PostsFeedModel(store, 'custom', {feed: feed.uri})
+        model.setup()
+        feeds.push(model)
+      }
+      pagerRef.current?.setPage(0)
+      setCustomFeeds(feeds)
+    }, [store, store.me.savedFeeds.pinned, setCustomFeeds])
+
+    React.useEffect(() => {
       // refresh whats hot when lang preferences change
       if (initialLanguages !== store.preferences.contentLanguages) {
         algoFeed.refresh()
@@ -94,6 +108,7 @@ export const HomeScreen = withAuthRequired(
     const initialPage = store.me.followsCount === 0 ? 1 : 0
     return (
       <Pager
+        ref={pagerRef}
         testID="homeScreen"
         onPageSelected={onPageSelected}
         renderTabBar={renderTabBar}
@@ -113,13 +128,13 @@ export const HomeScreen = withAuthRequired(
           feed={algoFeed}
           renderEmptyState={renderWhatsHotEmptyState}
         />
-        {store.me.savedFeeds.pinned.map((f, index) => {
+        {customFeeds.map((f, index) => {
           return (
             <FeedPage
-              key={String(3 + index)}
+              key={(f.params as GetCustomFeed.QueryParams).feed}
               testID="customFeedPage"
               isPageFocused={selectedPage === 2 + index}
-              feed={new PostsFeedModel(store, 'custom', {feed: f.uri})}
+              feed={f}
               renderEmptyState={renderFollowingEmptyState}
             />
           )