Add videos tab to profile (#7517)

* Add videos tab to profile

* Modify sourceContext for author feeds

* Use actual typecast, better name for feedUri

* Make EOF conditional

* Clearer condition

---------

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
Eric Bailey
2025-01-21 18:45:33 -06:00
committed by GitHub
parent 1403570a6a
commit 6538013484
4 changed files with 54 additions and 13 deletions
+3 -1
View File
@@ -45,6 +45,7 @@ export const ProfileFeedSection = React.forwardRef<
const [hasNew, setHasNew] = React.useState(false) const [hasNew, setHasNew] = React.useState(false)
const [isScrolledDown, setIsScrolledDown] = React.useState(false) const [isScrolledDown, setIsScrolledDown] = React.useState(false)
const shouldUseAdjustedNumToRender = feed.endsWith('posts_and_author_threads') const shouldUseAdjustedNumToRender = feed.endsWith('posts_and_author_threads')
const isVideoFeed = isNative && feed.endsWith('posts_with_video')
const adjustedInitialNumToRender = useInitialNumToRender({ const adjustedInitialNumToRender = useInitialNumToRender({
screenHeightOffset: headerHeight, screenHeightOffset: headerHeight,
}) })
@@ -84,11 +85,12 @@ export const ProfileFeedSection = React.forwardRef<
renderEmptyState={renderPostsEmpty} renderEmptyState={renderPostsEmpty}
headerOffset={headerHeight} headerOffset={headerHeight}
progressViewOffset={ios(0)} progressViewOffset={ios(0)}
renderEndOfFeed={ProfileEndOfFeed} renderEndOfFeed={isVideoFeed ? undefined : ProfileEndOfFeed}
ignoreFilterFor={ignoreFilterFor} ignoreFilterFor={ignoreFilterFor}
initialNumToRender={ initialNumToRender={
shouldUseAdjustedNumToRender ? adjustedInitialNumToRender : undefined shouldUseAdjustedNumToRender ? adjustedInitialNumToRender : undefined
} }
isVideoFeed={isVideoFeed}
/> />
{(isScrolledDown || hasNew) && ( {(isScrolledDown || hasNew) && (
<LoadLatestBtn <LoadLatestBtn
+1
View File
@@ -49,6 +49,7 @@ export type AuthorFilter =
| 'posts_no_replies' | 'posts_no_replies'
| 'posts_and_author_threads' | 'posts_and_author_threads'
| 'posts_with_media' | 'posts_with_media'
| 'posts_with_video'
type FeedUri = string type FeedUri = string
type ListUri = string type ListUri = string
+27 -12
View File
@@ -25,6 +25,7 @@ import {useFeedFeedbackContext} from '#/state/feed-feedback'
import {useTrendingSettings} from '#/state/preferences/trending' import {useTrendingSettings} from '#/state/preferences/trending'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import { import {
AuthorFilter,
FeedDescriptor, FeedDescriptor,
FeedParams, FeedParams,
FeedPostSlice, FeedPostSlice,
@@ -38,6 +39,7 @@ import {useProgressGuide} from '#/state/shell/progress-guide'
import {List, ListRef} from '#/view/com/util/List' import {List, ListRef} from '#/view/com/util/List'
import {PostFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {PostFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn' import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn'
import {VideoFeedSourceContext} from '#/screens/VideoFeed/types'
import {useBreakpoints} from '#/alf' import {useBreakpoints} from '#/alf'
import {ProgressGuide, SuggestedFollows} from '#/components/FeedInterstitials' import {ProgressGuide, SuggestedFollows} from '#/components/FeedInterstitials'
import { import {
@@ -194,7 +196,7 @@ let PostFeed = ({
const [isPTRing, setIsPTRing] = React.useState(false) const [isPTRing, setIsPTRing] = React.useState(false)
const checkForNewRef = React.useRef<(() => void) | null>(null) const checkForNewRef = React.useRef<(() => void) | null>(null)
const lastFetchRef = React.useRef<number>(Date.now()) const lastFetchRef = React.useRef<number>(Date.now())
const [feedType, feedUri, feedTab] = feed.split('|') const [feedType, feedUriOrActorDid, feedTab] = feed.split('|')
const {gtMobile, gtTablet} = useBreakpoints() const {gtMobile, gtTablet} = useBreakpoints()
const areVideoFeedsEnabled = isNative const areVideoFeedsEnabled = isNative
@@ -307,7 +309,7 @@ let PostFeed = ({
let feedKind: 'following' | 'discover' | 'profile' | 'thevids' | undefined let feedKind: 'following' | 'discover' | 'profile' | 'thevids' | undefined
if (feedType === 'following') { if (feedType === 'following') {
feedKind = 'following' feedKind = 'following'
} else if (feedUri === DISCOVER_FEED_URI) { } else if (feedUriOrActorDid === DISCOVER_FEED_URI) {
feedKind = 'discover' feedKind = 'discover'
} else if ( } else if (
feedType === 'author' && feedType === 'author' &&
@@ -318,7 +320,7 @@ let PostFeed = ({
} }
let arr: FeedRow[] = [] let arr: FeedRow[] = []
if (KNOWN_SHUTDOWN_FEEDS.includes(feedUri)) { if (KNOWN_SHUTDOWN_FEEDS.includes(feedUriOrActorDid)) {
arr.push({ arr.push({
type: 'feedShutdownMsg', type: 'feedShutdownMsg',
key: 'feedShutdownMsg', key: 'feedShutdownMsg',
@@ -376,7 +378,7 @@ let PostFeed = ({
type: 'videoGridRow', type: 'videoGridRow',
key: row.map(r => r.item._reactKey).join('-'), key: row.map(r => r.item._reactKey).join('-'),
items: row.map(r => r.item), items: row.map(r => r.item),
sourceFeedUri: feedUri, sourceFeedUri: feedUriOrActorDid,
feedContexts: row.map(r => r.feedContext), feedContexts: row.map(r => r.feedContext),
}) })
} }
@@ -504,7 +506,7 @@ let PostFeed = ({
lastFetchedAt, lastFetchedAt,
data, data,
feedType, feedType,
feedUri, feedUriOrActorDid,
feedTab, feedTab,
hasSession, hasSession,
showProgressIntersitial, showProgressIntersitial,
@@ -595,7 +597,7 @@ let PostFeed = ({
} else if (row.type === 'loading') { } else if (row.type === 'loading') {
return <PostFeedLoadingPlaceholder /> return <PostFeedLoadingPlaceholder />
} else if (row.type === 'feedShutdownMsg') { } else if (row.type === 'feedShutdownMsg') {
return <FeedShutdownMsg feedUri={feedUri} /> return <FeedShutdownMsg feedUri={feedUriOrActorDid} />
} else if (row.type === 'interstitialFollows') { } else if (row.type === 'interstitialFollows') {
return <SuggestedFollows feed={feed} /> return <SuggestedFollows feed={feed} />
} else if (row.type === 'interstitialProgressGuide') { } else if (row.type === 'interstitialProgressGuide') {
@@ -646,14 +648,25 @@ let PostFeed = ({
</View> </View>
) )
} else if (row.type === 'videoGridRow') { } else if (row.type === 'videoGridRow') {
let sourceContext: VideoFeedSourceContext
if (feedType === 'author') {
sourceContext = {
type: 'author',
did: feedUriOrActorDid,
filter: feedTab as AuthorFilter,
}
} else {
sourceContext = {
type: 'feedgen',
uri: row.sourceFeedUri,
sourceInterstitial: feedCacheKey ?? 'none',
}
}
return ( return (
<PostFeedVideoGridRow <PostFeedVideoGridRow
items={row.items} items={row.items}
sourceContext={{ sourceContext={sourceContext}
type: 'feedgen',
uri: row.sourceFeedUri,
sourceInterstitial: feedCacheKey ?? 'none',
}}
/> />
) )
} else { } else {
@@ -668,7 +681,9 @@ let PostFeed = ({
savedFeedConfig, savedFeedConfig,
_, _,
onPressRetryLoadMore, onPressRetryLoadMore,
feedUri, feedType,
feedUriOrActorDid,
feedTab,
feedCacheKey, feedCacheKey,
], ],
) )
+23
View File
@@ -195,6 +195,7 @@ function ProfileScreenLoaded({
const postsSectionRef = React.useRef<SectionRef>(null) const postsSectionRef = React.useRef<SectionRef>(null)
const repliesSectionRef = React.useRef<SectionRef>(null) const repliesSectionRef = React.useRef<SectionRef>(null)
const mediaSectionRef = React.useRef<SectionRef>(null) const mediaSectionRef = React.useRef<SectionRef>(null)
const videosSectionRef = React.useRef<SectionRef>(null)
const likesSectionRef = React.useRef<SectionRef>(null) const likesSectionRef = React.useRef<SectionRef>(null)
const feedsSectionRef = React.useRef<SectionRef>(null) const feedsSectionRef = React.useRef<SectionRef>(null)
const listsSectionRef = React.useRef<SectionRef>(null) const listsSectionRef = React.useRef<SectionRef>(null)
@@ -218,6 +219,7 @@ function ProfileScreenLoaded({
const showPostsTab = true const showPostsTab = true
const showRepliesTab = hasSession const showRepliesTab = hasSession
const showMediaTab = !hasLabeler const showMediaTab = !hasLabeler
const showVideosTab = !hasLabeler
const showLikesTab = isMe const showLikesTab = isMe
const showFeedsTab = isMe || (profile.associated?.feedgens || 0) > 0 const showFeedsTab = isMe || (profile.associated?.feedgens || 0) > 0
const showStarterPacksTab = const showStarterPacksTab =
@@ -231,6 +233,7 @@ function ProfileScreenLoaded({
showPostsTab ? _(msg`Posts`) : undefined, showPostsTab ? _(msg`Posts`) : undefined,
showRepliesTab ? _(msg`Replies`) : undefined, showRepliesTab ? _(msg`Replies`) : undefined,
showMediaTab ? _(msg`Media`) : undefined, showMediaTab ? _(msg`Media`) : undefined,
showVideosTab ? _(msg`Videos`) : undefined,
showLikesTab ? _(msg`Likes`) : undefined, showLikesTab ? _(msg`Likes`) : undefined,
showFeedsTab ? _(msg`Feeds`) : undefined, showFeedsTab ? _(msg`Feeds`) : undefined,
showStarterPacksTab ? _(msg`Starter Packs`) : undefined, showStarterPacksTab ? _(msg`Starter Packs`) : undefined,
@@ -242,6 +245,7 @@ function ProfileScreenLoaded({
let postsIndex: number | null = null let postsIndex: number | null = null
let repliesIndex: number | null = null let repliesIndex: number | null = null
let mediaIndex: number | null = null let mediaIndex: number | null = null
let videosIndex: number | null = null
let likesIndex: number | null = null let likesIndex: number | null = null
let feedsIndex: number | null = null let feedsIndex: number | null = null
let starterPacksIndex: number | null = null let starterPacksIndex: number | null = null
@@ -258,6 +262,9 @@ function ProfileScreenLoaded({
if (showMediaTab) { if (showMediaTab) {
mediaIndex = nextIndex++ mediaIndex = nextIndex++
} }
if (showVideosTab) {
videosIndex = nextIndex++
}
if (showLikesTab) { if (showLikesTab) {
likesIndex = nextIndex++ likesIndex = nextIndex++
} }
@@ -281,6 +288,8 @@ function ProfileScreenLoaded({
repliesSectionRef.current?.scrollToTop() repliesSectionRef.current?.scrollToTop()
} else if (index === mediaIndex) { } else if (index === mediaIndex) {
mediaSectionRef.current?.scrollToTop() mediaSectionRef.current?.scrollToTop()
} else if (index === videosIndex) {
videosSectionRef.current?.scrollToTop()
} else if (index === likesIndex) { } else if (index === likesIndex) {
likesSectionRef.current?.scrollToTop() likesSectionRef.current?.scrollToTop()
} else if (index === feedsIndex) { } else if (index === feedsIndex) {
@@ -296,6 +305,7 @@ function ProfileScreenLoaded({
postsIndex, postsIndex,
repliesIndex, repliesIndex,
mediaIndex, mediaIndex,
videosIndex,
likesIndex, likesIndex,
feedsIndex, feedsIndex,
listsIndex, listsIndex,
@@ -435,6 +445,19 @@ function ProfileScreenLoaded({
/> />
) )
: null} : null}
{showVideosTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileFeedSection
ref={videosSectionRef}
feed={`author|${profile.did}|posts_with_video`}
headerHeight={headerHeight}
isFocused={isFocused}
scrollElRef={scrollElRef as ListRef}
ignoreFilterFor={profile.did}
setScrollViewTag={setScrollViewTag}
/>
)
: null}
{showLikesTab {showLikesTab
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileFeedSection <ProfileFeedSection