import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import './App.css'; import TextField from '@mui/material/TextField'; import Select from '@mui/material/Select'; import MenuItem from '@mui/material/MenuItem'; import apiFetch from './api'; type AudioDevice = { index: number; name: string; default_sample_rate: number; channels: number; }; type Settings = { http_port: number; input_device: AudioDevice; output_device: AudioDevice; recording_length: number; save_path: string; }; const defaultSettings: Settings = { http_port: 0, input_device: { index: 0, name: '', default_sample_rate: 0, channels: 0 }, output_device: { index: 0, name: '', default_sample_rate: 0, channels: 0 }, recording_length: 0, save_path: '', }; async function fetchAudioDevices( type: 'input' | 'output', ): Promise { // Replace with actual backend call // Example: return window.api.getAudioDevices(); return apiFetch(`device/list?device_type=${type}`) .then((res) => res.json()) .then((data) => data.devices as AudioDevice[]) .catch((error) => { console.error('Error fetching audio devices:', error); return []; }); } async function fetchSettings(): Promise { // Replace with actual backend call // Example: return window.api.getAudioDevices(); console.log('Fetching settings from backend...'); return apiFetch('settings') .then((res) => res.json()) .then((data) => data.settings as Settings) .catch((error) => { console.error('Error fetching settings:', error); return defaultSettings; }); } const sendSettingsToBackend = async (settings: Settings) => { // Replace with actual backend call // Example: window.api.updateSettings(settings); console.log('Settings updated:', settings); await apiFetch('settings/update', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ settings }), }) .then((res) => res.json()) .then((data) => { console.log('Settings update response:', data); if (data.status === 'success') { window.audio.restartService(); } return data; }) .catch((error) => { console.error('Error updating settings:', error); }); }; export default function SettingsPage() { const [settings, setSettings] = useState(defaultSettings); const [inputDevices, setInputDevices] = useState([]); const [outputDevices, setOutputDevices] = useState([]); const navigate = useNavigate(); useEffect(() => { fetchSettings() .then((fetchedSettings) => { console.log('Fetched settings:', fetchedSettings); setSettings(fetchedSettings); return null; }) .then(() => { return fetchAudioDevices('input'); }) .then((devices) => { setInputDevices(devices); // console.log('Input devices:', devices); return fetchAudioDevices('output'); }) .then((devices) => { setOutputDevices(devices); // console.log('Output devices:', devices); return devices; }) .catch((error) => { console.error('Error fetching audio devices:', error); }); }, []); useEffect(() => {}, [settings]); const handleChange = () => { sendSettingsToBackend(settings); // const { name, value } = e.target; // setSettings((prev) => ({ // ...prev, // [name]: value, // })); }; const handleFolderChange = async () => { // Replace with actual folder picker // Example: const folder = await window.api.selectFolder(); // const folder = window.prompt( // 'Enter output folder path:', // settings.outputFolder, // ); // if (folder !== null) { // setSettings((prev) => ({ // ...prev, // outputFolder: folder, // })); // } }; return (
{/* X Close Button */} Settings
HTTP Port: handleChange()} onChange={(e) => { if (!Number.isNaN(Number(e.target.value))) { setSettings((prev) => ({ ...prev, http_port: Number(e.target.value), })); } }} className="ml-2 text-white w-[150px]" />
Input Audio Device:
Output Audio Device:
Recording Length (seconds): { if (!Number.isNaN(Number(e.target.value))) { setSettings((prev) => ({ ...prev, recording_length: Number(e.target.value), })); } }} onBlur={() => handleChange()} className="ml-2 w-[150px]" />
Clip Output Folder:
); }