From 0bd92c1bd0478e6276057bef7be3ac4e143f3232 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sun, 19 Jan 2025 20:10:28 +0000 Subject: [PATCH] Separate caches --- .../interstitials/TrendingVideos.tsx | 30 +++++++++++++++++-- src/lib/routes/links.ts | 8 +++-- src/lib/routes/types.ts | 6 +++- src/screens/Profile/ProfileFeed/index.tsx | 24 +++++++++++++-- .../components/ExploreTrendingVideos.tsx | 29 ++++++++++++++++-- src/screens/VideoFeed/index.tsx | 9 +++++- src/screens/VideoFeed/types.ts | 7 ++++- src/state/queries/post-feed.ts | 1 + src/view/com/posts/PostFeed.tsx | 3 ++ 9 files changed, 103 insertions(+), 14 deletions(-) diff --git a/src/components/interstitials/TrendingVideos.tsx b/src/components/interstitials/TrendingVideos.tsx index 9a08485536..0c94574d70 100644 --- a/src/components/interstitials/TrendingVideos.tsx +++ b/src/components/interstitials/TrendingVideos.tsx @@ -1,14 +1,16 @@ -import React from 'react' +import React, {useEffect} from 'react' import {ScrollView, View} from 'react-native' import {AppBskyEmbedVideo, AtUri} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useQueryClient} from '@tanstack/react-query' import {VIDEO_FEED_URI} from '#/lib/constants' import {makeCustomFeedLink} from '#/lib/routes/links' import {logEvent} from '#/lib/statsig/statsig' import {useTrendingSettingsApi} from '#/state/preferences/trending' import {usePostFeedQuery} from '#/state/queries/post-feed' +import {RQKEY} from '#/state/queries/post-feed' import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture' import {atoms as a, useGutters, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' @@ -25,11 +27,32 @@ import { const CARD_WIDTH = 100 +const FEED_DESC = `feedgen|${VIDEO_FEED_URI}` +const FEED_PARAMS: { + feedCacheKey: 'discover' +} = { + feedCacheKey: 'discover', +} + export function TrendingVideos() { const t = useTheme() const {_} = useLingui() const gutters = useGutters([0, 'base']) - const {data, isLoading, error} = usePostFeedQuery(`feedgen|${VIDEO_FEED_URI}`) + const {data, isLoading, error} = usePostFeedQuery(FEED_DESC, FEED_PARAMS) + + // Refetch on unmount if nothing else is using this query. + const queryClient = useQueryClient() + useEffect(() => { + return () => { + const query = queryClient + .getQueryCache() + .find({queryKey: RQKEY(FEED_DESC, FEED_PARAMS)}) + if (query && query.getObserversCount() <= 1) { + query.fetch() + } + } + }, [queryClient]) + const {setTrendingVideoDisabled} = useTrendingSettingsApi() const trendingPrompt = Prompt.usePromptControl() @@ -138,7 +161,7 @@ function VideoCards({ }, [data]) const href = React.useMemo(() => { const urip = new AtUri(VIDEO_FEED_URI) - return makeCustomFeedLink(urip.host, urip.rkey) + return makeCustomFeedLink(urip.host, urip.rkey, undefined, 'discover') }, []) return ( @@ -151,6 +174,7 @@ function VideoCards({ sourceContext={{ type: 'feedgen', uri: VIDEO_FEED_URI, + feedCacheKey: 'discover', }} onInteract={() => { logEvent('videoCard:click', { diff --git a/src/lib/routes/links.ts b/src/lib/routes/links.ts index 8a99502620..10c99b62d7 100644 --- a/src/lib/routes/links.ts +++ b/src/lib/routes/links.ts @@ -19,9 +19,13 @@ export function makeProfileLink( export function makeCustomFeedLink( did: string, rkey: string, - ...segments: string[] + segment?: string | undefined, + feedCacheKey?: 'discover' | 'explore' | undefined, ) { - return [`/profile`, did, 'feed', rkey, ...segments].join('/') + return ( + [`/profile`, did, 'feed', rkey, ...(segment ? [segment] : [])].join('/') + + (feedCacheKey ? `?feedCacheKey=${encodeURIComponent(feedCacheKey)}` : '') + ) } export function makeListLink(did: string, rkey: string, ...segments: string[]) { diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index fbade8223d..66ee7bffa7 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -22,7 +22,11 @@ export type CommonNavigatorParams = { PostLikedBy: {name: string; rkey: string} PostRepostedBy: {name: string; rkey: string} PostQuotes: {name: string; rkey: string} - ProfileFeed: {name: string; rkey: string} + ProfileFeed: { + name: string + rkey: string + feedCacheKey?: 'discover' | 'explore' | undefined + } ProfileFeedLikedBy: {name: string; rkey: string} ProfileLabelerLikedBy: {name: string} Debug: undefined diff --git a/src/screens/Profile/ProfileFeed/index.tsx b/src/screens/Profile/ProfileFeed/index.tsx index 6fcc4d103b..ba0f1cf5ce 100644 --- a/src/screens/Profile/ProfileFeed/index.tsx +++ b/src/screens/Profile/ProfileFeed/index.tsx @@ -21,7 +21,7 @@ import {isNative} from '#/platform/detection' import {listenSoftReset} from '#/state/events' import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback' import {FeedSourceFeedInfo, useFeedSourceInfoQuery} from '#/state/queries/feed' -import {FeedDescriptor} from '#/state/queries/post-feed' +import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' import { usePreferencesQuery, @@ -49,6 +49,11 @@ type Props = NativeStackScreenProps export function ProfileFeedScreen(props: Props) { const {rkey, name: handleOrDid} = props.route.params + const feedParams: FeedParams | undefined = props.route.params.feedCacheKey + ? { + feedCacheKey: props.route.params.feedCacheKey, + } + : undefined const pal = usePalette('default') const {_} = useLingui() const navigation = useNavigation() @@ -99,7 +104,10 @@ export function ProfileFeedScreen(props: Props) { return resolvedUri ? ( - + ) : ( @@ -111,7 +119,13 @@ export function ProfileFeedScreen(props: Props) { ) } -function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) { +function ProfileFeedScreenIntermediate({ + feedUri, + feedParams, +}: { + feedUri: string + feedParams: FeedParams | undefined +}) { const {data: preferences} = usePreferencesQuery() const {data: info} = useFeedSourceInfoQuery({uri: feedUri}) @@ -128,15 +142,18 @@ function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) { ) } export function ProfileFeedScreenInner({ feedInfo, + feedParams, }: { preferences: UsePreferencesQueryResponse feedInfo: FeedSourceFeedInfo + feedParams: FeedParams | undefined }) { const {_} = useLingui() const {hasSession} = useSession() @@ -190,6 +207,7 @@ export function ProfileFeedScreenInner({ { + return () => { + const query = queryClient + .getQueryCache() + .find({queryKey: RQKEY(FEED_DESC, FEED_PARAMS)}) + if (query && query.getObserversCount() <= 1) { + query.fetch() + } + } + }) const {data: saved} = useSavedFeeds() const isSavedAlready = React.useMemo(() => { @@ -179,7 +201,7 @@ function VideoCards({ }, [data]) const href = React.useMemo(() => { const urip = new AtUri(VIDEO_FEED_URI) - return makeCustomFeedLink(urip.host, urip.rkey) + return makeCustomFeedLink(urip.host, urip.rkey, undefined, 'explore') }, []) return ( @@ -192,6 +214,7 @@ function VideoCards({ sourceContext={{ type: 'feedgen', uri: VIDEO_FEED_URI, + feedCacheKey: 'explore', }} onInteract={() => { logEvent('videoCard:click', { diff --git a/src/screens/VideoFeed/index.tsx b/src/screens/VideoFeed/index.tsx index b89bdd9949..488c12cad4 100644 --- a/src/screens/VideoFeed/index.tsx +++ b/src/screens/VideoFeed/index.tsx @@ -190,7 +190,14 @@ function Feed() { }, [params]) const feedFeedback = useFeedFeedback(feedDesc, hasSession) const {data, error, hasNextPage, isFetchingNextPage, fetchNextPage} = - usePostFeedQuery(feedDesc) + usePostFeedQuery( + feedDesc, + params.type === 'feedgen' && params.feedCacheKey !== undefined + ? { + feedCacheKey: params.feedCacheKey, + } + : undefined, + ) const videos = useMemo(() => { let vids = diff --git a/src/screens/VideoFeed/types.ts b/src/screens/VideoFeed/types.ts index 22723bcc29..709ae959d2 100644 --- a/src/screens/VideoFeed/types.ts +++ b/src/screens/VideoFeed/types.ts @@ -4,7 +4,12 @@ import {AuthorFilter} from '#/state/queries/post-feed' * Kind of like `FeedDescriptor` but not */ export type VideoFeedSourceContext = - | {type: 'feedgen'; uri: string; initialPostUri?: string} + | { + type: 'feedgen' + uri: string + initialPostUri?: string + feedCacheKey?: 'discover' | 'explore' | undefined + } | { type: 'author' did: string diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 61dabf5f10..6f9af18f0c 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -61,6 +61,7 @@ export type FeedDescriptor = export interface FeedParams { mergeFeedEnabled?: boolean mergeFeedSources?: string[] + feedCacheKey?: 'discover' | 'explore' | undefined } type RQPageParam = {cursor: string | undefined; api: FeedAPI} | undefined diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx index 341dea3e54..28671d2f46 100644 --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -208,6 +208,7 @@ let PostFeed = ({ return isNative && gate('yolo') }, [gate]) + const feedCacheKey = feedParams?.feedCacheKey const opts = React.useMemo( () => ({enabled, ignoreFilterFor}), [enabled, ignoreFilterFor], @@ -654,6 +655,7 @@ let PostFeed = ({ sourceContext={{ type: 'feedgen', uri: row.sourceFeedUri, + feedCacheKey: feedCacheKey, }} /> ) @@ -670,6 +672,7 @@ let PostFeed = ({ _, onPressRetryLoadMore, feedUri, + feedCacheKey, ], )