Show replies in context of their threads (#4871)
* Don't reconstruct threads from separate posts * Remove post-level dedupe for now * Change repost dedupe condition to look just at length * Delete unused isThread * Delete another isThread field It is now meaningless because there's nothing special about author threads. * Narrow down slice item shape so it does not need reply * Consolidate slice validation criteria in one place * Show replies in context * Make fallback marker work * Remove misleading and now-unused property It was called rootUri but it was actually the leaf URI. Regardless, it's not used anymore. * Add by-thread dedupe to non-author feeds * Add post-level dedupe * Always count from the start This is easier to think about. * Only tuner state need to be untouched on dry run * Account for threads in reply filtering * Remove repost deduping This is already being taken care of by item-level deduping. It's also now wrong and removing too much (since it wasn't filtering for reposts directly). * Calculate rootUri correctly * Apply Following settings to all lists * Don't dedupe intentional reposts by thread * Show reply parent when ambiguous * Explicitly remove orphaned replies from following/lists * Fix thread dedupe to work across pages * Mark grandparent-blocked as orphaned * Guard tuner state change by dryRun * Remove dead code * Don't dedupe feedgen threads * Revert "Apply Following settings to all lists" This reverts commit aff86be6d37b60cc5d0ac38f22c31a4808342cf4. Let's not do this yet and have a bit more discussion. This is a chunky change already. * Reason belongs to a slice, not item * Logically feedContext belongs to the slice * Update comment to reflect latest behavior
This commit is contained in:
parent
18b423396b
commit
74b0318d89
8 changed files with 279 additions and 300 deletions
|
@ -14,7 +14,6 @@ import {msg} from '@lingui/macro'
|
|||
import {useLingui} from '@lingui/react'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {FALLBACK_MARKER_POST} from '#/lib/api/feed/home'
|
||||
import {DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS} from '#/lib/constants'
|
||||
import {logEvent, useGate} from '#/lib/statsig/statsig'
|
||||
import {logger} from '#/logger'
|
||||
|
@ -472,7 +471,7 @@ let Feed = ({
|
|||
} else if (item.type === progressGuideInterstitialType) {
|
||||
return <ProgressGuide />
|
||||
} else if (item.type === 'slice') {
|
||||
if (item.slice.rootUri === FALLBACK_MARKER_POST.post.uri) {
|
||||
if (item.slice.isFallbackMarker) {
|
||||
// HACK
|
||||
// tell the user we fell back to discover
|
||||
// see home.ts (feed api) for more info
|
||||
|
|
|
@ -345,11 +345,9 @@ let FeedItemInner = ({
|
|||
postHref={href}
|
||||
onOpenAuthor={onOpenAuthor}
|
||||
/>
|
||||
{!isThreadChild &&
|
||||
showReplyTo &&
|
||||
(parentAuthor || isParentBlocked) && (
|
||||
<ReplyToLabel blocked={isParentBlocked} profile={parentAuthor} />
|
||||
)}
|
||||
{showReplyTo && (parentAuthor || isParentBlocked) && (
|
||||
<ReplyToLabel blocked={isParentBlocked} profile={parentAuthor} />
|
||||
)}
|
||||
<LabelsOnMyPost post={post} />
|
||||
<PostContent
|
||||
moderation={moderation}
|
||||
|
|
|
@ -18,7 +18,7 @@ let FeedSlice = ({
|
|||
slice: FeedPostSlice
|
||||
hideTopBorder?: boolean
|
||||
}): React.ReactNode => {
|
||||
if (slice.isThread && slice.items.length > 3) {
|
||||
if (slice.isIncompleteThread && slice.items.length >= 3) {
|
||||
const beforeLast = slice.items.length - 2
|
||||
const last = slice.items.length - 1
|
||||
return (
|
||||
|
@ -27,25 +27,28 @@ let FeedSlice = ({
|
|||
key={slice.items[0]._reactKey}
|
||||
post={slice.items[0].post}
|
||||
record={slice.items[0].record}
|
||||
reason={slice.items[0].reason}
|
||||
feedContext={slice.items[0].feedContext}
|
||||
reason={slice.reason}
|
||||
feedContext={slice.feedContext}
|
||||
parentAuthor={slice.items[0].parentAuthor}
|
||||
showReplyTo={true}
|
||||
showReplyTo={false}
|
||||
moderation={slice.items[0].moderation}
|
||||
isThreadParent={isThreadParentAt(slice.items, 0)}
|
||||
isThreadChild={isThreadChildAt(slice.items, 0)}
|
||||
hideTopBorder={hideTopBorder}
|
||||
isParentBlocked={slice.items[0].isParentBlocked}
|
||||
/>
|
||||
<ViewFullThread slice={slice} />
|
||||
<ViewFullThread uri={slice.items[0].uri} />
|
||||
<FeedItem
|
||||
key={slice.items[beforeLast]._reactKey}
|
||||
post={slice.items[beforeLast].post}
|
||||
record={slice.items[beforeLast].record}
|
||||
reason={slice.items[beforeLast].reason}
|
||||
feedContext={slice.items[beforeLast].feedContext}
|
||||
reason={undefined}
|
||||
feedContext={slice.feedContext}
|
||||
parentAuthor={slice.items[beforeLast].parentAuthor}
|
||||
showReplyTo={false}
|
||||
showReplyTo={
|
||||
slice.items[beforeLast].parentAuthor?.did !==
|
||||
slice.items[beforeLast].post.author.did
|
||||
}
|
||||
moderation={slice.items[beforeLast].moderation}
|
||||
isThreadParent={isThreadParentAt(slice.items, beforeLast)}
|
||||
isThreadChild={isThreadChildAt(slice.items, beforeLast)}
|
||||
|
@ -55,8 +58,8 @@ let FeedSlice = ({
|
|||
key={slice.items[last]._reactKey}
|
||||
post={slice.items[last].post}
|
||||
record={slice.items[last].record}
|
||||
reason={slice.items[last].reason}
|
||||
feedContext={slice.items[last].feedContext}
|
||||
reason={undefined}
|
||||
feedContext={slice.feedContext}
|
||||
parentAuthor={slice.items[last].parentAuthor}
|
||||
showReplyTo={false}
|
||||
moderation={slice.items[last].moderation}
|
||||
|
@ -76,8 +79,8 @@ let FeedSlice = ({
|
|||
key={item._reactKey}
|
||||
post={slice.items[i].post}
|
||||
record={slice.items[i].record}
|
||||
reason={slice.items[i].reason}
|
||||
feedContext={slice.items[i].feedContext}
|
||||
reason={i === 0 ? slice.reason : undefined}
|
||||
feedContext={slice.feedContext}
|
||||
moderation={slice.items[i].moderation}
|
||||
parentAuthor={slice.items[i].parentAuthor}
|
||||
showReplyTo={i === 0}
|
||||
|
@ -96,12 +99,12 @@ let FeedSlice = ({
|
|||
FeedSlice = memo(FeedSlice)
|
||||
export {FeedSlice}
|
||||
|
||||
function ViewFullThread({slice}: {slice: FeedPostSlice}) {
|
||||
function ViewFullThread({uri}: {uri: string}) {
|
||||
const pal = usePalette('default')
|
||||
const itemHref = React.useMemo(() => {
|
||||
const urip = new AtUri(slice.rootUri)
|
||||
const urip = new AtUri(uri)
|
||||
return makeProfileLink({did: urip.hostname, handle: ''}, 'post', urip.rkey)
|
||||
}, [slice.rootUri])
|
||||
}, [uri])
|
||||
|
||||
return (
|
||||
<Link style={[styles.viewFullThread]} href={itemHref} asAnchor noFeedback>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue