Checkpoint parent rendering, can opt for slower handling here
This commit is contained in:
@@ -66,7 +66,7 @@ export function ThreadPost({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostThreadItemLoaded
|
<ThreadPostInner
|
||||||
// Safeguard from clobbering per-post state below:
|
// Safeguard from clobbering per-post state below:
|
||||||
key={postShadow.uri}
|
key={postShadow.uri}
|
||||||
item={item}
|
item={item}
|
||||||
@@ -99,7 +99,7 @@ function PostThreadItemDeleted({hideTopBorder}: {hideTopBorder?: boolean}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let PostThreadItemLoaded = ({
|
const ThreadPostInner = memo(function ThreadPostInner({
|
||||||
item,
|
item,
|
||||||
postShadow,
|
postShadow,
|
||||||
overrides,
|
overrides,
|
||||||
@@ -114,7 +114,7 @@ let PostThreadItemLoaded = ({
|
|||||||
}
|
}
|
||||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
@@ -305,8 +305,7 @@ let PostThreadItemLoaded = ({
|
|||||||
</View>
|
</View>
|
||||||
</SubtleHover>
|
</SubtleHover>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
PostThreadItemLoaded = memo(PostThreadItemLoaded)
|
|
||||||
|
|
||||||
function SubtleHover({children}: {children: React.ReactNode}) {
|
function SubtleHover({children}: {children: React.ReactNode}) {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export function ThreadReply({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostThreadItemLoaded
|
<ThreadReplyInner
|
||||||
// Safeguard from clobbering per-post state below:
|
// Safeguard from clobbering per-post state below:
|
||||||
key={postShadow.uri}
|
key={postShadow.uri}
|
||||||
item={item}
|
item={item}
|
||||||
@@ -103,7 +103,7 @@ function PostThreadItemDeleted({hideTopBorder}: {hideTopBorder?: boolean}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let PostThreadItemLoaded = ({
|
const ThreadReplyInner = memo(function ThreadReplyInner({
|
||||||
item,
|
item,
|
||||||
postShadow,
|
postShadow,
|
||||||
overrides,
|
overrides,
|
||||||
@@ -118,7 +118,7 @@ let PostThreadItemLoaded = ({
|
|||||||
}
|
}
|
||||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
@@ -336,8 +336,7 @@ let PostThreadItemLoaded = ({
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
PostThreadItemLoaded = memo(PostThreadItemLoaded)
|
|
||||||
|
|
||||||
function SubtleHover({children}: {children: React.ReactNode}) {
|
function SubtleHover({children}: {children: React.ReactNode}) {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {useMemo, useRef, useState} from 'react'
|
|||||||
import {useWindowDimensions, View} from 'react-native'
|
import {useWindowDimensions, View} from 'react-native'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {runOnJS} from 'react-native-reanimated'
|
||||||
|
|
||||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
|
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
|
||||||
@@ -29,6 +30,9 @@ import * as Layout from '#/components/Layout'
|
|||||||
import {ListFooter} from '#/components/Lists'
|
import {ListFooter} from '#/components/Lists'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
|
const PARENT_CHUNK_SIZE = 5
|
||||||
|
const CHILD_CHUNK_SIZE = 50
|
||||||
|
|
||||||
export function Inner({uri}: {uri: string | undefined}) {
|
export function Inner({uri}: {uri: string | undefined}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
@@ -144,6 +148,68 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
* scroll in onContentSizeChange instead.
|
* scroll in onContentSizeChange instead.
|
||||||
*/
|
*/
|
||||||
const [deferParents, setDeferParents] = useState(isNative)
|
const [deferParents, setDeferParents] = useState(isNative)
|
||||||
|
const [maxParentCount, setMaxParentCount] = useState(PARENT_CHUNK_SIZE)
|
||||||
|
const [maxChildCount, setMaxChildCount] = useState(CHILD_CHUNK_SIZE)
|
||||||
|
|
||||||
|
const needsBumpMaxParents = useRef(false)
|
||||||
|
const onStartReached = () => {
|
||||||
|
setMaxParentCount(n => n + PARENT_CHUNK_SIZE)
|
||||||
|
// needsBumpMaxParents.current = true
|
||||||
|
}
|
||||||
|
// const bumpMaxParentsIfNeeded = () => {
|
||||||
|
// if (!isNative) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if (needsBumpMaxParents.current) {
|
||||||
|
// needsBumpMaxParents.current = false
|
||||||
|
// setMaxParentCount(n => n + PARENT_CHUNK_SIZE)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// const onScrollToTop = bumpMaxParentsIfNeeded
|
||||||
|
// const onMomentumEnd = () => {
|
||||||
|
// 'worklet'
|
||||||
|
// runOnJS(bumpMaxParentsIfNeeded)()
|
||||||
|
// }
|
||||||
|
|
||||||
|
const onEndReached = () => {
|
||||||
|
if (isFetching) return
|
||||||
|
setMaxChildCount(prev => prev + CHILD_CHUNK_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = useMemo(() => {
|
||||||
|
const results: Slice[] = []
|
||||||
|
|
||||||
|
if (!data?.items) return results
|
||||||
|
|
||||||
|
let ci = 0
|
||||||
|
|
||||||
|
for (let i = 0; i < data.items.length; i++) {
|
||||||
|
const item = data.items[i]
|
||||||
|
|
||||||
|
if ('depth' in item) {
|
||||||
|
if (item.depth === 0) {
|
||||||
|
results.push(item)
|
||||||
|
|
||||||
|
if (!deferParents) {
|
||||||
|
const start = i - 1
|
||||||
|
const limit = Math.max(0, start - maxParentCount)
|
||||||
|
for (let pi = start; pi >= limit; pi--) {
|
||||||
|
results.unshift(data.items[pi])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (item.depth > 0) {
|
||||||
|
if (ci <= maxChildCount) {
|
||||||
|
results.push(item)
|
||||||
|
ci++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}, [data, deferParents, maxParentCount, maxChildCount])
|
||||||
const renderItem = ({item, index}: {item: Slice; index: number}) => {
|
const renderItem = ({item, index}: {item: Slice; index: number}) => {
|
||||||
if (item.type === 'threadPost') {
|
if (item.type === 'threadPost') {
|
||||||
if (item.depth < 0) {
|
if (item.depth < 0) {
|
||||||
@@ -273,18 +339,19 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
<PostThreadError error={error} />
|
<PostThreadError error={error} />
|
||||||
) : (
|
) : (
|
||||||
<ScrollProvider
|
<ScrollProvider
|
||||||
// onMomentumEnd={onMomentumEnd}
|
//onMomentumEnd={onMomentumEnd}
|
||||||
>
|
>
|
||||||
<List
|
<List
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
data={data?.items || []}
|
data={items}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
keyExtractor={keyExtractor}
|
keyExtractor={keyExtractor}
|
||||||
onContentSizeChange={onContentSizeChangeWebOnly}
|
onContentSizeChange={onContentSizeChangeWebOnly}
|
||||||
// onStartReached={onStartReached}
|
onStartReached={onStartReached}
|
||||||
// onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={2}
|
onEndReachedThreshold={2}
|
||||||
// onScrollToTop={onScrollToTop}
|
onStartReachedThreshold={1}
|
||||||
|
//onScrollToTop={onScrollToTop}
|
||||||
/**
|
/**
|
||||||
* @see https://reactnative.dev/docs/scrollview#maintainvisiblecontentposition
|
* @see https://reactnative.dev/docs/scrollview#maintainvisiblecontentposition
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user