'use client'; import { useNotificationSounds } from '@djangocfg/ui-core/hooks'; import { DEFAULT_CHAT_SOUNDS } from '../core/audio/defaults'; import type { ChatAudioConfig, ChatAudioEvent, UseChatAudioReturn, } from '../core/audio/types'; const STORAGE_KEY = 'djangocfg-chat-audio:prefs'; /** * Slack / Linear / Intercom-style per-event volume scale. Applied on top * of the master volume so error / status sounds don't startle the user * sitting next to a busy chat. Override per-event via * `config.eventVolumes`, or pass `eventVolumes: {}` to disable defaults. */ const DEFAULT_EVENT_VOLUMES: Partial> = { error: 0.25, mention: 1, messageSent: 0.5, messageReceived: 0.7, streamStart: 0.3, notification: 0.9, }; /** * Chat-specific audio facade. Thin wrapper over `useNotificationSounds` * from `@djangocfg/ui-core` — keeps the `ChatAudioEvent` typing while * the underlying bus / prefs / Safari-unlock logic lives in ui-core. */ export function useChatAudio(config: ChatAudioConfig = {}): UseChatAudioReturn { // Auto-fallback to built-in sounds when: // - host hasn't passed a `sounds` map (most apps) // - host hasn't opted into `silenced` mode (native hosts skip this) // Pass `sounds: {}` explicitly to disable both defaults and embedded. const resolvedSounds = config.sounds === undefined && !config.silenced ? DEFAULT_CHAT_SOUNDS : config.sounds; const api = useNotificationSounds({ storageKey: STORAGE_KEY, sounds: resolvedSounds, volume: config.volume, eventVolumes: config.eventVolumes ?? DEFAULT_EVENT_VOLUMES, muted: config.muted, shouldPlay: config.shouldPlay, respectReducedMotion: config.respectReducedMotion, respectReducedData: config.respectReducedData, muteWhenHidden: config.muteWhenHidden, silenced: config.silenced, onSoundEvent: config.onSoundEvent, }); return { play: api.play, preload: api.preload, unlock: api.unlock, isUnlocked: api.isUnlocked, muted: api.muted, setMuted: api.setMuted, toggleMute: api.toggleMute, volume: api.volume, setVolume: api.setVolume, isEventEnabled: api.isEventEnabled, setEventEnabled: api.setEventEnabled, isSilent: api.isSilent, }; }