feat(editor): thumbnail images in media panel; Del=ripple, Shift+Del=lift

This commit is contained in:
Zac Gaetano 2026-05-19 23:56:23 -04:00
parent 090452969c
commit 1e9710ce0c

View file

@ -183,6 +183,30 @@
}
.media-asset-item.active .media-asset-meta { color: var(--accent); opacity: 0.7; }
/* ── Thumbnail wrapper in media panel ──────────────────────── */
.media-thumb-wrap {
width: 48px;
height: 30px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-surface);
border-radius: 2px;
overflow: hidden;
}
.media-thumb {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.media-thumb-icon {
display: none;
color: var(--text-tertiary);
margin-top: 0;
}
/* ── Timeline panel ────────────────────────────────────────── */
.timeline-panel {
grid-area: timeline-panel;
@ -394,6 +418,14 @@
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="6" cy="10" r="3.5"/><path d="M8.7 7.3L13 3M11.5 3.5l1.5 1.5M13.5 2.5l1 1"/></svg>
Tokens
</a>
<a href="containers.html" class="nav-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="1" y="5" width="14" height="9" rx="1"/><path d="M1 5l2-3h10l2 3"/><line x1="5" y1="5" x2="5" y2="14"/><line x1="11" y1="5" x2="11" y2="14"/></svg>
Containers
</a>
<a href="cluster.html" class="nav-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="8" cy="3" r="2"/><circle cx="3" cy="13" r="2"/><circle cx="13" cy="13" r="2"/><line x1="8" y1="5" x2="8" y2="9"/><line x1="8" y1="9" x2="3" y2="11"/><line x1="8" y1="9" x2="13" y2="11"/></svg>
Cluster
</a>
</nav>
<div class="sidebar-footer">
@ -564,6 +596,8 @@
<div class="kbd-row"><kbd>Ctrl+Z</kbd><span>Undo</span></div>
<div class="kbd-row"><kbd>Ctrl+&#8679;+Z</kbd><span>Redo</span></div>
<div class="kbd-row"><kbd>Ctrl+S</kbd><span>Save</span></div>
<div class="kbd-row"><kbd>Del</kbd><span>Ripple delete</span></div>
<div class="kbd-row"><kbd>&#8679;+Del</kbd><span>Extract (lift)</span></div>
<div class="kbd-row"><kbd>?</kbd><span>This help</span></div>
</div>
</div>
@ -738,7 +772,7 @@ function renderMediaList() {
if (assets.length === 0) {
list.innerHTML = '<div style="padding:var(--sp-4) var(--sp-3);font-size:var(--text-xs);color:var(--text-tertiary);">' +
(query ? 'No clips match "' + esc(query) + '"' : 'No assets in this bin.') + '</div>';
(query ? 'No clips match &ldquo;' + esc(query) + '&rdquo;' : 'No assets in this bin.') + '</div>';
return;
}
@ -754,11 +788,17 @@ function renderMediaList() {
].filter(Boolean);
const metaStr = metaParts.join(' · ');
// Thumbnail wrapper: img with SVG fallback for assets without a thumbnail yet
el.innerHTML =
'<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.3" width="12" height="12">' +
'<rect x="1" y="3" width="8" height="8" rx="1"/>' +
'<path d="M9 6l4-2v6l-4-2"/>' +
'</svg>' +
'<div class="media-thumb-wrap">' +
'<img class="media-thumb" src="/api/v1/assets/' + esc(asset.id) + '/thumbnail?redirect=1" ' +
'alt="" loading="lazy" ' +
'onerror="this.style.display=\'none\';this.nextElementSibling.style.display=\'block\'">' +
'<svg class="media-thumb-icon" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.3" width="12" height="12">' +
'<rect x="1" y="3" width="8" height="8" rx="1"/>' +
'<path d="M9 6l4-2v6l-4-2"/>' +
'</svg>' +
'</div>' +
'<div class="media-asset-info">' +
'<span class="media-asset-name" title="' + esc(asset.display_name || asset.filename) + '">' +
esc(asset.display_name || asset.filename) +