import React, { useCallback, useEffect, useRef } from "react"; import { StyleSheet } from "react-native"; import { Gesture, GestureDetector } from "react-native-gesture-handler"; import Animated, { useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, withTiming, runOnJS, scrollTo, } from "react-native-reanimated"; import { useHeaderTabContext } from "./context"; import { useSharedScrollableRef, useSyncInitialPosition } from "./hooks"; import type { SceneProps } from "./types"; import { SCROLLABLE_STATE } from "./constants"; export function SceneComponent

({ index, onScroll: propOnScroll, onContentSizeChange, ContainerView, contentContainerStyle, scrollIndicatorInsets, forwardedRef, useExternalScrollView = false, ...restProps }: SceneProps

) { //#region refs const nativeGestureRef = useRef(Gesture.Native()); const scollViewRef = useSharedScrollableRef(forwardedRef); //#endregion //#region hooks const { shareAnimatedValue, headerHeight, expectHeight, refHasChanged, updateSceneInfo, scrollViewPaddingTop, animatedScrollableState, disableBounces, } = useHeaderTabContext(); //#endregion //#region animations/style const scrollY = useSharedValue(0); const { opacityValue, initialPosition } = useSyncInitialPosition(scollViewRef); const sceneStyle = useAnimatedStyle(() => { return { opacity: withTiming(opacityValue.value), }; }, [opacityValue]); //#endregion //#region methods const onScrollAnimateEvent = useAnimatedScrollHandler({ onScroll: (e) => { scrollY.value = e.contentOffset.y; if (animatedScrollableState.value === SCROLLABLE_STATE.LOCKED) { scrollTo(scollViewRef, 0, 0, false); } else { shareAnimatedValue.value = e.contentOffset.y; } if (propOnScroll) { runOnJS(propOnScroll as any)({ nativeEvent: e }); } }, onBeginDrag: () => { if (disableBounces) { disableBounces.value = true; } // console.log("onBeginDrag"); }, // onEndDrag: (e) => { // console.log("onEndDrag"); // }, // onMomentumEnd: () => { // console.log("onMomentumEnd"); // }, // onMomentumBegin: () => { // console.log("onMomentumBegin"); // }, }); // adjust the scene size const _onContentSizeChange = useCallback( (contentWidth: number, contentHeight: number) => { onContentSizeChange?.(contentWidth, contentHeight); if (Math.ceil(contentHeight) >= expectHeight) { initialPosition(shareAnimatedValue.value); } }, [onContentSizeChange, initialPosition, expectHeight, shareAnimatedValue] ); //#endregion useEffect(() => { refHasChanged?.(nativeGestureRef.current); }, [refHasChanged]); useEffect(() => { if (scollViewRef && scollViewRef.current) { updateSceneInfo({ scrollRef: scollViewRef, index, scrollY, }); } }, [scollViewRef, index, scrollY, updateSceneInfo]); return ( ); } const styles = StyleSheet.create({ container: { flex: 1, }, });