feat: Add audio alert for incoming messages on dashboard (#1738)
Fixes: #1345
This commit is contained in:
parent
ca4a766b82
commit
9e8a943ec7
6 changed files with 115 additions and 3 deletions
|
@ -1,5 +1,6 @@
|
|||
import AuthAPI from '../api/auth';
|
||||
import BaseActionCableConnector from '../../shared/helpers/BaseActionCableConnector';
|
||||
import { newMessageNotification } from 'shared/helpers/AudioNotificationHelper';
|
||||
|
||||
class ActionCableConnector extends BaseActionCableConnector {
|
||||
constructor(app, pubsubToken) {
|
||||
|
@ -63,6 +64,7 @@ class ActionCableConnector extends BaseActionCableConnector {
|
|||
onLogout = () => AuthAPI.logout();
|
||||
|
||||
onMessageCreated = data => {
|
||||
newMessageNotification(data);
|
||||
this.app.$store.dispatch('addMessage', data);
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
"TITLE": "Access Token",
|
||||
"NOTE": "This token can be used if you are building an API based integration"
|
||||
},
|
||||
"AUDIO_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Audio Notifications",
|
||||
"NOTE": "Enable audio notifications in dashboard for new messages and conversations.",
|
||||
"ENABLE_AUDIO": "Play audio notification when a new conversation is created or new messages arrives"
|
||||
},
|
||||
"EMAIL_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Email Notifications",
|
||||
"NOTE": "Update your email notification preferences here",
|
||||
|
|
|
@ -1,5 +1,33 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="profile--settings--row row">
|
||||
<div class="columns small-3 ">
|
||||
<h4 class="block-title">
|
||||
{{ $t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.TITLE') }}
|
||||
</h4>
|
||||
<p>
|
||||
{{ $t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.NOTE') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="columns small-9">
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="checkbox"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ENABLE_AUDIO'
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile--settings--row row">
|
||||
<div class="columns small-3 ">
|
||||
<h4 class="block-title">
|
||||
|
@ -185,6 +213,7 @@
|
|||
import { mapGetters } from 'vuex';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import configMixin from 'shared/mixins/configMixin';
|
||||
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||
import {
|
||||
hasPushPermissions,
|
||||
requestPushPermissions,
|
||||
|
@ -192,11 +221,12 @@ import {
|
|||
} from '../../../../helper/pushHelper';
|
||||
|
||||
export default {
|
||||
mixins: [alertMixin, configMixin],
|
||||
mixins: [alertMixin, configMixin, uiSettingsMixin],
|
||||
data() {
|
||||
return {
|
||||
selectedEmailFlags: [],
|
||||
selectedPushFlags: [],
|
||||
enableAudioAlerts: false,
|
||||
hasEnabledPushPermissions: false,
|
||||
};
|
||||
},
|
||||
|
@ -204,6 +234,7 @@ export default {
|
|||
...mapGetters({
|
||||
emailFlags: 'userNotificationSettings/getSelectedEmailFlags',
|
||||
pushFlags: 'userNotificationSettings/getSelectedPushFlags',
|
||||
uiSettings: 'getUISettings',
|
||||
}),
|
||||
isBrowserSafari() {
|
||||
if (window.browserConfig) {
|
||||
|
@ -219,6 +250,10 @@ export default {
|
|||
pushFlags(value) {
|
||||
this.selectedPushFlags = value;
|
||||
},
|
||||
uiSettings(value) {
|
||||
const { enable_audio_alerts: enableAudio = false } = value;
|
||||
this.enableAudioAlerts = enableAudio;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (hasPushPermissions()) {
|
||||
|
@ -226,6 +261,8 @@ export default {
|
|||
}
|
||||
|
||||
this.$store.dispatch('userNotificationSettings/get');
|
||||
const { enable_audio_alerts: enableAudio = false } = this.uiSettings;
|
||||
this.enableAudioAlerts = enableAudio;
|
||||
},
|
||||
methods: {
|
||||
onRegistrationSuccess() {
|
||||
|
@ -277,6 +314,13 @@ export default {
|
|||
|
||||
this.updateNotificationSettings();
|
||||
},
|
||||
handleAudioInput(e) {
|
||||
this.enableAudioAlerts = e.target.checked;
|
||||
this.updateUISettings({
|
||||
enable_audio_alerts: this.enableAudioAlerts,
|
||||
});
|
||||
this.showAlert(this.$t('PROFILE_SETTINGS.FORM.API.UPDATE_SUCCESS'));
|
||||
},
|
||||
toggleInput(selected, current) {
|
||||
if (selected.includes(current)) {
|
||||
const newSelectedFlags = selected.filter(flag => flag !== current);
|
||||
|
|
|
@ -20,6 +20,7 @@ import App from '../dashboard/App';
|
|||
import i18n from '../dashboard/i18n';
|
||||
import createAxios from '../dashboard/helper/APIHelper';
|
||||
import commonHelpers from '../dashboard/helper/commons';
|
||||
import { getAlertAudio } from '../shared/helpers/AudioNotificationHelper';
|
||||
import router from '../dashboard/routes';
|
||||
import store from '../dashboard/store';
|
||||
import vueActionCable from '../dashboard/helper/actionCable';
|
||||
|
@ -70,7 +71,6 @@ window.onload = () => {
|
|||
}).$mount('#app');
|
||||
vueActionCable.init();
|
||||
};
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
verifyServiceWorkerExistence(registration =>
|
||||
registration.pushManager.getSubscription().then(subscription => {
|
||||
|
@ -79,4 +79,5 @@ window.addEventListener('load', () => {
|
|||
}
|
||||
})
|
||||
);
|
||||
getAlertAudio();
|
||||
});
|
||||
|
|
|
@ -1,9 +1,69 @@
|
|||
import { MESSAGE_TYPE } from 'shared/constants/messages';
|
||||
const notificationAudio = require('shared/assets/audio/ding.mp3');
|
||||
import axios from 'axios';
|
||||
|
||||
export const playNotificationAudio = () => {
|
||||
try {
|
||||
new Audio(notificationAudio).play();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// error
|
||||
}
|
||||
};
|
||||
|
||||
export const getAlertAudio = async () => {
|
||||
window.playAudioAlert = () => {};
|
||||
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||
const playsound = audioBuffer => {
|
||||
window.playAudioAlert = () => {
|
||||
const source = audioCtx.createBufferSource();
|
||||
source.buffer = audioBuffer;
|
||||
source.connect(audioCtx.destination);
|
||||
source.loop = false;
|
||||
source.start();
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await axios.get('/dashboard/audios/ding.mp3', {
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
|
||||
audioCtx.decodeAudioData(response.data).then(playsound);
|
||||
} catch (error) {
|
||||
// error
|
||||
}
|
||||
};
|
||||
|
||||
const shouldPlayAudio = data => {
|
||||
const { conversation_id: currentConvId } = window.WOOT.$route.params;
|
||||
const currentUserId = window.WOOT.$store.getters.getCurrentUserID;
|
||||
const {
|
||||
conversation_id: incomingConvId,
|
||||
sender_id: senderId,
|
||||
message_type: messageType,
|
||||
} = data;
|
||||
const isFromCurrentUser = currentUserId === senderId;
|
||||
|
||||
const playAudio =
|
||||
currentConvId !== incomingConvId &&
|
||||
!isFromCurrentUser &&
|
||||
messageType === MESSAGE_TYPE.INCOMING;
|
||||
return playAudio;
|
||||
};
|
||||
|
||||
export const newMessageNotification = data => {
|
||||
const {
|
||||
enable_audio_alerts: enableAudioAlerts = false,
|
||||
} = window.WOOT.$store.getters.getUISettings;
|
||||
if (!enableAudioAlerts) return false;
|
||||
|
||||
if (document.hidden) {
|
||||
window.playAudioAlert();
|
||||
} else {
|
||||
const playAudio = shouldPlayAudio(data);
|
||||
if (playAudio) {
|
||||
window.playAudioAlert();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
BIN
public/dashboard/audios/ding.mp3
Normal file
BIN
public/dashboard/audios/ding.mp3
Normal file
Binary file not shown.
Loading…
Reference in a new issue