Add synthesized bubble pop sound to notifications
This commit is contained in:
parent
20872c9cc8
commit
197364e11d
@ -58,6 +58,36 @@ export function useNotifications(reminderSettings: ReminderSettings) {
|
|||||||
[isSupported, permission]
|
[isSupported, permission]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Play a "bubble pop" sound using Web Audio API
|
||||||
|
const playNotificationSound = useCallback(() => {
|
||||||
|
try {
|
||||||
|
const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
|
||||||
|
if (!AudioContext) return;
|
||||||
|
|
||||||
|
const ctx = new AudioContext();
|
||||||
|
const oscillator = ctx.createOscillator();
|
||||||
|
const gainNode = ctx.createGain();
|
||||||
|
|
||||||
|
oscillator.connect(gainNode);
|
||||||
|
gainNode.connect(ctx.destination);
|
||||||
|
|
||||||
|
// Bubble 'pop' effect: sine wave with rapid frequency drop
|
||||||
|
oscillator.type = 'sine';
|
||||||
|
oscillator.frequency.setValueAtTime(800, ctx.currentTime);
|
||||||
|
oscillator.frequency.exponentialRampToValueAtTime(100, ctx.currentTime + 0.1);
|
||||||
|
|
||||||
|
// Envelope: quick attack, quick decay
|
||||||
|
gainNode.gain.setValueAtTime(0, ctx.currentTime);
|
||||||
|
gainNode.gain.linearRampToValueAtTime(0.3, ctx.currentTime + 0.01);
|
||||||
|
gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.1);
|
||||||
|
|
||||||
|
oscillator.start();
|
||||||
|
oscillator.stop(ctx.currentTime + 0.15);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error playing notification sound:', e);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Check and send daily reminder
|
// Check and send daily reminder
|
||||||
const checkAndSendReminder = useCallback(() => {
|
const checkAndSendReminder = useCallback(() => {
|
||||||
if (!reminderSettings.enabled || permission !== 'granted') return;
|
if (!reminderSettings.enabled || permission !== 'granted') return;
|
||||||
@ -74,6 +104,7 @@ export function useNotifications(reminderSettings: ReminderSettings) {
|
|||||||
|
|
||||||
// If current time is past the reminder time, send it
|
// If current time is past the reminder time, send it
|
||||||
if (now >= reminderTime) {
|
if (now >= reminderTime) {
|
||||||
|
playNotificationSound();
|
||||||
sendNotification('QuitTraq Reminder', {
|
sendNotification('QuitTraq Reminder', {
|
||||||
body: "Time to log your daily usage! Every day counts on your journey.",
|
body: "Time to log your daily usage! Every day counts on your journey.",
|
||||||
tag: 'daily-reminder', // Tag ensures we don't stack multiple notifications
|
tag: 'daily-reminder', // Tag ensures we don't stack multiple notifications
|
||||||
@ -81,7 +112,7 @@ export function useNotifications(reminderSettings: ReminderSettings) {
|
|||||||
});
|
});
|
||||||
localStorage.setItem(LAST_NOTIFICATION_KEY, today);
|
localStorage.setItem(LAST_NOTIFICATION_KEY, today);
|
||||||
}
|
}
|
||||||
}, [reminderSettings, permission, sendNotification]);
|
}, [reminderSettings, permission, sendNotification, playNotificationSound]);
|
||||||
|
|
||||||
// Set up interval to check for reminder time
|
// Set up interval to check for reminder time
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user