@sendbird/uikit-react
Version:
Sendbird UIKit for React: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.
798 lines (786 loc) • 93.2 kB
JavaScript
'use strict';
var _tslib = require('../chunks/bundle-Conb-pOy.js');
var React = require('react');
var uikitTools = require('@sendbird/uikit-tools');
var UserProfileContext = require('../chunks/bundle-Bnb8seJF.js');
var _const = require('../chunks/bundle-BLz2EOZ5.js');
var utils = require('../chunks/bundle-B78tdF27.js');
var getIsReactionEnabled = require('../chunks/bundle-CXbYckbN.js');
var stringSet = require('../chunks/bundle-BbrBawlX.js');
var index$2 = require('../chunks/bundle-CHAKEXIJ.js');
var message = require('@sendbird/chat/message');
var index = require('../chunks/bundle-Dobj18FB.js');
var Channel_hooks_useInitialMessagesFetch = require('../chunks/bundle-DGb1FlkJ.js');
var compareIds = require('../chunks/bundle-CZ38Etcw.js');
var index$1 = require('../chunks/bundle-fYxs1lss.js');
var groupChannel = require('@sendbird/chat/groupChannel');
var uuid = require('../chunks/bundle-t8BQsgL5.js');
var useSendbird = require('../chunks/bundle-Bq15P9qk.js');
var useReconnectOnIdle = require('../chunks/bundle-C8INNeGk.js');
var consts = require('../chunks/bundle-Cfh78Xnm.js');
var pubSub_topics = require('../chunks/bundle-dUH189qO.js');
var resolvedReplyType = require('../chunks/bundle-BPUhuptz.js');
var useSendMultipleFilesMessage = require('../chunks/bundle-BLLzQxHS.js');
var LocalizationContext = require('../chunks/bundle-DPDyqKIJ.js');
var uikitConfigStorage = require('../chunks/bundle-C6rru8Hj.js');
require('../chunks/bundle-CVJwHwWn.js');
require('../chunks/bundle-Cyl6_qLo.js');
require('../utils/message/getOutgoingMessageState.js');
require('../chunks/bundle-DAdgL6r8.js');
require('../chunks/bundle-B19RHFpR.js');
require('@sendbird/chat');
require('@sendbird/chat/openChannel');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefaultCompat(React);
var initialState = {
initialized: false,
loading: true,
allMessages: [],
/**
* localMessages: pending & failed messages
*/
localMessages: [],
stringSet: stringSet.getStringSet(),
currentGroupChannel: null,
// for scrollup
hasMorePrev: false,
oldestMessageTimeStamp: 0,
// for scroll down
// onScrollDownCallback is added for navigation to different timestamps on messageSearch
// hasMorePrev, onScrollCallback -> scroll up(default behavior)
// hasMoreNext, onScrollDownCallback -> scroll down
hasMoreNext: false,
latestMessageTimeStamp: 0,
emojiContainer: { emojiCategories: [], emojiHash: '' },
/** @deprecated Please use `unreadSinceDate` instead. * */
unreadSince: null,
/**
* unreadSinceDate is a date information about message unread.
* It's used only for the {unreadSinceDate && <UnreadCount unreadSinceDate={unreadSinceDate} />}
*/
unreadSinceDate: null,
isInvalid: false,
readStatus: null,
messageListParams: null,
typingMembers: [],
};
var getOldestMessageTimeStamp = function (messages) {
if (messages === void 0) { messages = []; }
var oldestMessage = messages[0];
return (oldestMessage && oldestMessage.createdAt) || null;
};
var getLatestMessageTimeStamp = function (messages) {
if (messages === void 0) { messages = []; }
var latestMessage = messages[messages.length - 1];
return (latestMessage && latestMessage.createdAt) || null;
};
function hasReqId(message) {
return 'reqId' in message;
}
function channelReducer(state, action) {
return index.K(action)
.with({ type: Channel_hooks_useInitialMessagesFetch.RESET_MESSAGES }, function () {
return _tslib.__assign(_tslib.__assign({}, state), {
// when user switches channel, if the previous channel `hasMorePrev`
// the onScroll gets called twice, setting hasMorePrev false prevents this
hasMorePrev: false, hasMoreNext: false, allMessages: [], localMessages: [] });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_START }, function () {
return _tslib.__assign(_tslib.__assign({}, state), { loading: true, allMessages: state.allMessages.filter(function (m) { return index$1.isSendableMessage(m)
? m.sendingStatus !== message.SendingStatus.SUCCEEDED
: true; }), localMessages: [] });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_SUCCESS }, function (action) {
var _a;
var _b = action.payload, currentGroupChannel = _b.currentGroupChannel, messages = _b.messages;
if (!((currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url) === ((_a = state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url))) {
return state;
}
var oldestMessageTimeStamp = getOldestMessageTimeStamp(messages);
var latestMessageTimeStamp = getLatestMessageTimeStamp(messages);
return _tslib.__assign(_tslib.__assign({}, state), { loading: false, initialized: true, hasMorePrev: true, hasMoreNext: true, oldestMessageTimeStamp: oldestMessageTimeStamp, latestMessageTimeStamp: latestMessageTimeStamp, allMessages: _tslib.__spreadArray([], messages, true) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.FETCH_PREV_MESSAGES_SUCCESS }, function (action) {
var _a, _b, _c, _d;
var _e = action.payload, currentGroupChannel = _e.currentGroupChannel, messages = _e.messages;
if (!((currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url) === ((_a = state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url))) {
return state;
}
var hasMorePrev = ((_b = messages === null || messages === void 0 ? void 0 : messages.length) !== null && _b !== void 0 ? _b : 0)
>= ((_d = (_c = state === null || state === void 0 ? void 0 : state.messageListParams) === null || _c === void 0 ? void 0 : _c.prevResultSize) !== null && _d !== void 0 ? _d : Channel_hooks_useInitialMessagesFetch.PREV_RESULT_SIZE) + 1;
var oldestMessageTimeStamp = getOldestMessageTimeStamp(messages);
// Remove duplicated messages
var duplicatedMessageIds = [];
var updatedOldMessages = state.allMessages.map(function (msg) {
var duplicatedMessage = messages.find(function (_a) {
var messageId = _a.messageId;
return compareIds.compareIds(messageId, msg.messageId);
});
if (!duplicatedMessage) {
return msg;
}
duplicatedMessageIds.push(duplicatedMessage.messageId);
return duplicatedMessage.updatedAt > msg.updatedAt
? duplicatedMessage
: msg;
});
var filteredNewMessages = duplicatedMessageIds.length > 0
? messages.filter(function (msg) { return !duplicatedMessageIds.find(function (messageId) { return compareIds.compareIds(messageId, msg.messageId); }); })
: messages;
return _tslib.__assign(_tslib.__assign({}, state), { hasMorePrev: hasMorePrev, oldestMessageTimeStamp: oldestMessageTimeStamp, allMessages: _tslib.__spreadArray(_tslib.__spreadArray([], filteredNewMessages, true), updatedOldMessages, true) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.FETCH_NEXT_MESSAGES_SUCCESS }, function (action) {
var _a, _b, _c, _d;
var _e = action.payload, currentGroupChannel = _e.currentGroupChannel, messages = _e.messages;
if (!((currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url) === ((_a = state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url))) {
return state;
}
var hasMoreNext = ((_b = messages === null || messages === void 0 ? void 0 : messages.length) !== null && _b !== void 0 ? _b : 0)
=== ((_d = (_c = state === null || state === void 0 ? void 0 : state.messageListParams) === null || _c === void 0 ? void 0 : _c.nextResultSize) !== null && _d !== void 0 ? _d : Channel_hooks_useInitialMessagesFetch.NEXT_RESULT_SIZE) + 1;
var latestMessageTimeStamp = getLatestMessageTimeStamp(messages);
// sort ~
var sortedMessages = utils.mergeAndSortMessages(state.allMessages, messages);
return _tslib.__assign(_tslib.__assign({}, state), { hasMoreNext: hasMoreNext, latestMessageTimeStamp: latestMessageTimeStamp, allMessages: sortedMessages });
})
.with({
type: index.S.union(Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_FAILURE, Channel_hooks_useInitialMessagesFetch.FETCH_PREV_MESSAGES_FAILURE, Channel_hooks_useInitialMessagesFetch.FETCH_NEXT_MESSAGES_FAILURE),
}, function (action) {
var _a;
var currentGroupChannel = action.payload.currentGroupChannel;
if ((currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url) !== ((_a = state === null || state === void 0 ? void 0 : state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url))
return state;
// It shows something went wrong screen when fetching initial messages failed.
var shouldInvalid = [Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_FAILURE].includes(action.type);
return _tslib.__assign(_tslib.__assign({}, state), { loading: false, isInvalid: shouldInvalid, initialized: false, allMessages: [], hasMorePrev: false, hasMoreNext: false, oldestMessageTimeStamp: null, latestMessageTimeStamp: null });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.SEND_MESSAGE_START }, function (action) {
// Message should not be spread here
// it will loose some methods like `isUserMessage`
return _tslib.__assign(_tslib.__assign({}, state), { localMessages: _tslib.__spreadArray(_tslib.__spreadArray([], state.localMessages, true), [action.payload], false) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.SEND_MESSAGE_SUCCESS }, function (action) {
var message = action.payload;
/**
* Admin messages do not have reqId. We need to include them.
*/
var filteredMessages = state.allMessages.filter(function (m) { return !hasReqId(m) || (m === null || m === void 0 ? void 0 : m.reqId) !== (message === null || message === void 0 ? void 0 : message.reqId); });
// [Policy] Pending messages and failed messages
// must always be at the end of the message list
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: _tslib.__spreadArray(_tslib.__spreadArray([], filteredMessages, true), [message], false), localMessages: state.localMessages.filter(function (m) { return hasReqId(m) && (m === null || m === void 0 ? void 0 : m.reqId) !== (message === null || message === void 0 ? void 0 : message.reqId); }) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.SEND_MESSAGE_FAILURE }, function (action) {
// @ts-ignore
action.payload.failed = true;
return _tslib.__assign(_tslib.__assign({}, state), { localMessages: state.localMessages.map(function (m) { return compareIds.compareIds(hasReqId(m) && m.reqId, action.payload.reqId)
? action.payload
: m; }) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { currentGroupChannel: action.payload, isInvalid: false });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.SET_CHANNEL_INVALID }, function () {
return _tslib.__assign(_tslib.__assign({}, state), { currentGroupChannel: null, allMessages: [], localMessages: [], isInvalid: true });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_RECEIVED }, function (action) {
var _a, _b;
var _c = action.payload, channel = _c.channel, message = _c.message;
var members = channel.members;
var sender = message.sender;
var currentGroupChannel = state.currentGroupChannel, stringSet = state.stringSet;
var currentGroupChannelUrl = currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url;
if (!compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, currentGroupChannelUrl)) {
return state;
}
// Excluded overlapping messages
if (state.allMessages.some(function (msg) { return msg.messageId === message.messageId; })) {
return state;
}
// Filter by userFilledQuery
if (state.messageListParams
&& !index$1.filterMessageListParams(state.messageListParams, message)) {
return state;
}
if (message.isAdminMessage && message.isAdminMessage()) {
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: utils.passUnsuccessfullMessages(state.allMessages, message) });
}
// Update members when sender profileUrl, nickname, friendName has been changed
var senderMember = members === null || members === void 0 ? void 0 : members.find(function (m) { return (m === null || m === void 0 ? void 0 : m.userId) === (sender === null || sender === void 0 ? void 0 : sender.userId); });
if ((senderMember === null || senderMember === void 0 ? void 0 : senderMember.profileUrl) !== (sender === null || sender === void 0 ? void 0 : sender.profileUrl)
|| (senderMember === null || senderMember === void 0 ? void 0 : senderMember.friendName) !== (sender === null || sender === void 0 ? void 0 : sender.friendName)
|| (senderMember === null || senderMember === void 0 ? void 0 : senderMember.nickname) !== (sender === null || sender === void 0 ? void 0 : sender.nickname)) {
// @ts-ignore
channel.members = members.map(function (member) {
if (member.userId === sender.userId) {
return sender;
}
return member;
});
}
return _tslib.__assign(_tslib.__assign({}, state), { currentGroupChannel: channel, unreadSince: (_a = state.unreadSince) !== null && _a !== void 0 ? _a : index$2.format(new Date(), stringSet.DATE_FORMAT__UNREAD_SINCE), unreadSinceDate: (_b = state.unreadSinceDate) !== null && _b !== void 0 ? _b : new Date(), allMessages: utils.passUnsuccessfullMessages(state.allMessages, message) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_UPDATED }, function (action) {
var _a;
var _b = action.payload, channel = _b.channel, message = _b.message;
var currentGroupChannelUrl = ((_a = state === null || state === void 0 ? void 0 : state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url) || '';
if (!compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, currentGroupChannelUrl)) {
return state; // Ignore event when it is not for the current channel
}
if (state.messageListParams
&& !index$1.filterMessageListParams(state.messageListParams, message)) {
// Delete the message if it doesn't match to the params anymore
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: state.allMessages.filter(function (m) { return !compareIds.compareIds(m.messageId, message === null || message === void 0 ? void 0 : message.messageId); }) });
}
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: state.allMessages.map(function (m) {
if (compareIds.compareIds(m.messageId, message.messageId)) {
return message;
}
if (compareIds.compareIds(m.parentMessageId, message.messageId)) {
m.parentMessage = message; // eslint-disable-line no-param-reassign
}
return m;
}) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_THREAD_INFO_UPDATED }, function (action) {
var _a;
var _b = action.payload, channel = _b.channel, event = _b.event;
var channelUrl = event.channelUrl, threadInfo = event.threadInfo, targetMessageId = event.targetMessageId;
var currentGroupChannelUrl = ((_a = state === null || state === void 0 ? void 0 : state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url) || '';
if (!compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, currentGroupChannelUrl)
|| !compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
return state; // Ignore event when it is not for the current channel
}
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: state.allMessages.map(function (m) {
if (compareIds.compareIds(m.messageId, targetMessageId)) {
// eslint-disable-next-line no-param-reassign
m.threadInfo = threadInfo; // Upsert threadInfo to the target message
}
return m;
}) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.RESEND_MESSAGE_START }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { localMessages: state.localMessages.map(function (m) { return compareIds.compareIds(hasReqId(m) && m.reqId, action.payload.reqId)
? action.payload
: m; }) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.MARK_AS_READ }, function (action) {
var _a, _b, _c;
if (((_a = state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url) !== ((_c = (_b = action.payload) === null || _b === void 0 ? void 0 : _b.channel) === null || _c === void 0 ? void 0 : _c.url)) {
return state;
}
return _tslib.__assign(_tslib.__assign({}, state), { unreadSince: null, unreadSinceDate: null });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_DELETED }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: state.allMessages.filter(function (m) { return !compareIds.compareIds(m.messageId, action.payload); }) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_DELETED_BY_REQ_ID }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { localMessages: state.localMessages.filter(function (m) { return !compareIds.compareIds(hasReqId(m) && m.reqId, action.payload); }) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.SET_EMOJI_CONTAINER }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { emojiContainer: action.payload });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_REACTION_UPDATED }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { allMessages: state.allMessages.map(function (m) {
if (compareIds.compareIds(m.messageId, action.payload.messageId)) {
if (m.applyReactionEvent
&& typeof m.applyReactionEvent === 'function') {
m.applyReactionEvent(action.payload);
}
return m;
}
return m;
}) });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.MESSAGE_LIST_PARAMS_CHANGED }, function (action) {
return _tslib.__assign(_tslib.__assign({}, state), { messageListParams: action.payload });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_FILE_INFO_UPLOADED }, function (action) {
var _a, _b;
var _c = action.payload, channelUrl = _c.channelUrl, requestId = _c.requestId, index = _c.index, uploadableFileInfo = _c.uploadableFileInfo, error = _c.error;
if (!compareIds.compareIds(channelUrl, (_a = state === null || state === void 0 ? void 0 : state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url)) {
return state;
}
/**
* We don't have to do anything here because
* onFailed() will be called so handle error there instead.
*/
if (error)
return state;
var localMessages = state.localMessages;
var messageToUpdate = localMessages.find(function (message) { return compareIds.compareIds(hasReqId(message) && message.reqId, requestId); });
var fileInfoList = (_b = messageToUpdate
.messageParams) === null || _b === void 0 ? void 0 : _b.fileInfoList;
if (Array.isArray(fileInfoList)) {
fileInfoList[index] = uploadableFileInfo;
}
return _tslib.__assign(_tslib.__assign({}, state), { localMessages: localMessages });
})
.with({ type: Channel_hooks_useInitialMessagesFetch.ON_TYPING_STATUS_UPDATED }, function (action) {
var _a;
var _b = action.payload, channel = _b.channel, typingMembers = _b.typingMembers;
if (!compareIds.compareIds(channel.url, (_a = state === null || state === void 0 ? void 0 : state.currentGroupChannel) === null || _a === void 0 ? void 0 : _a.url)) {
return state;
}
return _tslib.__assign(_tslib.__assign({}, state), { typingMembers: typingMembers });
})
.otherwise(function () { return state; });
}
var DELIVERY_RECEIPT = 'delivery_receipt';
function useHandleChannelEvents(_a, _b) {
var _c, _d, _e;
var sdkInit = _a.sdkInit, currentGroupChannel = _a.currentGroupChannel, disableMarkAsRead = _a.disableMarkAsRead;
var sdk = _b.sdk, logger = _b.logger, scrollRef = _b.scrollRef, setQuoteMessage = _b.setQuoteMessage, messagesDispatcher = _b.messagesDispatcher;
var store = useSendbird.useSendbird().state;
var _f = store.config, markAsReadScheduler = _f.markAsReadScheduler, markAsDeliveredScheduler = _f.markAsDeliveredScheduler, disableMarkAsDelivered = _f.disableMarkAsDelivered;
var canSetMarkAsDelivered = (_e = (_d = (_c = store.stores.sdkStore.sdk) === null || _c === void 0 ? void 0 : _c.appInfo) === null || _d === void 0 ? void 0 : _d.premiumFeatureList) === null || _e === void 0 ? void 0 : _e.find(function (feature) { return (feature === DELIVERY_RECEIPT); });
React.useEffect(function () {
var _a;
var channelUrl = currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url;
var channelHandlerId = uuid.uuidv4();
if (channelUrl && sdkInit) {
var channelHandler = {
onMessageReceived: function (channel, message) {
var _a, _b;
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
var scrollToEnd = false;
try {
var current = scrollRef.current;
if (current) {
scrollToEnd = current.offsetHeight + current.scrollTop >= current.scrollHeight - 10;
}
// 10 is a buffer
}
catch (error) {
//
}
logger.info('Channel | useHandleChannelEvents: onMessageReceived', message);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_RECEIVED,
payload: { channel: channel, message: message },
});
if (scrollToEnd
&& ((_a = document.getElementById('sendbird-dropdown-portal')) === null || _a === void 0 ? void 0 : _a.childElementCount) === 0
&& ((_b = document.getElementById('sendbird-emoji-list-portal')) === null || _b === void 0 ? void 0 : _b.childElementCount) === 0) {
// and !openContextMenu
try {
setTimeout(function () { return utils.scrollIntoLast(0, scrollRef); });
if (!disableMarkAsRead) {
markAsReadScheduler.push(currentGroupChannel);
}
if (canSetMarkAsDelivered && !disableMarkAsDelivered) {
markAsDeliveredScheduler.push(currentGroupChannel);
}
}
catch (error) {
logger.warning('Channel | onMessageReceived | scroll to end failed');
}
}
}
},
onUnreadMemberStatusUpdated: function (channel) {
logger.info('Channel | useHandleChannelEvents: onUnreadMemberStatusUpdated', channel);
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onUserMarkedRead: function (channel, userIds) {
logger.info('Channel | useHandleChannelEvents: onUserMarkedAsRead', channel, userIds);
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.MARK_AS_READ,
payload: {
channel: channel,
userIds: userIds,
},
});
}
},
onUserMarkedUnread: function (channel, userIds) {
logger.info('Channel | useHandleChannelEvents: onUserMarkedUnread', channel, userIds);
// TODO:: MADOKA 이 부분에 대해서 명확하게 확인해야 함.
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.MARK_AS_UNREAD,
payload: {
channel: channel,
userIds: userIds,
},
});
}
},
// before(onDeliveryReceiptUpdated)
onUndeliveredMemberStatusUpdated: function (channel) {
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onDeliveryReceiptUpdated', channel);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onMessageUpdated: function (channel, message) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onMessageUpdated', message);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_UPDATED,
payload: { channel: channel, message: message },
});
}
},
onThreadInfoUpdated: function (channel, threadInfoUpdateEvent) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onThreadInfoUpdated', { channel: channel, threadInfoUpdateEvent: threadInfoUpdateEvent });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_THREAD_INFO_UPDATED,
payload: { channel: channel, event: threadInfoUpdateEvent },
});
}
},
onMessageDeleted: function (channel, messageId) {
logger.info('Channel | useHandleChannelEvents: onMessageDeleted', { channel: channel, messageId: messageId });
setQuoteMessage(null);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_DELETED,
payload: messageId,
});
},
onReactionUpdated: function (channel, reactionEvent) {
logger.info('Channel | useHandleChannelEvents: onReactionUpdated', { channel: channel, reactionEvent: reactionEvent });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_REACTION_UPDATED,
payload: reactionEvent,
});
},
onChannelChanged: function (channel) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onChannelChanged', channel);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onChannelFrozen: function (channel) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onChannelFrozen', channel);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onChannelUnfrozen: function (channel) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onChannelUnFrozen', channel);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onUserMuted: function (channel, user) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onUserMuted', { channel: channel, user: user });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onUserUnmuted: function (channel, user) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onUserUnmuted', { channel: channel, user: user });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onUserBanned: function (channel, user) {
var _a;
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl) && channel.isGroupChannel()) {
logger.info('Channel | useHandleChannelEvents: onUserBanned', { channel: channel, user: user });
var isByMe = (user === null || user === void 0 ? void 0 : user.userId) === ((_a = sdk === null || sdk === void 0 ? void 0 : sdk.currentUser) === null || _a === void 0 ? void 0 : _a.userId);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: isByMe ? null : channel,
});
}
},
onOperatorUpdated: function (channel, users) {
if (channel.isGroupChannel() && compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onOperatorUpdated', { channel: channel, users: users });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: channel,
});
}
},
onUserLeft: function (channel, user) {
var _a;
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | useHandleChannelEvents: onUserLeft', { channel: channel, user: user });
var isByMe = (user === null || user === void 0 ? void 0 : user.userId) === ((_a = sdk === null || sdk === void 0 ? void 0 : sdk.currentUser) === null || _a === void 0 ? void 0 : _a.userId);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: isByMe ? null : channel,
});
}
},
onTypingStatusUpdated: function (channel) {
if (compareIds.compareIds(channel === null || channel === void 0 ? void 0 : channel.url, channelUrl)) {
logger.info('Channel | onTypingStatusUpdated', { channel: channel });
var typingMembers = channel.getTypingUsers();
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_TYPING_STATUS_UPDATED,
payload: {
channel: channel,
typingMembers: typingMembers,
},
});
}
},
};
logger.info('Channel | useHandleChannelEvents: Setup event handler', { channelHandlerId: channelHandlerId, channelHandler: channelHandler });
// Add this group channel handler to the Sendbird chat instance
(_a = sdk.groupChannel) === null || _a === void 0 ? void 0 : _a.addGroupChannelHandler(channelHandlerId, new groupChannel.GroupChannelHandler(channelHandler));
}
return function () {
var _a;
if ((_a = sdk === null || sdk === void 0 ? void 0 : sdk.groupChannel) === null || _a === void 0 ? void 0 : _a.removeGroupChannelHandler) {
logger.info('Channel | useHandleChannelEvents: Removing message reciver handler', channelHandlerId);
sdk.groupChannel.removeGroupChannelHandler(channelHandlerId);
}
else if (sdk === null || sdk === void 0 ? void 0 : sdk.groupChannel) {
logger.error('Channel | useHandleChannelEvents: Not found the removeGroupChannelHandler');
}
};
}, [currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url, sdkInit]);
}
function useGetChannel(_a, _b) {
var channelUrl = _a.channelUrl, sdkInit = _a.sdkInit, disableMarkAsRead = _a.disableMarkAsRead;
var messagesDispatcher = _b.messagesDispatcher, sdk = _b.sdk, logger = _b.logger, markAsReadScheduler = _b.markAsReadScheduler;
React.useEffect(function () {
if (channelUrl && sdkInit && sdk && sdk.groupChannel) {
logger.info('Channel | useSetChannel fetching channel', channelUrl);
sdk.groupChannel
.getChannel(channelUrl)
.then(function (groupChannel) {
logger.info('Channel | useSetChannel fetched channel', groupChannel);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CURRENT_CHANNEL,
payload: groupChannel,
});
logger.info('Channel: Mark as read', groupChannel);
if (!disableMarkAsRead) {
markAsReadScheduler.push(groupChannel);
}
})
.catch(function (e) {
logger.warning('Channel | useSetChannel fetch channel failed', { channelUrl: channelUrl, e: e });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_CHANNEL_INVALID,
});
});
sdk
.getAllEmoji()
.then(function (emojiContainer_) {
logger.info('Channel: Getting emojis success', emojiContainer_);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.SET_EMOJI_CONTAINER,
payload: emojiContainer_,
});
})
.catch(function (err) {
logger.error('Channel: Getting emojis failed', err);
});
}
}, [channelUrl, sdkInit]);
}
function useHandleReconnect(_a, _b) {
var isOnline = _a.isOnline, replyType = _a.replyType, disableMarkAsRead = _a.disableMarkAsRead, reconnectOnIdle = _a.reconnectOnIdle;
var logger = _b.logger, sdk = _b.sdk, scrollRef = _b.scrollRef, currentGroupChannel = _b.currentGroupChannel, messagesDispatcher = _b.messagesDispatcher, markAsReadScheduler = _b.markAsReadScheduler, userFilledMessageListQuery = _b.userFilledMessageListQuery;
var shouldReconnect = useReconnectOnIdle.useReconnectOnIdle(isOnline, currentGroupChannel, reconnectOnIdle).shouldReconnect;
React.useEffect(function () {
return function () {
var _a, _b, _c;
// state changed from offline to online AND tab is visible
if (shouldReconnect) {
logger.info('Refreshing conversation state');
var isReactionEnabled = ((_a = sdk === null || sdk === void 0 ? void 0 : sdk.appInfo) === null || _a === void 0 ? void 0 : _a.useReaction) || false;
var messageListParams_1 = {
prevResultSize: Channel_hooks_useInitialMessagesFetch.PREV_RESULT_SIZE,
isInclusive: true,
includeReactions: isReactionEnabled,
includeMetaArray: true,
nextResultSize: Channel_hooks_useInitialMessagesFetch.NEXT_RESULT_SIZE,
};
if (replyType && replyType === 'QUOTE_REPLY') {
messageListParams_1.includeThreadInfo = true;
messageListParams_1.includeParentMessageInfo = true;
messageListParams_1.replyType = message.ReplyType.ONLY_REPLY_TO_CHANNEL;
}
if (userFilledMessageListQuery) {
Object.keys(userFilledMessageListQuery).forEach(function (key) {
// @ts-ignore
messageListParams_1[key] = userFilledMessageListQuery[key];
});
}
logger.info('Channel: Fetching messages', { currentGroupChannel: currentGroupChannel, userFilledMessageListQuery: userFilledMessageListQuery });
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_START,
payload: null,
});
(_b = sdk === null || sdk === void 0 ? void 0 : sdk.groupChannel) === null || _b === void 0 ? void 0 : _b.getChannel((_c = currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.url) !== null && _c !== void 0 ? _c : '').then(function (groupChannel) {
var lastMessageTime = new Date().getTime();
groupChannel.getMessagesByTimestamp(lastMessageTime, messageListParams_1)
.then(function (messages) {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_SUCCESS,
payload: {
currentGroupChannel: groupChannel,
messages: messages,
},
});
setTimeout(function () { return utils.scrollIntoLast(0, scrollRef); }, consts.SCROLL_BOTTOM_DELAY_FOR_FETCH);
})
.catch(function (error) {
logger.error('Channel: Fetching messages failed', error);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_INITIAL_MESSAGES_FAILURE,
payload: { currentGroupChannel: groupChannel },
});
});
if (!disableMarkAsRead) {
markAsReadScheduler.push(groupChannel);
}
});
}
};
}, [shouldReconnect, replyType]);
}
function useScrollCallback(_a, _b) {
var currentGroupChannel = _a.currentGroupChannel, oldestMessageTimeStamp = _a.oldestMessageTimeStamp, userFilledMessageListQuery = _a.userFilledMessageListQuery, replyType = _a.replyType;
var hasMorePrev = _b.hasMorePrev, logger = _b.logger, messagesDispatcher = _b.messagesDispatcher, sdk = _b.sdk;
return React.useCallback(function (callback) {
var _a, _b;
if (!hasMorePrev) {
return;
}
var messageListParams = {
prevResultSize: Channel_hooks_useInitialMessagesFetch.PREV_RESULT_SIZE,
isInclusive: true,
includeMetaArray: true,
includeReactions: (_b = (_a = sdk === null || sdk === void 0 ? void 0 : sdk.appInfo) === null || _a === void 0 ? void 0 : _a.useReaction) !== null && _b !== void 0 ? _b : false,
};
if (replyType === 'QUOTE_REPLY' || replyType === 'THREAD') {
messageListParams.includeThreadInfo = true;
messageListParams.includeParentMessageInfo = true;
messageListParams.replyType = message.ReplyType.ONLY_REPLY_TO_CHANNEL;
}
if (userFilledMessageListQuery) {
Object.keys(userFilledMessageListQuery).forEach(function (key) {
// @ts-ignore
messageListParams[key] = userFilledMessageListQuery[key];
});
}
logger.info('Channel: Fetching messages', {
currentGroupChannel: currentGroupChannel,
userFilledMessageListQuery: userFilledMessageListQuery,
});
currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.getMessagesByTimestamp(oldestMessageTimeStamp || new Date().getTime(), messageListParams).then(function (messages) {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_PREV_MESSAGES_SUCCESS,
payload: { currentGroupChannel: currentGroupChannel, messages: messages },
});
if (callback)
setTimeout(function () { return callback(); });
}).catch(function () {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_PREV_MESSAGES_FAILURE,
payload: { currentGroupChannel: currentGroupChannel },
});
});
}, [currentGroupChannel, oldestMessageTimeStamp, replyType]);
}
function useScrollDownCallback(_a, _b) {
var currentGroupChannel = _a.currentGroupChannel, latestMessageTimeStamp = _a.latestMessageTimeStamp, userFilledMessageListQuery = _a.userFilledMessageListQuery, hasMoreNext = _a.hasMoreNext, replyType = _a.replyType;
var logger = _b.logger, messagesDispatcher = _b.messagesDispatcher, sdk = _b.sdk;
return React.useCallback(function (cb) {
var _a, _b;
if (!hasMoreNext) {
return;
}
var isReactionEnabled = (_b = (_a = sdk === null || sdk === void 0 ? void 0 : sdk.appInfo) === null || _a === void 0 ? void 0 : _a.useReaction) !== null && _b !== void 0 ? _b : false;
var messageListParams = {
nextResultSize: Channel_hooks_useInitialMessagesFetch.NEXT_RESULT_SIZE,
isInclusive: true,
includeReactions: isReactionEnabled,
includeMetaArray: true,
};
if (replyType && (replyType === 'QUOTE_REPLY' || replyType === 'THREAD')) {
messageListParams.includeThreadInfo = true;
messageListParams.includeParentMessageInfo = true;
messageListParams.replyType = message.ReplyType.ONLY_REPLY_TO_CHANNEL;
}
if (userFilledMessageListQuery) {
Object.keys(userFilledMessageListQuery).forEach(function (key) {
// @ts-ignore
messageListParams[key] = userFilledMessageListQuery[key];
});
}
logger.info('Channel: Fetching later messages', { currentGroupChannel: currentGroupChannel, userFilledMessageListQuery: userFilledMessageListQuery });
currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.getMessagesByTimestamp(latestMessageTimeStamp || new Date().getTime(), messageListParams).then(function (messages) {
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_NEXT_MESSAGES_SUCCESS,
payload: { currentGroupChannel: currentGroupChannel, messages: messages },
});
setTimeout(function () { return cb([messages, null]); });
}).catch(function (error) {
logger.error('Channel: Fetching later messages failed', error);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.FETCH_NEXT_MESSAGES_FAILURE,
payload: { currentGroupChannel: currentGroupChannel },
});
setTimeout(function () { return cb([null, error]); });
});
}, [currentGroupChannel, latestMessageTimeStamp, hasMoreNext, replyType]);
}
function useDeleteMessageCallback(_a, _b) {
var currentGroupChannel = _a.currentGroupChannel, messagesDispatcher = _a.messagesDispatcher;
var logger = _b.logger;
return React.useCallback(function (message$1) {
logger.info('Channel | useDeleteMessageCallback: Deleting message', message$1);
var sendingStatus = index$1.isSendableMessage(message$1) ? message$1.sendingStatus : undefined;
return new Promise(function (resolve, reject) {
logger.info('Channel | useDeleteMessageCallback: Deleting message requestState:', sendingStatus);
// Message is only on local
if ((sendingStatus === message.SendingStatus.FAILED || sendingStatus === message.SendingStatus.PENDING) && 'reqId' in message$1) {
logger.info('Channel | useDeleteMessageCallback: Deleted message from local:', message$1);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_DELETED_BY_REQ_ID,
payload: message$1.reqId,
});
resolve();
}
else {
logger.info('Channel | useDeleteMessageCallback: Deleting message from remote:', sendingStatus);
currentGroupChannel === null || currentGroupChannel === void 0 ? void 0 : currentGroupChannel.deleteMessage(message$1).then(function () {
logger.info('Channel | useDeleteMessageCallback: Deleting message success!', message$1);
messagesDispatcher({
type: Channel_hooks_useInitialMessagesFetch.ON_MESSAGE_DELETED,
payload: message$1.messageId,
});
resolve();
}).catch(function (err) {
logger.warning('Channel | useDeleteMessageCallback: Deleting message failed!', err);
reject(err);
});
}
});
}, [currentGroupChannel, messagesDispatcher]);
}
function useUpdateMessageCallback(_a, _b) {
var currentGroupChannel = _a.currentGroupChannel, messagesDispatcher = _a.messagesDispatcher,