fix(gui): embed VST GUI show on mount, health-check timeout/retry, send preset in fx chain (issues 1/3/4)

This commit is contained in:
2026-08-19 10:56:22 +07:00
parent 466b2022f2
commit 77360578fd
2 changed files with 34 additions and 11 deletions
+26 -6
View File
@@ -11920,6 +11920,10 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
if (!deadRef.current) { deadRef.current = true; setDead(true); onDead && onDead(); }
});
}, 2000);
// Show immediately on mount even before the rect is known: bridge
// re-shows the native window at its last position, and the ~500ms
// rect refresh below re-anchors it over the panel.
try { fetch(url + '/show', { method: 'POST' }).catch(() => {}); } catch (e) {}
return () => {
clearInterval(tick); clearInterval(ping);
// Panel closed -> hide the native window (bridge stays alive so
@@ -11955,7 +11959,12 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
const rb = boxRef.current.getBoundingClientRect();
screenRectRef.current = { x: Math.round(pos.x + rb.left * sf), y: Math.round(pos.y + rb.top * sf), w: Math.round(rb.width * sf), h: Math.round(rb.height * sf) };
maybeShow();
}).catch(() => {});
}).catch(() => {
if (!alive || !boxRef.current) return;
const rb = boxRef.current.getBoundingClientRect();
screenRectRef.current = { x: Math.round((window.screenX || 0) + rb.left), y: Math.round((window.screenY || 0) + rb.top), w: Math.round(rb.width), h: Math.round(rb.height) };
maybeShow();
});
} else {
screenRectRef.current = { x: Math.round((window.screenX || 0) + r.left), y: Math.round((window.screenY || 0) + r.top), w: Math.round(r.width), h: Math.round(r.height) };
maybeShow();
@@ -12663,7 +12672,7 @@ const MasteringModal = ({ isOpen, onClose, masteringSettings, setMasteringSettin
// mix). v1: master chain only — per-track vstChain stays offline (defer).
React.useEffect(() => {
if (!window.NativeBridgeService || !window.NativeBridgeService.setFxChain) return;
const chain = (ozState.vstFxChain || []).map(s => ({ path: s.path || '', bypass: !!s.bypass }));
const chain = (ozState.vstFxChain || []).map(s => ({ path: s.path || '', bypass: !!s.bypass, preset_b64: s.preset_b64 || '' }));
window.NativeBridgeService.setFxChain(JSON.stringify(chain));
}, [ozState.vstFxChain]);
const toggleMasterVst = (idx) => setMasterVstChain(masterVstChain.map((s, i) => i === idx ? { ...s, bypass: !s.bypass } : s));
@@ -21363,9 +21372,20 @@ const App = () => {
return () => observer.disconnect();
}, [timelineWrapperNode]);
useEffect(() => {
fetch(API_BASE_URL).then(r => {
if (r.ok) setServerStatus('connected'); else setServerStatus('error');
}).catch(() => setServerStatus('offline'));
let cancelled = false, busy = false, iv = null;
const check = () => {
if (busy || cancelled) return;
busy = true;
const ctl = new AbortController();
const t = setTimeout(() => ctl.abort(), 3000);
fetch(API_BASE_URL, { signal: ctl.signal })
.then(r => { if (!cancelled) setServerStatus(r.ok ? 'connected' : 'error'); })
.catch(() => { if (!cancelled) setServerStatus('offline'); })
.finally(() => { busy = false; clearTimeout(t); });
};
check();
iv = setInterval(() => { if (!cancelled) check(); }, 3000);
return () => { cancelled = true; if (iv) clearInterval(iv); };
}, []);
// ── Computed Values ──
@@ -29413,7 +29433,7 @@ STRICT CONSTRAINTS:
}), /*#__PURE__*/React.createElement("div", {
className: "flex items-center gap-2 px-2"
}, /*#__PURE__*/React.createElement("span", {
className: `text-xs font-bold uppercase px-1.5 py-0.5 rounded ${serverStatus === 'connected' ? 'bg-emerald-950 text-emerald-400' : serverStatus === 'checking' ? 'bg-amber-950 text-amber-400' : 'bg-red-950 text-red-400'}`
className: `text-xs font-bold uppercase px-1.5 py-0.5 rounded ${serverStatus === 'connected' ? 'bg-emerald-950 text-emerald-400' : serverStatus === 'checking...' ? 'bg-amber-950 text-amber-400' : 'bg-red-950 text-red-400'}`
}, "Server: ", serverStatus, serverAddr ? " · " + serverAddr : ""), /*#__PURE__*/React.createElement("button", {
onClick: () => setShowAIConfig(!showAIConfig),
className: `px-1.5 py-0.5 rounded text-xs border transition ${showAIConfig ? 'bg-purple-900 text-purple-200 border-purple-700' : 'bg-zinc-800 text-zinc-400 border-zinc-700 hover:text-zinc-200'}`
File diff suppressed because one or more lines are too long