Adds a composer prompt on the home screen to invite users to post (#9464)

* Add a composer prompt on home

* Added image upload button

* Feed composer buttons

* Feed composer styles

* Add client events, auto-open gallery when button is pressed

* Add feature gate

* Move gate check to last

* Small style cleanups

---------

Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
Alex Benzer
2025-12-04 15:39:56 -08:00
committed by GitHub
parent 55eb6c5628
commit bc39b553f9
10 changed files with 308 additions and 2 deletions
+33 -1
View File
@@ -31,7 +31,7 @@ import {isStatusStillActive, validateStatus} from '#/lib/actor-status'
import {DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS} from '#/lib/constants'
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {logEvent} from '#/lib/statsig/statsig'
import {logEvent, useGate} from '#/lib/statsig/statsig'
import {isNetworkError} from '#/lib/strings/errors'
import {logger} from '#/logger'
import {isIOS, isNative, isWeb} from '#/platform/detection'
@@ -70,6 +70,7 @@ import {
} from '#/components/feeds/PostFeedVideoGridRow'
import {TrendingInterstitial} from '#/components/interstitials/Trending'
import {TrendingVideos as TrendingVideosInterstitial} from '#/components/interstitials/TrendingVideos'
import {ComposerPrompt} from '../feeds/ComposerPrompt'
import {DiscoverFallbackHeader} from './DiscoverFallbackHeader'
import {FeedShutdownMsg} from './FeedShutdownMsg'
import {PostFeedErrorMessage} from './PostFeedErrorMessage'
@@ -150,6 +151,10 @@ type FeedRow =
type: 'ageAssuranceBanner'
key: string
}
| {
type: 'composerPrompt'
key: string
}
export function getItemsForFeedback(feedRow: FeedRow): {
item: FeedPostSliceItem
@@ -225,6 +230,7 @@ let PostFeed = ({
const {_} = useLingui()
const queryClient = useQueryClient()
const {currentAccount, hasSession} = useSession()
const gate = useGate()
const initialNumToRender = useInitialNumToRender()
const feedFeedback = useFeedFeedbackContext()
const [isPTRing, setIsPTRing] = useState(false)
@@ -511,6 +517,18 @@ let PostFeed = ({
'interstitial2-' + sliceIndex + '-' + lastFetchedAt,
})
}
// Show composer prompt for Discover and Following feeds
if (
hasSession &&
(feedUriOrActorDid === DISCOVER_FEED_URI ||
feed === 'following') &&
gate('show_composer_prompt')
) {
arr.push({
type: 'composerPrompt',
key: 'composerPrompt-' + sliceIndex,
})
}
} else if (sliceIndex === 15) {
if (areVideoFeedsEnabled && !trendingVideoDisabled) {
arr.push({
@@ -524,6 +542,16 @@ let PostFeed = ({
key: 'interstitial-' + sliceIndex + '-' + lastFetchedAt,
})
}
} else if (feedKind === 'following') {
if (sliceIndex === 0) {
// Show composer prompt for Following feed
if (hasSession && gate('show_composer_prompt')) {
arr.push({
type: 'composerPrompt',
key: 'composerPrompt-' + sliceIndex,
})
}
}
} else if (feedKind === 'profile') {
if (sliceIndex === 5) {
arr.push({
@@ -638,6 +666,7 @@ let PostFeed = ({
isEmpty,
lastFetchedAt,
data,
feed,
feedType,
feedUriOrActorDid,
feedTab,
@@ -652,6 +681,7 @@ let PostFeed = ({
hasPressedShowLessUris,
ageAssuranceBannerState,
isCurrentFeedAtStartupSelected,
gate,
blockedOrMutedAuthors,
])
@@ -743,6 +773,8 @@ let PostFeed = ({
return <AgeAssuranceDismissibleFeedBanner />
} else if (row.type === 'interstitialTrending') {
return <TrendingInterstitial />
} else if (row.type === 'composerPrompt') {
return <ComposerPrompt />
} else if (row.type === 'interstitialTrendingVideos') {
return <TrendingVideosInterstitial />
} else if (row.type === 'fallbackMarker') {