import React, { forwardRef, useRef } from 'react'; import { FlatListProps, Platform, FlatList as RNFlatList, StyleSheet } from 'react-native'; import { useUIKitTheme } from '@sendbird/uikit-react-native-foundation'; import { NOOP, SendbirdMessage, getMessageUniqId, useFreshCallback } from '@sendbird/uikit-utils'; import FlatListInternal from './FlatListInternal'; function isInvertedFlatListFixedVersion() { if (Platform.constants.reactNativeVersion?.major < 1) { if (Platform.constants.reactNativeVersion?.minor < 73) { if (Platform.constants.reactNativeVersion?.patch < 4) { return false; } } } return true; } let ANDROID_BUG_ALERT_SHOWED = Platform.OS !== 'android' || isInvertedFlatListFixedVersion(); const BOTTOM_DETECT_THRESHOLD = 50; const UNREACHABLE_THRESHOLD = Number.MIN_SAFE_INTEGER; type Props = Omit, 'onEndReached'> & { onBottomReached: () => void; onTopReached: () => void; onScrolledAwayFromBottom: (value: boolean) => void; flatListComponent?: React.ComponentType>; }; const ChatFlatList = forwardRef(function ChatFlatList( { onTopReached, onBottomReached, onScrolledAwayFromBottom, onScroll, flatListComponent, ...props }, ref, ) { const { select } = useUIKitTheme(); const contentOffsetY = useRef(0); const _onScroll = useFreshCallback>((event) => { onScroll?.(event); const { contentOffset } = event.nativeEvent; const prevOffsetY = contentOffsetY.current; const currOffsetY = contentOffset.y; if (BOTTOM_DETECT_THRESHOLD < prevOffsetY && currOffsetY <= BOTTOM_DETECT_THRESHOLD) { onScrolledAwayFromBottom(false); } else if (BOTTOM_DETECT_THRESHOLD < currOffsetY && prevOffsetY <= BOTTOM_DETECT_THRESHOLD) { onScrolledAwayFromBottom(true); } contentOffsetY.current = contentOffset.y; }); if (__DEV__ && !ANDROID_BUG_ALERT_SHOWED) { ANDROID_BUG_ALERT_SHOWED = true; // eslint-disable-next-line no-console console.warn( 'UIKit Warning: The Inverted FlatList had performance issues on Android.\n' + 'This issue was fixed in 0.72.4+\n' + 'Please refer to the link: https://github.com/facebook/react-native/issues/30034', ); } const FlatList = flatListComponent ?? FlatListInternal; return ( ); }); export default ChatFlatList;