mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-23 19:06:35 +00:00
feat(widget): add audio notification for new messages
This commit is contained in:
@@ -33,6 +33,7 @@ export const createFormSchema = (t) => z.object({
|
||||
chat_introduction: z.string(),
|
||||
show_office_hours_in_chat: z.boolean(),
|
||||
show_office_hours_after_assignment: z.boolean(),
|
||||
chat_reply_expectation_message: z.string().optional(),
|
||||
notice_banner: z.object({
|
||||
enabled: z.boolean(),
|
||||
text: z.string().optional()
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<div
|
||||
class="libredesk-widget-app text-foreground bg-background"
|
||||
:class="{ dark: widgetStore.config.dark_mode }"
|
||||
@click.once="initAudioContext"
|
||||
@touchstart.once="initAudioContext"
|
||||
>
|
||||
<div class="widget-container">
|
||||
<MainLayout />
|
||||
@@ -16,6 +18,7 @@ import { useChatStore } from '@widget/store/chat.js'
|
||||
import { useUserStore } from './store/user.js'
|
||||
import { initWidgetWS, closeWidgetWebSocket } from './websocket.js'
|
||||
import { useUnreadCount } from './composables/useUnreadCount.js'
|
||||
import { initAudioContext } from './composables/useNotificationSound.js'
|
||||
import { applyCSSColor } from '@shared-ui/utils/color.js'
|
||||
import MainLayout from '@widget/layouts/MainLayout.vue'
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
import notificationSound from '../assets/notification.mp3'
|
||||
|
||||
let audio = null
|
||||
|
||||
// Call on first user interaction to unlock audio
|
||||
export function initAudioContext() {
|
||||
if (audio) return
|
||||
audio = new Audio(notificationSound)
|
||||
audio.volume = 0.5
|
||||
audio.load()
|
||||
}
|
||||
|
||||
export function playNotificationSound() {
|
||||
if (!audio) return
|
||||
audio.currentTime = 0
|
||||
audio.play().catch(() => {})
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
// Widget WebSocket message types (matching backend constants)
|
||||
import { useChatStore } from './store/chat.js'
|
||||
import { useWidgetStore } from './store/widget.js'
|
||||
import { useUserStore } from './store/user.js'
|
||||
import { playNotificationSound } from './composables/useNotificationSound.js'
|
||||
|
||||
export const WS_EVENT = {
|
||||
JOIN: 'join',
|
||||
@@ -83,8 +86,21 @@ export class WidgetWebSocketClient {
|
||||
this.lastPong = Date.now()
|
||||
},
|
||||
[WS_EVENT.NEW_MESSAGE]: () => {
|
||||
if (data.data) {
|
||||
chatStore.addMessageToConversation(data.data.conversation_uuid, data.data)
|
||||
if (!data.data) return
|
||||
|
||||
const message = data.data
|
||||
chatStore.addMessageToConversation(message.conversation_uuid, message)
|
||||
|
||||
// Play notification sound if message is from agent and widget is not focused on this conversation
|
||||
const widgetStore = useWidgetStore()
|
||||
const userStore = useUserStore()
|
||||
const isFromAgent = message.author?.id !== userStore.userID
|
||||
const isViewingConversation = widgetStore.isOpen &&
|
||||
widgetStore.isInChatView &&
|
||||
chatStore.currentConversation?.uuid === message.conversation_uuid
|
||||
|
||||
if (isFromAgent && !isViewingConversation) {
|
||||
playNotificationSound()
|
||||
}
|
||||
},
|
||||
[WS_EVENT.ERROR]: () => {
|
||||
|
||||
Reference in New Issue
Block a user