import { getSettings, updateSettings, restart } from "../api.js"; export async function loadSettings() { const content = document.getElementById("content"); if (!content) { console.error("Content element not found"); return; } // Показать индикатор загрузки content.innerHTML = '
Loading settings...
'; try { const settingsHtml = await fetch("pages/settings.html").then((res) => res.text() ); content.innerHTML = settingsHtml; const allSettings = await getSettings(); // Заполнение форм fillForm("vad-form", allSettings.vad); fillForm("system-form", allSettings.system); fillForm("stt-form", allSettings.stt); fillForm("commands-form", allSettings.commands); fillForm("auth-form", allSettings.auth); fillForm("tts-form", allSettings.tts); fillForm("audio-settings-form", allSettings.audio_settings); // Инициализация аккордеона initAccordion(); // Обработчики кнопок сохранения document.querySelectorAll(".save-btn").forEach((btn) => { btn.addEventListener("click", async () => { const section = btn.dataset.section; const formId = section.replace('_', '-') + '-form'; const form = document.getElementById(formId); if (!form) { console.error(`Form ${formId} not found`); alert(`Form for ${section} not found`); return; } // Собираем данные формы вручную const formData = {}; // Обрабатываем все поля ввода form.querySelectorAll("input, select").forEach((input) => { if (input.type === "checkbox") { formData[input.name] = input.checked; } else if (input.value !== "") { formData[input.name] = input.value; } }); // Выводим данные в консоль для отладки console.log("Отправляемые данные:", formData); try { await updateSettings(section, formData); alert( `${ section.charAt(0).toUpperCase() + section.slice(1) } settings saved successfully` ); } catch (error) { console.error(`Failed to save ${section} settings:`, error); alert(`Failed to save ${section} settings`); } }); }); // Обработчик переинициализации VAD const restartBtn = document.getElementById("restart-btn"); if (restartBtn) { restartBtn.addEventListener("click", async () => { if (confirm("Are you sure you want to restart VAD?")) { try { await restart(); alert("VAD restarted successfully"); } catch (error) { console.error("Failed to restart VAD:", error); alert("Failed to restart VAD"); } } }); } } catch (error) { console.error("Error loading settings:", error); content.innerHTML = '
Failed to load settings. Check console for details.
'; } } // Функция инициализации аккордеона function initAccordion() { // Получаем все заголовки секций const sectionHeaders = document.querySelectorAll(".section-header"); // Добавляем обработчик клика для каждого заголовка sectionHeaders.forEach((header) => { header.addEventListener("click", function () { // Получаем содержимое секции const content = this.nextElementSibling; // Если секция уже активна, просто сворачиваем её if (!this.classList.contains("collapsed")) { this.classList.add("collapsed"); content.classList.remove("active"); return; } // Сворачиваем все секции document.querySelectorAll(".section-header").forEach((h) => { h.classList.add("collapsed"); h.nextElementSibling.classList.remove("active"); }); // Разворачиваем текущую секцию this.classList.remove("collapsed"); content.classList.add("active"); }); }); } function fillForm(formId, data) { const form = document.getElementById(formId); if (!form) { console.warn(`Form ${formId} not found`); return; } for (const [key, value] of Object.entries(data)) { const input = form.querySelector(`[name="${key}"]`); if (input) { if (input.type === "checkbox") { input.checked = !!value; // Приводим к булевому типу } else { input.value = value !== undefined ? value : ""; } } else { console.warn(`Input for ${key} not found in ${formId}`); } } } function processFormData(section, formData) { const data = {}; for (let [key, value] of formData) { if (value === "") continue; // Пропускаем пустые значения switch (key) { case "mode": case "sample_rate": case "frame_duration_ms": case "ring_buffer_size": case "energy_threshold": case "min_speech_duration_ms": case "max_record_duration_sec": case "target_rms": case "max_gain": case "history_maxlen": case "polling_interval_ms": case "port": case "timeout": case "playback_device": case "capture_device": case "playback_volume": case "capture_volume": data[key] = parseInt(value); break; case "speech_threshold": case "record_stop_delay_sec": case "prebuffer_duration_sec": case "noise_reduction_factor": case "noise_update_alpha": case "min_rms_threshold_factor": case "gain_smoothing_alpha": case "adaptive_energy_std_factor": case "pause_duration": case "post_stop_wait": data[key] = parseFloat(value); break; case "adaptive_energy": case "noise_reduction_enabled": case "auto_gain_enabled": case "record_on_speech": case "log_save_file": case "save_TTS_files": data[key] = value === "on"; // Checkbox возвращает 'on' при checked или 'off' при unchecked break; default: data[key] = value; } } return data; }