mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve pinned feed management

+79 -71
+1 -1
src/state/models/ui/saved-feeds.ts
··· 81 81 82 82 togglePinnedFeed(feed: CustomFeedModel) { 83 83 if (!this.isPinned(feed)) { 84 - this.pinned.push(feed) 84 + this.pinned = [...this.pinned, feed] 85 85 } else { 86 86 this.removePinnedFeed(feed.data.uri) 87 87 }
+59 -66
src/view/com/pager/Pager.tsx
··· 1 - import React from 'react' 1 + import React, {forwardRef} from 'react' 2 2 import {Animated, View} from 'react-native' 3 3 import PagerView, {PagerViewOnPageSelectedEvent} from 'react-native-pager-view' 4 - import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 5 4 import {s} from 'lib/styles' 6 5 7 6 export type PageSelectedEvent = PagerViewOnPageSelectedEvent 8 7 const AnimatedPagerView = Animated.createAnimatedComponent(PagerView) 9 8 9 + export interface PagerRef { 10 + setPage: (index: number) => void 11 + } 12 + 10 13 export interface RenderTabBarFnProps { 11 14 selectedPage: number 12 - position: Animated.Value 13 - offset: Animated.Value 14 15 onSelect?: (index: number) => void 15 16 } 16 17 export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element ··· 22 23 onPageSelected?: (index: number) => void 23 24 testID?: string 24 25 } 25 - export const Pager = ({ 26 - children, 27 - tabBarPosition = 'top', 28 - initialPage = 0, 29 - renderTabBar, 30 - onPageSelected, 31 - testID, 32 - }: React.PropsWithChildren<Props>) => { 33 - const [selectedPage, setSelectedPage] = React.useState(0) 34 - const position = useAnimatedValue(0) 35 - const offset = useAnimatedValue(0) 36 - const pagerView = React.useRef<PagerView>() 26 + export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>( 27 + ( 28 + { 29 + children, 30 + tabBarPosition = 'top', 31 + initialPage = 0, 32 + renderTabBar, 33 + onPageSelected, 34 + testID, 35 + }: React.PropsWithChildren<Props>, 36 + ref, 37 + ) => { 38 + const [selectedPage, setSelectedPage] = React.useState(0) 39 + const pagerView = React.useRef<PagerView>() 40 + 41 + React.useImperativeHandle(ref, () => ({ 42 + setPage: (index: number) => pagerView.current?.setPage(index), 43 + })) 37 44 38 - const onPageSelectedInner = React.useCallback( 39 - (e: PageSelectedEvent) => { 40 - setSelectedPage(e.nativeEvent.position) 41 - onPageSelected?.(e.nativeEvent.position) 42 - }, 43 - [setSelectedPage, onPageSelected], 44 - ) 45 + const onPageSelectedInner = React.useCallback( 46 + (e: PageSelectedEvent) => { 47 + setSelectedPage(e.nativeEvent.position) 48 + onPageSelected?.(e.nativeEvent.position) 49 + }, 50 + [setSelectedPage, onPageSelected], 51 + ) 45 52 46 - const onTabBarSelect = React.useCallback( 47 - (index: number) => { 48 - pagerView.current?.setPage(index) 49 - }, 50 - [pagerView], 51 - ) 53 + const onTabBarSelect = React.useCallback( 54 + (index: number) => { 55 + pagerView.current?.setPage(index) 56 + }, 57 + [pagerView], 58 + ) 52 59 53 - return ( 54 - <View testID={testID}> 55 - {tabBarPosition === 'top' && 56 - renderTabBar({ 57 - selectedPage, 58 - position, 59 - offset, 60 - onSelect: onTabBarSelect, 61 - })} 62 - <AnimatedPagerView 63 - ref={pagerView} 64 - style={s.h100pct} 65 - initialPage={initialPage} 66 - onPageSelected={onPageSelectedInner} 67 - onPageScroll={Animated.event( 68 - [ 69 - { 70 - nativeEvent: { 71 - position: position, 72 - offset: offset, 73 - }, 74 - }, 75 - ], 76 - {useNativeDriver: true}, 77 - )}> 78 - {children} 79 - </AnimatedPagerView> 80 - {tabBarPosition === 'bottom' && 81 - renderTabBar({ 82 - selectedPage, 83 - position, 84 - offset, 85 - onSelect: onTabBarSelect, 86 - })} 87 - </View> 88 - ) 89 - } 60 + return ( 61 + <View testID={testID}> 62 + {tabBarPosition === 'top' && 63 + renderTabBar({ 64 + selectedPage, 65 + onSelect: onTabBarSelect, 66 + })} 67 + <AnimatedPagerView 68 + ref={pagerView} 69 + style={s.h100pct} 70 + initialPage={initialPage} 71 + onPageSelected={onPageSelectedInner}> 72 + {children} 73 + </AnimatedPagerView> 74 + {tabBarPosition === 'bottom' && 75 + renderTabBar({ 76 + selectedPage, 77 + onSelect: onTabBarSelect, 78 + })} 79 + </View> 80 + ) 81 + }, 82 + )
+19 -4
src/view/screens/Home.tsx
··· 1 1 import React from 'react' 2 2 import {FlatList, View} from 'react-native' 3 3 import {useFocusEffect, useIsFocused} from '@react-navigation/native' 4 + import {AppBskyFeedGetFeed as GetCustomFeed} from '@atproto/api' 4 5 import {observer} from 'mobx-react-lite' 5 6 import useAppState from 'react-native-appstate-hook' 6 7 import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types' ··· 12 13 import {WhatsHotEmptyState} from 'view/com/posts/WhatsHotEmptyState' 13 14 import {LoadLatestBtn} from '../com/util/load-latest/LoadLatestBtn' 14 15 import {FeedsTabBar} from '../com/pager/FeedsTabBar' 15 - import {Pager, RenderTabBarFnProps} from 'view/com/pager/Pager' 16 + import {Pager, PagerRef, RenderTabBarFnProps} from 'view/com/pager/Pager' 16 17 import {FAB} from '../com/util/fab/FAB' 17 18 import {SavedFeeds} from 'view/com/feeds/SavedFeeds' 18 19 import {useStores} from 'state/index' ··· 29 30 export const HomeScreen = withAuthRequired( 30 31 observer((_opts: Props) => { 31 32 const store = useStores() 33 + const pagerRef = React.useRef<PagerRef>(null) 32 34 const [selectedPage, setSelectedPage] = React.useState(0) 35 + const [customFeeds, setCustomFeeds] = React.useState<PostsFeedModel[]>([]) 33 36 const [initialLanguages] = React.useState( 34 37 store.preferences.contentLanguages, 35 38 ) ··· 41 44 }, [store]) 42 45 43 46 React.useEffect(() => { 47 + const feeds = [] 48 + for (const feed of store.me.savedFeeds.pinned) { 49 + const model = new PostsFeedModel(store, 'custom', {feed: feed.uri}) 50 + model.setup() 51 + feeds.push(model) 52 + } 53 + pagerRef.current?.setPage(0) 54 + setCustomFeeds(feeds) 55 + }, [store, store.me.savedFeeds.pinned, setCustomFeeds]) 56 + 57 + React.useEffect(() => { 44 58 // refresh whats hot when lang preferences change 45 59 if (initialLanguages !== store.preferences.contentLanguages) { 46 60 algoFeed.refresh() ··· 94 108 const initialPage = store.me.followsCount === 0 ? 1 : 0 95 109 return ( 96 110 <Pager 111 + ref={pagerRef} 97 112 testID="homeScreen" 98 113 onPageSelected={onPageSelected} 99 114 renderTabBar={renderTabBar} ··· 113 128 feed={algoFeed} 114 129 renderEmptyState={renderWhatsHotEmptyState} 115 130 /> 116 - {store.me.savedFeeds.pinned.map((f, index) => { 131 + {customFeeds.map((f, index) => { 117 132 return ( 118 133 <FeedPage 119 - key={String(3 + index)} 134 + key={(f.params as GetCustomFeed.QueryParams).feed} 120 135 testID="customFeedPage" 121 136 isPageFocused={selectedPage === 2 + index} 122 - feed={new PostsFeedModel(store, 'custom', {feed: f.uri})} 137 + feed={f} 123 138 renderEmptyState={renderFollowingEmptyState} 124 139 /> 125 140 )