198 lines
6.5 KiB
JavaScript
198 lines
6.5 KiB
JavaScript
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 = '<div class="loading">Loading settings...</div>';
|
|
|
|
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 =
|
|
'<div class="error">Failed to load settings. Check console for details.</div>';
|
|
}
|
|
}
|
|
|
|
// Функция инициализации аккордеона
|
|
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;
|
|
}
|