UNPKG

stream-chat-react-native-core

Version:

The official React Native and Expo components for Stream Chat, a service for building chat applications

961 lines 46 kB
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageList = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _reactNativeReanimated = _interopRequireDefault(require("react-native-reanimated")); var _debounce = _interopRequireDefault(require("lodash/debounce")); var _useMessageList2 = require("./hooks/useMessageList"); var _useScrollToBottomAccessibilityAction = require("./hooks/useScrollToBottomAccessibilityAction"); var _useShouldScrollToRecentOnNewOwnMessage = require("./hooks/useShouldScrollToRecentOnNewOwnMessage"); var _InlineLoadingMoreIndicator = require("./InlineLoadingMoreIndicator"); var _InlineLoadingMoreRecentIndicator = require("./InlineLoadingMoreRecentIndicator"); var _InlineLoadingMoreRecentThreadIndicator = require("./InlineLoadingMoreRecentThreadIndicator"); var _buildMessageListWithNeighbours = require("./utils/buildMessageListWithNeighbours"); var _AttachmentPickerContext = require("../../contexts/attachmentPickerContext/AttachmentPickerContext"); var _ChannelContext = require("../../contexts/channelContext/ChannelContext"); var _ChatContext = require("../../contexts/chatContext/ChatContext"); var _ComponentsContext = require("../../contexts/componentsContext/ComponentsContext"); var _DebugContext = require("../../contexts/debugContext/DebugContext"); var _MessageInputContext = require("../../contexts/messageInputContext/MessageInputContext"); var _MessageListItemContext = require("../../contexts/messageListItemContext/MessageListItemContext"); var _MessagesContext = require("../../contexts/messagesContext/MessagesContext"); var _OwnCapabilitiesContext = require("../../contexts/ownCapabilitiesContext/OwnCapabilitiesContext"); var _PaginatedMessageListContext = require("../../contexts/paginatedMessageListContext/PaginatedMessageListContext"); var _ThemeContext = require("../../contexts/themeContext/ThemeContext"); var _ThreadContext = require("../../contexts/threadContext/ThreadContext"); var _hooks = require("../../hooks"); var _useStateStore2 = require("../../hooks/useStateStore"); var _stateStore = require("../../state-store"); var _theme = require("../../theme"); var _transitions = require("../../utils/animations/transitions"); var _useIncomingMessageAnnouncements = require("../Accessibility/hooks/useIncomingMessageAnnouncements"); var _MessageWrapper = require("../Message/MessageItemView/MessageWrapper"); var _notificationFilters = require("../Notifications/notificationFilters"); var _UIComponents = require("../UIComponents"); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["contentContainerStyle", "style"]; var _jsxFileName = "/home/runner/work/stream-chat-react-native/stream-chat-react-native/package/src/components/MessageList/MessageList.tsx"; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } var WAIT_FOR_SCROLL_TIMEOUT = 0; var MAX_RETRIES_AFTER_SCROLL_FAILURE = 10; var useStyles = () => { var _useTheme = (0, _ThemeContext.useTheme)(), _useTheme$theme = _useTheme.theme, semantics = _useTheme$theme.semantics, _useTheme$theme$messa = _useTheme$theme.messageList, container = _useTheme$theme$messa.container, contentContainer = _useTheme$theme$messa.contentContainer, listContainer = _useTheme$theme$messa.listContainer, stickyHeaderContainer = _useTheme$theme$messa.stickyHeaderContainer, scrollToBottomButtonContainer = _useTheme$theme$messa.scrollToBottomButtonContainer, unreadMessagesNotificationContainer = _useTheme$theme$messa.unreadMessagesNotificationContainer, suggestionListContainer = _useTheme$theme.messageComposer.suggestionsListContainer.container; var backgroundCoreApp = semantics.backgroundCoreApp; return (0, _react.useMemo)(() => _reactNative.StyleSheet.create({ suggestionsListContainer: { backgroundColor: 'transparent', position: 'absolute', width: '100%', ...suggestionListContainer }, container: { flex: 1, width: '100%', backgroundColor: backgroundCoreApp, ...container }, contentContainer: { paddingBottom: 4, ...contentContainer }, flex: { flex: 1, backgroundColor: backgroundCoreApp }, listContainer: { flex: 1, width: '100%', ...listContainer }, scrollToBottomButtonContainer: { position: 'absolute', right: 16, ...scrollToBottomButtonContainer }, stickyHeaderContainer: { left: 0, position: 'absolute', right: 0, top: _theme.primitives.spacingMd, ...stickyHeaderContainer }, unreadMessagesNotificationContainer: { position: 'absolute', top: _theme.primitives.spacingMd, left: 0, right: 0, alignItems: 'center', ...unreadMessagesNotificationContainer } }), [backgroundCoreApp, container, contentContainer, listContainer, scrollToBottomButtonContainer, stickyHeaderContainer, unreadMessagesNotificationContainer, suggestionListContainer]); }; var keyExtractor = derivedItem => { var item = derivedItem.message; if (item.id) { return item.id; } if (item.created_at) { return typeof item.created_at === 'string' ? item.created_at : item.created_at.toISOString(); } return Date.now().toString(); }; var flatListViewabilityConfig = { viewAreaCoveragePercentThreshold: 1 }; var hasReadLastMessage = (channel, userId) => { var _channel$state$latest, _channel$state$read$u; var latestMessageIdInChannel = (_channel$state$latest = channel.state.latestMessages.slice(-1)[0]) == null ? void 0 : _channel$state$latest.id; var lastReadMessageIdServer = (_channel$state$read$u = channel.state.read[userId]) == null ? void 0 : _channel$state$read$u.last_read_message_id; return latestMessageIdInChannel === lastReadMessageIdServer; }; var getPreviousLastMessage = (messages, newMessage) => { if (!newMessage) return; var previousLastMessage; for (var i = messages.length - 1; i >= 0; i--) { var msg = messages[i]; if (!(msg != null && msg.id)) break; if (msg.id !== newMessage.id) { previousLastMessage = msg; break; } } return previousLastMessage; }; var messageInputHeightStoreSelector = state => ({ height: state.height }); var MessageListWithContext = props => { var _client$user, _client$user5; var LoadingMoreRecentIndicator = props.threadList ? _InlineLoadingMoreRecentThreadIndicator.InlineLoadingMoreRecentThreadIndicator : _InlineLoadingMoreRecentIndicator.InlineLoadingMoreRecentIndicator; var allowSendBeforeAttachmentsUpload = props.allowSendBeforeAttachmentsUpload, _props$animateLayout = props.animateLayout, animateLayout = _props$animateLayout === void 0 ? true : _props$animateLayout, attachmentPickerStore = props.attachmentPickerStore, additionalFlatListProps = props.additionalFlatListProps, channel = props.channel, channelUnreadStateStore = props.channelUnreadStateStore, client = props.client, closePicker = props.closePicker, disabled = props.disabled, disableTypingIndicator = props.disableTypingIndicator, FlatList = props.FlatList, _props$FooterComponen = props.FooterComponent, FooterComponent = _props$FooterComponen === void 0 ? _InlineLoadingMoreIndicator.InlineLoadingMoreIndicator : _props$FooterComponen, HeaderComponent = props.HeaderComponent, hideStickyDateHeader = props.hideStickyDateHeader, _props$inverted = props.inverted, inverted = _props$inverted === void 0 ? true : _props$inverted, _props$isLiveStreamin = props.isLiveStreaming, isLiveStreaming = _props$isLiveStreamin === void 0 ? false : _props$isLiveStreamin, loadChannelAroundMessage = props.loadChannelAroundMessage, loading = props.loading, loadMore = props.loadMore, loadMoreRecent = props.loadMoreRecent, loadMoreRecentThread = props.loadMoreRecentThread, loadMoreThread = props.loadMoreThread, markRead = props.markRead, maximumMessageLimit = props.maximumMessageLimit, messageInputFloating = props.messageInputFloating, messageInputHeightStore = props.messageInputHeightStore, myMessageTheme = props.myMessageTheme, noGroupByUser = props.noGroupByUser, onListScroll = props.onListScroll, onThreadSelect = props.onThreadSelect, readEvents = props.readEvents, reloadChannel = props.reloadChannel, setChannelUnreadState = props.setChannelUnreadState, setFlatListRef = props.setFlatListRef, setTargetedMessage = props.setTargetedMessage, targetedMessage = props.targetedMessage, thread = props.thread, threadInstance = props.threadInstance, _props$threadList = props.threadList, threadList = _props$threadList === void 0 ? false : _props$threadList, hasMore = props.hasMore, threadHasMore = props.threadHasMore; var _useComponentsContext = (0, _ComponentsContext.useComponentsContext)(), EmptyStateIndicator = _useComponentsContext.EmptyStateIndicator, LoadingIndicator = _useComponentsContext.MessageListLoadingIndicator, NetworkDownIndicator = _useComponentsContext.NetworkDownIndicator, NotificationList = _useComponentsContext.NotificationList, ScrollToBottomButton = _useComponentsContext.ScrollToBottomButton, StickyHeader = _useComponentsContext.StickyHeader, TypingIndicator = _useComponentsContext.TypingIndicator, TypingIndicatorContainer = _useComponentsContext.TypingIndicatorContainer, UnreadMessagesNotification = _useComponentsContext.UnreadMessagesNotification, AutoCompleteSuggestionList = _useComponentsContext.AutoCompleteSuggestionList; var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2.default)(_useState, 2), isUnreadNotificationOpen = _useState2[0], setIsUnreadNotificationOpen = _useState2[1]; var _useTheme2 = (0, _ThemeContext.useTheme)(), theme = _useTheme2.theme; var styles = useStyles(); var _useStateStore = (0, _useStateStore2.useStateStore)(messageInputHeightStore.store, messageInputHeightStoreSelector), messageInputHeight = _useStateStore.height; (0, _useIncomingMessageAnnouncements.useIncomingMessageAnnouncements)({ activeThreadId: thread == null ? void 0 : thread.id, channel, ownUserId: (_client$user = client.user) == null ? void 0 : _client$user.id, threadList }); var myMessageThemeString = (0, _react.useMemo)(() => JSON.stringify(myMessageTheme), [myMessageTheme]); var scheme = (0, _reactNative.useColorScheme)(); var modifiedTheme = (0, _react.useMemo)(() => (0, _ThemeContext.mergeThemes)({ scheme, style: myMessageTheme, theme }), [myMessageThemeString, scheme, theme]); var _useMessageList = (0, _useMessageList2.useMessageList)({ isLiveStreaming, threadList }), processedMessageList = _useMessageList.processedMessageList, rawMessageList = _useMessageList.rawMessageList, viewabilityChangedCallback = _useMessageList.viewabilityChangedCallback; var previousDerivedItemsRef = (0, _react.useRef)(undefined); var processedMessageListWithNeighbors = (0, _react.useMemo)(() => { if (!previousDerivedItemsRef.current) { previousDerivedItemsRef.current = new Map(); } var _buildMessageListWith = (0, _buildMessageListWithNeighbours.buildMessageListWithNeighbours)(processedMessageList, previousDerivedItemsRef.current), items = _buildMessageListWith.items, nextDerivedItems = _buildMessageListWith.nextDerivedItems; previousDerivedItemsRef.current = nextDerivedItems; return items; }, [processedMessageList]); var renderItem = (0, _hooks.useStableCallback)(({ item }) => { var message = item.message, previousMessage = item.previousMessage, nextMessage = item.nextMessage; return (0, _jsxRuntime.jsx)(_MessageWrapper.MessageWrapper, { message: message, previousMessage: previousMessage, nextMessage: nextMessage }); }); var messageListLengthBeforeUpdate = (0, _react.useRef)(0); var messageListLengthAfterUpdate = processedMessageList.length; var topMessageBeforeUpdate = (0, _react.useRef)(undefined); var latestNonCurrentMessageBeforeUpdateRef = (0, _react.useRef)(undefined); var topMessageAfterUpdate = rawMessageList[0]; var shouldScrollToRecentOnNewOwnMessageRef = (0, _useShouldScrollToRecentOnNewOwnMessage.useShouldScrollToRecentOnNewOwnMessage)(rawMessageList, client.userID); var _useState3 = (0, _react.useState)(false), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), autoscrollToRecent = _useState4[0], setAutoscrollToRecent = _useState4[1]; var minIndexForVisible = Math.min(1, processedMessageList.length); var isOverlayOpen = (0, _stateStore.useHasActiveId)(); var autoscrollToTopThreshold = autoscrollToRecent && !isOverlayOpen ? isLiveStreaming ? 300 : 10 : undefined; var maintainVisibleContentPosition = (0, _react.useMemo)(() => ({ autoscrollToTopThreshold, minIndexForVisible }), [autoscrollToTopThreshold, minIndexForVisible]); var onStartReachedTracker = (0, _react.useRef)({}); var onEndReachedTracker = (0, _react.useRef)({}); var onStartReachedInPromise = (0, _react.useRef)(null); var onEndReachedInPromise = (0, _react.useRef)(null); var flatListRef = (0, _react.useRef)(null); var channelResyncScrollSet = (0, _react.useRef)(true); var scrollToDebounceTimeoutRef = (0, _react.useRef)(undefined); var onScrollEventTimeoutRef = (0, _react.useRef)(undefined); var messageIdLastScrolledToRef = (0, _react.useRef)(undefined); var _useState5 = (0, _react.useState)(false), _useState6 = (0, _slicedToArray2.default)(_useState5, 2), hasMoved = _useState6[0], setHasMoved = _useState6[1]; var _useState7 = (0, _react.useState)(false), _useState8 = (0, _slicedToArray2.default)(_useState7, 2), scrollToBottomButtonVisible = _useState8[0], setScrollToBottomButtonVisible = _useState8[1]; var _useState9 = (0, _react.useState)(), _useState0 = (0, _slicedToArray2.default)(_useState9, 2), stickyHeaderDate = _useState0[0], setStickyHeaderDate = _useState0[1]; var stickyHeaderDateRef = (0, _react.useRef)(undefined); var channelRef = (0, _react.useRef)(channel); channelRef.current = channel; var updateStickyHeaderDateIfNeeded = (0, _hooks.useStableCallback)(viewableItems => { var _viewableItems$item; if (!viewableItems.length) { return; } var lastMessage = (_viewableItems$item = viewableItems[viewableItems.length - 1].item) == null ? void 0 : _viewableItems$item.message; if (lastMessage) { var _stickyHeaderDateRef$; if (!channel.state.messagePagination.hasPrev && processedMessageList[processedMessageList.length - 1].id === lastMessage.id) { setStickyHeaderDate(undefined); return; } var isMessageTypeDeleted = lastMessage.type === 'deleted'; if (lastMessage != null && lastMessage.created_at && !isMessageTypeDeleted && typeof lastMessage.created_at !== 'string' && lastMessage.created_at.toDateString() !== ((_stickyHeaderDateRef$ = stickyHeaderDateRef.current) == null ? void 0 : _stickyHeaderDateRef$.toDateString())) { stickyHeaderDateRef.current = lastMessage.created_at; setStickyHeaderDate(lastMessage.created_at); } } }); var updateStickyUnreadIndicator = (0, _hooks.useStableCallback)(viewableItems => { var channelUnreadState = channelUnreadStateStore.channelUnreadState; var lastReadMessageId = channelUnreadState == null ? void 0 : channelUnreadState.last_read_message_id; var lastReadMessageVisible = viewableItems.some(item => item.item.message.id === lastReadMessageId); var unreadNotificationSupported = readEvents || client.options.isLocalUnreadCountEnabled; if (!viewableItems.length || !unreadNotificationSupported || lastReadMessageVisible || attachmentPickerStore.state.getLatestValue().selectedPicker === 'images') { setIsUnreadNotificationOpen(false); return; } var lastItem = viewableItems[viewableItems.length - 1].item; if (lastItem) { var _channelUnreadState$l, _lastItemMessage$user; var lastItemMessage = lastItem.message; var lastItemCreatedAt = lastItemMessage.created_at; var unreadIndicatorDate = channelUnreadState == null || (_channelUnreadState$l = channelUnreadState.last_read) == null ? void 0 : _channelUnreadState$l.getTime(); var lastItemDate = lastItemCreatedAt.getTime(); if (!channel.state.messagePagination.hasPrev && processedMessageList[processedMessageList.length - 1].id === lastItemMessage.id) { setIsUnreadNotificationOpen(false); return; } if (viewableItems.length === 1 && channel.countUnread() === 0 && ((_lastItemMessage$user = lastItemMessage.user) == null ? void 0 : _lastItemMessage$user.id) === client.userID) { setIsUnreadNotificationOpen(false); return; } if (unreadIndicatorDate && lastItemDate > unreadIndicatorDate) { setIsUnreadNotificationOpen(true); } else { setIsUnreadNotificationOpen(false); } } }); var unstableOnViewableItemsChanged = ({ viewableItems }) => { viewabilityChangedCallback({ inverted, viewableItems }); if (!viewableItems) { return; } if (!hideStickyDateHeader) { updateStickyHeaderDateIfNeeded(viewableItems); } updateStickyUnreadIndicator(viewableItems); }; var onViewableItemsChanged = (0, _react.useRef)(unstableOnViewableItemsChanged); onViewableItemsChanged.current = unstableOnViewableItemsChanged; var stableOnViewableItemsChanged = (0, _react.useCallback)(({ viewableItems }) => { onViewableItemsChanged.current({ viewableItems }); }, []); var resetPaginationTrackersRef = (0, _react.useRef)(() => { onStartReachedTracker.current = {}; onEndReachedTracker.current = {}; }); (0, _react.useEffect)(() => { if (disabled) { setScrollToBottomButtonVisible(false); } }, [disabled]); (0, _react.useEffect)(() => { var shouldMarkRead = () => { var _client$user2, _client$user3; var channelUnreadState = channelUnreadStateStore.channelUnreadState; return !(channelUnreadState != null && channelUnreadState.first_unread_message_id) && !scrollToBottomButtonVisible && ((_client$user2 = client.user) == null ? void 0 : _client$user2.id) && !hasReadLastMessage(channel, (_client$user3 = client.user) == null ? void 0 : _client$user3.id); }; var handleEvent = function () { var _ref = (0, _asyncToGenerator2.default)(function* (event) { var _event$message, _event$message2, _event$message3, _client$user4; var mainChannelUpdated = !((_event$message = event.message) != null && _event$message.parent_id) || ((_event$message2 = event.message) == null ? void 0 : _event$message2.show_in_channel); var isMyOwnMessage = ((_event$message3 = event.message) == null || (_event$message3 = _event$message3.user) == null ? void 0 : _event$message3.id) === ((_client$user4 = client.user) == null ? void 0 : _client$user4.id); var channelUnreadState = channelUnreadStateStore.channelUnreadState; if ((scrollToBottomButtonVisible || channelUnreadState != null && channelUnreadState.first_unread_message_id) && !isMyOwnMessage) { var _channelUnreadState$u, _channelUnreadState$l2; var previousUnreadCount = (_channelUnreadState$u = channelUnreadState == null ? void 0 : channelUnreadState.unread_messages) != null ? _channelUnreadState$u : 0; var previousLastMessage = getPreviousLastMessage(channel.state.messages, event.message); setChannelUnreadState({ ...channelUnreadState, last_read: (_channelUnreadState$l2 = channelUnreadState == null ? void 0 : channelUnreadState.last_read) != null ? _channelUnreadState$l2 : previousUnreadCount === 0 && previousLastMessage != null && previousLastMessage.created_at ? new Date(previousLastMessage.created_at) : new Date(0), unread_messages: previousUnreadCount + 1 }); } else if (mainChannelUpdated && shouldMarkRead()) { yield markRead(); } }); return function handleEvent(_x) { return _ref.apply(this, arguments); }; }(); var listener = channel.on('message.new', handleEvent); return () => { listener == null || listener.unsubscribe(); }; }, [channel, channelUnreadStateStore, (_client$user5 = client.user) == null ? void 0 : _client$user5.id, markRead, scrollToBottomButtonVisible, setChannelUnreadState, threadList]); (0, _react.useEffect)(() => { var isMessageRemovedFromMessageList = messageListLengthAfterUpdate < messageListLengthBeforeUpdate.current; var scrollToBottomIfNeeded = () => { var _topMessageBeforeUpda; if (!client || !channel || rawMessageList.length === 0) { return; } if (isMessageRemovedFromMessageList || (_topMessageBeforeUpda = topMessageBeforeUpdate.current) != null && _topMessageBeforeUpda.created_at && topMessageAfterUpdate != null && topMessageAfterUpdate.created_at && topMessageBeforeUpdate.current.created_at < topMessageAfterUpdate.created_at) { channelResyncScrollSet.current = false; setScrollToBottomButtonVisible(false); resetPaginationTrackersRef.current(); setTimeout(() => { var _flatListRef$current; (_flatListRef$current = flatListRef.current) == null || _flatListRef$current.scrollToOffset({ offset: 0 }); }, WAIT_FOR_SCROLL_TIMEOUT); setTimeout(() => { channelResyncScrollSet.current = true; if (channel.countUnread() > 0) { markRead(); } }, 500); } }; if (threadList || isMessageRemovedFromMessageList) { if (maximumMessageLimit) { resetPaginationTrackersRef.current(); } else { scrollToBottomIfNeeded(); } } messageListLengthBeforeUpdate.current = messageListLengthAfterUpdate; topMessageBeforeUpdate.current = topMessageAfterUpdate; }, [threadList, messageListLengthAfterUpdate, topMessageAfterUpdate == null ? void 0 : topMessageAfterUpdate.id, maximumMessageLimit]); (0, _react.useEffect)(() => { if (threadList) { setAutoscrollToRecent(true); return; } if (!processedMessageList.length) { return; } var notLatestSet = channel.state.messages !== channel.state.latestMessages; if (notLatestSet) { latestNonCurrentMessageBeforeUpdateRef.current = channel.state.latestMessages[channel.state.latestMessages.length - 1]; setAutoscrollToRecent(false); setScrollToBottomButtonVisible(true); return; } var latestNonCurrentMessageBeforeUpdate = latestNonCurrentMessageBeforeUpdateRef.current; latestNonCurrentMessageBeforeUpdateRef.current = undefined; var latestCurrentMessageAfterUpdate = processedMessageList[0]; if (!latestCurrentMessageAfterUpdate) { setAutoscrollToRecent(true); return; } var didMergeMessageSetsWithNoUpdates = (latestNonCurrentMessageBeforeUpdate == null ? void 0 : latestNonCurrentMessageBeforeUpdate.id) === latestCurrentMessageAfterUpdate.id; var shouldForceScrollToRecent = !didMergeMessageSetsWithNoUpdates || processedMessageList.length - messageListLengthBeforeUpdate.current > 0; if (maximumMessageLimit && shouldForceScrollToRecent || !maximumMessageLimit) { setAutoscrollToRecent(shouldForceScrollToRecent); } if (!didMergeMessageSetsWithNoUpdates) { var shouldScrollToRecentOnNewOwnMessage = shouldScrollToRecentOnNewOwnMessageRef.current(); if (shouldScrollToRecentOnNewOwnMessage) { setTimeout(() => { var _flatListRef$current2; (_flatListRef$current2 = flatListRef.current) == null || _flatListRef$current2.scrollToOffset({ animated: true, offset: 0 }); }, WAIT_FOR_SCROLL_TIMEOUT); } } }, [channel, threadList, processedMessageList, shouldScrollToRecentOnNewOwnMessageRef, maximumMessageLimit]); var goToMessage = (0, _hooks.useStableCallback)(function () { var _ref2 = (0, _asyncToGenerator2.default)(function* (messageId) { var indexOfParentInMessageList = processedMessageList.findIndex(message => (message == null ? void 0 : message.id) === messageId); try { if (indexOfParentInMessageList === -1) { yield loadChannelAroundMessage({ messageId }); return; } else { if (!flatListRef.current) { return; } clearTimeout(failScrollTimeoutId.current); scrollToIndexFailedRetryCountRef.current = 0; messageIdLastScrolledToRef.current = messageId; setTargetedMessage(messageId); flatListRef.current.scrollToIndex({ animated: true, index: indexOfParentInMessageList, viewPosition: 0.5 }); return; } } catch (e) { console.warn('Error while scrolling to message', e); } }); return function (_x2) { return _ref2.apply(this, arguments); }; }()); (0, _react.useEffect)(() => { if (!targetedMessage) { return; } scrollToDebounceTimeoutRef.current = setTimeout((0, _asyncToGenerator2.default)(function* () { var indexOfParentInMessageList = processedMessageList.findIndex(message => (message == null ? void 0 : message.id) === targetedMessage); if (indexOfParentInMessageList === -1) { yield loadChannelAroundMessage({ messageId: targetedMessage, setTargetedMessage }); } else { if (!flatListRef.current) { return; } clearTimeout(scrollToDebounceTimeoutRef.current); clearTimeout(failScrollTimeoutId.current); scrollToIndexFailedRetryCountRef.current = 0; flatListRef.current.scrollToIndex({ animated: true, index: indexOfParentInMessageList, viewPosition: 0.5 }); setTargetedMessage(undefined); } }), WAIT_FOR_SCROLL_TIMEOUT); }, [targetedMessage]); var setNativeScrollability = (0, _hooks.useStableCallback)(value => { if (flatListRef.current) { flatListRef.current.setNativeProps({ scrollEnabled: value }); } }); var messageListItemContextValue = (0, _react.useMemo)(() => ({ goToMessage, modifiedTheme, noGroupByUser, onThreadSelect, setNativeScrollability }), [goToMessage, modifiedTheme, noGroupByUser, onThreadSelect, setNativeScrollability]); var maybeCallOnStartReached = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* () { if (processedMessageList != null && processedMessageList.length && onStartReachedTracker.current[processedMessageList.length]) { return; } if (processedMessageList != null && processedMessageList.length) { onStartReachedTracker.current[processedMessageList.length] = true; } var callback = () => { onStartReachedInPromise.current = null; return Promise.resolve(); }; var onError = () => { setTimeout(() => { onStartReachedTracker.current = {}; }, 2000); }; if (onEndReachedInPromise.current) { yield onEndReachedInPromise.current; } onStartReachedInPromise.current = (threadList && !!threadInstance && loadMoreRecentThread ? loadMoreRecentThread({}) : loadMoreRecent()).then(callback).catch(onError); })); var maybeCallOnEndReached = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* () { var shouldQuery = threadList && threadHasMore || !threadList && hasMore; if (processedMessageList != null && processedMessageList.length && onEndReachedTracker.current[processedMessageList.length] || !shouldQuery) { return; } if (processedMessageList != null && processedMessageList.length) { onEndReachedTracker.current[processedMessageList.length] = true; } var callback = () => { onEndReachedInPromise.current = null; return Promise.resolve(); }; var onError = () => { setTimeout(() => { onEndReachedTracker.current = {}; }, 2000); }; if (onStartReachedInPromise.current) { yield onStartReachedInPromise.current; } onEndReachedInPromise.current = (threadList ? loadMoreThread() : loadMore()).then(callback).catch(onError); })); var onUserScrollEvent = (0, _hooks.useStableCallback)(event => { var nativeEvent = event.nativeEvent; clearTimeout(onScrollEventTimeoutRef.current); var offset = nativeEvent.contentOffset.y; var visibleLength = nativeEvent.layoutMeasurement.height; var contentLength = nativeEvent.contentSize.height; if (!channel || !channelResyncScrollSet.current) { return; } var isScrollAtStart = offset < 100; var isScrollAtEnd = contentLength - visibleLength - offset < 100; if (isScrollAtStart) { maybeCallOnStartReached(); } if (isScrollAtEnd) { maybeCallOnEndReached(); } }); var handleScroll = (0, _hooks.useStableCallback)(event => { var messageListHasMessages = processedMessageList.length > 0; var offset = event.nativeEvent.contentOffset.y; var isScrollAtBottom = offset <= messageInputHeight; var notLatestSet = channel.state.messages !== channel.state.latestMessages; var showScrollToBottomButton = messageListHasMessages && (!threadList && notLatestSet || !isScrollAtBottom); setScrollToBottomButtonVisible(showScrollToBottomButton); if (onListScroll) { onListScroll(event); } }); var goToNewMessages = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* () { var isNotLatestSet = channel.state.messages !== channel.state.latestMessages; if (isNotLatestSet) { resetPaginationTrackersRef.current(); yield reloadChannel(); } else if (flatListRef.current) { flatListRef.current.scrollToOffset({ animated: true, offset: 0 }); } setScrollToBottomButtonVisible(false); yield markRead({ updateChannelUnreadState: false }); })); var scrollToBottomUnreadCount = scrollToBottomButtonVisible && !threadList ? channel == null ? void 0 : channel.countUnread() : undefined; var _useScrollToBottomAcc = (0, _useScrollToBottomAccessibilityAction.useScrollToBottomAccessibilityAction)({ accessibilityActions: additionalFlatListProps == null ? void 0 : additionalFlatListProps.accessibilityActions, onAccessibilityAction: additionalFlatListProps == null ? void 0 : additionalFlatListProps.onAccessibilityAction, onScrollToBottom: goToNewMessages, unreadCount: scrollToBottomUnreadCount, visible: scrollToBottomButtonVisible }), messageListAccessibilityActions = _useScrollToBottomAcc.accessibilityActions, messageListOnAccessibilityAction = _useScrollToBottomAcc.onAccessibilityAction; var scrollToIndexFailedRetryCountRef = (0, _react.useRef)(0); var failScrollTimeoutId = (0, _react.useRef)(undefined); var onScrollToIndexFailedRef = (0, _react.useRef)(info => { if (!flatListRef.current) { return; } failScrollTimeoutId.current = setTimeout(() => { try { var _flatListRef$current3; (_flatListRef$current3 = flatListRef.current) == null || _flatListRef$current3.scrollToIndex({ animated: true, index: info.index, viewPosition: 0.5 }); if (messageIdLastScrolledToRef.current) { setTargetedMessage(messageIdLastScrolledToRef.current); } scrollToIndexFailedRetryCountRef.current = 0; } catch (e) { if (!onScrollToIndexFailedRef.current || scrollToIndexFailedRetryCountRef.current > MAX_RETRIES_AFTER_SCROLL_FAILURE) { scrollToIndexFailedRetryCountRef.current = 0; return; } scrollToIndexFailedRetryCountRef.current += 1; onScrollToIndexFailedRef.current(info); } }, WAIT_FOR_SCROLL_TIMEOUT); }); var dismissImagePicker = (0, _hooks.useStableCallback)(() => { if (attachmentPickerStore.state.getLatestValue().selectedPicker) { attachmentPickerStore.setSelectedPicker(undefined); closePicker(); } }); var onScrollBeginDrag = (0, _hooks.useStableCallback)(event => { !hasMoved && attachmentPickerStore.state.getLatestValue().selectedPicker && setHasMoved(true); onUserScrollEvent(event); }); var onScrollEndDrag = (0, _hooks.useStableCallback)(event => { hasMoved && attachmentPickerStore.state.getLatestValue().selectedPicker && setHasMoved(false); onUserScrollEvent(event); }); var refCallback = (0, _hooks.useStableCallback)(ref => { flatListRef.current = ref; if (setFlatListRef) { setFlatListRef(ref); } }); var onUnreadNotificationClose = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* () { yield markRead(); setIsUnreadNotificationOpen(false); })); var debugRef = (0, _DebugContext.useDebugContext)(); var isDebugModeEnabled = __DEV__ && debugRef && debugRef.current; if (isDebugModeEnabled) { if (debugRef.current.setEventType) { debugRef.current.setEventType('send'); } if (debugRef.current.setSendEventParams) { debugRef.current.setSendEventParams({ action: thread ? 'ThreadList' : 'Messages', data: processedMessageList }); } } var additionalFlatListPropsExcludingStyle; if (additionalFlatListProps) { var contentContainerStyle = additionalFlatListProps.contentContainerStyle, style = additionalFlatListProps.style, rest = (0, _objectWithoutProperties2.default)(additionalFlatListProps, _excluded); additionalFlatListPropsExcludingStyle = rest; } var flatListStyle = (0, _react.useMemo)(() => [styles.listContainer, additionalFlatListProps == null ? void 0 : additionalFlatListProps.style], [additionalFlatListProps == null ? void 0 : additionalFlatListProps.style, styles.listContainer]); var liveStreamingListProps = (0, _react.useMemo)(() => ({ strictMode: isLiveStreaming }), [isLiveStreaming]); var flatListContentContainerStyle = (0, _react.useMemo)(() => [{ paddingTop: messageInputFloating ? messageInputHeight : 0 }, styles.contentContainer, additionalFlatListProps == null ? void 0 : additionalFlatListProps.contentContainerStyle], [additionalFlatListProps == null ? void 0 : additionalFlatListProps.contentContainerStyle, styles.contentContainer, messageInputHeight, messageInputFloating]); var ListComponent = animateLayout ? AnimatedList : FlatList; var viewportHeightRef = (0, _react.useRef)(undefined); var debouncedPrefillMessages = (0, _react.useMemo)(() => (0, _debounce.default)((viewportHeight, contentHeight) => { if (viewportHeight >= contentHeight) { maybeCallOnEndReached(); } }, 500, { leading: false, trailing: true }), [maybeCallOnEndReached]); var onContentSizeChange = (0, _hooks.useStableCallback)((width, height) => { var _viewportHeightRef$cu; if (additionalFlatListProps != null && additionalFlatListProps.onContentSizeChange) { additionalFlatListProps.onContentSizeChange(width, height); } debouncedPrefillMessages((_viewportHeightRef$cu = viewportHeightRef.current) != null ? _viewportHeightRef$cu : 0, height); }); var onLayout = (0, _hooks.useStableCallback)(event => { if (additionalFlatListProps != null && additionalFlatListProps.onLayout) { additionalFlatListProps.onLayout(event); } var nextViewportHeight = event.nativeEvent.layout.height; if (viewportHeightRef.current !== nextViewportHeight) { var _viewportHeightRef$cu2; var previousViewportHeight = (_viewportHeightRef$cu2 = viewportHeightRef.current) != null ? _viewportHeightRef$cu2 : nextViewportHeight; var closeCorrectionDeltaY = nextViewportHeight - previousViewportHeight; (0, _stateStore.bumpOverlayLayoutRevision)(closeCorrectionDeltaY); } viewportHeightRef.current = nextViewportHeight; }); var ListHeaderComponent = (0, _react.useCallback)(() => { if (HeaderComponent) { return (0, _jsxRuntime.jsx)(HeaderComponent, {}); } return (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [(0, _jsxRuntime.jsx)(LoadingMoreRecentIndicator, {}), !disableTypingIndicator && TypingIndicator && (0, _jsxRuntime.jsx)(TypingIndicatorContainer, { children: (0, _jsxRuntime.jsx)(TypingIndicator, {}) })] }); }, [HeaderComponent, LoadingMoreRecentIndicator, TypingIndicator, TypingIndicatorContainer, disableTypingIndicator]); if (!ListComponent) { return null; } if (loading) { return (0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.container, children: (0, _jsxRuntime.jsx)(LoadingIndicator, { listType: "message" }) }); } return (0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.container, testID: "message-flat-list-wrapper", children: [processedMessageList.length === 0 && !thread ? (0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.flex, testID: "empty-state", children: EmptyStateIndicator ? (0, _jsxRuntime.jsx)(EmptyStateIndicator, { listType: "message" }) : null }) : (0, _jsxRuntime.jsx)(_MessageListItemContext.MessageListItemProvider, { value: messageListItemContextValue, children: (0, _jsxRuntime.jsx)(ListComponent, { layout: _transitions.transitions.layout200, contentContainerStyle: flatListContentContainerStyle, data: processedMessageListWithNeighbors, extraData: disabled, inverted: inverted, keyboardShouldPersistTaps: "handled", keyExtractor: keyExtractor, ListFooterComponent: FooterComponent, ListHeaderComponent: ListHeaderComponent, maintainVisibleContentPosition: maintainVisibleContentPosition, maxToRenderPerBatch: 30, onContentSizeChange: onContentSizeChange, onLayout: onLayout, onMomentumScrollEnd: onUserScrollEvent, onScroll: handleScroll, onScrollBeginDrag: onScrollBeginDrag, onScrollEndDrag: onScrollEndDrag, onScrollToIndexFailed: onScrollToIndexFailedRef.current, onTouchEnd: dismissImagePicker, onViewableItemsChanged: stableOnViewableItemsChanged, ref: refCallback, renderItem: renderItem, scrollEventThrottle: isLiveStreaming ? 16 : undefined, showsVerticalScrollIndicator: false, style: flatListStyle, testID: "message-flat-list", viewabilityConfig: flatListViewabilityConfig, ...liveStreamingListProps, ...additionalFlatListPropsExcludingStyle, accessibilityActions: messageListAccessibilityActions, onAccessibilityAction: messageListOnAccessibilityAction }) }), (0, _jsxRuntime.jsx)(_reactNative.View, { accessibilityElementsHidden: true, accessible: false, importantForAccessibility: "no-hide-descendants", style: styles.stickyHeaderContainer, children: messageListLengthAfterUpdate && StickyHeader ? (0, _jsxRuntime.jsx)(StickyHeader, { date: stickyHeaderDate }) : null }), scrollToBottomButtonVisible ? (0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, { layout: _transitions.transitions.layout200, style: [{ bottom: messageInputFloating ? messageInputHeight + _theme.primitives.spacingMd + 16 : _theme.primitives.spacingMd }, styles.scrollToBottomButtonContainer], children: (0, _jsxRuntime.jsx)(ScrollToBottomButton, { onPress: goToNewMessages, showNotification: scrollToBottomButtonVisible, unreadCount: scrollToBottomUnreadCount }) }) : null, (0, _jsxRuntime.jsx)(NetworkDownIndicator, {}), isUnreadNotificationOpen && !threadList ? (0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.unreadMessagesNotificationContainer, children: (0, _jsxRuntime.jsx)(UnreadMessagesNotification, { onCloseHandler: onUnreadNotificationClose, channelUnreadStateStore: channelUnreadStateStore }) }) : null, (0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, { layout: _transitions.transitions.layout200, style: [{ bottom: messageInputFloating ? messageInputHeight + 16 : 0 }, styles.suggestionsListContainer], children: (0, _jsxRuntime.jsx)(_UIComponents.PortalWhileClosingView, { portalHostName: "overlay-suggestion-list", portalName: "autocomplete-suggestion-list", children: (0, _jsxRuntime.jsx)(AutoCompleteSuggestionList, {}) }) }), (0, _jsxRuntime.jsx)(NotificationList, { bottomOffset: messageInputFloating ? messageInputHeight + 16 : undefined, filter: allowSendBeforeAttachmentsUpload ? _notificationFilters.excludeCanceledUploadNotifications : undefined })] }); }; var MessageList = props => { var _useAttachmentPickerC = (0, _AttachmentPickerContext.useAttachmentPickerContext)(), closePicker = _useAttachmentPickerC.closePicker, attachmentPickerStore = _useAttachmentPickerC.attachmentPickerStore; var _useChannelContext = (0, _ChannelContext.useChannelContext)(), channel = _useChannelContext.channel, channelUnreadStateStore = _useChannelContext.channelUnreadStateStore, disabled = _useChannelContext.disabled, enableMessageGroupingByUser = _useChannelContext.enableMessageGroupingByUser, error = _useChannelContext.error, hideStickyDateHeader = _useChannelContext.hideStickyDateHeader, highlightedMessageId = _useChannelContext.highlightedMessageId, loadChannelAroundMessage = _useChannelContext.loadChannelAroundMessage, loading = _useChannelContext.loading, maximumMessageLimit = _useChannelContext.maximumMessageLimit, markRead = _useChannelContext.markRead, reloadChannel = _useChannelContext.reloadChannel, scrollToFirstUnreadThreshold = _useChannelContext.scrollToFirstUnreadThreshold, setChannelUnreadState = _useChannelContext.setChannelUnreadState, setTargetedMessage = _useChannelContext.setTargetedMessage, targetedMessage = _useChannelContext.targetedMessage, threadList = _useChannelContext.threadList; var _useChatContext = (0, _ChatContext.useChatContext)(), client = _useChatContext.client; var _useOwnCapabilitiesCo = (0, _OwnCapabilitiesContext.useOwnCapabilitiesContext)(), readEvents = _useOwnCapabilitiesCo.readEvents; var _useMessagesContext = (0, _MessagesContext.useMessagesContext)(), disableTypingIndicator = _useMessagesContext.disableTypingIndicator, FlatList = _useMessagesContext.FlatList, myMessageTheme = _useMessagesContext.myMessageTheme, shouldShowUnreadUnderlay = _useMessagesContext.shouldShowUnreadUnderlay; var _useMessageInputConte = (0, _MessageInputContext.useMessageInputContext)(), allowSendBeforeAttachmentsUpload = _useMessageInputConte.allowSendBeforeAttachmentsUpload, messageInputFloating = _useMessageInputConte.messageInputFloating, messageInputHeightStore = _useMessageInputConte.messageInputHeightStore; var _usePaginatedMessageL = (0, _PaginatedMessageListContext.usePaginatedMessageListContext)(), loadMore = _usePaginatedMessageL.loadMore, loadMoreRecent = _usePaginatedMessageL.loadMoreRecent, hasMore = _usePaginatedMessageL.hasMore; var _useThreadContext = (0, _ThreadContext.useThreadContext)(), loadMoreRecentThread = _useThreadContext.loadMoreRecentThread, loadMoreThread = _useThreadContext.loadMoreThread, threadHasMore = _useThreadContext.threadHasMore, thread = _useThreadContext.thread, threadInstance = _useThreadContext.threadInstance; return (0, _jsxRuntime.jsx)(MessageListWithContext, { allowSendBeforeAttachmentsUpload, attachmentPickerStore, channel, channelUnreadStateStore, client, closePicker, disabled, disableTypingIndicator, enableMessageGroupingByUser, error, FlatList, hideStickyDateHeader, highlightedMessageId, loadChannelAroundMessage, loading, loadMore, loadMoreRecent, loadMoreRecentThread, loadMoreThread, markRead, maximumMessageLimit, messageInputFloating, messageInputHeightStore, myMessageTheme, readEvents, reloadChannel, scrollToFirstUnreadThreshold, setChannelUnreadState, setTargetedMessage, shouldShowUnreadUnderlay, targetedMessage, thread, threadInstance, threadList, hasMore, threadHasMore, ...props, noGroupByUser: !enableMessageGroupingByUser || props.noGroupByUser }); }; exports.MessageList = MessageList; var AnimatedList = _react.default.memo(_reactNativeReanimated.default.createAnimatedComponent(_reactNative.FlatList)); //# sourceMappingURL=MessageList.js.map