/* eslint-disable react-hooks/exhaustive-deps */ import AnimatedTopView from '../header/AnimatedTopView'; import useAnimatedScroll from './useAnimatedScroll'; import React, { ReactNode, useCallback, useEffect, useMemo, useRef, useState, } from 'react'; import { RefreshControl, ScrollViewProps, StyleSheet } from 'react-native'; import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, } from 'react-native-reanimated'; import type { CollapsibleProps } from '../../types'; import useCollapsibleContext from '../../hooks/useCollapsibleContext'; import useInternalCollapsibleContext from '../../hooks/useInternalCollapsibleContext'; type Props = ScrollViewProps & CollapsibleProps & { children?: ReactNode; refreshing?: boolean; onRefresh?: () => void; }; export default function CollapsibleScrollView({ headerSnappable = true, children, refreshing = false, onRefresh, ...props }: Props) { const { contentMinHeight, scrollViewRef, fixedHeaderHeight } = useInternalCollapsibleContext(); const { headerHeight } = useCollapsibleContext(); const [internalProgressViewOffset, setInternalProgressViewOffset] = useState(0); const mounted = useRef(true); useEffect(() => { return () => { mounted.current = false; }; }, []); const scrollTo = useCallback((yValue: number, animated = true) => { scrollViewRef.current?.scrollTo?.({ y: yValue, animated }); }, []); const scrollToIndex = useCallback(() => { console.warn("CollapsibleScrollView doesn't support scrollToIndex"); }, []); const scrollToLocation = useCallback(() => { console.warn('CollapsibleFlatList does not support scrollToLocation'); }, []); const { scrollHandler } = useAnimatedScroll({ headerSnappable, scrollTo, scrollToIndex, scrollToLocation, }); const animatedStyle = useAnimatedStyle(() => { return { minHeight: contentMinHeight.value, }; }, []); const handleInternalProgressViewOffset = useCallback((value: number) => { if (mounted.current) { setInternalProgressViewOffset(value); } }, []); useAnimatedReaction( () => { return fixedHeaderHeight.value; }, (result, previous) => { if (result !== previous) { runOnJS(handleInternalProgressViewOffset)(result); } } ); const contentContainerStyle = useMemo( () => [styles.contentContainer, props.contentContainerStyle], [props.contentContainerStyle] ); return ( ) : undefined } {...props} style={[StyleSheet.absoluteFill, props.style]} contentContainerStyle={contentContainerStyle} onScroll={scrollHandler} keyboardDismissMode="on-drag" keyboardShouldPersistTaps="handled" scrollEventThrottle={1} > {children} ); } const styles = StyleSheet.create({ contentContainer: { flexGrow: 1, }, });