mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-30 18:47:51 +00:00
feat: Add new audio alert options (#6141)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
committed by
Pranav Raj S
parent
10a03cae24
commit
02a687b226
@@ -58,9 +58,19 @@
|
||||
"AUDIO_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Audio Notifications",
|
||||
"NOTE": "Enable audio notifications in dashboard for new messages and conversations.",
|
||||
"NONE": "None",
|
||||
"ASSIGNED": "Assigned Conversations",
|
||||
"ALL_CONVERSATIONS": "All Conversations"
|
||||
"ALERT_TYPE": {
|
||||
"TITLE": "Alert types:",
|
||||
"NONE": "None",
|
||||
"ASSIGNED": "Assigned Conversations",
|
||||
"ALL_CONVERSATIONS": "All Conversations"
|
||||
},
|
||||
"DEFAULT_TONE": {
|
||||
"TITLE": "Default tone:"
|
||||
},
|
||||
"CONDITIONS": {
|
||||
"TITLE": "Conditions:",
|
||||
"CONDITION_ONE": "Send audio alerts only if the browser window is not active"
|
||||
}
|
||||
},
|
||||
"EMAIL_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Email Notifications",
|
||||
|
||||
@@ -10,50 +10,115 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="columns small-9">
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert_none"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="radio"
|
||||
value="none"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert_none">
|
||||
{{ $t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.NONE') }}
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert_mine"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="radio"
|
||||
value="mine"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert_mine">
|
||||
{{
|
||||
$t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ASSIGNED')
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert_all"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="radio"
|
||||
value="all"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert_all">
|
||||
<div class="notification-items--wrapper">
|
||||
<span class="text-block-title notification-label">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ALL_CONVERSATIONS'
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ALERT_TYPE.TITLE'
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</span>
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert_none"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="radio"
|
||||
value="none"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert_none">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ALERT_TYPE.NONE'
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert_mine"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="radio"
|
||||
value="mine"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert_mine">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ALERT_TYPE.ASSIGNED'
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
id="audio_enable_alert_all"
|
||||
v-model="enableAudioAlerts"
|
||||
class="notification--checkbox"
|
||||
type="radio"
|
||||
value="all"
|
||||
@input="handleAudioInput"
|
||||
/>
|
||||
<label for="audio_enable_alert_all">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.ALERT_TYPE.ALL_CONVERSATIONS'
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification-items--wrapper">
|
||||
<span class="text-block-title notification-label">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.DEFAULT_TONE.TITLE'
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<div>
|
||||
<select
|
||||
v-model="notificationTone"
|
||||
class="tone-selector"
|
||||
@change="handleAudioToneChange"
|
||||
>
|
||||
<option
|
||||
v-for="tone in notificationAlertTones"
|
||||
:key="tone.value"
|
||||
:value="tone.value"
|
||||
>
|
||||
{{ tone.label }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification-items--wrapper">
|
||||
<span class="text-block-title notification-label">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.CONDITIONS.TITLE'
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<div>
|
||||
<input
|
||||
id="audio_alert_when_tab_is_inactive"
|
||||
v-model="playAudioWhenTabIsInactive"
|
||||
class="notification--checkbox"
|
||||
type="checkbox"
|
||||
value="tab_is_inactive"
|
||||
@input="handleAudioAlertConditions"
|
||||
/>
|
||||
<label for="audio_alert_when_tab_is_inactive">
|
||||
{{
|
||||
$t(
|
||||
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.CONDITIONS.CONDITION_ONE'
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -257,6 +322,18 @@ export default {
|
||||
selectedPushFlags: [],
|
||||
enableAudioAlerts: false,
|
||||
hasEnabledPushPermissions: false,
|
||||
playAudioWhenTabIsInactive: false,
|
||||
notificationTone: 'ding',
|
||||
notificationAlertTones: [
|
||||
{
|
||||
value: 'ding',
|
||||
label: 'Ding',
|
||||
},
|
||||
{
|
||||
value: 'bell',
|
||||
label: 'Bell',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -280,20 +357,27 @@ export default {
|
||||
this.selectedPushFlags = value;
|
||||
},
|
||||
uiSettings(value) {
|
||||
const { enable_audio_alerts: enableAudio = false } = value;
|
||||
this.enableAudioAlerts = enableAudio;
|
||||
this.notificationUISettings(value);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (hasPushPermissions()) {
|
||||
this.getPushSubscription();
|
||||
}
|
||||
|
||||
this.notificationUISettings(this.uiSettings);
|
||||
this.$store.dispatch('userNotificationSettings/get');
|
||||
const { enable_audio_alerts: enableAudio = false } = this.uiSettings;
|
||||
this.enableAudioAlerts = enableAudio;
|
||||
},
|
||||
methods: {
|
||||
notificationUISettings(uiSettings) {
|
||||
const {
|
||||
enable_audio_alerts: enableAudio = false,
|
||||
always_play_audio_alert: alwaysPlayAudioAlert,
|
||||
notification_tone: notificationTone,
|
||||
} = uiSettings;
|
||||
this.enableAudioAlerts = enableAudio;
|
||||
this.playAudioWhenTabIsInactive = !alwaysPlayAudioAlert;
|
||||
this.notificationTone = notificationTone || 'ding';
|
||||
},
|
||||
onRegistrationSuccess() {
|
||||
this.hasEnabledPushPermissions = true;
|
||||
},
|
||||
@@ -351,6 +435,19 @@ export default {
|
||||
});
|
||||
this.showAlert(this.$t('PROFILE_SETTINGS.FORM.API.UPDATE_SUCCESS'));
|
||||
},
|
||||
handleAudioAlertConditions(e) {
|
||||
let condition = e.target.value;
|
||||
if (condition === 'tab_is_inactive') {
|
||||
this.updateUISettings({
|
||||
always_play_audio_alert: !e.target.checked,
|
||||
});
|
||||
}
|
||||
this.showAlert(this.$t('PROFILE_SETTINGS.FORM.API.UPDATE_SUCCESS'));
|
||||
},
|
||||
handleAudioToneChange(e) {
|
||||
this.updateUISettings({ notification_tone: e.target.value });
|
||||
this.showAlert(this.$t('PROFILE_SETTINGS.FORM.API.UPDATE_SUCCESS'));
|
||||
},
|
||||
toggleInput(selected, current) {
|
||||
if (selected.includes(current)) {
|
||||
const newSelectedFlags = selected.filter(flag => flag !== current);
|
||||
@@ -372,4 +469,21 @@ export default {
|
||||
.push-notification--button {
|
||||
margin-bottom: var(--space-one);
|
||||
}
|
||||
|
||||
.notification-items--wrapper {
|
||||
margin-bottom: var(--space-smaller);
|
||||
}
|
||||
|
||||
.notification-label {
|
||||
display: flex;
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-bottom: var(--space-small);
|
||||
}
|
||||
|
||||
.tone-selector {
|
||||
height: var(--space-large);
|
||||
padding-bottom: var(--space-micro);
|
||||
padding-top: var(--space-micro);
|
||||
width: var(--space-mega);
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
app/javascript/shared/assets/audio/bell.mp3
Normal file
BIN
app/javascript/shared/assets/audio/bell.mp3
Normal file
Binary file not shown.
@@ -15,10 +15,20 @@ export const getAudioContext = () => {
|
||||
return audioCtx;
|
||||
};
|
||||
|
||||
const getAlertTone = alertType => {
|
||||
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 playsound = audioBuffer => {
|
||||
const playSound = audioBuffer => {
|
||||
window.playAudioAlert = () => {
|
||||
if (audioCtx) {
|
||||
const source = audioCtx.createBufferSource();
|
||||
@@ -31,13 +41,14 @@ export const getAlertAudio = async (baseUrl = '', type = 'dashboard') => {
|
||||
};
|
||||
|
||||
if (audioCtx) {
|
||||
const resourceUrl = `${baseUrl}/audio/${type}/ding.mp3`;
|
||||
const alertTone = getAlertTone(type);
|
||||
const resourceUrl = `${baseUrl}/audio/${type}/${alertTone}.mp3`;
|
||||
const audioRequest = new Request(resourceUrl);
|
||||
|
||||
fetch(audioRequest)
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(buffer => {
|
||||
audioCtx.decodeAudioData(buffer).then(playsound);
|
||||
audioCtx.decodeAudioData(buffer).then(playSound);
|
||||
return new Promise(res => res());
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -91,6 +102,7 @@ export const getAssigneeFromNotification = currentConv => {
|
||||
}
|
||||
return id;
|
||||
};
|
||||
|
||||
export const newMessageNotification = data => {
|
||||
const { conversation_id: currentConvId } = window.WOOT.$route.params;
|
||||
const currentUserId = window.WOOT.$store.getters.getCurrentUserID;
|
||||
@@ -98,10 +110,13 @@ export const newMessageNotification = data => {
|
||||
const currentConv =
|
||||
window.WOOT.$store.getters.getConversationById(incomingConvId) || {};
|
||||
const assigneeId = getAssigneeFromNotification(currentConv);
|
||||
const isDocHidden = document.hidden;
|
||||
|
||||
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,
|
||||
|
||||
BIN
public/audio/dashboard/bell.mp3
Normal file
BIN
public/audio/dashboard/bell.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user