fix: Media Explorer preview cập nhật realtime khi chọn file

This commit is contained in:
2026-08-02 16:48:11 +07:00
parent b075a5eca7
commit c435d00897
4 changed files with 26 additions and 9 deletions
+16 -4
View File
@@ -9051,6 +9051,7 @@ const MediaExplorerPanel = ({ height }) => {
const canvasRef = React.useRef(null);
const playStateRef = React.useRef(null);
const rafRef = React.useRef(null);
const selectTokenRef = React.useRef(0);
React.useEffect(() => {
if (window.SonicAPI && window.SonicAPI.listMyFiles) {
@@ -9084,12 +9085,15 @@ const MediaExplorerPanel = ({ height }) => {
}, [folderFiles, filterText]);
const loadWaveform = async (f) => {
const token = selectTokenRef.current;
if (f && (f.handle || f.path)) {
try {
const buf = await readLocalFileBuffer(f);
if (selectTokenRef.current !== token) return;
if (!buf) { setPeaks(null); return; }
const ctx = getAudioContext();
const decoded = await ctx.decodeAudioData(buf);
if (selectTokenRef.current !== token) return;
setAudioBuffer(decoded);
const data = decoded.getChannelData(0);
const count = 600;
@@ -9104,7 +9108,7 @@ const MediaExplorerPanel = ({ height }) => {
pk.push(m);
}
setPeaks(pk);
} catch (e) { setPeaks(null); }
} catch (e) { if (selectTokenRef.current === token) setPeaks(null); }
return;
}
const fid = f.file_id || f.fileId;
@@ -9112,6 +9116,7 @@ const MediaExplorerPanel = ({ height }) => {
try {
const resp = await fetch(`${API_BASE_URL}/api/v1/audio/waveform/${fid}?num_peaks=600`);
const data = await resp.json();
if (selectTokenRef.current !== token) return;
setPeaks(data.peaks || []);
} catch (e) { setPeaks(null); }
};
@@ -9275,7 +9280,7 @@ const MediaExplorerPanel = ({ height }) => {
setIsPaused(false);
}, []);
const playSelected = async (f) => {
const playSelected = async (f, token) => {
if (!f) return;
stopMediaPlayback();
if (isMidiFile(f)) {
@@ -9287,10 +9292,12 @@ const MediaExplorerPanel = ({ height }) => {
}
const fid = f.file_id || f.fileId;
const buf = await readLocalFileBuffer(f);
if (selectTokenRef.current !== (token || selectTokenRef.current)) return;
if (!buf) return;
try {
const ctx = getAudioContext();
const decoded = await ctx.decodeAudioData(buf);
if (selectTokenRef.current !== (token || selectTokenRef.current)) return;
setAudioBuffer(decoded);
const src = ctx.createBufferSource();
src.buffer = decoded;
@@ -9406,10 +9413,15 @@ const MediaExplorerPanel = ({ height }) => {
const handleSelect = (f) => {
if (!f || f.is_dir) return;
selectTokenRef.current++;
const token = selectTokenRef.current;
setSelected(f);
setCurrentTime(0);
if (f.kind === 'other') { stopMediaPlayback(); return; }
if (autoPlay) { playSelected(f); } else { stopMediaPlayback(); }
setPeaks(null);
setAudioBuffer(null);
stopMediaPlayback();
if (f.kind === 'other') return;
if (autoPlay) { playSelected(f, token); }
if (!isMidiFile(f) && (f.path || f.file_id || f.fileId)) loadWaveform(f);
};
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -23,7 +23,7 @@
<script src="/static/js/services/midiExtractor.js?v=202607281052"></script>
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
<script src="/static/js/app.precompiled.js?v=202608021640" defer></script>
<script src="/static/js/app.precompiled.js?v=202608021650" defer></script>
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
<style>
:root {
+5
View File
@@ -1099,3 +1099,8 @@
- **Tóm tắt thay đổi:** `MediaExplorerPanel` directory tree bỏ class `w-44` cố định → width động qua state `treeWidth` (default 176px, min 110 max 420, ref `treeWidthRef`). Thêm drag handle `w-1.5 cursor-ew-resize` bên phải tree (mousedown/mousemove/mouseup trên document, `startTreeResize`). File list bên phải tự co giãn theo `flex-1`.
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/app.precompiled.js`, `app/templates/index.html`
- **Ghi chú/Test (nếu có):** Smoke jsdom: kéo handle +80px → tree width 176→256px OK, clamp 110420. Hard reload.
### [2026-08-02 16:50] Task: Media Explorer preview không cập nhật realtime khi chọn file
- **Tóm tắt thay đổi:** `MediaExplorerPanel`: (1) `handleSelect` giờ clear ngay `setPeaks(null)` + `setAudioBuffer(null)` + `stopMediaPlayback()` khi chọn file mới → canvas xóa dữ liệu cũ ngay; (2) thêm `selectTokenRef` guard async race: `loadWaveform``playSelected` check token sau mỗi await, kết quả cũ (file trước) không ghi đè file mới chọn; (3) gọi `drawCanvas` qua effect phụ thuộc `[peaks, audioBuffer, selected]` → vẽ lại realtime.
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/app.precompiled.js`, `app/templates/index.html`
- **Ghi chú/Test (nếu có):** Smoke jsdom: click file → row selected + metadata MIDI events hiển thị; switch nhanh liên tục → file cuối đúng được chọn, không bị race. Hard reload.