import { useEffect, useRef } from 'react'; import { useSetAtom } from 'jotai'; import { Icons } from 'folds'; import { CallEmbed } from '../plugins/call'; import { toastQueueAtom } from '../state/toast'; import { useSetting } from '../state/hooks/settings'; import { settingsAtom } from '../state/settings'; import { denoiseNotice, DenoiseStateReport } from '../utils/denoiseNotice'; /** * [Gitea #260] Tell the user when ML noise suppression didn't attach (raw mic) * or fell back to another model. The fork's `io.lotus.denoise_state` used to * go unanswered ("unsupported action"), so failures were silent. */ export function useDenoiseNotices(embed: CallEmbed): void { const setToast = useSetAtom(toastQueueAtom); const [mode] = useSetting(settingsAtom, 'callNoiseSuppression'); const [model] = useSetting(settingsAtom, 'callDenoiseModel'); const latest = useRef({ mode, model }); latest.current = { mode, model }; useEffect( () => embed.listenAction<{ data?: DenoiseStateReport }>('io.lotus.denoise_state', (evt) => { if (latest.current.mode !== 'ml') return; const body = denoiseNotice(latest.current.model, evt.detail?.data); if (!body) return; setToast({ id: `denoise-state-${Date.now()}`, iconSrc: Icons.Mic, displayName: 'Noise suppression', body, roomName: embed.room.name ?? 'Voice call', roomId: embed.roomId, }); }), [embed, setToast], ); }