fix: media bin thumbnails no longer reload on every reference toggle
The panel rebuilds its whole DOM on any relevant store change, including marking/unmarking a reference -- which only actually changes one card's badge. That recreated every <img>/<video> thumb from scratch each time, so every preview visibly reloaded and every video redecoded its first frame for an unrelated single-item toggle. Cache the built preview node per media id and re-append (move, not recreate) it across rebuilds instead. Verified live: toggling a reference mark on/off now leaves the same DOM node instances in place. Adversarially reviewed; holds up. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
59f91a9e24
commit
063fa5a55b
@@ -6,6 +6,17 @@
|
||||
const API = window.MovieEditorAPI;
|
||||
const body = document.getElementById("media-body");
|
||||
|
||||
// Every store change that touches this panel (e.g. toggling a reference mark) rebuilds
|
||||
// the whole grid from scratch — cheap for the buttons/badges, but a fresh <img>/<video>
|
||||
// per card meant every thumbnail visibly reloaded and every video re-decoded its first
|
||||
// frame, just because an unrelated R button was clicked. Cache the already-built preview
|
||||
// node per media id and re-append (move, not recreate) it into the new card instead.
|
||||
const thumbCache = new Map(); // media id -> {url, node}
|
||||
function _pruneThumbCache(bin) {
|
||||
const ids = new Set(bin.map((m) => m.id));
|
||||
for (const id of thumbCache.keys()) if (!ids.has(id)) thumbCache.delete(id);
|
||||
}
|
||||
|
||||
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";
|
||||
@@ -83,6 +94,8 @@
|
||||
|
||||
function _appendMediaThumb(thumb, m) {
|
||||
const url = API.mediaUrl(m.id);
|
||||
const cached = thumbCache.get(m.id);
|
||||
if (cached && cached.url === url) { thumb.append(cached.node); return; }
|
||||
if (m.kind === "image") {
|
||||
const img = el("img");
|
||||
img.src = url;
|
||||
@@ -93,6 +106,7 @@
|
||||
// decode and rasterize the full-size bitmap first, which is why big images felt like
|
||||
// they "resisted" dragging. Opting the image out hands the drag back to the card.
|
||||
img.draggable = false;
|
||||
thumbCache.set(m.id, { url, node: img });
|
||||
thumb.append(img);
|
||||
return;
|
||||
}
|
||||
@@ -120,6 +134,7 @@
|
||||
canvas.getContext("2d").drawImage(vid, 0, 0, canvas.width, canvas.height);
|
||||
ph.remove();
|
||||
thumb.append(canvas);
|
||||
thumbCache.set(m.id, { url, node: canvas });
|
||||
} catch (_) {}
|
||||
}
|
||||
release();
|
||||
@@ -434,6 +449,7 @@
|
||||
function mediaTab(st) {
|
||||
const bin = st.mediaBin || [];
|
||||
_pruneMediaSelection(bin);
|
||||
_pruneThumbCache(bin);
|
||||
const total = bin.length;
|
||||
const items = _sortMediaBin(_filterMediaBin(bin));
|
||||
const shown = items.length;
|
||||
|
||||
Reference in New Issue
Block a user