feat: Adds the ability to play audio alert every 30 sec (#6150)

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Sivin Varghese
2022-12-30 11:46:58 +05:30
committed by Pranav Raj S
parent 6ffb7fe34e
commit 34e509b9b7
4 changed files with 79 additions and 4 deletions

View File

@@ -6,11 +6,14 @@ import {
initOnEvents, initOnEvents,
} from 'shared/helpers/AudioNotificationHelper'; } from 'shared/helpers/AudioNotificationHelper';
const NOTIFICATION_TIME = 30000;
class DashboardAudioNotificationHelper { class DashboardAudioNotificationHelper {
constructor() { constructor() {
this.recurringNotificationTimer = null; this.recurringNotificationTimer = null;
this.audioAlertType = 'none'; this.audioAlertType = 'none';
this.playAlertOnlyWhenHidden = true; this.playAlertOnlyWhenHidden = true;
this.alertIfUnreadConversationExist = false;
this.currentUserId = null; this.currentUserId = null;
this.audioAlertTone = 'ding'; this.audioAlertTone = 'ding';
} }
@@ -18,11 +21,13 @@ class DashboardAudioNotificationHelper {
setInstanceValues = ({ setInstanceValues = ({
currentUserId, currentUserId,
alwaysPlayAudioAlert, alwaysPlayAudioAlert,
alertIfUnreadConversationExist,
audioAlertType, audioAlertType,
audioAlertTone, audioAlertTone,
}) => { }) => {
this.audioAlertType = audioAlertType; this.audioAlertType = audioAlertType;
this.playAlertOnlyWhenHidden = !alwaysPlayAudioAlert; this.playAlertOnlyWhenHidden = !alwaysPlayAudioAlert;
this.alertIfUnreadConversationExist = alertIfUnreadConversationExist;
this.currentUserId = currentUserId; this.currentUserId = currentUserId;
this.audioAlertTone = audioAlertTone; this.audioAlertTone = audioAlertTone;
initOnEvents.forEach(e => { initOnEvents.forEach(e => {
@@ -40,11 +45,53 @@ class DashboardAudioNotificationHelper {
initOnEvents.forEach(event => { initOnEvents.forEach(event => {
document.removeEventListener(event, this.onAudioListenEvent, false); document.removeEventListener(event, this.onAudioListenEvent, false);
}); });
this.playAudioEvery30Seconds();
} catch (error) { } catch (error) {
// Ignore audio fetch errors // Ignore audio fetch errors
} }
}; };
executeRecurringNotification = () => {
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 => { isConversationAssignedToCurrentUser = message => {
const conversationAssigneeId = message?.conversation?.assignee_id; const conversationAssigneeId = message?.conversation?.assignee_id;
return conversationAssigneeId === this.currentUserId; return conversationAssigneeId === this.currentUserId;
@@ -94,6 +141,7 @@ class DashboardAudioNotificationHelper {
window.playAudioAlert(); window.playAudioAlert();
showBadgeOnFavicon(); showBadgeOnFavicon();
this.playAudioEvery30Seconds();
}; };
} }

View File

@@ -20,6 +20,7 @@ const initializeAudioAlerts = user => {
const { const {
always_play_audio_alert: alwaysPlayAudioAlert, always_play_audio_alert: alwaysPlayAudioAlert,
enable_audio_alerts: audioAlertType, enable_audio_alerts: audioAlertType,
alert_if_unread_assigned_conversation_exist: alertIfUnreadConversationExist,
notification_tone: audioAlertTone, notification_tone: audioAlertTone,
} = uiSettings; } = uiSettings;
@@ -28,6 +29,7 @@ const initializeAudioAlerts = user => {
audioAlertType: audioAlertType || 'none', audioAlertType: audioAlertType || 'none',
audioAlertTone: audioAlertTone || 'ding', audioAlertTone: audioAlertTone || 'ding',
alwaysPlayAudioAlert: alwaysPlayAudioAlert || false, alwaysPlayAudioAlert: alwaysPlayAudioAlert || false,
alertIfUnreadConversationExist: alertIfUnreadConversationExist || false,
}); });
}; };

View File

@@ -59,17 +59,18 @@
"TITLE": "Audio Notifications", "TITLE": "Audio Notifications",
"NOTE": "Enable audio notifications in dashboard for new messages and conversations.", "NOTE": "Enable audio notifications in dashboard for new messages and conversations.",
"ALERT_TYPE": { "ALERT_TYPE": {
"TITLE": "Alert types:", "TITLE": "Alert events:",
"NONE": "None", "NONE": "None",
"ASSIGNED": "Assigned Conversations", "ASSIGNED": "Assigned Conversations",
"ALL_CONVERSATIONS": "All Conversations" "ALL_CONVERSATIONS": "All Conversations"
}, },
"DEFAULT_TONE": { "DEFAULT_TONE": {
"TITLE": "Default tone:" "TITLE": "Alert tone:"
}, },
"CONDITIONS": { "CONDITIONS": {
"TITLE": "Conditions:", "TITLE": "Alert conditions:",
"CONDITION_ONE": "Send audio alerts only if the browser window is not active" "CONDITION_ONE": "Send audio alerts only if the browser window is not active",
"CONDITION_TWO": "Send alerts every 30s until all the assigned conversations are read"
} }
}, },
"EMAIL_NOTIFICATIONS_SECTION": { "EMAIL_NOTIFICATIONS_SECTION": {

View File

@@ -119,6 +119,23 @@
}} }}
</label> </label>
</div> </div>
<div>
<input
id="audio_alert_until_all_conversations_are_read"
v-model="alertIfUnreadConversationExist"
class="notification--checkbox"
type="checkbox"
value="conversations_are_read"
@input="handleAudioAlertConditions"
/>
<label for="audio_alert_until_all_conversations_are_read">
{{
$t(
'PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.CONDITIONS.CONDITION_TWO'
)
}}
</label>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -323,6 +340,7 @@ export default {
enableAudioAlerts: false, enableAudioAlerts: false,
hasEnabledPushPermissions: false, hasEnabledPushPermissions: false,
playAudioWhenTabIsInactive: false, playAudioWhenTabIsInactive: false,
alertIfUnreadConversationExist: false,
notificationTone: 'ding', notificationTone: 'ding',
notificationAlertTones: [ notificationAlertTones: [
{ {
@@ -372,10 +390,12 @@ export default {
const { const {
enable_audio_alerts: enableAudio = false, enable_audio_alerts: enableAudio = false,
always_play_audio_alert: alwaysPlayAudioAlert, always_play_audio_alert: alwaysPlayAudioAlert,
alert_if_unread_assigned_conversation_exist: alertIfUnreadConversationExist,
notification_tone: notificationTone, notification_tone: notificationTone,
} = uiSettings; } = uiSettings;
this.enableAudioAlerts = enableAudio; this.enableAudioAlerts = enableAudio;
this.playAudioWhenTabIsInactive = !alwaysPlayAudioAlert; this.playAudioWhenTabIsInactive = !alwaysPlayAudioAlert;
this.alertIfUnreadConversationExist = alertIfUnreadConversationExist;
this.notificationTone = notificationTone || 'ding'; this.notificationTone = notificationTone || 'ding';
}, },
onRegistrationSuccess() { onRegistrationSuccess() {
@@ -441,6 +461,10 @@ export default {
this.updateUISettings({ this.updateUISettings({
always_play_audio_alert: !e.target.checked, always_play_audio_alert: !e.target.checked,
}); });
} else if (condition === 'conversations_are_read') {
this.updateUISettings({
alert_if_unread_assigned_conversation_exist: e.target.checked,
});
} }
this.showAlert(this.$t('PROFILE_SETTINGS.FORM.API.UPDATE_SUCCESS')); this.showAlert(this.$t('PROFILE_SETTINGS.FORM.API.UPDATE_SUCCESS'));
}, },