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
				
			
		| 
						 | 
				
			
			@ -1,18 +1,24 @@
 | 
			
		|||
import React from 'react'
 | 
			
		||||
import {View, StyleSheet} from 'react-native'
 | 
			
		||||
import {useNavigationState} from '@react-navigation/native'
 | 
			
		||||
import {useNavigationState, useNavigation} from '@react-navigation/native'
 | 
			
		||||
import {usePalette} from 'lib/hooks/usePalette'
 | 
			
		||||
import {TextLink} from 'view/com/util/Link'
 | 
			
		||||
import {getCurrentRoute} from 'lib/routes/helpers'
 | 
			
		||||
import {useLingui} from '@lingui/react'
 | 
			
		||||
import {msg} from '@lingui/macro'
 | 
			
		||||
import {usePinnedFeedsInfos} from '#/state/queries/feed'
 | 
			
		||||
import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed'
 | 
			
		||||
import {FeedDescriptor} from '#/state/queries/post-feed'
 | 
			
		||||
import {NavigationProp} from 'lib/routes/types'
 | 
			
		||||
import {emitSoftReset} from '#/state/events'
 | 
			
		||||
 | 
			
		||||
export function DesktopFeeds() {
 | 
			
		||||
  const pal = usePalette('default')
 | 
			
		||||
  const {_} = useLingui()
 | 
			
		||||
  const {feeds} = usePinnedFeedsInfos()
 | 
			
		||||
 | 
			
		||||
  const {feeds: pinnedFeedInfos} = usePinnedFeedsInfos()
 | 
			
		||||
  const selectedFeed = useSelectedFeed()
 | 
			
		||||
  const setSelectedFeed = useSetSelectedFeed()
 | 
			
		||||
  const navigation = useNavigation<NavigationProp>()
 | 
			
		||||
  const route = useNavigationState(state => {
 | 
			
		||||
    if (!state) {
 | 
			
		||||
      return {name: 'Home'}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,30 +28,34 @@ export function DesktopFeeds() {
 | 
			
		|||
 | 
			
		||||
  return (
 | 
			
		||||
    <View style={[styles.container, pal.view]}>
 | 
			
		||||
      <FeedItem href="/" title="Following" current={route.name === 'Home'} />
 | 
			
		||||
      {feeds
 | 
			
		||||
        .filter(f => f.displayName !== 'Following')
 | 
			
		||||
        .map(feed => {
 | 
			
		||||
          try {
 | 
			
		||||
            const params = route.params as Record<string, string>
 | 
			
		||||
            const routeName =
 | 
			
		||||
              feed.type === 'feed' ? 'ProfileFeed' : 'ProfileList'
 | 
			
		||||
            return (
 | 
			
		||||
              <FeedItem
 | 
			
		||||
                key={feed.uri}
 | 
			
		||||
                href={feed.route.href}
 | 
			
		||||
                title={feed.displayName}
 | 
			
		||||
                current={
 | 
			
		||||
                  route.name === routeName &&
 | 
			
		||||
                  params.name === feed.route.params.name &&
 | 
			
		||||
                  params.rkey === feed.route.params.rkey
 | 
			
		||||
                }
 | 
			
		||||
              />
 | 
			
		||||
            )
 | 
			
		||||
          } catch {
 | 
			
		||||
            return null
 | 
			
		||||
          }
 | 
			
		||||
        })}
 | 
			
		||||
      {pinnedFeedInfos.map(feedInfo => {
 | 
			
		||||
        const uri = feedInfo.uri
 | 
			
		||||
        let feed: FeedDescriptor
 | 
			
		||||
        if (!uri) {
 | 
			
		||||
          feed = 'home'
 | 
			
		||||
        } else if (uri.includes('app.bsky.feed.generator')) {
 | 
			
		||||
          feed = `feedgen|${uri}`
 | 
			
		||||
        } else if (uri.includes('app.bsky.graph.list')) {
 | 
			
		||||
          feed = `list|${uri}`
 | 
			
		||||
        } else {
 | 
			
		||||
          return null
 | 
			
		||||
        }
 | 
			
		||||
        return (
 | 
			
		||||
          <FeedItem
 | 
			
		||||
            key={feed}
 | 
			
		||||
            href={'/?' + new URLSearchParams([['feed', feed]])}
 | 
			
		||||
            title={feedInfo.displayName}
 | 
			
		||||
            current={route.name === 'Home' && feed === selectedFeed}
 | 
			
		||||
            onPress={() => {
 | 
			
		||||
              setSelectedFeed(feed)
 | 
			
		||||
              navigation.navigate('Home')
 | 
			
		||||
              if (feed === selectedFeed) {
 | 
			
		||||
                emitSoftReset()
 | 
			
		||||
              }
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        )
 | 
			
		||||
      })}
 | 
			
		||||
      <View style={{paddingTop: 8, paddingBottom: 6}}>
 | 
			
		||||
        <TextLink
 | 
			
		||||
          type="lg"
 | 
			
		||||
| 
						 | 
				
			
			@ -62,10 +72,12 @@ function FeedItem({
 | 
			
		|||
  title,
 | 
			
		||||
  href,
 | 
			
		||||
  current,
 | 
			
		||||
  onPress,
 | 
			
		||||
}: {
 | 
			
		||||
  title: string
 | 
			
		||||
  href: string
 | 
			
		||||
  current: boolean
 | 
			
		||||
  onPress: () => void
 | 
			
		||||
}) {
 | 
			
		||||
  const pal = usePalette('default')
 | 
			
		||||
  return (
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +86,7 @@ function FeedItem({
 | 
			
		|||
        type="xl"
 | 
			
		||||
        href={href}
 | 
			
		||||
        text={title}
 | 
			
		||||
        onPress={onPress}
 | 
			
		||||
        style={[
 | 
			
		||||
          current ? pal.text : pal.textLight,
 | 
			
		||||
          {letterSpacing: 0.15, fontWeight: current ? '500' : 'normal'},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue