Cleanup
This commit is contained in:
@@ -6,7 +6,6 @@ import {TabBar} from './TabBar'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {ListMethods} from '../util/List'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
|
||||
export interface PagerWithHeaderChildParams {
|
||||
headerHeight: number
|
||||
@@ -108,6 +107,7 @@ let PagerTabBar = ({
|
||||
renderHeader?: () => JSX.Element
|
||||
onCurrentPageSelected?: (index: number) => void
|
||||
onSelect?: (index: number) => void
|
||||
tabBarAnchor?: JSX.Element
|
||||
}): React.ReactNode => {
|
||||
const pal = usePalette('default')
|
||||
const {isMobile} = useWebMediaQueries()
|
||||
|
||||
@@ -197,7 +197,7 @@ function PostThreadLoaded({
|
||||
|
||||
// wait for loading to finish
|
||||
if (thread.type === 'post' && !!thread.parent) {
|
||||
function onMeasure(pageY) {
|
||||
function onMeasure(pageY: number) {
|
||||
let spinnerHeight = 0
|
||||
if (isDesktop) {
|
||||
spinnerHeight = 40
|
||||
@@ -216,8 +216,12 @@ function PostThreadLoaded({
|
||||
},
|
||||
)
|
||||
} else {
|
||||
const pageY = highlightedPostRef.current.getBoundingClientRect().top
|
||||
onMeasure(pageY)
|
||||
// Measure synchronously to avoid a layout jump.
|
||||
const domNode = highlightedPostRef.current
|
||||
if (domNode) {
|
||||
const pageY = (domNode as any as Element).getBoundingClientRect().top
|
||||
onMeasure(pageY)
|
||||
}
|
||||
}
|
||||
needsScrollAdjustment.current = false
|
||||
}
|
||||
|
||||
@@ -86,9 +86,9 @@ function ListImpl<ItemT>(
|
||||
return (
|
||||
<FlatList_INTERNAL
|
||||
{...props}
|
||||
scrollIndicatorInsets={{right: 1}}
|
||||
contentOffset={contentOffset}
|
||||
refreshControl={refreshControl}
|
||||
scrollIndicatorInsets={{right: 1}}
|
||||
onScroll={scrollHandler}
|
||||
scrollEventThrottle={1}
|
||||
style={style}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {useScrollHandlers} from '#/lib/ScrollContext'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {batchedUpdates} from '#/lib/batchedUpdates'
|
||||
|
||||
export type ListMethods = FlatList_INTERNAL
|
||||
export type ListMethods = any // TODO: Better types.
|
||||
export type ListProps<ItemT> = Omit<
|
||||
FlatListProps<ItemT>,
|
||||
| 'onScroll' // Use ScrollContext instead.
|
||||
@@ -18,8 +18,9 @@ export type ListProps<ItemT> = Omit<
|
||||
headerOffset?: number
|
||||
refreshing?: boolean
|
||||
onRefresh?: () => void
|
||||
desktopFixedHeight: any // TODO: Better types.
|
||||
}
|
||||
export type ListRef = React.MutableRefObject<FlatList_INTERNAL | null>
|
||||
export type ListRef = React.MutableRefObject<any | null> // TODO: Better types.
|
||||
|
||||
function ListImpl<ItemT>(
|
||||
{
|
||||
@@ -27,7 +28,7 @@ function ListImpl<ItemT>(
|
||||
ListFooterComponent,
|
||||
contentContainerStyle,
|
||||
data,
|
||||
desktopFixedHeight, // TODO
|
||||
desktopFixedHeight,
|
||||
headerOffset,
|
||||
keyExtractor,
|
||||
refreshing: _unsupportedRefreshing,
|
||||
@@ -53,7 +54,7 @@ function ListImpl<ItemT>(
|
||||
)
|
||||
}
|
||||
|
||||
let header: ListProps<ItemT>['ListHeaderComponent'] = null
|
||||
let header: JSX.Element | null = null
|
||||
if (ListHeaderComponent != null) {
|
||||
if (typeof ListHeaderComponent === 'object') {
|
||||
header = ListHeaderComponent
|
||||
@@ -63,7 +64,7 @@ function ListImpl<ItemT>(
|
||||
}
|
||||
}
|
||||
|
||||
let footer: ListProps<ItemT>['ListHeaderComponent'] = null
|
||||
let footer: JSX.Element | null = null
|
||||
if (ListFooterComponent != null) {
|
||||
if (typeof ListFooterComponent === 'object') {
|
||||
footer = ListFooterComponent
|
||||
@@ -100,11 +101,15 @@ function ListImpl<ItemT>(
|
||||
behavior: animated ? 'smooth' : 'instant',
|
||||
})
|
||||
},
|
||||
} as any), // TODO: Types.
|
||||
} as any), // TODO: Better types.
|
||||
[],
|
||||
)
|
||||
|
||||
const [isVisible, setIsVisible] = React.useState(false)
|
||||
// --- onContentSizeChange ---
|
||||
const containerRef = useRef(null)
|
||||
useResizeObserver(containerRef, onContentSizeChange)
|
||||
|
||||
// --- onScroll ---
|
||||
const handleScroll = useNonReactiveCallback(() => {
|
||||
contextScrollHandlers.onScroll?.(
|
||||
{
|
||||
@@ -112,21 +117,22 @@ function ListImpl<ItemT>(
|
||||
x: window.scrollX,
|
||||
y: window.scrollY,
|
||||
},
|
||||
// TODO
|
||||
},
|
||||
{
|
||||
/* TODO */
|
||||
},
|
||||
} as any, // TODO: Better types.
|
||||
null as any,
|
||||
)
|
||||
})
|
||||
const [isParentTreeVisible, setIsParentTreeVisible] = React.useState(false)
|
||||
React.useEffect(() => {
|
||||
if (!isVisible) {
|
||||
if (!isParentTreeVisible) {
|
||||
// Prevents hidden tabs from firing scroll events.
|
||||
// Only one list is expected to be firing these at a time.
|
||||
return
|
||||
}
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}, [isVisible, handleScroll])
|
||||
}, [isParentTreeVisible, handleScroll])
|
||||
|
||||
// --- onScrolledDownChange ---
|
||||
const isScrolledDown = useRef(false)
|
||||
function handleAboveTheFoldVisibleChange(isAboveTheFold: boolean) {
|
||||
const didScrollDown = !isAboveTheFold
|
||||
@@ -138,13 +144,21 @@ function ListImpl<ItemT>(
|
||||
}
|
||||
}
|
||||
|
||||
const containerRef = useRef(null)
|
||||
useResizeObserver(containerRef, onContentSizeChange)
|
||||
// --- onEndReached ---
|
||||
const onTailVisibilityChange = useNonReactiveCallback(
|
||||
(isTailVisible: boolean) => {
|
||||
if (isTailVisible) {
|
||||
onEndReached?.({
|
||||
distanceFromEnd: onEndReachedThreshold || 0,
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return (
|
||||
<View {...props} style={style} ref={nativeRef}>
|
||||
<Visibility
|
||||
onVisibleChange={setIsVisible}
|
||||
onVisibleChange={setIsParentTreeVisible}
|
||||
style={styles.parentTreeVisibilityDetector}
|
||||
/>
|
||||
<View
|
||||
@@ -172,13 +186,7 @@ function ListImpl<ItemT>(
|
||||
{onEndReached && (
|
||||
<Visibility
|
||||
topMargin={(onEndReachedThreshold ?? 0) * 100 + '%'}
|
||||
onVisibleChange={isVisible => {
|
||||
if (isVisible) {
|
||||
onEndReached?.({
|
||||
distanceFromEnd: onEndReachedThreshold || 0,
|
||||
})
|
||||
}
|
||||
}}
|
||||
onVisibleChange={onTailVisibilityChange}
|
||||
/>
|
||||
)}
|
||||
{footer}
|
||||
@@ -187,17 +195,25 @@ function ListImpl<ItemT>(
|
||||
)
|
||||
}
|
||||
|
||||
function useResizeObserver(ref, onResize) {
|
||||
function useResizeObserver(
|
||||
ref: React.RefObject<Element>,
|
||||
onResize: undefined | ((w: number, h: number) => void),
|
||||
) {
|
||||
const handleResize = useNonReactiveCallback(onResize ?? (() => {}))
|
||||
const isActive = !!onResize
|
||||
React.useEffect(() => {
|
||||
if (!isActive) {
|
||||
return
|
||||
}
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
handleResize()
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
batchedUpdates(() => {
|
||||
for (let entry of entries) {
|
||||
const rect = entry.contentRect
|
||||
handleResize(rect.width, rect.height)
|
||||
}
|
||||
})
|
||||
})
|
||||
const node = ref.current
|
||||
const node = ref.current!
|
||||
resizeObserver.observe(node)
|
||||
return () => {
|
||||
resizeObserver.unobserve(node)
|
||||
|
||||
Reference in New Issue
Block a user