[Starter Packs] Posts tab (#4660)

* [Starter Packs] Posts tab

* oops
zio/stable
dan 2024-06-27 01:07:56 +01:00 committed by GitHub
parent 3b0a177544
commit da4dfeb9cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 103 additions and 9 deletions

View File

@ -0,0 +1,51 @@
import React, {useCallback} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {FeedDescriptor} from '#/state/queries/post-feed'
import {isNative} from 'platform/detection'
import {Feed} from 'view/com/posts/Feed'
import {EmptyState} from 'view/com/util/EmptyState'
import {ListRef} from 'view/com/util/List'
import {SectionRef} from '#/screens/Profile/Sections/types'
interface ProfilesListProps {
listUri: string
headerHeight: number
scrollElRef: ListRef
}
export const PostsList = React.forwardRef<SectionRef, ProfilesListProps>(
function PostsListImpl({listUri, headerHeight, scrollElRef}, ref) {
const feed: FeedDescriptor = `list|${listUri}|as_following`
const {_} = useLingui()
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({
animated: isNative,
offset: -headerHeight,
})
}, [scrollElRef, headerHeight])
React.useImperativeHandle(ref, () => ({
scrollToTop: onScrollToTop,
}))
const renderPostsEmpty = useCallback(() => {
return <EmptyState icon="hashtag" message={_(msg`This feed is empty.`)} />
}, [_])
return (
<View>
<Feed
feed={feed}
pollInterval={60e3}
scrollElRef={scrollElRef}
renderEmptyState={renderPostsEmpty}
headerOffset={headerHeight}
/>
</View>
)
},
)

View File

@ -55,6 +55,7 @@ import * as Prompt from '#/components/Prompt'
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog' import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {FeedsList} from '#/components/StarterPack/Main/FeedsList' import {FeedsList} from '#/components/StarterPack/Main/FeedsList'
import {PostsList} from '#/components/StarterPack/Main/PostsList'
import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList' import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList'
import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog' import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog'
import {ShareDialog} from '#/components/StarterPack/ShareDialog' import {ShareDialog} from '#/components/StarterPack/ShareDialog'
@ -132,9 +133,14 @@ function StarterPackScreenInner({
> >
moderationOpts: ModerationOpts moderationOpts: ModerationOpts
}) { }) {
const showPeopleTab = Boolean(starterPack.list)
const showFeedsTab = Boolean(starterPack.feeds?.length)
const showPostsTab = Boolean(starterPack.list)
const tabs = [ const tabs = [
...(starterPack.list ? ['People'] : []), ...(showPeopleTab ? ['People'] : []),
...(starterPack.feeds?.length ? ['Feeds'] : []), ...(showFeedsTab ? ['Feeds'] : []),
...(showPostsTab ? ['Posts'] : []),
] ]
const qrCodeDialogControl = useDialogControl() const qrCodeDialogControl = useDialogControl()
@ -180,10 +186,9 @@ function StarterPackScreenInner({
onOpenShareDialog={onOpenShareDialog} onOpenShareDialog={onOpenShareDialog}
/> />
)}> )}>
{starterPack.list != null {showPeopleTab
? ({headerHeight, scrollElRef}) => ( ? ({headerHeight, scrollElRef}) => (
<ProfilesList <ProfilesList
key={0}
// Validated above // Validated above
listUri={starterPack!.list!.uri} listUri={starterPack!.list!.uri}
headerHeight={headerHeight} headerHeight={headerHeight}
@ -194,10 +199,9 @@ function StarterPackScreenInner({
/> />
) )
: null} : null}
{starterPack.feeds != null {showFeedsTab
? ({headerHeight, scrollElRef}) => ( ? ({headerHeight, scrollElRef}) => (
<FeedsList <FeedsList
key={1}
// @ts-expect-error ? // @ts-expect-error ?
feeds={starterPack?.feeds} feeds={starterPack?.feeds}
headerHeight={headerHeight} headerHeight={headerHeight}
@ -206,6 +210,18 @@ function StarterPackScreenInner({
/> />
) )
: null} : null}
{showPostsTab
? ({headerHeight, scrollElRef}) => (
<PostsList
// Validated above
listUri={starterPack!.list!.uri}
headerHeight={headerHeight}
// @ts-expect-error
scrollElRef={scrollElRef}
moderationOpts={moderationOpts}
/>
)
: null}
</PagerWithHeader> </PagerWithHeader>
</View> </View>

View File

@ -19,7 +19,34 @@ export function useFeedTuners(feedDesc: FeedDescriptor) {
] ]
} }
if (feedDesc.startsWith('list')) { if (feedDesc.startsWith('list')) {
return [FeedTuner.dedupReposts] const feedTuners = []
if (feedDesc.endsWith('|as_following')) {
// Same as Following tuners below, copypaste for now.
if (preferences?.feedViewPrefs.hideReposts) {
feedTuners.push(FeedTuner.removeReposts)
} else {
feedTuners.push(FeedTuner.dedupReposts)
}
if (preferences?.feedViewPrefs.hideReplies) {
feedTuners.push(FeedTuner.removeReplies)
} else {
feedTuners.push(
FeedTuner.thresholdRepliesOnly({
userDid: currentAccount?.did || '',
minLikes: preferences?.feedViewPrefs.hideRepliesByLikeCount || 0,
followedOnly:
!!preferences?.feedViewPrefs.hideRepliesByUnfollowed,
}),
)
}
if (preferences?.feedViewPrefs.hideQuotePosts) {
feedTuners.push(FeedTuner.removeQuotePosts)
}
} else {
feedTuners.push(FeedTuner.dedupReposts)
}
return feedTuners
} }
if (feedDesc === 'following') { if (feedDesc === 'following') {
const feedTuners = [] const feedTuners = []
@ -29,7 +56,6 @@ export function useFeedTuners(feedDesc: FeedDescriptor) {
} else { } else {
feedTuners.push(FeedTuner.dedupReposts) feedTuners.push(FeedTuner.dedupReposts)
} }
if (preferences?.feedViewPrefs.hideReplies) { if (preferences?.feedViewPrefs.hideReplies) {
feedTuners.push(FeedTuner.removeReplies) feedTuners.push(FeedTuner.removeReplies)
} else { } else {
@ -41,7 +67,6 @@ export function useFeedTuners(feedDesc: FeedDescriptor) {
}), }),
) )
} }
if (preferences?.feedViewPrefs.hideQuotePosts) { if (preferences?.feedViewPrefs.hideQuotePosts) {
feedTuners.push(FeedTuner.removeQuotePosts) feedTuners.push(FeedTuner.removeQuotePosts)
} }

View File

@ -49,6 +49,7 @@ type AuthorFilter =
| 'posts_with_media' | 'posts_with_media'
type FeedUri = string type FeedUri = string
type ListUri = string type ListUri = string
type ListFilter = 'as_following' // Applies current Following settings. Currently client-side.
export type FeedDescriptor = export type FeedDescriptor =
| 'following' | 'following'
@ -56,6 +57,7 @@ export type FeedDescriptor =
| `feedgen|${FeedUri}` | `feedgen|${FeedUri}`
| `likes|${ActorDid}` | `likes|${ActorDid}`
| `list|${ListUri}` | `list|${ListUri}`
| `list|${ListUri}|${ListFilter}`
export interface FeedParams { export interface FeedParams {
disableTuner?: boolean disableTuner?: boolean
mergeFeedEnabled?: boolean mergeFeedEnabled?: boolean