Files
leadchat/app/javascript/dashboard/helper/AudioAlerts/DashboardAudioNotificationHelper.js
Shivam Mishra f14edd5242 fix: initOnEvents not removed [CW-3594] (#10200)
The `initOnEvents` was used to get the notification sound file and
trigger the 30 second loop, but since the function was replaced to using
class syntax, the removeEvent listener was not working. This PR fixes it
by reverting to the old syntax but moving it inside the constructor
instead and also adding a `once: true` to ensure it is always removed
automatically
2024-10-03 15:03:44 +05:30

185 lines
5.3 KiB
JavaScript

import { MESSAGE_TYPE } from 'shared/constants/messages';
import { showBadgeOnFavicon } from './faviconHelper';
import { initFaviconSwitcher } from './faviconHelper';
import {
getAlertAudio,
initOnEvents,
} from 'shared/helpers/AudioNotificationHelper';
import {
ROLES,
CONVERSATION_PERMISSIONS,
} from 'dashboard/constants/permissions.js';
import { getUserPermissions } from 'dashboard/helper/permissionsHelper.js';
const NOTIFICATION_TIME = 30000;
class DashboardAudioNotificationHelper {
constructor() {
this.recurringNotificationTimer = null;
this.audioAlertType = 'none';
this.playAlertOnlyWhenHidden = true;
this.alertIfUnreadConversationExist = false;
this.currentUser = null;
this.currentUserId = null;
this.audioAlertTone = 'ding';
this.onAudioListenEvent = async () => {
try {
await getAlertAudio('', {
type: 'dashboard',
alertTone: this.audioAlertTone,
});
initOnEvents.forEach(event => {
document.removeEventListener(event, this.onAudioListenEvent, false);
});
this.playAudioEvery30Seconds();
} catch (error) {
// Ignore audio fetch errors
}
};
}
setInstanceValues({
currentUser,
alwaysPlayAudioAlert,
alertIfUnreadConversationExist,
audioAlertType,
audioAlertTone,
}) {
this.audioAlertType = audioAlertType;
this.playAlertOnlyWhenHidden = !alwaysPlayAudioAlert;
this.alertIfUnreadConversationExist = alertIfUnreadConversationExist;
this.currentUser = currentUser;
this.currentUserId = currentUser.id;
this.audioAlertTone = audioAlertTone;
initOnEvents.forEach(e => {
document.addEventListener(e, this.onAudioListenEvent, {
once: true,
});
});
initFaviconSwitcher();
}
executeRecurringNotification() {
if (!window.WOOT_STORE) {
this.clearSetTimeout();
return;
}
const mineConversation = window.WOOT_STORE.getters.getMineChats({
assigneeType: 'me',
status: 'open',
});
const hasUnreadConversation = mineConversation.some(conv => {
return conv.unread_count > 0;
});
const shouldPlayAlert = !this.playAlertOnlyWhenHidden || document.hidden;
if (hasUnreadConversation && shouldPlayAlert) {
window.playAudioAlert();
showBadgeOnFavicon();
}
this.clearSetTimeout();
}
clearSetTimeout() {
if (this.recurringNotificationTimer) {
clearTimeout(this.recurringNotificationTimer);
}
this.recurringNotificationTimer = setTimeout(
this.executeRecurringNotification,
NOTIFICATION_TIME
);
}
playAudioEvery30Seconds() {
// Audio alert is disabled dismiss the timer
if (this.audioAlertType === 'none') {
return;
}
// If assigned conversation flag is disabled dismiss the timer
if (!this.alertIfUnreadConversationExist) {
return;
}
this.clearSetTimeout();
}
isConversationAssignedToCurrentUser(message) {
const conversationAssigneeId = message?.conversation?.assignee_id;
return conversationAssigneeId === this.currentUserId;
}
// eslint-disable-next-line class-methods-use-this
isMessageFromCurrentConversation(message) {
return (
window.WOOT_STORE.getters.getSelectedChat?.id === message.conversation_id
);
}
isMessageFromCurrentUser(message) {
return message?.sender_id === this.currentUserId;
}
isUserHasConversationPermission() {
const currentAccountId = window.WOOT_STORE.getters.getCurrentAccountId;
// Get the user permissions for the current account
const userPermissions = getUserPermissions(
this.currentUser,
currentAccountId
);
// Check if the user has the required permissions
const hasRequiredPermission = [...ROLES, ...CONVERSATION_PERMISSIONS].some(
permission => userPermissions.includes(permission)
);
return hasRequiredPermission;
}
shouldNotifyOnMessage(message) {
if (this.audioAlertType === 'mine') {
return this.isConversationAssignedToCurrentUser(message);
}
return this.audioAlertType === 'all';
}
onNewMessage(message) {
// If the user does not have the permission to view the conversation, then dismiss the alert
if (!this.isUserHasConversationPermission()) {
return;
}
// If the message is sent by the current user or the
// correct notification is not enabled, then dismiss the alert
if (
this.isMessageFromCurrentUser(message) ||
!this.shouldNotifyOnMessage(message)
) {
return;
}
// If the message type is not incoming or private, then dismiss the alert
const { message_type: messageType, private: isPrivate } = message;
if (messageType !== MESSAGE_TYPE.INCOMING && !isPrivate) {
return;
}
// If the user looking at the conversation, then dismiss the alert
if (this.isMessageFromCurrentConversation(message) && !document.hidden) {
return;
}
// If the user has disabled alerts when active on the dashboard, the dismiss the alert
if (this.playAlertOnlyWhenHidden && !document.hidden) {
return;
}
window.playAudioAlert();
showBadgeOnFavicon();
this.playAudioEvery30Seconds();
}
}
const notifHelper = new DashboardAudioNotificationHelper();
window.notifHelper = notifHelper;
export default notifHelper;