feat(export): modal tien trinh export rieng (khong dung statusbar) - dong modal settings ngay khi bam Export + bao loi that khi khong ghi duoc file
This commit is contained in:
+48
-11
@@ -12628,16 +12628,6 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4 pt-3 border-t border-slate-700 space-y-2">
|
||||
{isExporting && (
|
||||
<div className="bg-[#141414] border border-zinc-800 rounded px-2 py-1.5">
|
||||
<div className="h-1.5 bg-zinc-800 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-cyan-500 transition-all duration-200" style={{ width: (exportProgress >= 0 ? exportProgress : 25) + '%' }} />
|
||||
</div>
|
||||
<div className="text-[8px] text-zinc-500 mt-1">
|
||||
{exportProgress >= 0 ? 'Đang xuất... ' + Math.round(exportProgress) + '%' : 'Đang xử lý...'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<button onClick={onExport} disabled={isExporting}
|
||||
className="w-full py-1 bg-cyan-700 hover:bg-cyan-600 text-zinc-100 font-bold rounded text-xs flex items-center justify-center gap-1">
|
||||
@@ -12654,6 +12644,38 @@ const ExportModal = ({ open, onClose, exportSettings, setExportSettings, isExpor
|
||||
);
|
||||
};
|
||||
|
||||
// ── Export progress modal (RIÊNG, không dùng statusbar — vị trí đó cho tools) ──
|
||||
// Settings modal đóng ngay khi bấm Export; modal này hiện tiến trình render +
|
||||
// encode + ghi file, tự đóng khi xong (success/error qua toast).
|
||||
const ExportProgressModal = ({ open, exportProgress, isExporting, onClose }) => {
|
||||
if (!open) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 z-[310] bg-black/70 backdrop-blur-sm flex items-center justify-center p-6">
|
||||
<div className="w-full max-w-md bg-slate-900 border border-slate-700 rounded-2xl shadow-2xl overflow-hidden">
|
||||
<div className="h-9 bg-slate-800/80 border-b border-slate-700 flex items-center justify-between px-3 select-none">
|
||||
<span className="text-xs font-bold text-cyan-300 font-mono flex items-center gap-1.5">
|
||||
<span className="w-3 h-3 border-2 border-cyan-300 border-t-transparent rounded-full animate-spin" />
|
||||
ĐANG XUẤT ÂM THANH
|
||||
</span>
|
||||
</div>
|
||||
<div className="p-5 space-y-3">
|
||||
<div className="h-2.5 bg-zinc-800 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-cyan-500 transition-all duration-200" style={{ width: (exportProgress >= 0 ? exportProgress : 25) + '%' }} />
|
||||
</div>
|
||||
<div className="text-xs text-zinc-400 text-center">
|
||||
{exportProgress >= 0 ? 'Đang xuất... ' + Math.round(exportProgress) + '%' : 'Đang xử lý...'}
|
||||
</div>
|
||||
{!isExporting && (
|
||||
<button onClick={onClose} className="w-full py-1.5 bg-zinc-700 hover:bg-zinc-600 text-zinc-100 font-bold rounded text-xs">
|
||||
Đóng
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// --- Embedded VST GUI (PLAN_MASTERBUS_VST_GUI_EMBED.md) --------------------
|
||||
// Frame-capture + input relay: hiển thị native GUI qua HTTP /frame (~10fps),
|
||||
// gửi pointer/key về bridge qua /input. Dùng chung MasteringModal + FXRackModal.
|
||||
@@ -18100,6 +18122,7 @@ const App = () => {
|
||||
const lastTempCompileTimeRef = useRef(0);
|
||||
const nextMetronomeBeatRef = useRef(0);
|
||||
const [showExportPanel, setShowExportPanel] = useState(false);
|
||||
const [showExportProgress, setShowExportProgress] = useState(false); // modal tiến trình export RIÊNG
|
||||
React.useEffect(() => {
|
||||
if (showExportPanel) setTimeout(() => { try { window.lucide && window.lucide.createIcons(); } catch (e) { } }, 80);
|
||||
}, [showExportPanel]);
|
||||
@@ -28041,6 +28064,8 @@ const App = () => {
|
||||
if (!exportSettings.loop && allOnServer && serverStatus === 'connected') {
|
||||
// Use server-side export
|
||||
setIsExporting(true);
|
||||
setShowExportPanel(false);
|
||||
setShowExportProgress(true);
|
||||
setExportProgress(-1);
|
||||
showToast("Đang gửi yêu cầu xuất âm thanh đến máy chủ...", "info");
|
||||
try {
|
||||
@@ -28113,6 +28138,7 @@ const App = () => {
|
||||
clientSideExport(exportTracks);
|
||||
} finally {
|
||||
setIsExporting(false);
|
||||
setShowExportProgress(false);
|
||||
}
|
||||
} else {
|
||||
// Client-side export (existing working code)
|
||||
@@ -28177,6 +28203,8 @@ const App = () => {
|
||||
if (!masterBus) { showToast("Hãy phát thử một lần để khởi tạo audio engine trước.", "warning"); return; }
|
||||
if (isExporting) return;
|
||||
setIsExporting(true);
|
||||
setShowExportPanel(false);
|
||||
setShowExportProgress(true);
|
||||
const audioCtx = getAudioContext();
|
||||
try {
|
||||
const allTracks = (activeTracksRef.current && activeTracksRef.current.length) ? activeTracksRef.current : tracks;
|
||||
@@ -28275,6 +28303,7 @@ const App = () => {
|
||||
showToast("Lỗi bounce: " + err.message, "error");
|
||||
} finally {
|
||||
setIsExporting(false);
|
||||
setShowExportProgress(false);
|
||||
}
|
||||
};
|
||||
const handleSaveLocalProject = (name) => {
|
||||
@@ -28483,6 +28512,8 @@ const App = () => {
|
||||
};
|
||||
const clientSideExport = async (activeTracks, loopInfo) => {
|
||||
setIsExporting(true);
|
||||
setShowExportPanel(false);
|
||||
setShowExportProgress(true);
|
||||
setExportProgress(5);
|
||||
showToast("Đang trộn âm thanh đa kênh (Offline Mixdown)...", "info");
|
||||
// Yield 1 frame → React vẽ thanh "Đang xử lý..." trước khi graph build +
|
||||
@@ -28789,7 +28820,7 @@ const App = () => {
|
||||
if (dres && dres.saved_path) {
|
||||
showToast(`Xuất bản âm thanh hoàn tất → ${dres.saved_path}`, "success");
|
||||
} else {
|
||||
showToast("Xuất bản âm thanh hoàn tất!", "success");
|
||||
showToast("Không thể ghi file export — engine không lưu được file. Kiểm tra kết nối engine và thư mục export.", "error");
|
||||
}
|
||||
}
|
||||
// Export hoàn tất → tự đóng modal.
|
||||
@@ -28822,6 +28853,7 @@ const App = () => {
|
||||
} finally {
|
||||
setExportProgress(-1);
|
||||
setIsExporting(false);
|
||||
setShowExportProgress(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34613,6 +34645,11 @@ STRICT CONSTRAINTS:
|
||||
onNoteOn: vkbNoteOn,
|
||||
onNoteOff: vkbNoteOff,
|
||||
bpm: bpm
|
||||
}), /*#__PURE__*/React.createElement(ExportProgressModal, {
|
||||
open: showExportProgress,
|
||||
exportProgress: exportProgress,
|
||||
isExporting: isExporting,
|
||||
onClose: () => setShowExportProgress(false)
|
||||
}), /*#__PURE__*/React.createElement(ExportModal, {
|
||||
open: showExportPanel,
|
||||
onClose: () => setShowExportPanel(false),
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -51,7 +51,7 @@
|
||||
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
|
||||
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
|
||||
<script src="/static/js/services/chordTheory.js?v=202608211300"></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608240110" defer></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608231800" defer></script>
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||
<style>
|
||||
:root {
|
||||
|
||||
Reference in New Issue
Block a user