Files
chatwoot/app/javascript/dashboard/helper/ReconnectService.js
Sivin Varghese af90f21cfd feat: Reconnect logic (#9453)
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2024-06-03 15:54:19 +05:30

141 lines
4.3 KiB
JavaScript

import { emitter } from 'shared/helpers/mitt';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import { differenceInSeconds } from 'date-fns';
import {
isAConversationRoute,
isAInboxViewRoute,
isNotificationRoute,
} from 'dashboard/helper/routeHelpers';
const MAX_DISCONNECT_SECONDS = 10800;
class ReconnectService {
constructor(store, router) {
this.store = store;
this.router = router;
this.disconnectTime = null;
this.setupEventListeners();
}
disconnect = () => this.removeEventListeners();
setupEventListeners = () => {
window.addEventListener('online', this.handleOnlineEvent);
emitter.on(BUS_EVENTS.WEBSOCKET_RECONNECT, this.onReconnect);
emitter.on(BUS_EVENTS.WEBSOCKET_DISCONNECT, this.onDisconnect);
};
removeEventListeners = () => {
window.removeEventListener('online', this.handleOnlineEvent);
emitter.off(BUS_EVENTS.WEBSOCKET_RECONNECT, this.onReconnect);
emitter.off(BUS_EVENTS.WEBSOCKET_DISCONNECT, this.onDisconnect);
};
getSecondsSinceDisconnect = () =>
this.disconnectTime
? Math.max(differenceInSeconds(new Date(), this.disconnectTime), 0)
: 0;
// Force reload if the user is disconnected for more than 3 hours
handleOnlineEvent = () => {
if (this.getSecondsSinceDisconnect() >= MAX_DISCONNECT_SECONDS) {
window.location.reload();
}
};
fetchConversations = async () => {
await this.store.dispatch('updateChatListFilters', {
page: null,
updatedWithin: this.getSecondsSinceDisconnect(),
});
await this.store.dispatch('fetchAllConversations');
// Reset the updatedWithin in the store chat list filter after fetching conversations when the user is reconnected
await this.store.dispatch('updateChatListFilters', {
updatedWithin: null,
});
};
fetchFilteredOrSavedConversations = async queryData => {
await this.store.dispatch('fetchFilteredConversations', {
queryData,
page: 1,
});
};
fetchConversationsOnReconnect = async () => {
const {
getAppliedConversationFiltersQuery,
'customViews/getActiveConversationFolder': activeFolder,
} = this.store.getters;
const query = getAppliedConversationFiltersQuery?.payload?.length
? getAppliedConversationFiltersQuery
: activeFolder?.query;
if (query) {
await this.fetchFilteredOrSavedConversations(query);
} else {
await this.fetchConversations();
}
};
fetchConversationMessagesOnReconnect = async () => {
const { conversation_id: conversationId } = this.router.currentRoute.params;
if (conversationId) {
await this.store.dispatch('syncActiveConversationMessages', {
conversationId: Number(conversationId),
});
}
};
fetchNotificationsOnReconnect = async filter => {
await this.store.dispatch('notifications/index', { ...filter, page: 1 });
};
revalidateCaches = async () => {
const { label, inbox, team } = await this.store.dispatch(
'accounts/getCacheKeys'
);
await Promise.all([
this.store.dispatch('labels/revalidate', { newKey: label }),
this.store.dispatch('inboxes/revalidate', { newKey: inbox }),
this.store.dispatch('teams/revalidate', { newKey: team }),
]);
};
handleRouteSpecificFetch = async () => {
const currentRoute = this.router.currentRoute.name;
if (isAConversationRoute(currentRoute, true)) {
await this.fetchConversationsOnReconnect();
await this.fetchConversationMessagesOnReconnect();
} else if (isAInboxViewRoute(currentRoute, true)) {
await this.fetchNotificationsOnReconnect(
this.store.getters['notifications/getNotificationFilters']
);
} else if (isNotificationRoute(currentRoute)) {
await this.fetchNotificationsOnReconnect();
}
};
setConversationLastMessageId = async () => {
const { conversation_id: conversationId } = this.router.currentRoute.params;
if (conversationId) {
await this.store.dispatch('setConversationLastMessageId', {
conversationId: Number(conversationId),
});
}
};
onDisconnect = () => {
this.disconnectTime = new Date();
this.setConversationLastMessageId();
};
onReconnect = async () => {
await this.handleRouteSpecificFetch();
await this.revalidateCaches();
emitter.emit(BUS_EVENTS.WEBSOCKET_RECONNECT_COMPLETED);
};
}
export default ReconnectService;