refactor: reuse director file-key segment lookup

This commit is contained in:
OpenClaw Agent
2026-07-09 15:09:50 +00:00
parent a1a4be4fc3
commit 268e543210

View File

@@ -1568,12 +1568,10 @@ class TimelineEditor {
canvas.width = w; canvas.height = h; canvas.width = w; canvas.height = h;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
for (let i = 0; i < numFrames; i++) { for (let i = 0; i < numFrames; i++) {
// Check if the file/segment is still active in the current timeline // Check if the file/segment is still active in the current timeline
const exists = this.timeline.segments.find(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) || const exists = this._getSegmentsByFileKey(fileKey).length > 0;
this.timeline.motionSegments.find(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) || if (!exists) break;
(this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey));
if (!exists) break;
const time = (i / numFrames) * duration; const time = (i / numFrames) * duration;
bgVid.currentTime = time; bgVid.currentTime = time;
@@ -1590,19 +1588,13 @@ class TimelineEditor {
img.src = canvas.toDataURL('image/jpeg', 0.5); img.src = canvas.toDataURL('image/jpeg', 0.5);
await new Promise(r => { img.onload = r; }); await new Promise(r => { img.onload = r; });
thumbs.push({ time, img }); thumbs.push({ time, img });
// Propagate the partial progress live to all active segments sharing this file // Propagate the partial progress live to all active segments sharing this file
const matchingSegs = [ const matchingSegs = this._getSegmentsByFileKey(fileKey);
...this.timeline.segments.filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey), for (const ms of matchingSegs) {
...(this.timeline.motionSegments || []).filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) ms.thumbnails = thumbs;
]; }
if (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)) {
matchingSegs.push(this.timeline.retakeVideo);
}
for (const ms of matchingSegs) {
ms.thumbnails = thumbs;
}
this.render(); this.render();
} }
@@ -1623,20 +1615,14 @@ class TimelineEditor {
this._thumbnailPromises.set(fileKey, extractPromise); this._thumbnailPromises.set(fileKey, extractPromise);
try { try {
const thumbs = await extractPromise; const thumbs = await extractPromise;
this._thumbnailCache.set(fileKey, thumbs); this._thumbnailCache.set(fileKey, thumbs);
const matchingSegs = [ const matchingSegs = this._getSegmentsByFileKey(fileKey);
...this.timeline.segments.filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey), for (const ms of matchingSegs) {
...(this.timeline.motionSegments || []).filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) ms.thumbnails = thumbs;
]; ms._extractingThumbs = false;
if (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)) {
matchingSegs.push(this.timeline.retakeVideo);
}
for (const ms of matchingSegs) {
ms.thumbnails = thumbs;
ms._extractingThumbs = false;
// If fileKey is a blob URL, and the segment now has a server file path, cache under that path too // If fileKey is a blob URL, and the segment now has a server file path, cache under that path too
if (fileKey.startsWith("blob:")) { if (fileKey.startsWith("blob:")) {
@@ -1645,19 +1631,13 @@ class TimelineEditor {
this._thumbnailCache.set(serverKey, thumbs); this._thumbnailCache.set(serverKey, thumbs);
} }
} }
} }
} catch (err) { } catch (err) {
console.error("Extraction error:", err); console.error("Extraction error:", err);
const matchingSegs = [ const matchingSegs = this._getSegmentsByFileKey(fileKey);
...this.timeline.segments.filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey), for (const ms of matchingSegs) {
...(this.timeline.motionSegments || []).filter(s => s.imageFile === fileKey || s.videoFile === fileKey || s._blobUrl === fileKey) ms._extractingThumbs = false;
]; }
if (this.timeline.retakeVideo && (this.timeline.retakeVideo.imageFile === fileKey || this.timeline.retakeVideo._blobUrl === fileKey)) {
matchingSegs.push(this.timeline.retakeVideo);
}
for (const ms of matchingSegs) {
ms._extractingThumbs = false;
}
} finally { } finally {
this._thumbnailPromises.delete(fileKey); this._thumbnailPromises.delete(fileKey);
this.render(); this.render();
@@ -1960,6 +1940,21 @@ class TimelineEditor {
return api.apiURL(`/view?filename=${encodeURIComponent(filename)}&type=input&subfolder=${encodeURIComponent(subfolder)}`); return api.apiURL(`/view?filename=${encodeURIComponent(filename)}&type=input&subfolder=${encodeURIComponent(subfolder)}`);
} }
_segmentMatchesFileKey(seg, fileKey) {
return !!seg && (seg.imageFile === fileKey || seg.videoFile === fileKey || seg._blobUrl === fileKey);
}
_getSegmentsByFileKey(fileKey) {
const matches = [
...(this.timeline.segments || []).filter(s => this._segmentMatchesFileKey(s, fileKey)),
...(this.timeline.motionSegments || []).filter(s => this._segmentMatchesFileKey(s, fileKey)),
];
if (this._segmentMatchesFileKey(this.timeline.retakeVideo, fileKey)) {
matches.push(this.timeline.retakeVideo);
}
return matches;
}
async _decodeBase64Audio(audioB64) { async _decodeBase64Audio(audioB64) {
const binaryString = window.atob(audioB64); const binaryString = window.atob(audioB64);
const len = binaryString.length; const len = binaryString.length;