2021-03-10 04:52:20 +08:00
|
|
|
import { useContext, useEffect, useState } from 'react';
|
2023-03-02 21:25:08 +08:00
|
|
|
import { throttle } from '/imports/utils/throttle';
|
2021-04-14 01:35:46 +08:00
|
|
|
import { ChatContext, ACTIONS, MESSAGE_TYPES } from './context';
|
2021-01-20 01:06:32 +08:00
|
|
|
import { UsersContext } from '../users-context/context';
|
2021-03-10 04:52:20 +08:00
|
|
|
import { makeCall } from '/imports/ui/services/api';
|
2021-01-20 01:06:32 +08:00
|
|
|
import ChatLogger from '/imports/ui/components/chat/chat-logger/ChatLogger';
|
2021-03-23 01:00:03 +08:00
|
|
|
import Auth from '/imports/ui/services/auth';
|
2021-10-20 04:35:39 +08:00
|
|
|
import CollectionEventsBroker from '/imports/ui/services/LiveDataEventBroker/LiveDataEventBroker';
|
2021-01-20 01:06:32 +08:00
|
|
|
|
2021-04-23 02:43:45 +08:00
|
|
|
let prevUserData = {};
|
|
|
|
let currentUserData = {};
|
2021-02-09 04:00:18 +08:00
|
|
|
let messageQueue = [];
|
2021-03-10 04:52:20 +08:00
|
|
|
|
|
|
|
const CHAT_CONFIG = Meteor.settings.public.chat;
|
2021-05-29 08:28:47 +08:00
|
|
|
const SYSTEM_CHAT_TYPE = CHAT_CONFIG.type_system;
|
|
|
|
const CHAT_CLEAR_MESSAGE = CHAT_CONFIG.system_messages_keys.chat_clear;
|
2021-03-10 04:52:20 +08:00
|
|
|
const ITENS_PER_PAGE = CHAT_CONFIG.itemsPerPage;
|
|
|
|
const TIME_BETWEEN_FETCHS = CHAT_CONFIG.timeBetweenFetchs;
|
2021-04-14 01:35:46 +08:00
|
|
|
const EVENT_NAME = 'bbb-group-chat-messages-subscription-has-stoppped';
|
2021-07-09 01:08:32 +08:00
|
|
|
const EVENT_NAME_SUBSCRIPTION_READY = 'bbb-group-chat-messages-subscriptions-ready';
|
2021-03-10 04:52:20 +08:00
|
|
|
|
|
|
|
const getMessagesBeforeJoinCounter = async () => {
|
|
|
|
const counter = await makeCall('chatMessageBeforeJoinCounter');
|
|
|
|
return counter;
|
|
|
|
};
|
|
|
|
|
|
|
|
const startSyncMessagesbeforeJoin = async (dispatch) => {
|
|
|
|
const chatsMessagesCount = await getMessagesBeforeJoinCounter();
|
2021-07-09 01:08:32 +08:00
|
|
|
const pagesPerChat = chatsMessagesCount
|
|
|
|
.map((chat) => ({ ...chat, pages: Math.ceil(chat.count / ITENS_PER_PAGE), syncedPages: 0 }));
|
2021-03-10 04:52:20 +08:00
|
|
|
|
|
|
|
const syncRoutine = async (chatsToSync) => {
|
|
|
|
if (!chatsToSync.length) return;
|
|
|
|
|
|
|
|
const pagesToFetch = [...chatsToSync].sort((a, b) => a.pages - b.pages);
|
|
|
|
const chatWithLessPages = pagesToFetch[0];
|
|
|
|
chatWithLessPages.syncedPages += 1;
|
|
|
|
const messagesFromPage = await makeCall('fetchMessagePerPage', chatWithLessPages.chatId, chatWithLessPages.syncedPages);
|
|
|
|
|
|
|
|
if (messagesFromPage.length) {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.ADDED,
|
|
|
|
value: messagesFromPage,
|
2021-04-14 01:35:46 +08:00
|
|
|
messageType: MESSAGE_TYPES.HISTORY,
|
2021-03-10 04:52:20 +08:00
|
|
|
});
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.SYNC_STATUS,
|
|
|
|
value: {
|
|
|
|
chatId: chatWithLessPages.chatId,
|
|
|
|
percentage: Math.floor((chatWithLessPages.syncedPages / chatWithLessPages.pages) * 100),
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-07-09 01:08:32 +08:00
|
|
|
await new Promise((r) => setTimeout(r, TIME_BETWEEN_FETCHS));
|
|
|
|
syncRoutine(pagesToFetch.filter((chat) => !(chat.syncedPages > chat.pages)));
|
2021-03-10 04:52:20 +08:00
|
|
|
};
|
|
|
|
syncRoutine(pagesPerChat);
|
|
|
|
};
|
|
|
|
|
2021-01-20 01:06:32 +08:00
|
|
|
const Adapter = () => {
|
|
|
|
const usingChatContext = useContext(ChatContext);
|
|
|
|
const { dispatch } = usingChatContext;
|
|
|
|
const usingUsersContext = useContext(UsersContext);
|
|
|
|
const { users } = usingUsersContext;
|
2021-03-10 04:52:20 +08:00
|
|
|
const [syncStarted, setSync] = useState(true);
|
2021-07-09 01:08:32 +08:00
|
|
|
const [subscriptionReady, setSubscriptionReady] = useState(false);
|
2021-04-15 20:12:21 +08:00
|
|
|
ChatLogger.trace('chatAdapter::body::users', users[Auth.meetingID]);
|
2021-02-09 04:00:18 +08:00
|
|
|
|
2021-04-14 01:35:46 +08:00
|
|
|
useEffect(() => {
|
2021-04-23 02:43:45 +08:00
|
|
|
window.addEventListener(EVENT_NAME, () => {
|
2021-04-23 04:01:12 +08:00
|
|
|
/* needed to prevent an issue with dupĺicated messages when user role is changed
|
|
|
|
more info: https://github.com/bigbluebutton/bigbluebutton/issues/11842 */
|
2021-04-23 02:43:45 +08:00
|
|
|
if (prevUserData.role && prevUserData?.role !== currentUserData?.role) {
|
2021-04-21 04:36:04 +08:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.CLEAR_STREAM_MESSAGES,
|
|
|
|
});
|
|
|
|
}
|
2021-04-14 01:35:46 +08:00
|
|
|
});
|
2021-07-09 01:08:32 +08:00
|
|
|
|
|
|
|
window.addEventListener(EVENT_NAME_SUBSCRIPTION_READY, () => {
|
|
|
|
setSubscriptionReady(true);
|
|
|
|
});
|
2021-04-14 01:35:46 +08:00
|
|
|
}, []);
|
|
|
|
|
2021-03-10 04:52:20 +08:00
|
|
|
useEffect(() => {
|
|
|
|
const connectionStatus = Meteor.status();
|
2021-07-09 01:08:32 +08:00
|
|
|
if (connectionStatus.connected && !syncStarted && Auth.userID && subscriptionReady) {
|
|
|
|
setTimeout(() => {
|
|
|
|
setSync(true);
|
|
|
|
startSyncMessagesbeforeJoin(dispatch);
|
|
|
|
}, 1000);
|
2021-03-10 04:52:20 +08:00
|
|
|
}
|
2021-07-09 01:08:32 +08:00
|
|
|
}, [Meteor.status().connected, syncStarted, Auth.userID, subscriptionReady]);
|
2021-03-10 04:52:20 +08:00
|
|
|
|
2021-04-23 04:01:12 +08:00
|
|
|
/* needed to prevent an issue with dupĺicated messages when user role is changed
|
|
|
|
more info: https://github.com/bigbluebutton/bigbluebutton/issues/11842 */
|
2021-01-20 01:06:32 +08:00
|
|
|
useEffect(() => {
|
2022-06-29 03:26:25 +08:00
|
|
|
if (users[Auth.meetingID] && users[Auth.meetingID][Auth.userID]) {
|
2022-07-12 21:25:50 +08:00
|
|
|
if (currentUserData?.role !== users[Auth.meetingID][Auth.userID]?.role) {
|
2021-04-23 02:43:45 +08:00
|
|
|
prevUserData = currentUserData;
|
|
|
|
}
|
|
|
|
currentUserData = users[Auth.meetingID][Auth.userID];
|
|
|
|
}
|
2021-01-20 01:06:32 +08:00
|
|
|
}, [usingUsersContext]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-03-10 04:52:20 +08:00
|
|
|
if (!Meteor.status().connected) return;
|
|
|
|
setSync(false);
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.CLEAR_ALL,
|
|
|
|
});
|
2023-03-02 02:13:29 +08:00
|
|
|
const throttledDispatch = throttle(() => {
|
2021-02-09 04:00:18 +08:00
|
|
|
const dispatchedMessageQueue = [...messageQueue];
|
|
|
|
messageQueue = [];
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.ADDED,
|
|
|
|
value: dispatchedMessageQueue,
|
2021-04-14 01:35:46 +08:00
|
|
|
messageType: MESSAGE_TYPES.STREAM,
|
2021-02-09 04:00:18 +08:00
|
|
|
});
|
|
|
|
}, 1000, { trailing: true, leading: true });
|
|
|
|
|
2021-09-22 01:33:54 +08:00
|
|
|
const insertToContext = (fields) => {
|
|
|
|
if (fields.id === `${SYSTEM_CHAT_TYPE}-${CHAT_CLEAR_MESSAGE}`) {
|
|
|
|
messageQueue = [];
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.REMOVED,
|
|
|
|
});
|
2021-02-04 04:49:58 +08:00
|
|
|
}
|
2021-09-22 01:33:54 +08:00
|
|
|
|
|
|
|
messageQueue.push(fields);
|
|
|
|
throttledDispatch();
|
|
|
|
};
|
|
|
|
|
2021-09-22 21:05:43 +08:00
|
|
|
CollectionEventsBroker.addListener('group-chat-msg', 'added', insertToContext);
|
2021-03-24 04:30:38 +08:00
|
|
|
}, [Meteor.status().connected, Meteor.connection._lastSessionId]);
|
2021-01-20 01:06:32 +08:00
|
|
|
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Adapter;
|