Răsfoiți Sursa

Neo: native lists inside a list add no page-header spacer (#5886)

A post page without page-level comments draws its comments block as one of the list's rows; that
block's own UniList added the page-header spacer and band at its top, so a header-sized strip in
the band colour sat between the post and its comments (a coloured block with a brand band, an
empty gap with the default card band). UniList now provides a nesting context to its rows and
header, and a nested list skips the spacer.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Andrey Yasko 5 zile în urmă
părinte
comite
9920d90b87
1 a modificat fișierele cu 19 adăugiri și 8 ștergeri
  1. 19 8
      neo/packages/app/ui/atoms/unilist/index.tsx

+ 19 - 8
neo/packages/app/ui/atoms/unilist/index.tsx

@@ -1,5 +1,5 @@
 import { View } from 'app/design/view'
-import { useCallback, useMemo, useEffect, useRef, type ComponentType, type ReactElement } from 'react'
+import { createContext, useCallback, useContext, useMemo, useEffect, useRef, type ComponentType, type ReactElement } from 'react'
 import { Platform, RefreshControl } from 'react-native'
 import { AnimatedLegendList } from '@legendapp/list/reanimated'
 import { useSharedValue } from 'react-native-reanimated'
@@ -35,6 +35,13 @@ import { useListScrollPublisher } from './use-list-scroll-publisher'
 
 const EMPTY_LIST_DATA: any[] = []
 
+/**
+ * True inside a UniList's rows and header. A list there is part of the page's list (a post's
+ * comments block drawn as one of its rows), so it adds no page-header spacer or band of its own:
+ * that would put a header-sized strip in the band colour between the blocks.
+ */
+const NestedUniListContext = createContext(false)
+
 /**
  * Stable header component. LegendList reconciles ListHeaderComponent by type;
  * a new `useCallback` header on every chrome/filter change would remount the
@@ -221,6 +228,7 @@ export default function UniList(props: UniListProps) {
     // Page-header / cover offsets
     // ------------------------------------------------------------------
 
+    const isNested = useContext(NestedUniListContext)
     const headerHeightFromAtom = useHeaderHeight()
     const headerHeight = typeof headerHeightFromAtom === 'number'
         ? headerHeightFromAtom
@@ -230,15 +238,16 @@ export default function UniList(props: UniListProps) {
     const listHeaderOffset = useMemo(() => {
         if (headerHeight <= 0) return 0
         const fadeExtra =
-            Platform.OS !== 'web' && !skipHeaderOffset && !inverted && !isModal
+            Platform.OS !== 'web' && !skipHeaderOffset && !isNested && !inverted && !isModal
                 ? getHeaderFadeExtend()
                 : 0
         return headerHeight + fadeExtra
-    }, [headerHeight, skipHeaderOffset, inverted, isModal])
+    }, [headerHeight, skipHeaderOffset, isNested, inverted, isModal])
 
     // Normal list: spacer at the top for the page header. Inverted (chat):
     // the "top" of the content is at the bottom, so the spacer goes there.
-    const applyHeaderOffset = !inverted && !isModal && !skipHeaderOffset
+    // A nested list has none: the page's own list already carries it.
+    const applyHeaderOffset = !inverted && !isModal && !skipHeaderOffset && !isNested
     const applyFooterOffset = inverted && !isModal
 
     // Bottom padding applied while the profile cover is collapsed on a short
@@ -342,10 +351,12 @@ export default function UniList(props: UniListProps) {
     // lets the keyboard follow a drag that reaches it, like iOS.
     if (chatKeyboardEnabled && Platform.OS === 'android') {
         return (
-            <KeyboardGestureArea interpolator="ios" style={{ flex: 1 }}>
-                {list}
-            </KeyboardGestureArea>
+            <NestedUniListContext.Provider value={true}>
+                <KeyboardGestureArea interpolator="ios" style={{ flex: 1 }}>
+                    {list}
+                </KeyboardGestureArea>
+            </NestedUniListContext.Provider>
         )
     }
-    return list
+    return <NestedUniListContext.Provider value={true}>{list}</NestedUniListContext.Provider>
 }