diff --git a/packages/mobile/src/components/lineup/Lineup.tsx b/packages/mobile/src/components/lineup/Lineup.tsx index 6a712f137a..117eea6bf0 100644 --- a/packages/mobile/src/components/lineup/Lineup.tsx +++ b/packages/mobile/src/components/lineup/Lineup.tsx @@ -206,6 +206,7 @@ export const Lineup = ({ header, LineupEmptyComponent, isTrending, + lazy, leadingElementId, leadingElementDelineator, lineup: lineupProp, @@ -232,8 +233,9 @@ export const Lineup = ({ const [refreshing, setRefreshing] = useState(refreshingProp) const selectedLineup = useSelector(lineupSelector) const lineup = selectedLineup ?? lineupProp - const { status, entries } = lineup + const { status, entries, inView: lineupInView } = lineup const lineupLength = entries.length + const inView = lazy ? lineupInView : true const handleRefresh = useCallback(() => { setRefreshing(true) @@ -334,27 +336,25 @@ export const Lineup = ({ useReachableEffect( useCallback(() => { - if (status === Status.LOADING) return + if (status === Status.LOADING || !inView) return handleLoadMore(true) - // using the latest creates infinite loop, and we only need the initial state - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [entries]) + }, [status, inView, handleLoadMore]) ) // When scrolled past the end threshold of the lineup and the lineup is not loading, // trigger another load useEffect(() => { - if (isPastLoadThreshold && status !== Status.LOADING) { + if (isPastLoadThreshold && status !== Status.LOADING && inView) { setIsPastLoadThreshold(false) handleLoadMore() } - }, [isPastLoadThreshold, status, handleLoadMore]) + }, [isPastLoadThreshold, status, handleLoadMore, inView]) useEffect(() => { - if (selfLoad && lineupLength === 0 && status !== Status.LOADING) { + if (selfLoad && status === Status.IDLE && inView) { handleLoadMore() } - }, [handleLoadMore, selfLoad, lineupLength, status]) + }, [handleLoadMore, selfLoad, lineupLength, status, inView]) const togglePlay = useCallback( ({ uid, id, source }: TogglePlayConfig) => { @@ -401,6 +401,7 @@ export const Lineup = ({ const getSkeletonCount = () => { const shouldCalculateSkeletons = + inView && items.length < limit && // Lineup has more items to load hasMore && @@ -456,6 +457,7 @@ export const Lineup = ({ return [{ delineate: false, data }] }, [ + inView, count, countOrDefault, delineate, diff --git a/packages/mobile/src/components/lineup/types.ts b/packages/mobile/src/components/lineup/types.ts index 5d26b4c289..07148c0263 100644 --- a/packages/mobile/src/components/lineup/types.ts +++ b/packages/mobile/src/components/lineup/types.ts @@ -74,6 +74,13 @@ export type LineupProps = { /** Are we in a trending lineup? Allows tiles to specialize their rendering */ isTrending?: boolean + /** + * When `true` lineup waits until visible before fetching. + * This is especcially needed for lineups inside collapsible-tab-view + * which do not support tab-navigator lazy mode + */ + lazy?: boolean + /** * Indicator if a track should be displayed differently (ie. artist pick) * The leadingElementId is displayed at the top of the lineup diff --git a/packages/mobile/src/components/top-tab-bar/TopTabNavigator.tsx b/packages/mobile/src/components/top-tab-bar/TopTabNavigator.tsx index 48e773f30d..c12f848683 100644 --- a/packages/mobile/src/components/top-tab-bar/TopTabNavigator.tsx +++ b/packages/mobile/src/components/top-tab-bar/TopTabNavigator.tsx @@ -14,18 +14,13 @@ type TabNavigatorProps = { screenOptions?: MaterialTopTabNavigationOptions } -export const TabNavigator = ({ - initialScreenName, - children, - screenOptions -}: TabNavigatorProps) => { +export const TabNavigator = (props: TabNavigatorProps) => { + const { initialScreenName, children, screenOptions } = props return ( } - screenOptions={{ - ...screenOptions - }} + screenOptions={screenOptions} > {children} @@ -63,14 +58,16 @@ export const tabScreen = (config: TabScreenConfig) => { type TopTabsProps = { initialScreenName?: string screens?: ScreenConfig[] + screenOptions?: MaterialTopTabNavigationOptions } -export const TopTabNavigator = ({ - initialScreenName, - screens -}: TopTabsProps) => { +export const TopTabNavigator = (props: TopTabsProps) => { + const { initialScreenName, screens, screenOptions } = props return ( - + {screens?.map((screen) => tabScreen({ key: screen.name, ...screen }))} ) diff --git a/packages/mobile/src/screens/explore-screen/ExploreScreen.tsx b/packages/mobile/src/screens/explore-screen/ExploreScreen.tsx index 4698383e7e..6cec2bfb9e 100644 --- a/packages/mobile/src/screens/explore-screen/ExploreScreen.tsx +++ b/packages/mobile/src/screens/explore-screen/ExploreScreen.tsx @@ -63,7 +63,10 @@ const ExploreScreen = () => { iconProps={{ height: 30 }} /> - + ) diff --git a/packages/mobile/src/screens/favorites-screen/FavoritesScreen.tsx b/packages/mobile/src/screens/favorites-screen/FavoritesScreen.tsx index c928c32c54..f386fb1275 100644 --- a/packages/mobile/src/screens/favorites-screen/FavoritesScreen.tsx +++ b/packages/mobile/src/screens/favorites-screen/FavoritesScreen.tsx @@ -64,7 +64,10 @@ export const FavoritesScreen = () => { {isOfflineModeEnabled ? : null} - {} + ) diff --git a/packages/mobile/src/screens/profile-screen/RepostsTab.tsx b/packages/mobile/src/screens/profile-screen/RepostsTab.tsx index d6d11bee6b..0fc842f581 100644 --- a/packages/mobile/src/screens/profile-screen/RepostsTab.tsx +++ b/packages/mobile/src/screens/profile-screen/RepostsTab.tsx @@ -14,26 +14,24 @@ import { useSelectProfile } from './selectors' const { getProfileFeedLineup } = profilePageSelectors export const RepostsTab = () => { - const { handle } = useSelectProfile(['handle']) + const { handle, repost_count } = useSelectProfile(['handle', 'repost_count']) const handleLower = handle.toLowerCase() const lineup = useProxySelector( (state) => getProfileFeedLineup(state, handleLower), [handleLower] ) - const { repost_count } = useSelectProfile(['repost_count']) const extraFetchOptions = useMemo( () => ({ handle: handleLower }), [handleLower] ) - if (!lineup) return null - return ( { - const isProfileLoaded = useIsProfileLoaded() const dispatch = useDispatch() const { handle, user_id, track_count, artist_pick_track_id } = @@ -32,20 +31,6 @@ export const TracksTab = () => { [handleLower] ) - useEffect(() => { - if (isProfileLoaded) { - dispatch( - tracksActions.fetchLineupMetadatas( - undefined, - undefined, - undefined, - { userId: user_id }, - { handle: handleLower } - ) - ) - } - }, [dispatch, isProfileLoaded, user_id, handleLower]) - const loadMore = useCallback( (offset: number, limit: number) => { dispatch( @@ -53,9 +38,7 @@ export const TracksTab = () => { offset, limit, false, - { - userId: user_id - }, + { userId: user_id }, { handle } ) ) @@ -63,14 +46,9 @@ export const TracksTab = () => { [dispatch, user_id, handle] ) - if (!lineup) return null - - /** - * If the profile isn't loaded yet, pass the lineup an empty entries - * array so only skeletons are displayed - */ return ( { - + )