UNPKG

@sendbird/uikit-react

Version:

Sendbird UIKit for React: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.

929 lines (919 loc) 74.6 kB
import React__default, { useEffect, useCallback, useState, useReducer, useRef, useMemo } from 'react'; import { u as useLocalization } from './bundle-BiqO1upP.js'; import { U as UserProfileProvider } from './bundle-CS_zfDpT.js'; import { _ as __assign, c as __spreadArray, a as __awaiter, b as __generator } from './bundle-CzBQNSmE.js'; import { c as compareIds } from './bundle-yd76uvgx.js'; import { p as pubSubTopics } from './bundle-DAYo2mkS.js'; import { ChannelType } from '@sendbird/chat'; import { OpenChannelHandler } from '@sendbird/chat/openChannel'; import { u as uuidv4 } from './bundle-CgQaz0Nj.js'; import { c as compressImages } from './bundle-D1G8sq-4.js'; import { useGlobalModalContext } from '../hooks/useModal.js'; import { O as ONE_MiB } from './bundle-DmYFHm_s.js'; import { c as ModalFooter } from './bundle-yCvBYPzY.js'; import './bundle-LBf6CphS.js'; import { ButtonTypes } from '../ui/Button.js'; import { u as useSendbird } from './bundle-DMcf5OHL.js'; var shouldFetchMore = function (messageLength, maxMessages) { if (typeof maxMessages !== 'number') { return true; } return maxMessages > messageLength; }; /* eslint-disable default-param-last */ var scrollIntoLast = function (initialTry, scrollRef) { if (initialTry === void 0) { initialTry = 0; } var MAX_TRIES = 10; if (initialTry > MAX_TRIES) { return; } var scrollDOM = (scrollRef === null || scrollRef === void 0 ? void 0 : scrollRef.current) || document.querySelector('.sendbird-openchannel-conversation-scroll__container__item-container'); if (scrollDOM) { var applyScroll = function () { scrollDOM.style.overflow = 'auto'; scrollDOM.scrollTop = scrollDOM.scrollHeight; }; setTimeout(applyScroll); } else { setTimeout(function () { scrollIntoLast(initialTry + 1, scrollRef); }, 500 * initialTry); } }; var kFormatter = function (num) { if (Math.abs(num) > 999999) { return "".concat((Math.abs(num) / 1000000).toFixed(1), "M"); } if (Math.abs(num) > 999) { return "".concat((Math.abs(num) / 1000).toFixed(1), "K"); } return "".concat(num); }; var isOperator = function (openChannel, userId) { var operators = openChannel === null || openChannel === void 0 ? void 0 : openChannel.operators; if (operators.map(function (operator) { return operator.userId; }).indexOf(userId) < 0) { return false; } return true; }; var isDisabledBecauseFrozen = function (openChannel, userId) { if (!openChannel) return false; var isFrozen = openChannel.isFrozen; return isFrozen && !isOperator(openChannel, userId); }; var isDisabledBecauseMuted = function (mutedParticipantIds, userId) { return mutedParticipantIds.indexOf(userId) > -1; }; var fetchWithListQuery = function (listQuery, logger, eachQueryNextCallback) { var fetchList = function (query) { var hasNext = query.hasNext; if (hasNext) { query.next().then(function (users) { eachQueryNextCallback(users); fetchList(query); }).catch(function (error) { logger.warning('OpenChannel | FetchUserList failed', error); }); } else { logger.info('OpenChannel | FetchUserList finished'); } }; logger.info('OpenChannel | FetchUserList start', listQuery); fetchList(listQuery); }; var SET_CURRENT_CHANNEL = 'SET_CURRENT_CHANNEL'; var SET_CHANNEL_INVALID = 'SET_CHANNEL_INVALID'; var RESET_MESSAGES = 'RESET_MESSAGES'; var EXIT_CURRENT_CHANNEL = 'EXIT_CURRENT_CHANNEL'; var GET_PREV_MESSAGES_START = 'GET_PREV_MESSAGES_START'; var GET_PREV_MESSAGES_SUCESS = 'GET_PREV_MESSAGES_SUCESS'; var GET_PREV_MESSAGES_FAIL = 'GET_PREV_MESSAGES_FAIL'; var SENDING_MESSAGE_FAILED = 'SENDING_MESSAGE_FAILED'; var SENDING_MESSAGE_SUCCEEDED = 'SENDING_MESSAGE_SUCCEEDED'; var SENDING_MESSAGE_START = 'SENDING_MESSAGE_START'; var RESENDING_MESSAGE_START = 'RESENDING_MESSAGE_START'; var FETCH_PARTICIPANT_LIST = 'FETCH_PARTICIPANT_LIST'; var FETCH_BANNED_USER_LIST = 'FETCH_BANNED_USER_LIST'; var FETCH_MUTED_USER_LIST = 'FETCH_MUTED_USER_LIST'; var TRIM_MESSAGE_LIST = 'TRIM_MESSAGE_LIST'; // event handlers var ON_MESSAGE_RECEIVED = 'ON_MESSAGE_RECEIVED'; var ON_MESSAGE_UPDATED = 'ON_MESSAGE_UPDATED'; var ON_MESSAGE_DELETED = 'ON_MESSAGE_DELETED'; var ON_MESSAGE_DELETED_BY_REQ_ID = 'ON_MESSAGE_DELETED_BY_REQ_ID'; var ON_OPERATOR_UPDATED = 'ON_OPERATOR_UPDATED'; var ON_USER_ENTERED = 'ON_USER_ENTERED'; var ON_USER_EXITED = 'ON_USER_EXITED'; var ON_USER_MUTED = 'ON_USER_MUTED'; var ON_USER_UNMUTED = 'ON_USER_UNMUTED'; var ON_USER_BANNED = 'ON_USER_BANNED'; var ON_USER_UNBANNED = 'ON_USER_UNBANNED'; var ON_CHANNEL_FROZEN = 'ON_CHANNEL_FROZEN'; var ON_CHANNEL_UNFROZEN = 'ON_CHANNEL_UNFROZEN'; var ON_CHANNEL_CHANGED = 'ON_CHANNEL_CHANGED'; var ON_CHANNEL_DELETED = 'ON_CHANNEL_DELETED'; var ON_META_DATA_CREATED = 'ON_META_DATA_CREATED'; var ON_META_DATA_UPDATED = 'ON_META_DATA_UPDATED'; var ON_META_DATA_DELETED = 'ON_META_DATA_DELETED'; var ON_META_COUNTERS_CREATED = 'ON_META_COUNTERS_CREATED'; var ON_META_COUNTERS_UPDATED = 'ON_META_COUNTERS_UPDATED'; var ON_META_COUNTERS_DELETED = 'ON_META_COUNTERS_DELETED'; var ON_MENTION_RECEIVED = 'ON_MENTION_RECEIVED'; function reducer(state, action) { var _a, _b, _c, _d, _e, _f, _g, _h; switch (action.type) { case RESET_MESSAGES: { return __assign(__assign({}, state), { allMessages: [] }); } case EXIT_CURRENT_CHANNEL: { if (((_a = action.payload) === null || _a === void 0 ? void 0 : _a.url) === ((_b = state.currentOpenChannel) === null || _b === void 0 ? void 0 : _b.url)) { return __assign(__assign({}, state), { currentOpenChannel: null }); } return state; } case SET_CURRENT_CHANNEL: { var gottenChannel = action.payload; var operators = gottenChannel.operators; if (!state.isInvalid && state.currentOpenChannel && state.currentOpenChannel.url && (state.currentOpenChannel.url === gottenChannel.url)) { return state; } return __assign(__assign({}, state), { currentOpenChannel: gottenChannel, isInvalid: false, operators: operators, participants: operators, bannedParticipantIds: [], mutedParticipantIds: [] }); } case SET_CHANNEL_INVALID: { return __assign(__assign({}, state), { isInvalid: true }); } case GET_PREV_MESSAGES_START: { return __assign(__assign({}, state), { loading: true }); } case GET_PREV_MESSAGES_SUCESS: case GET_PREV_MESSAGES_FAIL: { var isFailed = (action.type === GET_PREV_MESSAGES_FAIL); var _j = action.payload, _k = _j.currentOpenChannel, currentOpenChannel = _k === void 0 ? {} : _k, _l = _j.messages, messages = _l === void 0 ? [] : _l, hasMore = _j.hasMore, lastMessageTimestamp = _j.lastMessageTimestamp; var actionChannelUrl = currentOpenChannel.url; var receivedMessages_1 = (isFailed ? [] : messages); var _hasMore = isFailed ? false : hasMore; var _lastMessageTimestamp = isFailed ? 0 : lastMessageTimestamp; var stateChannel = state.currentOpenChannel; var stateChannelUrl = stateChannel === null || stateChannel === void 0 ? void 0 : stateChannel.url; if (actionChannelUrl !== stateChannelUrl) { return state; } var filteredAllMessages = state.allMessages.filter(function (message) { return (!(receivedMessages_1.find(function (_a) { var messageId = _a.messageId; return compareIds(messageId, message.messageId); }))); }); return __assign(__assign({}, state), { loading: false, initialized: true, hasMore: _hasMore, lastMessageTimestamp: _lastMessageTimestamp, allMessages: __spreadArray(__spreadArray([], receivedMessages_1, true), filteredAllMessages, true) }); } case SENDING_MESSAGE_START: { var _m = action.payload, message_1 = _m.message, channel = _m.channel; if ((channel === null || channel === void 0 ? void 0 : channel.url) !== ((_c = state.currentOpenChannel) === null || _c === void 0 ? void 0 : _c.url) || state.allMessages.some(function (m) { return m.reqId === message_1.reqId; }) // Handing failed first than sending start issue ) { return state; } return __assign(__assign({}, state), { allMessages: __spreadArray(__spreadArray([], state.allMessages, true), [ message_1, ], false) }); } case SENDING_MESSAGE_SUCCEEDED: { var sentMessage_1 = action.payload; var newMessages = state.allMessages.map(function (m) { return (compareIds(m.reqId, sentMessage_1.reqId) ? sentMessage_1 : m); }); return __assign(__assign({}, state), { allMessages: newMessages }); } case SENDING_MESSAGE_FAILED: { var sentMessage_2 = action.payload; sentMessage_2.sendingStatus = 'failed'; if (!(state.allMessages.some(function (m) { return (m === null || m === void 0 ? void 0 : m.reqId) === (sentMessage_2 === null || sentMessage_2 === void 0 ? void 0 : sentMessage_2.reqId); }))) { // Handling failed first than sending start issue return __assign(__assign({}, state), { allMessages: __spreadArray(__spreadArray([], state.allMessages.filter(function (m) { return !compareIds(m.reqId, sentMessage_2); }), true), [ sentMessage_2, ], false) }); } else { return __assign(__assign({}, state), { allMessages: state.allMessages.map(function (m) { return (compareIds(m.reqId, sentMessage_2.reqId) ? sentMessage_2 : m); }) }); } } case TRIM_MESSAGE_LIST: { var allMessages = state.allMessages; var messageLimit = (_d = action.payload) === null || _d === void 0 ? void 0 : _d.messageLimit; if (messageLimit && messageLimit > 0 && (allMessages === null || allMessages === void 0 ? void 0 : allMessages.length) > messageLimit) { var sliceAt = allMessages.length - messageLimit; return __assign(__assign({}, state), { allMessages: allMessages.slice(sliceAt) }); } return state; } case RESENDING_MESSAGE_START: { var eventedChannel = action.payload.channel; var resentMessage_1 = action.payload.message; if (eventedChannel.url !== ((_e = state.currentOpenChannel) === null || _e === void 0 ? void 0 : _e.url)) { return state; } return __assign(__assign({}, state), { allMessages: state.allMessages.map(function (m) { return (compareIds(m.reqId, resentMessage_1.reqId) ? resentMessage_1 : m); }) }); } case FETCH_PARTICIPANT_LIST: { var eventedChannel = action.payload.channel; var fetchedParticipantList = action.payload.users; if (eventedChannel.url !== ((_f = state.currentOpenChannel) === null || _f === void 0 ? void 0 : _f.url)) { return state; } return __assign(__assign({}, state), { participants: __spreadArray(__spreadArray([], state.participants, true), fetchedParticipantList, true) }); } case FETCH_BANNED_USER_LIST: { var eventedChannel = action.payload.channel; var fetchedBannedUserList = action.payload.users; if ((eventedChannel.url !== ((_g = state.currentOpenChannel) === null || _g === void 0 ? void 0 : _g.url)) || !(fetchedBannedUserList.every(function (user) { return typeof user.userId === 'string'; }))) { return state; } return __assign(__assign({}, state), { bannedParticipantIds: __spreadArray(__spreadArray([], state.bannedParticipantIds, true), fetchedBannedUserList.map(function (user) { return user.userId; }), true) }); } case FETCH_MUTED_USER_LIST: { var eventedChannel = action.payload.channel; var fetchedMutedUserList = action.payload.users; if ((eventedChannel.url !== ((_h = state.currentOpenChannel) === null || _h === void 0 ? void 0 : _h.url)) || !(fetchedMutedUserList.every(function (user) { return typeof user.userId === 'string'; }))) { return state; } return __assign(__assign({}, state), { mutedParticipantIds: __spreadArray(__spreadArray([], state.mutedParticipantIds, true), fetchedMutedUserList.map(function (user) { return user.userId; }), true) }); } // events case ON_MESSAGE_RECEIVED: { var eventedChannel = action.payload.channel; var receivedMessage = action.payload.message; var currentOpenChannel = state.currentOpenChannel; if (!compareIds(eventedChannel.url, currentOpenChannel === null || currentOpenChannel === void 0 ? void 0 : currentOpenChannel.url) || (!(state.allMessages.map(function (message) { return message.messageId; }).indexOf(receivedMessage.messageId) < 0))) { return state; } return __assign(__assign({}, state), { allMessages: __spreadArray(__spreadArray([], state.allMessages, true), [receivedMessage], false) }); } case ON_MESSAGE_UPDATED: { var eventedChannel = action.payload.channel; var updatedMessage_1 = action.payload.message; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== eventedChannel.url)) { return state; } return __assign(__assign({}, state), { allMessages: state.allMessages.map(function (message) { return (message.isIdentical(updatedMessage_1) ? updatedMessage_1 : message); }) }); } case ON_MESSAGE_DELETED: { var eventedChannel = action.payload.channel; var deletedMessageId_1 = action.payload.messageId; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== eventedChannel.url)) { return state; } return __assign(__assign({}, state), { allMessages: state.allMessages.filter(function (message) { return (!compareIds(message.messageId, deletedMessageId_1)); }) }); } case ON_MESSAGE_DELETED_BY_REQ_ID: { return __assign(__assign({}, state), { allMessages: state.allMessages.filter(function (m) { return (!compareIds(m.reqId, action.payload)); }) }); } case ON_OPERATOR_UPDATED: { var eventedChannel = action.payload.channel; var updatedOperators = action.payload.operators; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== eventedChannel.url)) { return state; } return __assign(__assign({}, state), { currentOpenChannel: eventedChannel, operators: updatedOperators }); } case ON_USER_ENTERED: { var eventedChannel = action.payload.channel; var enteredUser = action.payload.user; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== eventedChannel.url)) { return state; } return __assign(__assign({}, state), { participants: __spreadArray(__spreadArray([], state.participants, true), [enteredUser], false) }); } case ON_USER_EXITED: { var eventedChannel = action.payload.channel; var exitedUser_1 = action.payload.user; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== eventedChannel.url)) { return state; } return __assign(__assign({}, state), { participants: state.participants.filter(function (participant) { return (!compareIds(participant.userId, exitedUser_1.userId)); }) }); } case ON_USER_MUTED: { var eventedChannel = action.payload.channel; var mutedUser = action.payload.user; var currentChannel = state.currentOpenChannel; if (!currentChannel || (currentChannel.url && (currentChannel.url !== eventedChannel.url)) || state.mutedParticipantIds.indexOf(mutedUser.userId) >= 0) { return state; } return __assign(__assign({}, state), { mutedParticipantIds: __spreadArray(__spreadArray([], state.mutedParticipantIds, true), [mutedUser.userId], false) }); } case ON_USER_UNMUTED: { var eventedChannel = action.payload.channel; var unmutedUser_1 = action.payload.user; var currentChannel = state.currentOpenChannel; if (!currentChannel || (currentChannel.url && (currentChannel.url !== eventedChannel.url)) || state.mutedParticipantIds.indexOf(unmutedUser_1.userId) < 0) { return state; } return __assign(__assign({}, state), { mutedParticipantIds: state.mutedParticipantIds.filter(function (userId) { return userId !== unmutedUser_1.userId; }) }); } case ON_USER_BANNED: { var eventedChannel = action.payload.channel; var bannedUser = action.payload.user; var currentUser = action.payload.currentUser; var currentChannel = state.currentOpenChannel; if ((currentChannel === null || currentChannel === void 0 ? void 0 : currentChannel.url) === (eventedChannel === null || eventedChannel === void 0 ? void 0 : eventedChannel.url) && (bannedUser === null || bannedUser === void 0 ? void 0 : bannedUser.userId) === (currentUser === null || currentUser === void 0 ? void 0 : currentUser.userId)) { return __assign(__assign({}, state), { currentOpenChannel: null }); } else if ((currentChannel === null || currentChannel === void 0 ? void 0 : currentChannel.url) === (eventedChannel === null || eventedChannel === void 0 ? void 0 : eventedChannel.url)) { return __assign(__assign({}, state), { bannedParticipantIds: __spreadArray(__spreadArray([], state.bannedParticipantIds, true), [bannedUser.userId], false) }); } return state; } case ON_USER_UNBANNED: { var eventedChannel = action.payload.channel; var unbannedUser_1 = action.payload.user; var currentChannel = state.currentOpenChannel; if ((currentChannel === null || currentChannel === void 0 ? void 0 : currentChannel.url) === (eventedChannel === null || eventedChannel === void 0 ? void 0 : eventedChannel.url)) { return __assign(__assign({}, state), { bannedParticipantIds: state.bannedParticipantIds.filter(function (userId) { return userId !== unbannedUser_1.userId; }) }); } return state; } case ON_CHANNEL_FROZEN: { var frozenChannel = action.payload; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== frozenChannel.url)) { return state; } return __assign(__assign({}, state), { frozen: true }); } case ON_CHANNEL_UNFROZEN: { var unfrozenChannel = action.payload; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== unfrozenChannel.url)) { return state; } return __assign(__assign({}, state), { frozen: false }); } case ON_CHANNEL_CHANGED: { var changedChannel = action.payload; var currentChannel = state.currentOpenChannel; if (!currentChannel || currentChannel.url && (currentChannel.url !== changedChannel.url)) { return state; } return __assign(__assign({}, state), { currentOpenChannel: changedChannel }); } case ON_CHANNEL_DELETED: { var deletedChannelUrl = action.payload; var currentChannel = state === null || state === void 0 ? void 0 : state.currentOpenChannel; if ((currentChannel === null || currentChannel === void 0 ? void 0 : currentChannel.url) === deletedChannelUrl) { return __assign(__assign({}, state), { currentOpenChannel: null }); } return state; } case ON_META_DATA_CREATED: { // const eventedChannel = action.payload.channel; // const createdMetaData = action.payload.metaData; // return { // ...state // }; return state; } case ON_META_DATA_UPDATED: { // const eventedChannel = action.payload.channel; // const updatedMetaData = action.payload.metaData; // return { // ...state // }; return state; } case ON_META_DATA_DELETED: { // const eventedChannel = action.payload.channel; // const deletedMetaDataKeys = action.payload.metaDataKeys; // return { // ...state // }; return state; } case ON_META_COUNTERS_CREATED: { // const eventedChannel = action.payload.channel; // const createdMetaCounter = action.payload.metaCounter; // return { // ...state // }; return state; } case ON_META_COUNTERS_UPDATED: { // const eventedChannel = action.payload.channel; // const updatedMetaCounter = action.payload.metaCounter; // return { // ...state // }; return state; } case ON_META_COUNTERS_DELETED: { // const eventedChannel = action.payload.channel; // const deletedMetaCounterKeys = action.payload.metaCounterKeys; // return { // ...state // }; return state; } case ON_MENTION_RECEIVED: { // const eventedChannel = action.payload.channel; // const mentionedMessage = action.payload.message; // return { // ...state // }; return state; } default: return state; } } var initialState = { allMessages: [], loading: false, initialized: false, currentOpenChannel: null, isInvalid: false, hasMore: false, lastMessageTimestamp: 0, frozen: false, operators: [], participants: [], bannedParticipantIds: [], mutedParticipantIds: [], }; function useSetChannel(_a, _b) { var channelUrl = _a.channelUrl, sdkInit = _a.sdkInit, fetchingParticipants = _a.fetchingParticipants, userId = _a.userId, currentOpenChannel = _a.currentOpenChannel; var sdk = _b.sdk, logger = _b.logger, messagesDispatcher = _b.messagesDispatcher; useEffect(function () { var _a; if (channelUrl && sdkInit && (sdk === null || sdk === void 0 ? void 0 : sdk.openChannel)) { if (currentOpenChannel && (currentOpenChannel === null || currentOpenChannel === void 0 ? void 0 : currentOpenChannel.exit)) { (_a = currentOpenChannel.exit) === null || _a === void 0 ? void 0 : _a.call(currentOpenChannel).then(function () { logger.info('OpenChannel | useSetChannel: Exit from the previous open channel', currentOpenChannel === null || currentOpenChannel === void 0 ? void 0 : currentOpenChannel.url); messagesDispatcher({ type: EXIT_CURRENT_CHANNEL, payload: currentOpenChannel, }); }); } logger.info('OpenChannel | useSetChannel: Fetching channel', channelUrl); sdk.openChannel.getChannel(channelUrl).then(function (openChannel) { logger.info('OpenChannel | useSetChannel: Succeeded to fetch channel', openChannel); messagesDispatcher({ type: SET_CURRENT_CHANNEL, payload: openChannel, }); openChannel.enter().then(function () { if (openChannel.isOperator(userId)) { // only operator has a permission to fetch these list var bannedParticipantListQuery = openChannel.createBannedUserListQuery(); var mutedParticipantListQuery = openChannel.createMutedUserListQuery(); fetchWithListQuery(bannedParticipantListQuery, logger, function (users) { messagesDispatcher({ type: FETCH_BANNED_USER_LIST, payload: { channel: openChannel, users: users, }, }); }); fetchWithListQuery(mutedParticipantListQuery, logger, function (users) { messagesDispatcher({ type: FETCH_MUTED_USER_LIST, payload: { channel: openChannel, users: users, }, }); }); } else { openChannel.getMyMutedInfo() .then(function (mutedInfo) { if (mutedInfo === null || mutedInfo === void 0 ? void 0 : mutedInfo.isMuted) { messagesDispatcher({ type: FETCH_MUTED_USER_LIST, payload: { channel: openChannel, users: [sdk === null || sdk === void 0 ? void 0 : sdk.currentUser], }, }); } }); } if (fetchingParticipants) { // fetch participants list var participantListQuery = openChannel.createParticipantListQuery({ limit: openChannel.participantCount, }); fetchWithListQuery(participantListQuery, logger, function (users) { messagesDispatcher({ type: FETCH_PARTICIPANT_LIST, payload: { channel: openChannel, users: users, }, }); }); } }).catch(function (error) { logger.warning('OpenChannel | useSetChannel: Failed to enter channel', { channelUrl: channelUrl, error: error }); messagesDispatcher({ type: SET_CHANNEL_INVALID, payload: null, }); }); }).catch(function (error) { logger.warning('OpenChannel | useSetChannel: Failed to fetch channel', { channelUrl: channelUrl, error: error }); messagesDispatcher({ type: SET_CHANNEL_INVALID, payload: null, }); }); } }, [channelUrl, sdkInit, fetchingParticipants]); } function useHandleChannelEvents(_a, _b) { var currentOpenChannel = _a.currentOpenChannel, checkScrollBottom = _a.checkScrollBottom; var sdk = _b.sdk, logger = _b.logger, messagesDispatcher = _b.messagesDispatcher, scrollRef = _b.scrollRef; useEffect(function () { var _a, _b; var messageReceiverId = uuidv4(); if (currentOpenChannel && currentOpenChannel.url && ((_a = sdk === null || sdk === void 0 ? void 0 : sdk.openChannel) === null || _a === void 0 ? void 0 : _a.addOpenChannelHandler)) { logger.info('OpenChannel | useHandleChannelEvents: Setup evnet handler', messageReceiverId); var channelHandlerParams = { onMessageReceived: function (channel, message) { var scrollToEnd = checkScrollBottom(); var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMessageReceived', { channelUrl: channelUrl, message: message }); messagesDispatcher({ type: ON_MESSAGE_RECEIVED, payload: { channel: channel, message: message }, }); if (scrollToEnd) { try { setTimeout(function () { scrollIntoLast(0, scrollRef); }); } catch (error) { logger.warning('OpenChannel | onMessageReceived | scroll to end failed'); } } }, onMessageUpdated: function (channel, message) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMessageUpdated', { channelUrl: channelUrl, message: message }); messagesDispatcher({ type: ON_MESSAGE_UPDATED, payload: { channel: channel, message: message }, }); }, onMessageDeleted: function (channel, messageId) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMessageDeleted', { channelUrl: channelUrl, messageId: messageId }); messagesDispatcher({ type: ON_MESSAGE_DELETED, payload: { channel: channel, messageId: messageId }, }); }, onOperatorUpdated: function (channel, operators) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onOperatorUpdated', { channelUrl: channelUrl, operators: operators }); messagesDispatcher({ type: ON_OPERATOR_UPDATED, payload: { channel: channel, operators: operators }, }); }, onUserEntered: function (channel, user) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onUserEntered', { channelUrl: channelUrl, user: user }); messagesDispatcher({ type: ON_USER_ENTERED, payload: { channel: channel, user: user }, }); }, onUserExited: function (channel, user) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onUserExited', { channelUrl: channelUrl, user: user }); messagesDispatcher({ type: ON_USER_EXITED, payload: { channel: channel, user: user }, }); }, onUserMuted: function (channel, user) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onUserMuted', { channelUrl: channelUrl, user: user }); messagesDispatcher({ type: ON_USER_MUTED, payload: { channel: channel, user: user }, }); }, onUserUnmuted: function (channel, user) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onUserUnmuted', { channelUrl: channelUrl, user: user }); messagesDispatcher({ type: ON_USER_UNMUTED, payload: { channel: channel, user: user }, }); }, onUserBanned: function (channel, user) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onUserBanned', { channelUrl: channelUrl, user: user }); messagesDispatcher({ type: ON_USER_BANNED, payload: { channel: channel, user: user, currentUser: sdk === null || sdk === void 0 ? void 0 : sdk.currentUser }, }); }, onUserUnbanned: function (channel, user) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onUserUnbanned', { channelUrl: channelUrl, user: user }); messagesDispatcher({ type: ON_USER_UNBANNED, payload: { channel: channel, user: user }, }); }, onChannelFrozen: function (channel) { logger.info('OpenChannel | useHandleChannelEvents: onChannelFrozen', channel); messagesDispatcher({ type: ON_CHANNEL_FROZEN, payload: channel, }); }, onChannelUnfrozen: function (channel) { logger.info('OpenChannel | useHandleChannelEvents: onChannelUnfrozen', channel); messagesDispatcher({ type: ON_CHANNEL_UNFROZEN, payload: channel, }); }, onChannelChanged: function (channel) { logger.info('OpenChannel | useHandleChannelEvents: onChannelChanged', channel); messagesDispatcher({ type: ON_CHANNEL_CHANGED, payload: channel, }); }, onMetaDataCreated: function (channel, metaData) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMetaDataCreated', { channelUrl: channelUrl, metaData: metaData }); messagesDispatcher({ type: ON_META_DATA_CREATED, payload: { channel: channel, metaData: metaData }, }); }, onMetaDataUpdated: function (channel, metaData) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMetaDataUpdated', { channelUrl: channelUrl, metaData: metaData }); messagesDispatcher({ type: ON_META_DATA_UPDATED, payload: { channel: channel, metaData: metaData }, }); }, onMetaDataDeleted: function (channel, metaDataKeys) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMetaDataDeleted', { channelUrl: channelUrl, metaDataKeys: metaDataKeys }); messagesDispatcher({ type: ON_META_DATA_DELETED, payload: { channel: channel, metaDataKeys: metaDataKeys }, }); }, onMetaCounterCreated: function (channel, metaCounter) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMetaCountersCreated', { channelUrl: channelUrl, metaCounter: metaCounter }); messagesDispatcher({ type: ON_META_COUNTERS_CREATED, payload: { channel: channel, metaCounter: metaCounter }, }); }, onMetaCounterUpdated: function (channel, metaCounter) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMetaCountersUpdated', { channelUrl: channelUrl, metaCounter: metaCounter }); messagesDispatcher({ type: ON_META_COUNTERS_UPDATED, payload: { channel: channel, metaCounter: metaCounter }, }); }, onMetaCounterDeleted: function (channel, metaCounterKeys) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMetaCountersDeleted', { channelUrl: channelUrl, metaCounterKeys: metaCounterKeys }); messagesDispatcher({ type: ON_META_COUNTERS_DELETED, payload: { channel: channel, metaCounterKeys: metaCounterKeys }, }); }, onMentionReceived: function (channel, message) { var channelUrl = channel === null || channel === void 0 ? void 0 : channel.url; logger.info('OpenChannel | useHandleChannelEvents: onMentionReceived', { channelUrl: channelUrl, message: message }); messagesDispatcher({ type: ON_MENTION_RECEIVED, payload: { channel: channel, message: message }, }); }, onChannelDeleted: function (channelUrl, channelType) { if (channelType === ChannelType.OPEN && (currentOpenChannel === null || currentOpenChannel === void 0 ? void 0 : currentOpenChannel.url) === channelUrl) { messagesDispatcher({ type: ON_CHANNEL_DELETED, payload: channelUrl, }); } }, }; var ChannelHandler = new OpenChannelHandler(channelHandlerParams); (_b = sdk === null || sdk === void 0 ? void 0 : sdk.openChannel) === null || _b === void 0 ? void 0 : _b.addOpenChannelHandler(messageReceiverId, ChannelHandler); } return function () { var _a; if ((_a = sdk === null || sdk === void 0 ? void 0 : sdk.openChannel) === null || _a === void 0 ? void 0 : _a.removeOpenChannelHandler) { logger.info('OpenChannel | useHandleChannelEvents: Removing message receiver handler', messageReceiverId); sdk.openChannel.removeOpenChannelHandler(messageReceiverId); } }; }, [currentOpenChannel]); } function useInitialMessagesFetch(_a, _b) { var currentOpenChannel = _a.currentOpenChannel, userFilledMessageListParams = _a.userFilledMessageListParams; var logger = _b.logger, messagesDispatcher = _b.messagesDispatcher, scrollRef = _b.scrollRef; useEffect(function () { logger === null || logger === void 0 ? void 0 : logger.info('OpenChannel | useInitialMessagesFetch: Setup started', currentOpenChannel); messagesDispatcher({ type: RESET_MESSAGES, payload: null, }); if (currentOpenChannel && currentOpenChannel.getMessagesByTimestamp) { var messageListParams_1 = { nextResultSize: 0, prevResultSize: 30, isInclusive: true, includeReactions: false, }; if (userFilledMessageListParams) { Object.keys(userFilledMessageListParams).forEach(function (key) { // @ts-ignore messageListParams_1[key] = userFilledMessageListParams[key]; }); logger === null || logger === void 0 ? void 0 : logger.info('OpenChannel | useInitialMessagesFetch: Used customizedMessageListParams'); } logger === null || logger === void 0 ? void 0 : logger.info('OpenChannel | useInitialMessagesFetch: Fetching messages', { currentOpenChannel: currentOpenChannel, messageListParams: messageListParams_1 }); messagesDispatcher({ type: GET_PREV_MESSAGES_START, payload: null, }); currentOpenChannel.getMessagesByTimestamp(new Date().getTime(), messageListParams_1).then(function (messages) { logger === null || logger === void 0 ? void 0 : logger.info('OpenChannel | useInitialMessagesFetch: Fetching messages succeeded', messages); var hasMore = (messages && messages.length > 0); var lastMessageTimestamp = hasMore ? messages[0].createdAt : null; messagesDispatcher({ type: GET_PREV_MESSAGES_SUCESS, payload: { currentOpenChannel: currentOpenChannel, messages: messages, hasMore: hasMore, lastMessageTimestamp: lastMessageTimestamp, }, }); setTimeout(function () { scrollIntoLast(0, scrollRef); }); }).catch(function (error) { logger === null || logger === void 0 ? void 0 : logger.error('OpenChannel | useInitialMessagesFetch: Fetching messages failed', error); messagesDispatcher({ type: GET_PREV_MESSAGES_FAIL, payload: { currentOpenChannel: currentOpenChannel, messages: [], hasMore: false, lastMessageTimestamp: 0, }, }); }); } }, [currentOpenChannel, userFilledMessageListParams]); } function useScrollCallback(_a, _b) { var currentOpenChannel = _a.currentOpenChannel, lastMessageTimestamp = _a.lastMessageTimestamp, fetchMore = _a.fetchMore; var sdk = _b.sdk, logger = _b.logger, messagesDispatcher = _b.messagesDispatcher, hasMore = _b.hasMore, userFilledMessageListParams = _b.userFilledMessageListParams; return useCallback(function (callback) { if (fetchMore && hasMore) { logger.info('OpenChannel | useScrollCallback: start'); var messageListParams_1 = { prevResultSize: 30, includeReactions: false, nextResultSize: 0, }; if (userFilledMessageListParams) { Object.keys(userFilledMessageListParams).forEach(function (key) { // @ts-ignore messageListParams_1[key] = userFilledMessageListParams[key]; }); logger.info('OpenChannel | useScrollCallback: Used userFilledMessageListParams', userFilledMessageListParams); } logger.info('OpenChannel | useScrollCallback: Fetching messages', { currentOpenChannel: currentOpenChannel, messageListParams: messageListParams_1 }); currentOpenChannel === null || currentOpenChannel === void 0 ? void 0 : currentOpenChannel.getMessagesByTimestamp(lastMessageTimestamp || new Date().getTime(), messageListParams_1).then(function (messages) { logger.info('OpenChannel | useScrollCallback: Fetching messages succeeded', messages); var hasMore = (messages && messages.length > 0); var lastMessageTimestamp = hasMore ? messages[0].createdAt : null; messagesDispatcher({ type: GET_PREV_MESSAGES_SUCESS, payload: { currentOpenChannel: currentOpenChannel, messages: messages, hasMore: hasMore, lastMessageTimestamp: lastMessageTimestamp, }, }); setTimeout(function () { callback(); }); }).catch(function (error) { logger.error('OpenChannel | useScrollCallback: Fetching messages failed', error); messagesDispatcher({ type: GET_PREV_MESSAGES_FAIL, payload: { currentOpenChannel: currentOpenChannel, messages: [], hasMore: false, lastMessageTimestamp: 0, }, }); }); } }, [currentOpenChannel, lastMessageTimestamp, fetchMore, sdk]); } function useCheckScrollBottom(_a, _b) { var conversationScrollRef = _a.conversationScrollRef; var logger = _b.logger; return useCallback(function () { var isBottom = true; if (conversationScrollRef && (conversationScrollRef === null || conversationScrollRef === void 0 ? void 0 : conversationScrollRef.current)) { try { var conversationScroll = conversationScrollRef.current; isBottom = conversationScroll.scrollHeight <= conversationScroll.scrollTop + conversationScroll.clientHeight; } catch (error) { logger.error('OpenChannel | useCheckScrollBottom', error); } } return isBottom; }, [conversationScrollRef]); } function useSendMessageCallback(_a, _b) { var currentOpenChannel = _a.currentOpenChannel, onBeforeSendUserMessage = _a.onBeforeSendUserMessage, messageInputRef = _a.messageInputRef; var sdk = _b.sdk, logger = _b.logger, messagesDispatcher = _b.messagesDispatcher, scrollRef = _b.scrollRef; return useCallback(function () { var _a; if (sdk) { var text = (_a = messageInputRef.current) === null || _a === void 0 ? void 0 : _a.innerText; var createParamsDefault = function (txt) { var message = txt; var params = { message: message, }; return params; }; var createCustomParams = onBeforeSendUserMessage && typeof onBeforeSendUserMessage === 'function'; if (createCustomParams) { logger.info('OpenChannel | useSendMessageCallback: Creating params using onBeforeSendUserMessage', onBeforeSendUserMessage); } var params = onBeforeSendUserMessage ? onBeforeSendUserMessage(text !== null && text !== void 0 ? text : '') : createParamsDefault(text !== null && text !== void 0 ? text : ''); logger.info('OpenChannel | useSendMessageCallback: Sending message has started', params); var pendingMsg_1; currentOpenChannel === null || currentOpenChannel === void 0 ? void 0 : currentOpenChannel.sendUserMessage(params).onPending(function (pendingMessage) { messagesDispatcher({ type: SENDING_MESSAGE_START, payload: { message: pendingMessage, channel: currentOpenChannel, }, }); pendingMsg_1 = pendingMessage; setTimeout(function () { return scrollIntoLast(0, scrollRef); }); }).onSucceeded(function (message) { logger.info('OpenChannel | useSendMessageCallback: Sending message succeeded', message); messagesDispatcher({ type: SENDING_MESSAGE_SUCCEEDED, payload: message, }); }).onFailed(function (error) { logger.warning('OpenChannel | useSendMessageCallback: Sending message failed', error); messagesDispatcher({ type: SENDING_MESSAGE_FAILED, payload: pendingMsg_1, }); // https://sendbird.com/docs/chat/v3/javascript/guides/error-codes#2-server-error-codes // TODO: Do we need to handle the error cases? // @ts-ignore if ((error === null || error ==