From 51e62a1158515aa11df664d1df66fadbea02a1df Mon Sep 17 00:00:00 2001 From: locphamtran Date: Mon, 24 Aug 2026 17:47:40 +0700 Subject: [PATCH] fix(ui): persist transport loop + panel mixer + redesign export modal (folder picker + default dir) --- app/static/js/app.jsx | 192 +++++++++++++++++++++++++------ app/static/js/app.precompiled.js | 32 ++++-- app/templates/index.html | 2 +- 3 files changed, 180 insertions(+), 46 deletions(-) diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 2cefd4f..d06dc1e 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -11784,7 +11784,10 @@ const serializeProjectToSchema = (projectId, name, bpmVal, tracksList, subTabsLi time_signature_numerator: 4, time_signature_denominator: 4, sample_rate: 44100, - zoom: window.__sfTimelineZoom || window.__currentZoom || 1.0 + zoom: window.__sfTimelineZoom || window.__currentZoom || 1.0, + loop_selection: !!window.__sfLoopSelection, + selection_start: (window.__sfLoopSelection && window.__sfSelectionStart != null) ? window.__sfSelectionStart : null, + selection_end: (window.__sfLoopSelection && window.__sfSelectionEnd != null) ? window.__sfSelectionEnd : null }, main_session: { id: "main", @@ -11969,7 +11972,10 @@ const deserializeProjectFromSchema = (schemaObj) => { masterMuted: !!(_masterBus.muted || _masterBus.mute), masterAutoVol: (_masterBus.automation && Array.isArray(_masterBus.automation.volume_db)) ? _masterBus.automation.volume_db.filter(p => p && typeof p.time === 'number' && typeof p.db === 'number') : [], masterAutoOn: !!(_masterBus.automation && Array.isArray(_masterBus.automation.volume_db) && _masterBus.automation.volume_db.length), - zoom: schemaObj.metadata && schemaObj.metadata.zoom ? parseFloat(schemaObj.metadata.zoom) : 1.0 + zoom: schemaObj.metadata && schemaObj.metadata.zoom ? parseFloat(schemaObj.metadata.zoom) : 1.0, + loopSelection: !!(schemaObj.metadata && schemaObj.metadata.loop_selection), + selectionStart: (schemaObj.metadata && schemaObj.metadata.selection_start != null) ? schemaObj.metadata.selection_start : null, + selectionEnd: (schemaObj.metadata && schemaObj.metadata.selection_end != null) ? schemaObj.metadata.selection_end : null }; }; @@ -12426,6 +12432,15 @@ const InteractiveEqPro = ({ track, params, onChange, getModule, applyTo, spectru const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExporting, onExport, onBounce, onRenderMastering }) => { if (!open) return null; + const pickDir = async () => { + try { + const r = await fetch(`${API_BASE_URL}/api/v1/plugins/pick-dir`, { method: 'POST' }); + if (r.ok) { + const d = await r.json(); + if (d && d.path) setExportSettings(p => ({ ...p, exportDir: d.path })); + } + } catch (e) { } + }; return (
e.stopPropagation()}> @@ -12436,6 +12451,38 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
+
+
+ + setExportSettings(p => ({ ...p, fileName: e.target.value }))} + placeholder="Để trống = dùng tên mặc định" + className="w-full bg-[#0d0d0d] border border-zinc-800 rounded px-1 py-0.5 text-xs text-zinc-300 focus:outline-none" /> +
+
+
+ +
+ + {exportSettings.exportDir ? ( + {exportSettings.exportDir} + ) : ( + Chưa chọn — xuất sẽ mở Save-As + )} +
+
+ +
+ +
@@ -12459,7 +12506,7 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
{exportSettings.format === 'wav' ? ( -
+
+
+ + +
) : (
@@ -12489,20 +12544,16 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
-
+
+ + +
)} -
-
- - -
-
-