UNPKG

stream-chat-react-native-core

Version:

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

288 lines 11.6 kB
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.useMessageListPagination = void 0; var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _react = require("react"); var _debounce = _interopRequireDefault(require("lodash/debounce")); var _useChannelDataState = require("./useChannelDataState"); var _TranslationContext = require("../../../contexts/translationContext/TranslationContext"); var _hooks = require("../../../hooks"); var _utils = require("../../../utils/utils"); var _Notifications = require("../../Notifications"); var defaultDebounceInterval = 500; var debounceOptions = { leading: true, trailing: true }; var useMessageListPagination = ({ channel }) => { var _useNotificationApi = (0, _Notifications.useNotificationApi)(), addNotification = _useNotificationApi.addNotification; var _useTranslationContex = (0, _TranslationContext.useTranslationContext)(), t = _useTranslationContex.t; var _useChannelMessageDat = (0, _useChannelDataState.useChannelMessageDataState)(channel), copyMessagesStateFromChannel = _useChannelMessageDat.copyMessagesStateFromChannel, jumpToLatestMessage = _useChannelMessageDat.jumpToLatestMessage, jumpToMessageFinished = _useChannelMessageDat.jumpToMessageFinished, loadInitialMessagesStateFromChannel = _useChannelMessageDat.loadInitialMessagesStateFromChannel, loadMoreFinishedFn = _useChannelMessageDat.loadMoreFinished, loadMoreRecentFinishedFn = _useChannelMessageDat.loadMoreRecentFinished, setLoading = _useChannelMessageDat.setLoading, setLoadingMore = _useChannelMessageDat.setLoadingMore, setLoadingMoreRecent = _useChannelMessageDat.setLoadingMoreRecent, state = _useChannelMessageDat.state; var loadMoreFinished = (0, _react.useRef)((0, _debounce.default)((hasMore, messages) => { loadMoreFinishedFn(hasMore, messages); }, defaultDebounceInterval, debounceOptions)).current; var loadMoreRecentFinished = (0, _react.useRef)((0, _debounce.default)((hasMore, newMessages) => { loadMoreRecentFinishedFn(hasMore, newMessages); }, defaultDebounceInterval, debounceOptions)).current; var loadLatestMessages = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* () { try { setLoading(true); yield channel.state.loadMessageIntoState('latest'); loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); jumpToLatestMessage(); } catch (err) { console.warn('Loading latest messages failed with error:', err); } })); var loadMore = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* (limit = 25) { if (!channel.state.messagePagination.hasPrev) { return; } if (state.loadingMore || state.loadingMoreRecent) { return; } setLoadingMore(true); var oldestMessage = state.messages?.[0]; var oldestID = oldestMessage?.id; try { yield channel.query({ messages: { id_lt: oldestID, limit }, watchers: { limit } }); loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); setLoadingMore(false); } catch (e) { setLoadingMore(false); console.warn('Message pagination(fetching old messages) request failed with error:', e); } })); var loadMoreRecent = (0, _hooks.useStableCallback)((0, _asyncToGenerator2.default)(function* (limit = 10) { if (!channel.state.messagePagination.hasNext) { return; } if (state.loadingMore || state.loadingMoreRecent) { return; } setLoadingMoreRecent(true); var newestMessage = state.messages?.[state?.messages.length - 1]; var newestID = newestMessage?.id; try { yield channel.query({ messages: { id_gt: newestID, limit }, watchers: { limit } }); loadMoreRecentFinished(channel.state.messagePagination.hasNext, channel.state.messages); } catch (e) { setLoadingMoreRecent(false); console.warn('Message pagination(fetching new messages) request failed with error:', e); return; } })); var loadChannelAroundMessage = (0, _hooks.useStableCallback)(function () { var _ref4 = (0, _asyncToGenerator2.default)(function* ({ limit = 25, messageId: messageIdToLoadAround, setTargetedMessage }) { if (!messageIdToLoadAround) { return; } setLoadingMore(true); setLoading(true); try { yield channel.state.loadMessageIntoState(messageIdToLoadAround, undefined, limit); loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); jumpToMessageFinished(channel.state.messagePagination.hasNext, messageIdToLoadAround); if (setTargetedMessage) { setTargetedMessage(messageIdToLoadAround); } } catch (error) { setLoadingMore(false); setLoading(false); console.warn('Message pagination(fetching messages in the channel around a message id) request failed with error:', error); return; } }); return function (_x) { return _ref4.apply(this, arguments); }; }()); var fetchMessagesAround = (0, _hooks.useStableCallback)(function () { var _ref5 = (0, _asyncToGenerator2.default)(function* (channel, timestamp, limit) { try { var _yield$channel$query = yield channel.query({ messages: { created_at_around: timestamp, limit } }, 'new'), messages = _yield$channel$query.messages; return messages; } catch (error) { console.error('Error fetching messages around timestamp:', error); throw error; } }); return function (_x2, _x3, _x4) { return _ref5.apply(this, arguments); }; }()); var notifyJumpToFirstUnreadError = (0, _hooks.useStableCallback)(error => { addNotification({ message: t('Failed to jump to the first unread message'), options: { ...(error instanceof Error ? { originalError: error } : {}), severity: 'error', type: 'channel:jumpToFirstUnread:failed' }, origin: { context: { feature: 'jumpToFirstUnread' }, emitter: 'Channel' } }); }); var loadChannelAtFirstUnreadMessage = (0, _hooks.useStableCallback)(function () { var _ref6 = (0, _asyncToGenerator2.default)(function* ({ channelUnreadState, limit = 25, setChannelUnreadState, setTargetedMessage }) { try { if (!channelUnreadState?.unread_messages) { return; } var first_unread_message_id = channelUnreadState.first_unread_message_id, last_read = channelUnreadState.last_read, last_read_message_id = channelUnreadState.last_read_message_id; var firstUnreadMessageId = first_unread_message_id; var lastReadMessageId = last_read_message_id; var isInCurrentMessageSet = false; var messagesState = channel.state.messages; if (firstUnreadMessageId) { var messageIdx = (0, _utils.findInMessagesById)(messagesState, firstUnreadMessageId); isInCurrentMessageSet = messageIdx !== -1; } else if (lastReadMessageId) { var _messageIdx = (0, _utils.findInMessagesById)(messagesState, lastReadMessageId); isInCurrentMessageSet = _messageIdx !== -1; firstUnreadMessageId = _messageIdx > -1 ? messagesState[_messageIdx + 1]?.id : undefined; } else { var lastReadTimestamp = last_read.getTime(); var _findInMessagesByDate = (0, _utils.findInMessagesByDate)(messagesState, last_read), lastReadIdx = _findInMessagesByDate.index, lastReadMessage = _findInMessagesByDate.message; if (lastReadMessage) { lastReadMessageId = lastReadMessage.id; firstUnreadMessageId = messagesState[lastReadIdx + 1].id; isInCurrentMessageSet = !!firstUnreadMessageId; } else { setLoadingMore(true); setLoading(true); var messages; try { messages = yield fetchMessagesAround(channel, last_read.toISOString(), limit); } catch (error) { setLoading(false); loadMoreFinished(channel.state.messagePagination.hasPrev, messagesState); notifyJumpToFirstUnreadError(error); return; } var firstMessageWithCreationDate = messages.find(msg => msg.created_at); if (!firstMessageWithCreationDate) { loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); throw new Error('Failed to jump to first unread message id.'); } var firstMessageTimestamp = new Date(firstMessageWithCreationDate.created_at).getTime(); if (lastReadTimestamp < firstMessageTimestamp) { firstUnreadMessageId = firstMessageWithCreationDate.id; } else { var result = (0, _utils.findInMessagesByDate)(messages, last_read); lastReadMessageId = result.message?.id; } loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); } } if (!firstUnreadMessageId && !lastReadMessageId) { throw new Error('Failed to jump to first unread message id.'); } if (!isInCurrentMessageSet) { try { setLoadingMore(true); setLoading(true); var targetedMessage = firstUnreadMessageId || lastReadMessageId; yield channel.state.loadMessageIntoState(targetedMessage, undefined, limit); var indexOfTarget = channel.state.messages.findIndex(message => message.id === targetedMessage); loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); firstUnreadMessageId = firstUnreadMessageId ?? channel.state.messages[indexOfTarget + 1].id; } catch (error) { setLoading(false); loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages); notifyJumpToFirstUnreadError(error); return; } } if (!firstUnreadMessageId) { throw new Error('Failed to jump to first unread message id.'); } if (!first_unread_message_id && setChannelUnreadState) { setChannelUnreadState({ ...channelUnreadState, first_unread_message_id: firstUnreadMessageId, last_read_message_id: lastReadMessageId }); } jumpToMessageFinished(channel.state.messagePagination.hasNext, firstUnreadMessageId); if (setTargetedMessage) { setTargetedMessage(firstUnreadMessageId); } } catch (error) { notifyJumpToFirstUnreadError(error); } }); return function (_x5) { return _ref6.apply(this, arguments); }; }()); return { copyMessagesStateFromChannel, loadChannelAroundMessage, loadChannelAtFirstUnreadMessage, loadInitialMessagesStateFromChannel, loadLatestMessages, loadMore, loadMoreRecent, state }; }; exports.useMessageListPagination = useMessageListPagination; //# sourceMappingURL=useMessageListPagination.js.map