From 9503913e2b625b3186e5575771052239a8440c8c Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 24 Sep 2024 13:53:44 -0500 Subject: [PATCH 1/5] Add gate to increase post-feed page size --- src/lib/statsig/gates.ts | 4 +++- src/state/queries/post-feed.ts | 26 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index 7966767d1b..866d87aef0 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -1,3 +1,5 @@ export type Gate = // Keep this alphabetic please. - 'debug_show_feedcontext' | 'suggested_feeds_interstitial' + | 'debug_show_feedcontext' + | 'post_feed_lang_window' + | 'suggested_feeds_interstitial' diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 7daf441adb..8374b3da7e 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -15,24 +15,25 @@ import { useInfiniteQuery, } from '@tanstack/react-query' +import {AuthorFeedAPI} from '#/lib/api/feed/author' +import {CustomFeedAPI} from '#/lib/api/feed/custom' +import {FollowingFeedAPI} from '#/lib/api/feed/following' import {HomeFeedAPI} from '#/lib/api/feed/home' +import {LikesFeedAPI} from '#/lib/api/feed/likes' +import {ListFeedAPI} from '#/lib/api/feed/list' +import {MergeFeedAPI} from '#/lib/api/feed/merge' +import {FeedAPI, ReasonFeedSource} from '#/lib/api/feed/types' import {aggregateUserInterests} from '#/lib/api/feed/utils' +import {FeedTuner, FeedTunerFn} from '#/lib/api/feed-manip' import {DISCOVER_FEED_URI} from '#/lib/constants' +import {BSKY_FEED_OWNER_DIDS} from '#/lib/constants' import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' +import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' import {STALE} from '#/state/queries' import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' import {useAgent} from '#/state/session' import * as userActionHistory from '#/state/userActionHistory' -import {AuthorFeedAPI} from 'lib/api/feed/author' -import {CustomFeedAPI} from 'lib/api/feed/custom' -import {FollowingFeedAPI} from 'lib/api/feed/following' -import {LikesFeedAPI} from 'lib/api/feed/likes' -import {ListFeedAPI} from 'lib/api/feed/list' -import {MergeFeedAPI} from 'lib/api/feed/merge' -import {FeedAPI, ReasonFeedSource} from 'lib/api/feed/types' -import {FeedTuner, FeedTunerFn} from 'lib/api/feed-manip' -import {BSKY_FEED_OWNER_DIDS} from 'lib/constants' import {KnownError} from '#/view/com/posts/FeedErrorMessage' import {useFeedTuners} from '../preferences/feed-tuners' import {useModerationOpts} from '../preferences/moderation-opts' @@ -116,6 +117,7 @@ export function usePostFeedQuery( params?: FeedParams, opts?: {enabled?: boolean; ignoreFilterFor?: string}, ) { + const gate = useGate() const feedTuners = useFeedTuners(feedDesc) const moderationOpts = useModerationOpts() const {data: preferences} = usePreferencesQuery() @@ -135,6 +137,10 @@ export function usePostFeedQuery( } | null>(null) const isDiscover = feedDesc.includes(DISCOVER_FEED_URI) + const [pageSize] = React.useState(() => { + return gate('post_feed_lang_window') ? 100 : PAGE_SIZE + }) + // Make sure this doesn't invalidate unless really needed. const selectArgs = React.useMemo( () => ({ @@ -175,7 +181,7 @@ export function usePostFeedQuery( } try { - const res = await api.fetch({cursor, limit: PAGE_SIZE}) + const res = await api.fetch({cursor, limit: pageSize}) /* * If this is a public view, we need to check if posts fail moderation. From 0e00552c9094e6400a84ca208875b9406fd6fc31 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 24 Sep 2024 14:13:35 -0500 Subject: [PATCH 2/5] Exclude Discover --- src/state/queries/post-feed.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 8374b3da7e..4e5722ac2c 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -138,7 +138,9 @@ export function usePostFeedQuery( const isDiscover = feedDesc.includes(DISCOVER_FEED_URI) const [pageSize] = React.useState(() => { - return gate('post_feed_lang_window') ? 100 : PAGE_SIZE + // add exclusions here + const isExcluded = isDiscover + return !isExcluded && gate('post_feed_lang_window') ? 100 : PAGE_SIZE }) // Make sure this doesn't invalidate unless really needed. From c4743dad88b15dad86f844ffc05d1613b0b17271 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 24 Sep 2024 18:15:38 -0500 Subject: [PATCH 3/5] Remove exception --- src/state/queries/post-feed.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 4e5722ac2c..8374b3da7e 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -138,9 +138,7 @@ export function usePostFeedQuery( const isDiscover = feedDesc.includes(DISCOVER_FEED_URI) const [pageSize] = React.useState(() => { - // add exclusions here - const isExcluded = isDiscover - return !isExcluded && gate('post_feed_lang_window') ? 100 : PAGE_SIZE + return gate('post_feed_lang_window') ? 100 : PAGE_SIZE }) // Make sure this doesn't invalidate unless really needed. From 1fe3264418f5766e3c214ce73bd530a1046dcd76 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 25 Sep 2024 09:14:02 -0500 Subject: [PATCH 4/5] Clarify intent --- src/state/queries/post-feed.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 8374b3da7e..f23b59978e 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -110,7 +110,12 @@ export interface FeedPage { fetchedAt: number } -const PAGE_SIZE = 30 +/** + * The minimum number of posts we want in a single "page" of results. Since we + * filter out unwanted content, we may fetch more than this number to ensure + * that we get _at least_ this number. + */ +const MIN_POSTS = 30 export function usePostFeedQuery( feedDesc: FeedDescriptor, @@ -137,9 +142,14 @@ export function usePostFeedQuery( } | null>(null) const isDiscover = feedDesc.includes(DISCOVER_FEED_URI) - const [pageSize] = React.useState(() => { - return gate('post_feed_lang_window') ? 100 : PAGE_SIZE - }) + /** + * The number of posts to fetch in a single request. Because we filter + * unwanted content, we may over-fetch here to try and fill pages by + * `MIN_POSTS`. + */ + const fetchLimit = React.useState(() => { + return gate('post_feed_lang_window') ? 100 : MIN_POSTS + })[0] // Make sure this doesn't invalidate unless really needed. const selectArgs = React.useMemo( @@ -181,7 +191,7 @@ export function usePostFeedQuery( } try { - const res = await api.fetch({cursor, limit: pageSize}) + const res = await api.fetch({cursor, limit: fetchLimit}) /* * If this is a public view, we need to check if posts fail moderation. @@ -379,13 +389,13 @@ export function usePostFeedQuery( // Now track how many items we really want, and fetch more if needed. if (isLoading || isRefetching) { // During the initial fetch, we want to get an entire page's worth of items. - wantedItemCount.current = PAGE_SIZE + wantedItemCount.current = MIN_POSTS } else if (isFetchingNextPage) { if (itemCount > wantedItemCount.current) { // We have more items than wantedItemCount, so wantedItemCount must be out of date. // Some other code must have called fetchNextPage(), for example, from onEndReached. // Adjust the wantedItemCount to reflect that we want one more full page of items. - wantedItemCount.current = itemCount + PAGE_SIZE + wantedItemCount.current = itemCount + MIN_POSTS } } else if (hasNextPage) { // At this point we're not fetching anymore, so it's time to make a decision. From 950487e75022f01dbb9031e12db9b42efeea9847 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 25 Sep 2024 10:10:42 -0500 Subject: [PATCH 5/5] Let gate cache --- src/state/queries/post-feed.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index f23b59978e..bf83636f16 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -147,9 +147,7 @@ export function usePostFeedQuery( * unwanted content, we may over-fetch here to try and fill pages by * `MIN_POSTS`. */ - const fetchLimit = React.useState(() => { - return gate('post_feed_lang_window') ? 100 : MIN_POSTS - })[0] + const fetchLimit = gate('post_feed_lang_window') ? 100 : MIN_POSTS // Make sure this doesn't invalidate unless really needed. const selectArgs = React.useMemo(