Refactor feed manipulation and rendering to be more robust (#297)

This commit is contained in:
Paul Frazee 2023-03-16 15:54:06 -05:00 committed by GitHub
parent 93df983692
commit c50a20d214
7 changed files with 360 additions and 260 deletions

View file

@ -16,7 +16,7 @@ import {Text} from '../util/text/Text'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {Button} from '../util/forms/Button'
import {FeedModel} from 'state/models/feed-view'
import {FeedItem} from './FeedItem'
import {FeedSlice} from './FeedSlice'
import {OnScrollCb} from 'lib/hooks/useOnMainScroll'
import {s} from 'lib/styles'
import {useAnalytics} from 'lib/analytics'
@ -61,11 +61,11 @@ export const Feed = observer(function Feed({
if (feed.isEmpty) {
feedItems = feedItems.concat([EMPTY_FEED_ITEM])
} else {
feedItems = feedItems.concat(feed.nonReplyFeed)
feedItems = feedItems.concat(feed.slices)
}
}
return feedItems
}, [feed.hasError, feed.hasLoaded, feed.isEmpty, feed.nonReplyFeed])
}, [feed.hasError, feed.hasLoaded, feed.isEmpty, feed.slices])
// events
// =
@ -92,10 +92,6 @@ export const Feed = observer(function Feed({
// rendering
// =
// TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf
// VirtualizedList: You have a large list that is slow to update - make sure your
// renderItem function renders components that follow React performance best practices
// like PureComponent, shouldComponentUpdate, etc
const renderItem = React.useCallback(
({item}: {item: any}) => {
if (item === EMPTY_FEED_ITEM) {
@ -138,7 +134,7 @@ export const Feed = observer(function Feed({
/>
)
}
return <FeedItem item={item} showFollowBtn={showPostFollowBtn} />
return <FeedSlice slice={item} showFollowBtn={showPostFollowBtn} />
},
[feed, onPressTryAgain, showPostFollowBtn, pal, palInverted, navigation],
)

View file

@ -26,11 +26,14 @@ import {useAnalytics} from 'lib/analytics'
export const FeedItem = observer(function ({
item,
showReplyLine,
isThreadChild,
isThreadParent,
showFollowBtn,
ignoreMuteFor,
}: {
item: FeedItemModel
isThreadChild?: boolean
isThreadParent?: boolean
showReplyLine?: boolean
showFollowBtn?: boolean
ignoreMuteFor?: string
@ -110,10 +113,8 @@ export const FeedItem = observer(function ({
return <View />
}
const isChild =
item._isThreadChild || (!item.reason && !item._hideParent && item.reply)
const isSmallTop = isChild && item._isThreadChild
const isNoTop = isChild && !item._isThreadChild
const isSmallTop = isThreadChild
const isNoTop = false //isChild && !item._isThreadChild
const isMuted =
item.post.author.viewer?.muted && ignoreMuteFor !== item.post.author.did
const outerStyles = [
@ -122,25 +123,18 @@ export const FeedItem = observer(function ({
{borderColor: pal.colors.border},
isSmallTop ? styles.outerSmallTop : undefined,
isNoTop ? styles.outerNoTop : undefined,
item._isThreadParent ? styles.outerNoBottom : undefined,
isThreadParent ? styles.outerNoBottom : undefined,
]
return (
<PostMutedWrapper isMuted={isMuted}>
{isChild && !item._isThreadChild && item.replyParent ? (
<FeedItem
item={item.replyParent}
showReplyLine
ignoreMuteFor={ignoreMuteFor}
/>
) : undefined}
<Link style={outerStyles} href={itemHref} title={itemTitle} noFeedback>
{item._isThreadChild && (
{isThreadChild && (
<View
style={[styles.topReplyLine, {borderColor: pal.colors.replyLine}]}
/>
)}
{(showReplyLine || item._isThreadParent) && (
{isThreadParent && (
<View
style={[
styles.bottomReplyLine,
@ -199,7 +193,7 @@ export const FeedItem = observer(function ({
declarationCid={item.post.author.declaration.cid}
showFollowBtn={showFollowBtn}
/>
{!isChild && replyAuthorDid !== '' && (
{!isThreadChild && replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
@ -259,7 +253,7 @@ export const FeedItem = observer(function ({
</View>
</View>
</Link>
{item._isThreadChildElided ? (
{false /*isThreadChildElided*/ ? (
<Link
style={[pal.view, styles.viewFullThread]}
href={itemHref}

View file

@ -0,0 +1,28 @@
import React from 'react'
import {FeedSliceModel} from 'state/models/feed-view'
import {FeedItem} from './FeedItem'
export function FeedSlice({
slice,
showFollowBtn,
ignoreMuteFor,
}: {
slice: FeedSliceModel
showFollowBtn?: boolean
ignoreMuteFor?: string
}) {
return (
<>
{slice.items.map((item, i) => (
<FeedItem
key={item._reactKey}
item={item}
isThreadParent={slice.isThreadParentAt(i)}
isThreadChild={slice.isThreadChildAt(i)}
showFollowBtn={showFollowBtn}
ignoreMuteFor={ignoreMuteFor}
/>
))}
</>
)
}