diff --git a/app/javascript/dashboard/helper/AudioAlerts/DashboardAudioNotificationHelper.js b/app/javascript/dashboard/helper/AudioAlerts/DashboardAudioNotificationHelper.js index 66bfa4cd4..986a1a0ad 100644 --- a/app/javascript/dashboard/helper/AudioAlerts/DashboardAudioNotificationHelper.js +++ b/app/javascript/dashboard/helper/AudioAlerts/DashboardAudioNotificationHelper.js @@ -6,11 +6,14 @@ import { initOnEvents, } from 'shared/helpers/AudioNotificationHelper'; +const NOTIFICATION_TIME = 30000; + class DashboardAudioNotificationHelper { constructor() { this.recurringNotificationTimer = null; this.audioAlertType = 'none'; this.playAlertOnlyWhenHidden = true; + this.alertIfUnreadConversationExist = false; this.currentUserId = null; this.audioAlertTone = 'ding'; } @@ -18,11 +21,13 @@ class DashboardAudioNotificationHelper { setInstanceValues = ({ currentUserId, alwaysPlayAudioAlert, + alertIfUnreadConversationExist, audioAlertType, audioAlertTone, }) => { this.audioAlertType = audioAlertType; this.playAlertOnlyWhenHidden = !alwaysPlayAudioAlert; + this.alertIfUnreadConversationExist = alertIfUnreadConversationExist; this.currentUserId = currentUserId; this.audioAlertTone = audioAlertTone; initOnEvents.forEach(e => { @@ -40,11 +45,53 @@ class DashboardAudioNotificationHelper { initOnEvents.forEach(event => { document.removeEventListener(event, this.onAudioListenEvent, false); }); + this.playAudioEvery30Seconds(); } catch (error) { // 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 => { const conversationAssigneeId = message?.conversation?.assignee_id; return conversationAssigneeId === this.currentUserId; @@ -94,6 +141,7 @@ class DashboardAudioNotificationHelper { window.playAudioAlert(); showBadgeOnFavicon(); + this.playAudioEvery30Seconds(); }; } diff --git a/app/javascript/dashboard/helper/scriptHelpers.js b/app/javascript/dashboard/helper/scriptHelpers.js index 291769d2d..3aa0f5379 100644 --- a/app/javascript/dashboard/helper/scriptHelpers.js +++ b/app/javascript/dashboard/helper/scriptHelpers.js @@ -20,6 +20,7 @@ const initializeAudioAlerts = user => { const { always_play_audio_alert: alwaysPlayAudioAlert, enable_audio_alerts: audioAlertType, + alert_if_unread_assigned_conversation_exist: alertIfUnreadConversationExist, notification_tone: audioAlertTone, } = uiSettings; @@ -28,6 +29,7 @@ const initializeAudioAlerts = user => { audioAlertType: audioAlertType || 'none', audioAlertTone: audioAlertTone || 'ding', alwaysPlayAudioAlert: alwaysPlayAudioAlert || false, + alertIfUnreadConversationExist: alertIfUnreadConversationExist || false, }); }; diff --git a/app/javascript/dashboard/i18n/locale/en/settings.json b/app/javascript/dashboard/i18n/locale/en/settings.json index f87e59930..6e05e3bad 100644 --- a/app/javascript/dashboard/i18n/locale/en/settings.json +++ b/app/javascript/dashboard/i18n/locale/en/settings.json @@ -59,17 +59,18 @@ "TITLE": "Audio Notifications", "NOTE": "Enable audio notifications in dashboard for new messages and conversations.", "ALERT_TYPE": { - "TITLE": "Alert types:", + "TITLE": "Alert events:", "NONE": "None", "ASSIGNED": "Assigned Conversations", "ALL_CONVERSATIONS": "All Conversations" }, "DEFAULT_TONE": { - "TITLE": "Default tone:" + "TITLE": "Alert tone:" }, "CONDITIONS": { - "TITLE": "Conditions:", - "CONDITION_ONE": "Send audio alerts only if the browser window is not active" + "TITLE": "Alert conditions:", + "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": { diff --git a/app/javascript/dashboard/routes/dashboard/settings/profile/NotificationSettings.vue b/app/javascript/dashboard/routes/dashboard/settings/profile/NotificationSettings.vue index af8f14f8f..f6b216b96 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/profile/NotificationSettings.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/profile/NotificationSettings.vue @@ -119,6 +119,23 @@ }} +
+ + +
@@ -323,6 +340,7 @@ export default { enableAudioAlerts: false, hasEnabledPushPermissions: false, playAudioWhenTabIsInactive: false, + alertIfUnreadConversationExist: false, notificationTone: 'ding', notificationAlertTones: [ { @@ -372,10 +390,12 @@ export default { const { enable_audio_alerts: enableAudio = false, always_play_audio_alert: alwaysPlayAudioAlert, + alert_if_unread_assigned_conversation_exist: alertIfUnreadConversationExist, notification_tone: notificationTone, } = uiSettings; this.enableAudioAlerts = enableAudio; this.playAudioWhenTabIsInactive = !alwaysPlayAudioAlert; + this.alertIfUnreadConversationExist = alertIfUnreadConversationExist; this.notificationTone = notificationTone || 'ding'; }, onRegistrationSuccess() { @@ -441,6 +461,10 @@ export default { this.updateUISettings({ 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')); },