fix: upload progress was rebuilding the whole media panel per tick
The previous fix (67b1324) put mediaUpload straight into the mediabrowser
zone's fingerprint, so every XHR progress tick did a full rebuild of the
media grid, thumbnails, and project list -- and closed any open <select>
in there (e.g. "Sort by"), the same class of bug just fixed in Engine
settings. Only the file boundary (which file, 1-of-how-many) is in the
fingerprint now; byte-level progress goes through a quiet
updateMediaUploadProgress + a funpack-media-upload-progress event that
mediabrowser.js uses to patch the bar/percent in place, mirroring the
existing updateGenProgress/funpack-gen-progress pattern for the player.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
1205c20255
commit
a456a856e6
@@ -17,6 +17,19 @@
|
||||
for (const id of thumbCache.keys()) if (!ids.has(id)) thumbCache.delete(id);
|
||||
}
|
||||
|
||||
// Drop-zone upload bar, patched in place on funpack-media-upload-progress (below) instead
|
||||
// of rebuilding — a full render only happens once per file, at the fpMediabrowser fingerprint
|
||||
// in view_bus.js's granularity (see mediaTab). Cleared whenever the zone isn't currently the
|
||||
// "uploading" one, so a stale reference from a since-discarded render never gets written to.
|
||||
let _uploadFillEl = null, _uploadPctEl = null;
|
||||
window.addEventListener("funpack-media-upload-progress", (e) => {
|
||||
if (!_uploadFillEl || !_uploadFillEl.isConnected) return;
|
||||
const up = (e && e.detail) || {};
|
||||
const pct = up.size > 0 ? Math.min(100, Math.round((up.loaded / up.size) * 100)) : null;
|
||||
_uploadFillEl.style.width = (pct == null ? 0 : pct) + "%";
|
||||
if (_uploadPctEl) _uploadPctEl.textContent = pct == null ? "uploading…" : `${pct}%`;
|
||||
});
|
||||
|
||||
const mediaSelected = new Set(); // media bin multi-select
|
||||
let mediaSelectMode = false; // when off, click = preview; when on, click = toggle selection
|
||||
const MF_KEY = "fp_media_filter";
|
||||
@@ -473,8 +486,13 @@
|
||||
bar.style.width = (pct == null ? 0 : pct) + "%";
|
||||
barWrap.append(bar);
|
||||
drop.append(barWrap);
|
||||
drop.append(el("div", "pj-meta", pct == null ? "uploading…" : `${pct}%`));
|
||||
const pctEl = el("div", "pj-meta", pct == null ? "uploading…" : `${pct}%`);
|
||||
drop.append(pctEl);
|
||||
// Live-patched by the funpack-media-upload-progress listener above for every tick
|
||||
// within this file — this render only happens once per file (see fpMediabrowser).
|
||||
_uploadFillEl = bar; _uploadPctEl = pctEl;
|
||||
} else {
|
||||
_uploadFillEl = null; _uploadPctEl = null;
|
||||
drop.append(el("div", "big", "🎞"));
|
||||
drop.append(el("div", null, "Drop images, video & audio here"));
|
||||
drop.append(el("div", "pj-meta", "or click to browse · drag onto a clip to set its anchor"));
|
||||
|
||||
@@ -211,6 +211,16 @@
|
||||
Object.assign(state.gen, patch);
|
||||
try { window.dispatchEvent(new CustomEvent("funpack-gen-progress", { detail: state.gen })); } catch (_) {}
|
||||
}
|
||||
|
||||
// Same idea as updateGenProgress: XHR upload progress fires many times a second, and a
|
||||
// full notify() would rebuild the whole media bin (thumbnails, project list, any open
|
||||
// <select>) on every tick. Mutate quietly and let mediabrowser.js patch its own bar/percent
|
||||
// in place instead.
|
||||
function updateMediaUploadProgress(patch) {
|
||||
if (!state.mediaUpload) return;
|
||||
Object.assign(state.mediaUpload, patch);
|
||||
try { window.dispatchEvent(new CustomEvent("funpack-media-upload-progress", { detail: state.mediaUpload })); } catch (_) {}
|
||||
}
|
||||
function get() { return state; }
|
||||
|
||||
function _promptPreviewKey(project) {
|
||||
@@ -4427,19 +4437,15 @@
|
||||
// uploading over a slow connection just looked like nothing was happening.
|
||||
async function uploadMedia(files) {
|
||||
const list = [...files];
|
||||
let lastNotify = 0;
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const f = list[i];
|
||||
// A full notify() here (once per file) is what builds the "uploading" drop zone in the
|
||||
// first place -- see fpMediabrowser in view_bus.js. Progress WITHIN a file goes through
|
||||
// updateMediaUploadProgress instead, which never touches the store's subscribers.
|
||||
set({ mediaUpload: { current: i + 1, total: list.length, name: f.name, loaded: 0, size: f.size } });
|
||||
lastNotify = Date.now();
|
||||
try {
|
||||
await API.uploadMedia(f, (loaded, total) => {
|
||||
state.mediaUpload = { ...state.mediaUpload, loaded, size: total || f.size };
|
||||
// XHR fires this many times a second -- notify() rebuilds the whole media grid,
|
||||
// so this throttles to a still-smooth ~8fps instead of hammering a full re-render
|
||||
// on every tick. The final `loaded === total` (upload done) always gets through.
|
||||
const now = Date.now();
|
||||
if (now - lastNotify >= 120 || loaded >= total) { lastNotify = now; notify(); }
|
||||
updateMediaUploadProgress({ loaded, size: total || f.size });
|
||||
});
|
||||
} catch (e) { console.error("upload failed", e); }
|
||||
}
|
||||
|
||||
@@ -176,10 +176,15 @@
|
||||
projects: st.projects?.length,
|
||||
media: st.mediaBin?.length,
|
||||
mediaPreview: st.mediaPreviewId,
|
||||
// The upload progress bar/percent live in this zone and change on every XHR
|
||||
// progress tick without touching mediaBin's length -- without this the drop
|
||||
// zone never repaints and looks stale for the whole upload.
|
||||
upload: st.mediaUpload,
|
||||
// Only the file boundary (which file, 1-of-how-many) belongs in the fingerprint --
|
||||
// that's rare enough to justify a full rebuild, which is what creates the "uploading"
|
||||
// drop zone in the first place. `loaded` ticks many times a second and is deliberately
|
||||
// left out: a full rebuild on every tick would tear down and rebuild the whole bin
|
||||
// (thumbs, project list, any open <select> like "Sort by"). See the
|
||||
// funpack-media-upload-progress listener in mediabrowser.js, which patches the drop
|
||||
// zone's bar/percent in place instead, the same way funpack-gen-progress does for the
|
||||
// player's readout.
|
||||
upload: st.mediaUpload ? `${st.mediaUpload.current}/${st.mediaUpload.total}:${st.mediaUpload.name}` : null,
|
||||
// Continuity pin renders on gallery cards (📌 button state + thumb badge).
|
||||
pin: st.project?.continuity_settings?.identity_pin_ref,
|
||||
// Reference marks render the same way (R button + numbered badge), and their ORDER
|
||||
|
||||
Reference in New Issue
Block a user