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
JavaScript
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