import { useEffect } from "react"; import { SettingsItem } from "@components/SettingsItem"; import { SettingsPageHeader } from "@components/SettingsPageheader"; import { useSettingsStore } from "@/hooks/stores"; import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc"; import { SelectMenuBasic } from "@components/SelectMenuBasic"; import Checkbox from "@components/Checkbox"; import { m } from "@localizations/messages.js"; import notifications from "../notifications"; interface AudioConfigResult { bitrate: number; complexity: number; dtx_enabled: boolean; fec_enabled: boolean; buffer_periods: number; packet_loss_perc: number; } const AUDIO_DEFAULTS = { bitrate: 192, complexity: 8, packetLossPerc: 20, } as const; export default function SettingsAudioRoute() { const { send } = useJsonRpc(); const handleRpcError = (resp: JsonRpcResponse, defaultMsg?: string) => { if ("error" in resp) { notifications.error(String(resp.error.data || defaultMsg || m.unknown_error())); return true; } return false; }; const { setAudioOutputEnabled, setAudioInputAutoEnable, setAudioOutputSource, audioOutputEnabled, audioInputAutoEnable, audioOutputSource, audioBitrate, setAudioBitrate, audioComplexity, setAudioComplexity, audioDTXEnabled, setAudioDTXEnabled, audioFECEnabled, setAudioFECEnabled, audioBufferPeriods, setAudioBufferPeriods, audioPacketLossPerc, setAudioPacketLossPerc, } = useSettingsStore(); useEffect(() => { send("getAudioOutputEnabled", {}, (resp: JsonRpcResponse) => { if ("error" in resp) return; setAudioOutputEnabled(resp.result as boolean); }); send("getAudioInputAutoEnable", {}, (resp: JsonRpcResponse) => { if ("error" in resp) return; setAudioInputAutoEnable(resp.result as boolean); }); send("getAudioOutputSource", {}, (resp: JsonRpcResponse) => { if ("error" in resp) return; setAudioOutputSource(resp.result as string); }); send("getAudioConfig", {}, (resp: JsonRpcResponse) => { if ("error" in resp) return; const config = resp.result as AudioConfigResult; setAudioBitrate(config.bitrate); setAudioComplexity(config.complexity); setAudioDTXEnabled(config.dtx_enabled); setAudioFECEnabled(config.fec_enabled); setAudioBufferPeriods(config.buffer_periods); setAudioPacketLossPerc(config.packet_loss_perc); }); }, [send, setAudioOutputEnabled, setAudioInputAutoEnable, setAudioOutputSource, setAudioBitrate, setAudioComplexity, setAudioDTXEnabled, setAudioFECEnabled, setAudioBufferPeriods, setAudioPacketLossPerc]); const handleAudioOutputEnabledChange = (enabled: boolean) => { send("setAudioOutputEnabled", { enabled }, (resp: JsonRpcResponse) => { if ("error" in resp) { const errorMsg = enabled ? m.audio_output_failed_enable({ error: String(resp.error.data || m.unknown_error()) }) : m.audio_output_failed_disable({ error: String(resp.error.data || m.unknown_error()) }); notifications.error(errorMsg); return; } setAudioOutputEnabled(enabled); const successMsg = enabled ? m.audio_output_enabled() : m.audio_output_disabled(); notifications.success(successMsg); }); }; const handleAudioOutputSourceChange = (source: string) => { send("setAudioOutputSource", { source }, (resp: JsonRpcResponse) => { if ("error" in resp) { const errorMsg = m.audio_settings_output_source_failed({ error: String(resp.error.data || m.unknown_error()) }); notifications.error(errorMsg); return; } setAudioOutputSource(source); notifications.success(m.audio_settings_output_source_success()); }); }; const handleAudioInputAutoEnableChange = (enabled: boolean) => { send("setAudioInputAutoEnable", { enabled }, (resp: JsonRpcResponse) => { if (handleRpcError(resp)) return; setAudioInputAutoEnable(enabled); const successMsg = enabled ? m.audio_input_auto_enable_enabled() : m.audio_input_auto_enable_disabled(); notifications.success(successMsg); }); }; const getCurrentConfig = () => ({ bitrate: audioBitrate, complexity: audioComplexity, dtxEnabled: audioDTXEnabled, fecEnabled: audioFECEnabled, bufferPeriods: audioBufferPeriods, packetLossPerc: audioPacketLossPerc, }); const handleAudioConfigChange = (updates: Partial>) => { const config = { ...getCurrentConfig(), ...updates }; send("setAudioConfig", config, (resp: JsonRpcResponse) => { if (handleRpcError(resp)) return; setAudioBitrate(config.bitrate); setAudioComplexity(config.complexity); setAudioDTXEnabled(config.dtxEnabled); setAudioFECEnabled(config.fecEnabled); setAudioBufferPeriods(config.bufferPeriods); setAudioPacketLossPerc(config.packetLossPerc); notifications.success(m.audio_settings_config_updated()); }); }; const handleRestartAudio = () => { send("restartAudioOutput", {}, (resp: JsonRpcResponse) => { if (handleRpcError(resp)) return; notifications.success(m.audio_settings_applied()); }); }; return (
handleAudioOutputEnabledChange(e.target.checked)} /> handleAudioOutputSourceChange(e.target.value)} /> handleAudioInputAutoEnableChange(e.target.checked)} /> handleAudioConfigChange({ bitrate: parseInt(e.target.value) })} /> handleAudioConfigChange({ complexity: parseInt(e.target.value) })} /> handleAudioConfigChange({ dtxEnabled: e.target.checked })} /> handleAudioConfigChange({ fecEnabled: e.target.checked })} /> handleAudioConfigChange({ bufferPeriods: parseInt(e.target.value) })} /> handleAudioConfigChange({ packetLossPerc: parseInt(e.target.value) })} />
); }