Keep pager feeds in sync with the right pane (#2775)
* Hoist selected feed state * Seed state from params * Refine and fix logic * Fix scroll restoration * Soft reset on second click
This commit is contained in:
parent
80c482b026
commit
06f81d6948
6 changed files with 148 additions and 63 deletions
|
@ -7,7 +7,7 @@ import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
|
|||
import {FollowingEndOfFeed} from 'view/com/posts/FollowingEndOfFeed'
|
||||
import {CustomFeedEmptyState} from 'view/com/posts/CustomFeedEmptyState'
|
||||
import {FeedsTabBar} from '../com/pager/FeedsTabBar'
|
||||
import {Pager, RenderTabBarFnProps} from 'view/com/pager/Pager'
|
||||
import {Pager, RenderTabBarFnProps, PagerRef} from 'view/com/pager/Pager'
|
||||
import {FeedPage} from 'view/com/feeds/FeedPage'
|
||||
import {HomeLoggedOutCTA} from '../com/auth/HomeLoggedOutCTA'
|
||||
import {useSetMinimalShellMode, useSetDrawerSwipeDisabled} from '#/state/shell'
|
||||
|
@ -16,25 +16,19 @@ import {usePinnedFeedsInfos, FeedSourceInfo} from '#/state/queries/feed'
|
|||
import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
|
||||
import {emitSoftReset} from '#/state/events'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import * as persisted from '#/state/persisted'
|
||||
import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed'
|
||||
|
||||
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
|
||||
export function HomeScreen(props: Props) {
|
||||
const {data: preferences} = usePreferencesQuery()
|
||||
const {feeds: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} =
|
||||
usePinnedFeedsInfos()
|
||||
const {isDesktop} = useWebMediaQueries()
|
||||
const [rawInitialFeed] = React.useState<string>(
|
||||
() => persisted.get('lastSelectedHomeFeed') ?? 'home',
|
||||
)
|
||||
if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) {
|
||||
return (
|
||||
<HomeScreenReady
|
||||
{...props}
|
||||
preferences={preferences}
|
||||
pinnedFeedInfos={pinnedFeedInfos}
|
||||
rawInitialFeed={isDesktop ? 'home' : rawInitialFeed}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
|
@ -49,11 +43,9 @@ export function HomeScreen(props: Props) {
|
|||
function HomeScreenReady({
|
||||
preferences,
|
||||
pinnedFeedInfos,
|
||||
rawInitialFeed,
|
||||
}: Props & {
|
||||
preferences: UsePreferencesQueryResponse
|
||||
pinnedFeedInfos: FeedSourceInfo[]
|
||||
rawInitialFeed: string
|
||||
}) {
|
||||
const allFeeds = React.useMemo(() => {
|
||||
const feeds: FeedDescriptor[] = []
|
||||
|
@ -68,12 +60,24 @@ function HomeScreenReady({
|
|||
return feeds
|
||||
}, [pinnedFeedInfos])
|
||||
|
||||
const [rawSelectedFeed, setSelectedFeed] =
|
||||
React.useState<string>(rawInitialFeed)
|
||||
const rawSelectedFeed = useSelectedFeed()
|
||||
const setSelectedFeed = useSetSelectedFeed()
|
||||
const maybeFoundIndex = allFeeds.indexOf(rawSelectedFeed as FeedDescriptor)
|
||||
const selectedIndex = Math.max(0, maybeFoundIndex)
|
||||
const selectedFeed = allFeeds[selectedIndex]
|
||||
|
||||
const pagerRef = React.useRef<PagerRef>(null)
|
||||
const lastPagerReportedIndexRef = React.useRef(selectedIndex)
|
||||
React.useLayoutEffect(() => {
|
||||
// Since the pager is not a controlled component, adjust it imperatively
|
||||
// if the selected index gets out of sync with what it last reported.
|
||||
// This is supposed to only happen on the web when you use the right nav.
|
||||
if (selectedIndex !== lastPagerReportedIndexRef.current) {
|
||||
lastPagerReportedIndexRef.current = selectedIndex
|
||||
pagerRef.current?.setPage(selectedIndex)
|
||||
}
|
||||
}, [selectedIndex])
|
||||
|
||||
const {hasSession} = useSession()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
|
||||
|
@ -93,7 +97,7 @@ function HomeScreenReady({
|
|||
setDrawerSwipeDisabled(index > 0)
|
||||
const feed = allFeeds[index]
|
||||
setSelectedFeed(feed)
|
||||
persisted.write('lastSelectedHomeFeed', feed)
|
||||
lastPagerReportedIndexRef.current = index
|
||||
},
|
||||
[setDrawerSwipeDisabled, setSelectedFeed, setMinimalShellMode, allFeeds],
|
||||
)
|
||||
|
@ -147,6 +151,7 @@ function HomeScreenReady({
|
|||
return hasSession ? (
|
||||
<Pager
|
||||
key={allFeeds.join(',')}
|
||||
ref={pagerRef}
|
||||
testID="homeScreen"
|
||||
initialPage={selectedIndex}
|
||||
onPageSelected={onPageSelected}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue