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