From 86e30e6ec3f1b237519a65ba5a61c4036bc4efb4 Mon Sep 17 00:00:00 2001 From: michalcourson Date: Sun, 22 Feb 2026 13:10:22 -0500 Subject: [PATCH] settings page created --- audio-service/metadata.json | 2 +- electron-ui/src/renderer/App.tsx | 45 +++++- electron-ui/src/renderer/Settings.tsx | 196 ++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 7 deletions(-) create mode 100644 electron-ui/src/renderer/Settings.tsx diff --git a/audio-service/metadata.json b/audio-service/metadata.json index f4420fd..c47f133 100644 --- a/audio-service/metadata.json +++ b/audio-service/metadata.json @@ -27,7 +27,7 @@ "name": "Clip 20260220_200442", "playbackType": "playOverlap", "startTime": 25.120307988450435, - "volume": 1 + "volume": 0.64 } ] } diff --git a/electron-ui/src/renderer/App.tsx b/electron-ui/src/renderer/App.tsx index f9cfde0..545b7f0 100644 --- a/electron-ui/src/renderer/App.tsx +++ b/electron-ui/src/renderer/App.tsx @@ -12,6 +12,8 @@ import './App.css'; import ClipList from './components/ClipList'; import { useAppDispatch, useAppSelector } from './hooks'; import { store } from '../redux/main'; +import { useNavigate } from 'react-router-dom'; +import SettingsPage from './Settings'; function MainPage() { const dispatch = useAppDispatch(); @@ -23,6 +25,7 @@ function MainPage() { ); const [newCollectionOpen, setNewCollectionOpen] = useState(false); const [newCollectionName, setNewCollectionName] = useState(''); + const navigate = useNavigate(); useEffect(() => { const fetchMetadata = async () => { @@ -139,6 +142,22 @@ function MainPage() { ))} + {/* Settings Button at Bottom Left */} +
+ +
{/* Main Content */}
@@ -168,6 +200,7 @@ export default function App() { } /> + } /> diff --git a/electron-ui/src/renderer/Settings.tsx b/electron-ui/src/renderer/Settings.tsx new file mode 100644 index 0000000..c1576ec --- /dev/null +++ b/electron-ui/src/renderer/Settings.tsx @@ -0,0 +1,196 @@ +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'; + +type AudioDevice = { + id: string; + label: string; +}; + +type Settings = { + httpPort: string; + inputDevice: AudioDevice; + outputDevice: AudioDevice; + recordingLength: number; + outputFolder: string; +}; + +const defaultSettings: Settings = { + httpPort: '', + inputDevice: { id: '', label: '' }, + outputDevice: { id: '', label: '' }, + recordingLength: 0, + outputFolder: '', +}; + +const fetchAudioDevices = async (): Promise => { + // Replace with actual backend call + // Example: return window.api.getAudioDevices(); + return [ + { id: 'default-in', label: 'Default Input' }, + { id: 'mic-1', label: 'Microphone 1' }, + { id: 'default-out', label: 'Default Output' }, + { id: 'spk-1', label: 'Speakers 1' }, + ]; +}; + +const sendSettingsToBackend = (settings: Settings) => { + // Replace with actual backend call + // Example: window.api.updateSettings(settings); + console.log('Settings updated:', settings); +}; + +export default function SettingsPage() { + const [settings, setSettings] = useState(defaultSettings); + const [inputDevices, setInputDevices] = useState([]); + const [outputDevices, setOutputDevices] = useState([]); + const navigate = useNavigate(); + + useEffect(() => { + fetchAudioDevices() + .then((devices) => { + // For demo, split devices by id + setInputDevices(devices.filter((d) => d.id.includes('in'))); + setOutputDevices(devices.filter((d) => d.id.includes('out'))); + return devices; + }) + .catch((error) => { + console.error('Error fetching audio devices:', error); + }); + }, []); + + useEffect(() => { + sendSettingsToBackend(settings); + }, [settings]); + + const handleChange = () => { + // 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: + { + setSettings((prev) => ({ ...prev, httpPort: e.target.value })); + }} + className="ml-2 text-white w-[150px]" + /> +
+
+ Input Audio Device: + +
+
+ Output Audio Device: + +
+
+ Recording Length (seconds): + { + setSettings((prev) => ({ + ...prev, + recordingLength: e.target.value, + })); + }} + className="ml-2 w-[150px]" + /> +
+
+ Clip Output Folder: +
+ + +
+
+
+
+ ); +}