diff --git a/package.json b/package.json index 0bea8fc..126d9c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chatter", - "version": "0.0.1", + "version": "0.0.2", "module": "index.ts", "type": "module", "packageManager": "bun@1.1.36", diff --git a/public/pages/index/modules/audio.js b/public/pages/index/modules/audio.js new file mode 100644 index 0000000..9b734b3 --- /dev/null +++ b/public/pages/index/modules/audio.js @@ -0,0 +1,37 @@ +export class AudioManager { + constructor() { + this.notificationSound = new Audio('/public/sounds/notification.mp3'); + this.notificationSound.volume = 1; // Full volume + + // Handle loading errors + this.notificationSound.addEventListener('error', (e) => { + console.error('Error loading notification sound:', e.error); + }); + + // Preload the audio + this.notificationSound.load(); + } + + playMessageNotification(overrideFocus = false) { + // Only play if the window is not focused (unless overrideFocus is true) + if (!document.hasFocus() || overrideFocus) { + try { + this.notificationSound.currentTime = 0; // Reset audio to start + const playPromise = this.notificationSound.play(); + + if (playPromise !== undefined) { + playPromise.catch(error => { + console.log('Error playing notification sound:', error); + }); + } + } catch (error) { + console.error('Error playing notification sound:', error); + } + } + } + + setVolume(volume) { + // volume should be between 0 and 1 + this.notificationSound.volume = Math.max(0, Math.min(1, volume)); + } +} diff --git a/public/pages/index/modules/chat.js b/public/pages/index/modules/chat.js index c8bad5a..57ad5c4 100644 --- a/public/pages/index/modules/chat.js +++ b/public/pages/index/modules/chat.js @@ -1,7 +1,8 @@ export class ChatManager { - constructor(websocketManager, uiManager) { + constructor(websocketManager, uiManager, audioManager) { this.websocketManager = websocketManager; this.uiManager = uiManager; + this.audioManager = audioManager; this.typingTimeout = null; this.isTyping = false; @@ -119,6 +120,7 @@ export class ChatManager { switch (data.type) { case "message": this.uiManager.appendMessage(data); + this.audioManager.playMessageNotification(); break; case "typing": diff --git a/public/pages/index/modules/main.js b/public/pages/index/modules/main.js index 1e20587..52f844d 100644 --- a/public/pages/index/modules/main.js +++ b/public/pages/index/modules/main.js @@ -1,11 +1,13 @@ import { WebSocketManager } from './websocket.js'; import { UIManager } from './ui.js'; import { ChatManager } from './chat.js'; +import { AudioManager } from './audio.js'; document.addEventListener("DOMContentLoaded", () => { // Initialize managers const uiManager = new UIManager(); - + const audioManager = new AudioManager(); + // Show initial loading state uiManager.showLoadingState(); @@ -26,7 +28,7 @@ document.addEventListener("DOMContentLoaded", () => { ); // Initialize chat manager - const chatManager = new ChatManager(websocketManager, uiManager); + const chatManager = new ChatManager(websocketManager, uiManager, audioManager); // Start WebSocket connection websocketManager.connect(); diff --git a/public/sounds/notification.mp3 b/public/sounds/notification.mp3 new file mode 100644 index 0000000..71d80c7 Binary files /dev/null and b/public/sounds/notification.mp3 differ