Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix orphaned feed slices, handle blocks #4944

Merged
merged 5 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions src/lib/api/feed-manip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type FeedSliceItem = {
record: AppBskyFeedPost.Record
parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined
isParentBlocked: boolean
isParentNotFound: boolean
}

type AuthorContext = {
Expand Down Expand Up @@ -68,6 +69,7 @@ export class FeedViewPostsSlice {
}
const parent = reply?.parent
const isParentBlocked = AppBskyFeedDefs.isBlockedPost(parent)
const isParentNotFound = AppBskyFeedDefs.isNotFoundPost(parent)
let parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined
if (AppBskyFeedDefs.isPostView(parent)) {
parentAuthor = parent.author
Expand All @@ -77,6 +79,7 @@ export class FeedViewPostsSlice {
record: post.record,
parentAuthor,
isParentBlocked,
isParentNotFound,
})
if (!reply || reason) {
return
Expand All @@ -89,23 +92,40 @@ export class FeedViewPostsSlice {
this.isOrphan = true
return
}
const root = reply.root
const rootIsView =
gaearon marked this conversation as resolved.
Show resolved Hide resolved
AppBskyFeedDefs.isPostView(root) ||
AppBskyFeedDefs.isBlockedPost(root) ||
AppBskyFeedDefs.isNotFoundPost(root)
/*
* If the parent is also the root, we just so happen to have the data we
* need to compute if the parent's parent (grandparent) is blocked. This
* doesn't always happen, of course, but we can take advantage of it when
* it does.
*/
const grandparent =
rootIsView && parent.record.reply?.parent.uri === root.uri
? root
: undefined
const grandparentAuthor = reply.grandparentAuthor
const isGrandparentBlocked = Boolean(
grandparentAuthor?.viewer?.blockedBy ||
grandparentAuthor?.viewer?.blocking ||
grandparentAuthor?.viewer?.blockingByList,
grandparent && AppBskyFeedDefs.isBlockedPost(grandparent),
)
const isGrandparentNotFound = Boolean(
grandparent && AppBskyFeedDefs.isNotFoundPost(grandparent),
)
this.items.unshift({
post: parent,
record: parent.record,
parentAuthor: grandparentAuthor,
isParentBlocked: isGrandparentBlocked,
isParentNotFound: isGrandparentNotFound,
})
if (isGrandparentBlocked) {
this.isOrphan = true
// Keep going, it might still have a root.
// Keep going, it might still have a root, and we need this for thread
// de-deduping
}
const root = reply.root
if (
!AppBskyFeedDefs.isPostView(root) ||
!AppBskyFeedPost.isRecord(root.record) ||
Expand All @@ -121,6 +141,7 @@ export class FeedViewPostsSlice {
post: root,
record: root.record,
isParentBlocked: false,
isParentNotFound: false,
parentAuthor: undefined,
})
if (parent.record.reply?.parent.uri !== root.uri) {
Expand Down
2 changes: 2 additions & 0 deletions src/state/queries/post-feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export interface FeedPostSliceItem {
moderation: ModerationDecision
parentAuthor?: AppBskyActorDefs.ProfileViewBasic
isParentBlocked?: boolean
isParentNotFound?: boolean
}

export interface FeedPostSlice {
Expand Down Expand Up @@ -326,6 +327,7 @@ export function usePostFeedQuery(
moderation: moderations[i],
parentAuthor: item.parentAuthor,
isParentBlocked: item.isParentBlocked,
isParentNotFound: item.isParentNotFound,
}
return feedPostSliceItem
}),
Expand Down
19 changes: 16 additions & 3 deletions src/view/com/posts/FeedItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ interface FeedItemProps {
feedContext: string | undefined
hideTopBorder?: boolean
isParentBlocked?: boolean
isParentNotFound?: boolean
}

export function FeedItem({
Expand All @@ -78,6 +79,7 @@ export function FeedItem({
isThreadParent,
hideTopBorder,
isParentBlocked,
isParentNotFound,
}: FeedItemProps & {post: AppBskyFeedDefs.PostView}): React.ReactNode {
const postShadowed = usePostShadow(post)
const richText = useMemo(
Expand Down Expand Up @@ -109,6 +111,7 @@ export function FeedItem({
isThreadParent={isThreadParent}
hideTopBorder={hideTopBorder}
isParentBlocked={isParentBlocked}
isParentNotFound={isParentNotFound}
/>
)
}
Expand All @@ -129,6 +132,7 @@ let FeedItemInner = ({
isThreadParent,
hideTopBorder,
isParentBlocked,
isParentNotFound,
}: FeedItemProps & {
richText: RichTextAPI
post: Shadow<AppBskyFeedDefs.PostView>
Expand Down Expand Up @@ -344,9 +348,14 @@ let FeedItemInner = ({
postHref={href}
onOpenAuthor={onOpenAuthor}
/>
{showReplyTo && (parentAuthor || isParentBlocked) && (
<ReplyToLabel blocked={isParentBlocked} profile={parentAuthor} />
)}
{showReplyTo &&
(parentAuthor || isParentBlocked || isParentNotFound) && (
<ReplyToLabel
blocked={isParentBlocked}
notFound={isParentNotFound}
profile={parentAuthor}
/>
)}
<LabelsOnMyPost post={post} />
<PostContent
moderation={moderation}
Expand Down Expand Up @@ -438,16 +447,20 @@ PostContent = memo(PostContent)
function ReplyToLabel({
profile,
blocked,
notFound,
}: {
profile: AppBskyActorDefs.ProfileViewBasic | undefined
blocked?: boolean
notFound?: boolean
}) {
const pal = usePalette('default')
const {currentAccount} = useSession()

let label
if (blocked) {
label = <Trans context="description">Reply to a blocked post</Trans>
} else if (notFound) {
label = <Trans context="description">Reply to an unknown post</Trans>
} else if (profile != null) {
const isMe = profile.did === currentAccount?.did
if (isMe) {
Expand Down
4 changes: 4 additions & 0 deletions src/view/com/posts/FeedSlice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ let FeedSlice = ({
isThreadChild={isThreadChildAt(slice.items, 0)}
hideTopBorder={hideTopBorder}
isParentBlocked={slice.items[0].isParentBlocked}
isParentNotFound={slice.items[0].isParentNotFound}
/>
<ViewFullThread uri={slice.items[0].uri} />
<FeedItem
Expand All @@ -53,6 +54,7 @@ let FeedSlice = ({
isThreadParent={isThreadParentAt(slice.items, beforeLast)}
isThreadChild={isThreadChildAt(slice.items, beforeLast)}
isParentBlocked={slice.items[beforeLast].isParentBlocked}
isParentNotFound={slice.items[beforeLast].isParentNotFound}
/>
<FeedItem
key={slice.items[last]._reactKey}
Expand All @@ -66,6 +68,7 @@ let FeedSlice = ({
isThreadParent={isThreadParentAt(slice.items, last)}
isThreadChild={isThreadChildAt(slice.items, last)}
isParentBlocked={slice.items[last].isParentBlocked}
isParentNotFound={slice.items[last].isParentNotFound}
isThreadLastChild
/>
</>
Expand All @@ -90,6 +93,7 @@ let FeedSlice = ({
isThreadChildAt(slice.items, i) && slice.items.length === i + 1
}
isParentBlocked={slice.items[i].isParentBlocked}
isParentNotFound={slice.items[i].isParentNotFound}
hideTopBorder={hideTopBorder && i === 0}
/>
))}
Expand Down
Loading