feat(notifications): add notification sound playback for new alerts and include sound file documentation
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m27s
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m27s
This commit is contained in:
13
public/sounds/README.md
Normal file
13
public/sounds/README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Notification Sound
|
||||||
|
|
||||||
|
Pop-up Sound by BeezleFM -- https://freesound.org/s/512135/ -- License: Attribution 4.0
|
||||||
|
|
||||||
|
Place your notification sound file here as:
|
||||||
|
|
||||||
|
`notification.mp3`
|
||||||
|
|
||||||
|
The file is served at `/sounds/notification.mp3` and played automatically
|
||||||
|
whenever a new in-app notification arrives.
|
||||||
|
|
||||||
|
Supported formats: MP3, OGG, WAV — MP3 recommended for broadest browser support.
|
||||||
|
Keep the file short (< 2 s) and not too loud.
|
||||||
BIN
public/sounds/notification.mp3
Normal file
BIN
public/sounds/notification.mp3
Normal file
Binary file not shown.
@@ -3,6 +3,24 @@ import toast from 'react-hot-toast';
|
|||||||
import { useAuth } from './AuthContext';
|
import { useAuth } from './AuthContext';
|
||||||
import api from '../services/api';
|
import api from '../services/api';
|
||||||
|
|
||||||
|
// Lazily created Audio instance — reused across calls to avoid memory churn
|
||||||
|
let _audio = null;
|
||||||
|
function playNotificationSound() {
|
||||||
|
try {
|
||||||
|
if (!_audio) {
|
||||||
|
_audio = new Audio('/sounds/notification.mp3');
|
||||||
|
_audio.volume = 0.5;
|
||||||
|
}
|
||||||
|
// Reset to start so rapid arrivals always play from beginning
|
||||||
|
_audio.currentTime = 0;
|
||||||
|
_audio.play().catch(() => {
|
||||||
|
// Autoplay blocked (user hasn't interacted yet) or file missing — silent fail
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// Ignore any other errors (e.g. unsupported format)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const NotificationContext = createContext();
|
const NotificationContext = createContext();
|
||||||
|
|
||||||
export function NotificationProvider({ children }) {
|
export function NotificationProvider({ children }) {
|
||||||
@@ -30,6 +48,9 @@ export function NotificationProvider({ children }) {
|
|||||||
|
|
||||||
// Subsequent fetches: toast new unread notifications
|
// Subsequent fetches: toast new unread notifications
|
||||||
const newItems = incoming.filter(n => !n.read && !seenIds.current.has(n.id));
|
const newItems = incoming.filter(n => !n.read && !seenIds.current.has(n.id));
|
||||||
|
if (newItems.length > 0) {
|
||||||
|
playNotificationSound();
|
||||||
|
}
|
||||||
newItems.forEach(n => {
|
newItems.forEach(n => {
|
||||||
seenIds.current.add(n.id);
|
seenIds.current.add(n.id);
|
||||||
const icon = notificationIcon(n.type);
|
const icon = notificationIcon(n.type);
|
||||||
|
|||||||
Reference in New Issue
Block a user