From 5ca9e05be0b45e5acc92a97fd50c5f87f235aba1 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 29 May 2025 21:11:26 -0500 Subject: [PATCH] Checkpoint parent rendering, can opt for slower handling here --- .../PostThread/components/ThreadPost.tsx | 9 +-- .../PostThread/components/ThreadReply.tsx | 9 +-- src/screens/PostThread/index.tsx | 77 +++++++++++++++++-- 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/src/screens/PostThread/components/ThreadPost.tsx b/src/screens/PostThread/components/ThreadPost.tsx index 4f85f21c5d..9f77a4f750 100644 --- a/src/screens/PostThread/components/ThreadPost.tsx +++ b/src/screens/PostThread/components/ThreadPost.tsx @@ -66,7 +66,7 @@ export function ThreadPost({ } return ( - void threadgateRecord?: AppBskyFeedThreadgate.Record -}): React.ReactNode => { +}): React.ReactNode { const t = useTheme() const pal = usePalette('default') const {_} = useLingui() @@ -305,8 +305,7 @@ let PostThreadItemLoaded = ({ ) -} -PostThreadItemLoaded = memo(PostThreadItemLoaded) +}) function SubtleHover({children}: {children: React.ReactNode}) { const { diff --git a/src/screens/PostThread/components/ThreadReply.tsx b/src/screens/PostThread/components/ThreadReply.tsx index e7acf5499a..ea72a7fa98 100644 --- a/src/screens/PostThread/components/ThreadReply.tsx +++ b/src/screens/PostThread/components/ThreadReply.tsx @@ -70,7 +70,7 @@ export function ThreadReply({ } return ( - void threadgateRecord?: AppBskyFeedThreadgate.Record -}): React.ReactNode => { +}): React.ReactNode { const t = useTheme() const pal = usePalette('default') const {_} = useLingui() @@ -336,8 +336,7 @@ let PostThreadItemLoaded = ({ ) -} -PostThreadItemLoaded = memo(PostThreadItemLoaded) +}) function SubtleHover({children}: {children: React.ReactNode}) { const { diff --git a/src/screens/PostThread/index.tsx b/src/screens/PostThread/index.tsx index 9d440dc863..54c33f4335 100644 --- a/src/screens/PostThread/index.tsx +++ b/src/screens/PostThread/index.tsx @@ -2,6 +2,7 @@ import {useMemo, useRef, useState} from 'react' import {useWindowDimensions, View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {runOnJS} from 'react-native-reanimated' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' @@ -29,6 +30,9 @@ import * as Layout from '#/components/Layout' import {ListFooter} from '#/components/Lists' import {Text} from '#/components/Typography' +const PARENT_CHUNK_SIZE = 5 +const CHILD_CHUNK_SIZE = 50 + export function Inner({uri}: {uri: string | undefined}) { const t = useTheme() const {_} = useLingui() @@ -144,6 +148,68 @@ export function Inner({uri}: {uri: string | undefined}) { * scroll in onContentSizeChange instead. */ 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}) => { if (item.type === 'threadPost') { if (item.depth < 0) { @@ -273,18 +339,19 @@ export function Inner({uri}: {uri: string | undefined}) { ) : (