feat: Add audio alert for incoming messages on dashboard (#1738)

Fixes: #1345
This commit is contained in:
Nithin David Thomas 2021-03-04 19:24:03 +05:30 committed by GitHub
parent ca4a766b82
commit 9e8a943ec7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 3 deletions

View file

@ -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);
};

View file

@ -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",

View file

@ -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);

View file

@ -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();
});

View file

@ -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;
};

Binary file not shown.