diff --git a/frontend-react/src/App.jsx b/frontend-react/src/App.jsx index 35b4556..cd35121 100644 --- a/frontend-react/src/App.jsx +++ b/frontend-react/src/App.jsx @@ -20,15 +20,31 @@ const T = { const API = window.location.origin; const WS_URL = API.replace(/^http/, 'ws') + '/ws'; +// ── Channel state (module-level, synced from localStorage) ───── +let _channel = 'guitar'; +try { + const saved = localStorage.getItem('pedal_channel'); + if (saved === 'guitar' || saved === 'bass') _channel = saved; +} catch {} + +export function getChannel() { return _channel; } +export function setChannel(ch) { _channel = ch; } + +function _ch(url) { + const c = _channel; + if (!c) return url; + return url + (url.includes('?') ? '&' : '?') + 'channel=' + encodeURIComponent(c); +} + // ── API helpers ──────────────────────────────────────────────── async function apiGet(path) { - const r = await fetch(`${API}${path}`); + const r = await fetch(`${API}${_ch(path)}`); if (!r.ok) throw new Error(`${path} => ${r.status}`); return r.json(); } async function apiPost(path, data) { - const r = await fetch(`${API}${path}`, { + const r = await fetch(`${API}${_ch(path)}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: data != null ? JSON.stringify(data) : undefined, }); @@ -37,7 +53,7 @@ async function apiPost(path, data) { } async function apiPut(path, data) { - const r = await fetch(`${API}${path}`, { + const r = await fetch(`${API}${_ch(path)}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); @@ -46,7 +62,7 @@ async function apiPut(path, data) { } async function apiDelete(path) { - const r = await fetch(`${API}${path}`, { method: 'DELETE' }); + const r = await fetch(`${API}${_ch(path)}`, { method: 'DELETE' }); if (!r.ok) throw new Error(`${path} => ${r.status}`); return r.json(); } @@ -54,7 +70,7 @@ async function apiDelete(path) { async function apiUpload(path, file) { const fd = new FormData(); fd.append('file', file); - const r = await fetch(`${API}${path}`, { method: 'POST', body: fd }); + const r = await fetch(`${API}${_ch(path)}`, { method: 'POST', body: fd }); if (!r.ok) throw new Error(`${path} => ${r.status}`); return r.json(); } @@ -86,6 +102,7 @@ function usePedalState() { if (msg.type === 'bypass_changed') setState(prev => prev ? { ...prev, bypass: msg.bypass } : prev); if (msg.type === 'tuner_changed') setState(prev => prev ? { ...prev, tuner_enabled: msg.tuner_enabled } : prev); if (msg.type === 'routing_changed') setState(prev => prev ? { ...prev, routing_mode: msg.routing_mode, routing_breakpoint: msg.routing_breakpoint } : prev); + if (msg.type === 'channel_mode_changed') setState(prev => prev ? { ...prev, channel_mode: msg.channel_mode } : prev); if (msg.type === 'model_loaded' || msg.type === 'ir_loaded') { apiGet('/api/state').then(s => setState(s)); } @@ -1285,11 +1302,13 @@ function SettingsScreen({ state, connected, refresh }) { const [showConnect, setShowConnect] = useState(null); const [routingMode, setRoutingMode] = useState(state?.routing_mode || 'mono'); const [routingBp, setRoutingBp] = useState(state?.routing_breakpoint || 7); + const [channelMode, setChannelMode] = useState(state?.channel_mode || 'dual-mono'); useEffect(() => { if (state?.routing_mode) setRoutingMode(state.routing_mode); if (state?.routing_breakpoint != null) setRoutingBp(state.routing_breakpoint); - }, [state?.routing_mode, state?.routing_breakpoint]); + if (state?.channel_mode) setChannelMode(state.channel_mode); + }, [state?.routing_mode, state?.routing_breakpoint, state?.channel_mode]); const scanWifi = async () => { setWifiScanning(true); @@ -1351,6 +1370,13 @@ function SettingsScreen({ state, connected, refresh }) { try { await apiPost('/api/routing', { routing_mode: mode, routing_breakpoint: bp }); } catch (e) { /* ignore */ } }; + const handleChannelMode = async (mode) => { + try { + await apiPost('/api/channel-mode', { channel_mode: mode }); + setChannelMode(mode); + } catch (e) { /* ignore */ } + }; + useEffect(() => { if (connected) { scanWifi(); loadBtPaired(); } }, [connected]); const wifiState = state?.wifi; @@ -1521,6 +1547,7 @@ function SettingsScreen({ state, connected, refresh }) { {/* ── Routing Tab ───────────────────────────────────────────*/} {tab === 'routing' && ( + <>