Remove `getProfile` calls when loading feed (#3881)
* remove unnecessary `getProfile()` calls from feed load add comments ensure only if first simplify nit handle cases where the parent is removed add a comment remove unnecessary `getProfile()` calls from feed load limit only to the first post in the returned items move the logic out of the render and into the query add the grandparent properly update `FeedItem` bump package update `FeedItem` update `post-feed` query update `FeedSlice` * nit * simplify logic * always pass `parentAuthor` * oops! * update `DebugMod`zio/stable
parent
6d647551cd
commit
70f190d44f
|
@ -1,6 +1,7 @@
|
|||
import React, {useCallback, useEffect, useRef} from 'react'
|
||||
import {AppState} from 'react-native'
|
||||
import {
|
||||
AppBskyActorDefs,
|
||||
AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
AtUri,
|
||||
|
@ -72,6 +73,7 @@ export interface FeedPostSliceItem {
|
|||
reason?: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource
|
||||
feedContext: string | undefined
|
||||
moderation: ModerationDecision
|
||||
parentAuthor?: AppBskyActorDefs.ProfileViewBasic
|
||||
}
|
||||
|
||||
export interface FeedPostSlice {
|
||||
|
@ -302,6 +304,10 @@ export function usePostFeedQuery(
|
|||
AppBskyFeedPost.validateRecord(item.post.record)
|
||||
.success
|
||||
) {
|
||||
const parentAuthor =
|
||||
item.reply?.parent?.author ??
|
||||
slice.items[i + 1]?.reply?.grandparentAuthor
|
||||
|
||||
return {
|
||||
_reactKey: `${slice._reactKey}-${i}-${item.post.uri}`,
|
||||
uri: item.post.uri,
|
||||
|
@ -313,6 +319,7 @@ export function usePostFeedQuery(
|
|||
: item.reason,
|
||||
feedContext: item.feedContext || slice.feedContext,
|
||||
moderation: moderations[i],
|
||||
parentAuthor,
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, {memo, useMemo, useState} from 'react'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import {
|
||||
AppBskyActorDefs,
|
||||
AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
AtUri,
|
||||
|
@ -40,7 +41,18 @@ import {PostEmbeds} from '../util/post-embeds'
|
|||
import {PostMeta} from '../util/PostMeta'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {PreviewableUserAvatar} from '../util/UserAvatar'
|
||||
import {UserInfoText} from '../util/UserInfoText'
|
||||
|
||||
interface FeedItemProps {
|
||||
record: AppBskyFeedPost.Record
|
||||
reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined
|
||||
moderation: ModerationDecision
|
||||
parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined
|
||||
showReplyTo: boolean
|
||||
isThreadChild?: boolean
|
||||
isThreadLastChild?: boolean
|
||||
isThreadParent?: boolean
|
||||
feedContext: string | undefined
|
||||
}
|
||||
|
||||
export function FeedItem({
|
||||
post,
|
||||
|
@ -48,19 +60,12 @@ export function FeedItem({
|
|||
reason,
|
||||
feedContext,
|
||||
moderation,
|
||||
parentAuthor,
|
||||
showReplyTo,
|
||||
isThreadChild,
|
||||
isThreadLastChild,
|
||||
isThreadParent,
|
||||
}: {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
record: AppBskyFeedPost.Record
|
||||
reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined
|
||||
feedContext: string | undefined
|
||||
moderation: ModerationDecision
|
||||
isThreadChild?: boolean
|
||||
isThreadLastChild?: boolean
|
||||
isThreadParent?: boolean
|
||||
}) {
|
||||
}: FeedItemProps & {post: AppBskyFeedDefs.PostView}): React.ReactNode {
|
||||
const postShadowed = usePostShadow(post)
|
||||
const richText = useMemo(
|
||||
() =>
|
||||
|
@ -83,6 +88,8 @@ export function FeedItem({
|
|||
reason={reason}
|
||||
feedContext={feedContext}
|
||||
richText={richText}
|
||||
parentAuthor={parentAuthor}
|
||||
showReplyTo={showReplyTo}
|
||||
moderation={moderation}
|
||||
isThreadChild={isThreadChild}
|
||||
isThreadLastChild={isThreadLastChild}
|
||||
|
@ -100,19 +107,14 @@ let FeedItemInner = ({
|
|||
feedContext,
|
||||
richText,
|
||||
moderation,
|
||||
parentAuthor,
|
||||
showReplyTo,
|
||||
isThreadChild,
|
||||
isThreadLastChild,
|
||||
isThreadParent,
|
||||
}: {
|
||||
post: Shadow<AppBskyFeedDefs.PostView>
|
||||
record: AppBskyFeedPost.Record
|
||||
reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined
|
||||
feedContext: string | undefined
|
||||
}: FeedItemProps & {
|
||||
richText: RichTextAPI
|
||||
moderation: ModerationDecision
|
||||
isThreadChild?: boolean
|
||||
isThreadLastChild?: boolean
|
||||
isThreadParent?: boolean
|
||||
post: Shadow<AppBskyFeedDefs.PostView>
|
||||
}): React.ReactNode => {
|
||||
const queryClient = useQueryClient()
|
||||
const {openComposer} = useComposerControls()
|
||||
|
@ -124,14 +126,6 @@ let FeedItemInner = ({
|
|||
}, [post.uri, post.author])
|
||||
const {sendInteraction} = useFeedFeedbackContext()
|
||||
|
||||
const replyAuthorDid = useMemo(() => {
|
||||
if (!record?.reply) {
|
||||
return ''
|
||||
}
|
||||
const urip = new AtUri(record.reply.parent?.uri || record.reply.root.uri)
|
||||
return urip.hostname
|
||||
}, [record?.reply])
|
||||
|
||||
const onPressReply = React.useCallback(() => {
|
||||
sendInteraction({
|
||||
item: post.uri,
|
||||
|
@ -318,34 +312,8 @@ let FeedItemInner = ({
|
|||
postHref={href}
|
||||
onOpenAuthor={onOpenAuthor}
|
||||
/>
|
||||
{!isThreadChild && replyAuthorDid !== '' && (
|
||||
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
|
||||
<FontAwesomeIcon
|
||||
icon="reply"
|
||||
size={9}
|
||||
style={[
|
||||
{color: pal.colors.textLight} as FontAwesomeIconStyle,
|
||||
s.mr5,
|
||||
]}
|
||||
/>
|
||||
<Text
|
||||
type="md"
|
||||
style={[pal.textLight, s.mr2]}
|
||||
lineHeight={1.2}
|
||||
numberOfLines={1}>
|
||||
<Trans context="description">
|
||||
Reply to{' '}
|
||||
<ProfileHoverCard inline did={replyAuthorDid}>
|
||||
<UserInfoText
|
||||
type="md"
|
||||
did={replyAuthorDid}
|
||||
attr="displayName"
|
||||
style={[pal.textLight]}
|
||||
/>
|
||||
</ProfileHoverCard>
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
{!isThreadChild && showReplyTo && parentAuthor && (
|
||||
<ReplyToLabel profile={parentAuthor} />
|
||||
)}
|
||||
<LabelsOnMyPost post={post} />
|
||||
<PostContent
|
||||
|
@ -434,6 +402,43 @@ let PostContent = ({
|
|||
}
|
||||
PostContent = memo(PostContent)
|
||||
|
||||
function ReplyToLabel({profile}: {profile: AppBskyActorDefs.ProfileViewBasic}) {
|
||||
const pal = usePalette('default')
|
||||
|
||||
return (
|
||||
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
|
||||
<FontAwesomeIcon
|
||||
icon="reply"
|
||||
size={9}
|
||||
style={[{color: pal.colors.textLight} as FontAwesomeIconStyle, s.mr5]}
|
||||
/>
|
||||
<Text
|
||||
type="md"
|
||||
style={[pal.textLight, s.mr2]}
|
||||
lineHeight={1.2}
|
||||
numberOfLines={1}>
|
||||
<Trans context="description">
|
||||
Reply to{' '}
|
||||
<ProfileHoverCard inline did={profile.did}>
|
||||
<TextLinkOnWebOnly
|
||||
type="md"
|
||||
style={pal.textLight}
|
||||
lineHeight={1.2}
|
||||
numberOfLines={1}
|
||||
href={makeProfileLink(profile)}
|
||||
text={
|
||||
profile.displayName
|
||||
? sanitizeDisplayName(profile.displayName)
|
||||
: sanitizeHandle(profile.handle)
|
||||
}
|
||||
/>
|
||||
</ProfileHoverCard>
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
borderTopWidth: 1,
|
||||
|
|
|
@ -22,6 +22,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
|
|||
record={slice.items[0].record}
|
||||
reason={slice.items[0].reason}
|
||||
feedContext={slice.items[0].feedContext}
|
||||
parentAuthor={slice.items[0].parentAuthor}
|
||||
showReplyTo={true}
|
||||
moderation={slice.items[0].moderation}
|
||||
isThreadParent={isThreadParentAt(slice.items, 0)}
|
||||
isThreadChild={isThreadChildAt(slice.items, 0)}
|
||||
|
@ -32,6 +34,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
|
|||
record={slice.items[1].record}
|
||||
reason={slice.items[1].reason}
|
||||
feedContext={slice.items[1].feedContext}
|
||||
parentAuthor={slice.items[1].parentAuthor}
|
||||
showReplyTo={false}
|
||||
moderation={slice.items[1].moderation}
|
||||
isThreadParent={isThreadParentAt(slice.items, 1)}
|
||||
isThreadChild={isThreadChildAt(slice.items, 1)}
|
||||
|
@ -43,6 +47,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
|
|||
record={slice.items[last].record}
|
||||
reason={slice.items[last].reason}
|
||||
feedContext={slice.items[last].feedContext}
|
||||
parentAuthor={slice.items[2].parentAuthor}
|
||||
showReplyTo={false}
|
||||
moderation={slice.items[last].moderation}
|
||||
isThreadParent={isThreadParentAt(slice.items, last)}
|
||||
isThreadChild={isThreadChildAt(slice.items, last)}
|
||||
|
@ -62,6 +68,8 @@ let FeedSlice = ({slice}: {slice: FeedPostSlice}): React.ReactNode => {
|
|||
reason={slice.items[i].reason}
|
||||
feedContext={slice.items[i].feedContext}
|
||||
moderation={slice.items[i].moderation}
|
||||
parentAuthor={slice.items[i].parentAuthor}
|
||||
showReplyTo={i === 0}
|
||||
isThreadParent={isThreadParentAt(slice.items, i)}
|
||||
isThreadChild={isThreadChildAt(slice.items, i)}
|
||||
isThreadLastChild={
|
||||
|
|
|
@ -803,6 +803,8 @@ function MockPostFeedItem({
|
|||
post={post}
|
||||
record={post.record as AppBskyFeedPost.Record}
|
||||
moderation={moderation}
|
||||
parentAuthor={undefined}
|
||||
showReplyTo={false}
|
||||
reason={undefined}
|
||||
feedContext={''}
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue