fix: reuse video preview widgets to support Vue Nodes 2.0 mode
- SaveVideo/PreviewVideo: reuse existing video-preview widgets instead of removing and recreating them on each execution, preventing WidgetDOM from losing its mounted element reference in VueNodes mode - UploadVideo: remove duplicate updateVideoWidget call in handleVideoUpload that caused parallel fetch/decrypt race on the same widget element
This commit is contained in:
+2
-1
@@ -114,4 +114,5 @@ yarn-error.log*
|
||||
node.zip
|
||||
.vscode/
|
||||
.claude/
|
||||
.*/
|
||||
.*/
|
||||
opencode.json
|
||||
+35
-20
@@ -55,38 +55,53 @@ app.registerExtension({
|
||||
if (message?.cryptio_images) {
|
||||
const autoDownload = this.widgets.find((n: any) => n.name === "auto_download")?.value;
|
||||
|
||||
// Remove existing video preview widgets
|
||||
// Get existing video preview widgets (reuse them to avoid re-mount in VueNodes mode)
|
||||
const existingWidgets = this.widgets.filter((w: any) =>
|
||||
w.type === "video-preview"
|
||||
);
|
||||
for (const widget of existingWidgets) {
|
||||
clearVideoWidget(widget);
|
||||
this.removeWidget(widget);
|
||||
|
||||
// Remove excess widgets if fewer videos than existing widgets
|
||||
for (let i = message.cryptio_images.length; i < existingWidgets.length; i++) {
|
||||
clearVideoWidget(existingWidgets[i]);
|
||||
this.removeWidget(existingWidgets[i]);
|
||||
}
|
||||
|
||||
// Create widgets and decrypt videos in parallel
|
||||
// Reuse existing widgets or create new ones as needed
|
||||
const updatePromises: Promise<void>[] = [];
|
||||
for (let i = 0; i < message.cryptio_images.length; i++) {
|
||||
const videoInfo = message.cryptio_images[i];
|
||||
if (videoInfo.filename && videoInfo.filename.endsWith(".encrypted")) {
|
||||
const widget = createVideoWidget(this, {
|
||||
if (!videoInfo.filename || !videoInfo.filename.endsWith(".encrypted")) continue;
|
||||
|
||||
let widget = existingWidgets[i];
|
||||
if (widget) {
|
||||
// Clean up previous video content before reusing the widget
|
||||
if (widget.videoElement) {
|
||||
widget.videoElement.pause();
|
||||
widget.videoElement.src = "";
|
||||
}
|
||||
if (widget.videoUrl) {
|
||||
URL.revokeObjectURL(widget.videoUrl);
|
||||
}
|
||||
widget.videoInfo = videoInfo;
|
||||
widget.value = { ...widget.value, videoInfo };
|
||||
} else {
|
||||
widget = createVideoWidget(this, {
|
||||
widgetName: `video_${i}`,
|
||||
videoInfo,
|
||||
});
|
||||
|
||||
updatePromises.push(
|
||||
updateVideoWidget(widget, videoInfo)
|
||||
.then((videoUrl) => {
|
||||
if (autoDownload) {
|
||||
downloadDecryptedVideo(videoUrl, videoInfo.filename);
|
||||
console.log(`Auto-downloaded decrypted video: ${videoInfo.filename.replace(/\.encrypted$/, "")}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed to load video:", error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
updatePromises.push(
|
||||
updateVideoWidget(widget, videoInfo)
|
||||
.then((videoUrl) => {
|
||||
if (autoDownload) {
|
||||
downloadDecryptedVideo(videoUrl, videoInfo.filename);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed to load video:", error);
|
||||
})
|
||||
);
|
||||
}
|
||||
await Promise.allSettled(updatePromises);
|
||||
}
|
||||
|
||||
@@ -48,21 +48,13 @@ async function handleVideoUpload(node: CryptIONode, file: File, app: CryptIOApp)
|
||||
// Upload encrypted video
|
||||
const result = await uploadEncryptedFile(file);
|
||||
|
||||
// Update video widget value
|
||||
// Update video widget value (callback handles preview update)
|
||||
const videoWidget = node.widgets.find(
|
||||
(w: any) => w.name === "video"
|
||||
);
|
||||
if (videoWidget) {
|
||||
videoWidget.value = result.name;
|
||||
videoWidget.callback?.call(videoWidget, result.name);
|
||||
}
|
||||
|
||||
// Update preview
|
||||
const previewWidget = node.widgets.find(
|
||||
(w: any) => w.type === "video-preview"
|
||||
) as VideoPreviewWidget;
|
||||
if (previewWidget) {
|
||||
await updateVideoWidget(previewWidget, result.name);
|
||||
await videoWidget.callback?.call(videoWidget, result.name);
|
||||
}
|
||||
|
||||
if (app.rootGraph) {
|
||||
|
||||
Reference in New Issue
Block a user