mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 12:08:01 +00:00
chore: Refactor audio notification helper (#6148)
This commit is contained in:
@@ -0,0 +1,100 @@
|
|||||||
|
import { MESSAGE_TYPE } from 'shared/constants/messages';
|
||||||
|
import { showBadgeOnFavicon } from './faviconHelper';
|
||||||
|
import { initFaviconSwitcher } from './faviconHelper';
|
||||||
|
import {
|
||||||
|
getAlertAudio,
|
||||||
|
initOnEvents,
|
||||||
|
} from 'shared/helpers/AudioNotificationHelper';
|
||||||
|
|
||||||
|
class DashboardAudioNotificationHelper {
|
||||||
|
constructor() {
|
||||||
|
this.recurringNotificationTimer = null;
|
||||||
|
this.audioAlertType = 'none';
|
||||||
|
this.playAlertOnlyWhenHidden = true;
|
||||||
|
this.currentUserId = null;
|
||||||
|
this.audioAlertTone = 'ding';
|
||||||
|
}
|
||||||
|
|
||||||
|
setInstanceValues = ({
|
||||||
|
currentUserId,
|
||||||
|
alwaysPlayAudioAlert,
|
||||||
|
audioAlertType,
|
||||||
|
audioAlertTone,
|
||||||
|
}) => {
|
||||||
|
this.audioAlertType = audioAlertType;
|
||||||
|
this.playAlertOnlyWhenHidden = !alwaysPlayAudioAlert;
|
||||||
|
this.currentUserId = currentUserId;
|
||||||
|
this.audioAlertTone = audioAlertTone;
|
||||||
|
initOnEvents.forEach(e => {
|
||||||
|
document.addEventListener(e, this.onAudioListenEvent, false);
|
||||||
|
});
|
||||||
|
initFaviconSwitcher();
|
||||||
|
};
|
||||||
|
|
||||||
|
onAudioListenEvent = async () => {
|
||||||
|
try {
|
||||||
|
await getAlertAudio('', {
|
||||||
|
type: 'dashboard',
|
||||||
|
alertTone: this.audioAlertTone,
|
||||||
|
});
|
||||||
|
initOnEvents.forEach(event => {
|
||||||
|
document.removeEventListener(event, this.onAudioListenEvent, false);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore audio fetch errors
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
isConversationAssignedToCurrentUser = message => {
|
||||||
|
const conversationAssigneeId = message?.conversation?.assignee_id;
|
||||||
|
return conversationAssigneeId === this.currentUserId;
|
||||||
|
};
|
||||||
|
|
||||||
|
isMessageFromCurrentConversation = message => {
|
||||||
|
return (
|
||||||
|
window.WOOT.$store.getters.getSelectedChat?.id === message.conversation_id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
isMessageFromCurrentUser = message => {
|
||||||
|
return message?.sender_id === this.currentUserId;
|
||||||
|
};
|
||||||
|
|
||||||
|
shouldNotifyOnMessage = message => {
|
||||||
|
if (this.audioAlertType === 'mine') {
|
||||||
|
return this.isConversationAssignedToCurrentUser(message);
|
||||||
|
}
|
||||||
|
return this.audioAlertType === 'all';
|
||||||
|
};
|
||||||
|
|
||||||
|
onNewMessage = message => {
|
||||||
|
// 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();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new DashboardAudioNotificationHelper();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import AuthAPI from '../api/auth';
|
import AuthAPI from '../api/auth';
|
||||||
import BaseActionCableConnector from '../../shared/helpers/BaseActionCableConnector';
|
import BaseActionCableConnector from '../../shared/helpers/BaseActionCableConnector';
|
||||||
import { newMessageNotification } from 'shared/helpers/AudioNotificationHelper';
|
import DashboardAudioNotificationHelper from './AudioAlerts/DashboardAudioNotificationHelper';
|
||||||
|
|
||||||
class ActionCableConnector extends BaseActionCableConnector {
|
class ActionCableConnector extends BaseActionCableConnector {
|
||||||
constructor(app, pubsubToken) {
|
constructor(app, pubsubToken) {
|
||||||
@@ -74,7 +74,7 @@ class ActionCableConnector extends BaseActionCableConnector {
|
|||||||
onLogout = () => AuthAPI.logout();
|
onLogout = () => AuthAPI.logout();
|
||||||
|
|
||||||
onMessageCreated = data => {
|
onMessageCreated = data => {
|
||||||
newMessageNotification(data);
|
DashboardAudioNotificationHelper.onNewMessage(data);
|
||||||
this.app.$store.dispatch('addMessage', data);
|
this.app.$store.dispatch('addMessage', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import AnalyticsHelper from './AnalyticsHelper';
|
import AnalyticsHelper from './AnalyticsHelper';
|
||||||
|
import DashboardAudioNotificationHelper from './AudioAlerts/DashboardAudioNotificationHelper';
|
||||||
|
|
||||||
export const CHATWOOT_SET_USER = 'CHATWOOT_SET_USER';
|
export const CHATWOOT_SET_USER = 'CHATWOOT_SET_USER';
|
||||||
export const CHATWOOT_RESET = 'CHATWOOT_RESET';
|
export const CHATWOOT_RESET = 'CHATWOOT_RESET';
|
||||||
@@ -13,6 +14,23 @@ export const initializeAnalyticsEvents = () => {
|
|||||||
window.bus.$on(ANALYTICS_RESET, () => {});
|
window.bus.$on(ANALYTICS_RESET, () => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initializeAudioAlerts = user => {
|
||||||
|
// InitializeAudioNotifications
|
||||||
|
const { ui_settings: uiSettings } = user || {};
|
||||||
|
const {
|
||||||
|
always_play_audio_alert: alwaysPlayAudioAlert,
|
||||||
|
enable_audio_alerts: audioAlertType,
|
||||||
|
notification_tone: audioAlertTone,
|
||||||
|
} = uiSettings;
|
||||||
|
|
||||||
|
DashboardAudioNotificationHelper.setInstanceValues({
|
||||||
|
currentUserId: user.id,
|
||||||
|
audioAlertType: audioAlertType || 'none',
|
||||||
|
audioAlertTone: audioAlertTone || 'ding',
|
||||||
|
alwaysPlayAudioAlert: alwaysPlayAudioAlert || false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const initializeChatwootEvents = () => {
|
export const initializeChatwootEvents = () => {
|
||||||
window.bus.$on(CHATWOOT_RESET, () => {
|
window.bus.$on(CHATWOOT_RESET, () => {
|
||||||
if (window.$chatwoot) {
|
if (window.$chatwoot) {
|
||||||
@@ -32,5 +50,7 @@ export const initializeChatwootEvents = () => {
|
|||||||
cloudCustomer: 'true',
|
cloudCustomer: 'true',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initializeAudioAlerts(user);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,11 +16,6 @@ import App from '../dashboard/App';
|
|||||||
import i18n from '../dashboard/i18n';
|
import i18n from '../dashboard/i18n';
|
||||||
import createAxios from '../dashboard/helper/APIHelper';
|
import createAxios from '../dashboard/helper/APIHelper';
|
||||||
import commonHelpers, { isJSONValid } from '../dashboard/helper/commons';
|
import commonHelpers, { isJSONValid } from '../dashboard/helper/commons';
|
||||||
import {
|
|
||||||
getAlertAudio,
|
|
||||||
initOnEvents,
|
|
||||||
} from '../shared/helpers/AudioNotificationHelper';
|
|
||||||
import { initFaviconSwitcher } from '../shared/helpers/faviconHelper';
|
|
||||||
import router, { initalizeRouter } from '../dashboard/routes';
|
import router, { initalizeRouter } from '../dashboard/routes';
|
||||||
import store from '../dashboard/store';
|
import store from '../dashboard/store';
|
||||||
import constants from '../dashboard/constants';
|
import constants from '../dashboard/constants';
|
||||||
@@ -93,17 +88,6 @@ window.onload = () => {
|
|||||||
}).$mount('#app');
|
}).$mount('#app');
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupAudioListeners = () => {
|
|
||||||
getAlertAudio().then(() => {
|
|
||||||
initOnEvents.forEach(event => {
|
|
||||||
document.removeEventListener(event, setupAudioListeners, false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
window.playAudioAlert = () => {};
|
window.playAudioAlert = () => {};
|
||||||
initOnEvents.forEach(e => {
|
|
||||||
document.addEventListener(e, setupAudioListeners, false);
|
|
||||||
});
|
|
||||||
initFaviconSwitcher();
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export const IFrameHelper = {
|
|||||||
|
|
||||||
setupAudioListeners: () => {
|
setupAudioListeners: () => {
|
||||||
const { baseUrl = '' } = window.$chatwoot;
|
const { baseUrl = '' } = window.$chatwoot;
|
||||||
getAlertAudio(baseUrl, 'widget').then(() =>
|
getAlertAudio(baseUrl, { type: 'widget', alertTone: 'ding' }).then(() =>
|
||||||
initOnEvents.forEach(event => {
|
initOnEvents.forEach(event => {
|
||||||
document.removeEventListener(
|
document.removeEventListener(
|
||||||
event,
|
event,
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
import { MESSAGE_TYPE } from 'shared/constants/messages';
|
|
||||||
import { IFrameHelper } from 'widget/helpers/utils';
|
|
||||||
|
|
||||||
import { showBadgeOnFavicon } from './faviconHelper';
|
|
||||||
|
|
||||||
export const initOnEvents = ['click', 'touchstart', 'keypress', 'keydown'];
|
export const initOnEvents = ['click', 'touchstart', 'keypress', 'keydown'];
|
||||||
|
|
||||||
export const getAudioContext = () => {
|
export const getAudioContext = () => {
|
||||||
@@ -15,19 +10,8 @@ export const getAudioContext = () => {
|
|||||||
return audioCtx;
|
return audioCtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAlertTone = alertType => {
|
export const getAlertAudio = async (baseUrl = '', requestContext) => {
|
||||||
if (alertType === 'dashboard') {
|
|
||||||
const {
|
|
||||||
notification_tone: tone,
|
|
||||||
} = window.WOOT.$store.getters.getUISettings;
|
|
||||||
return tone;
|
|
||||||
}
|
|
||||||
return 'ding';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAlertAudio = async (baseUrl = '', type = 'dashboard') => {
|
|
||||||
const audioCtx = getAudioContext();
|
const audioCtx = getAudioContext();
|
||||||
|
|
||||||
const playSound = audioBuffer => {
|
const playSound = audioBuffer => {
|
||||||
window.playAudioAlert = () => {
|
window.playAudioAlert = () => {
|
||||||
if (audioCtx) {
|
if (audioCtx) {
|
||||||
@@ -41,7 +25,7 @@ export const getAlertAudio = async (baseUrl = '', type = 'dashboard') => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (audioCtx) {
|
if (audioCtx) {
|
||||||
const alertTone = getAlertTone(type);
|
const { type = 'dashboard', alertTone = 'ding' } = requestContext || {};
|
||||||
const resourceUrl = `${baseUrl}/audio/${type}/${alertTone}.mp3`;
|
const resourceUrl = `${baseUrl}/audio/${type}/${alertTone}.mp3`;
|
||||||
const audioRequest = new Request(resourceUrl);
|
const audioRequest = new Request(resourceUrl);
|
||||||
|
|
||||||
@@ -56,87 +40,3 @@ export const getAlertAudio = async (baseUrl = '', type = 'dashboard') => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const notificationEnabled = (enableAudioAlerts, id, userId) => {
|
|
||||||
if (enableAudioAlerts === 'mine') {
|
|
||||||
return userId === id;
|
|
||||||
}
|
|
||||||
if (enableAudioAlerts === 'all') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const shouldPlayAudio = (
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHidden
|
|
||||||
) => {
|
|
||||||
const {
|
|
||||||
conversation_id: incomingConvId,
|
|
||||||
sender_id: senderId,
|
|
||||||
message_type: messageType,
|
|
||||||
private: isPrivate,
|
|
||||||
} = message;
|
|
||||||
if (!isDocHidden && messageType === MESSAGE_TYPE.INCOMING) {
|
|
||||||
showBadgeOnFavicon();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const isFromCurrentUser = userId === senderId;
|
|
||||||
|
|
||||||
const playAudio =
|
|
||||||
!isFromCurrentUser && (messageType === MESSAGE_TYPE.INCOMING || isPrivate);
|
|
||||||
if (isDocHidden) return playAudio;
|
|
||||||
if (conversationId !== incomingConvId) return playAudio;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAssigneeFromNotification = currentConv => {
|
|
||||||
let id;
|
|
||||||
if (currentConv.meta) {
|
|
||||||
const assignee = currentConv.meta.assignee;
|
|
||||||
if (assignee) {
|
|
||||||
id = assignee.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const newMessageNotification = data => {
|
|
||||||
const { conversation_id: currentConvId } = window.WOOT.$route.params;
|
|
||||||
const currentUserId = window.WOOT.$store.getters.getCurrentUserID;
|
|
||||||
const { conversation_id: incomingConvId } = data;
|
|
||||||
const currentConv =
|
|
||||||
window.WOOT.$store.getters.getConversationById(incomingConvId) || {};
|
|
||||||
const assigneeId = getAssigneeFromNotification(currentConv);
|
|
||||||
|
|
||||||
const {
|
|
||||||
enable_audio_alerts: enableAudioAlerts = false,
|
|
||||||
always_play_audio_alert: alwaysPlayAudioAlert,
|
|
||||||
} = window.WOOT.$store.getters.getUISettings;
|
|
||||||
const isDocHidden = alwaysPlayAudioAlert ? true : document.hidden;
|
|
||||||
|
|
||||||
const playAudio = shouldPlayAudio(
|
|
||||||
data,
|
|
||||||
currentConvId,
|
|
||||||
currentUserId,
|
|
||||||
isDocHidden
|
|
||||||
);
|
|
||||||
const isNotificationEnabled = notificationEnabled(
|
|
||||||
enableAudioAlerts,
|
|
||||||
currentUserId,
|
|
||||||
assigneeId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (playAudio && isNotificationEnabled) {
|
|
||||||
window.playAudioAlert();
|
|
||||||
showBadgeOnFavicon();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const playNewMessageNotificationInWidget = () => {
|
|
||||||
IFrameHelper.sendMessage({
|
|
||||||
event: 'playAudio',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,151 +0,0 @@
|
|||||||
/**
|
|
||||||
* @jest-environment jsdom
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {
|
|
||||||
shouldPlayAudio,
|
|
||||||
notificationEnabled,
|
|
||||||
getAssigneeFromNotification,
|
|
||||||
} from '../AudioNotificationHelper';
|
|
||||||
|
|
||||||
describe('shouldPlayAudio', () => {
|
|
||||||
describe('Document active', () => {
|
|
||||||
it('Retuns true if incoming message', () => {
|
|
||||||
const message = {
|
|
||||||
conversation_id: 10,
|
|
||||||
sender_id: 5,
|
|
||||||
message_type: 0,
|
|
||||||
private: false,
|
|
||||||
};
|
|
||||||
const [conversationId, userId, isDocHiddden] = [1, 2, true];
|
|
||||||
const result = shouldPlayAudio(
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHiddden
|
|
||||||
);
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
it('Retuns false if outgoing message', () => {
|
|
||||||
const message = {
|
|
||||||
conversation_id: 10,
|
|
||||||
sender_id: 5,
|
|
||||||
message_type: 1,
|
|
||||||
private: false,
|
|
||||||
};
|
|
||||||
const [conversationId, userId, isDocHiddden] = [1, 2, false];
|
|
||||||
const result = shouldPlayAudio(
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHiddden
|
|
||||||
);
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Retuns false if from Same sender', () => {
|
|
||||||
const message = {
|
|
||||||
conversation_id: 1,
|
|
||||||
sender_id: 2,
|
|
||||||
message_type: 0,
|
|
||||||
private: false,
|
|
||||||
};
|
|
||||||
const [conversationId, userId, isDocHiddden] = [1, 2, true];
|
|
||||||
const result = shouldPlayAudio(
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHiddden
|
|
||||||
);
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
it('Retuns true if private message from another agent', () => {
|
|
||||||
const message = {
|
|
||||||
conversation_id: 1,
|
|
||||||
sender_id: 5,
|
|
||||||
message_type: 1,
|
|
||||||
private: true,
|
|
||||||
};
|
|
||||||
const [conversationId, userId, isDocHiddden] = [1, 2, true];
|
|
||||||
const result = shouldPlayAudio(
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHiddden
|
|
||||||
);
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe('Document inactive', () => {
|
|
||||||
it('Retuns true if incoming message', () => {
|
|
||||||
const message = {
|
|
||||||
conversation_id: 1,
|
|
||||||
sender_id: 5,
|
|
||||||
message_type: 0,
|
|
||||||
private: false,
|
|
||||||
};
|
|
||||||
const [conversationId, userId, isDocHiddden] = [1, 2, true];
|
|
||||||
const result = shouldPlayAudio(
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHiddden
|
|
||||||
);
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
it('Retuns false if outgoing message', () => {
|
|
||||||
const message = {
|
|
||||||
conversation_id: 1,
|
|
||||||
sender_id: 5,
|
|
||||||
message_type: 1,
|
|
||||||
private: false,
|
|
||||||
};
|
|
||||||
const [conversationId, userId, isDocHiddden] = [1, 2, true];
|
|
||||||
const result = shouldPlayAudio(
|
|
||||||
message,
|
|
||||||
conversationId,
|
|
||||||
userId,
|
|
||||||
isDocHiddden
|
|
||||||
);
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe('notificationEnabled', () => {
|
|
||||||
it('returns true if mine', () => {
|
|
||||||
const [enableAudioAlerts, userId, id] = ['mine', 1, 1];
|
|
||||||
const result = notificationEnabled(enableAudioAlerts, userId, id);
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
it('returns true if all', () => {
|
|
||||||
const [enableAudioAlerts, userId, id] = ['all', 1, 2];
|
|
||||||
const result = notificationEnabled(enableAudioAlerts, userId, id);
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
it('returns false if none', () => {
|
|
||||||
const [enableAudioAlerts, userId, id] = ['none', 1, 2];
|
|
||||||
const result = notificationEnabled(enableAudioAlerts, userId, id);
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe('getAssigneeFromNotification', () => {
|
|
||||||
it('Retuns true if gets notification from assignee', () => {
|
|
||||||
const currentConv = {
|
|
||||||
id: 1,
|
|
||||||
accountId: 1,
|
|
||||||
meta: {
|
|
||||||
assignee: {
|
|
||||||
id: 1,
|
|
||||||
name: 'John',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const result = getAssigneeFromNotification(currentConv);
|
|
||||||
expect(result).toBe(1);
|
|
||||||
});
|
|
||||||
it('Retuns true if gets notification from assignee is udefined', () => {
|
|
||||||
const currentConv = {};
|
|
||||||
const result = getAssigneeFromNotification(currentConv);
|
|
||||||
expect(result).toBe(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { IFrameHelper } from 'widget/helpers/utils';
|
||||||
|
|
||||||
|
export const playNewMessageNotificationInWidget = () => {
|
||||||
|
IFrameHelper.sendMessage({ event: 'playAudio' });
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import BaseActionCableConnector from '../../shared/helpers/BaseActionCableConnector';
|
import BaseActionCableConnector from '../../shared/helpers/BaseActionCableConnector';
|
||||||
import { playNewMessageNotificationInWidget } from 'shared/helpers/AudioNotificationHelper';
|
import { playNewMessageNotificationInWidget } from 'widget/helpers/WidgetAudioNotificationHelper';
|
||||||
import { ON_AGENT_MESSAGE_RECEIVED } from '../constants/widgetBusEvents';
|
import { ON_AGENT_MESSAGE_RECEIVED } from '../constants/widgetBusEvents';
|
||||||
|
|
||||||
class ActionCableConnector extends BaseActionCableConnector {
|
class ActionCableConnector extends BaseActionCableConnector {
|
||||||
|
|||||||
Reference in New Issue
Block a user