Browse Source

feat(08-01): add error overlay and toast trigger to GenerateVideoNode

- Import useToast and useRef for error handling
- Add useEffect to trigger persistent toast when error occurs
- Add red error overlay visible over previous output video
- Overlay shows error icon and directs user to toast for details

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
7356fd06c8
  1. 34
      src/components/nodes/GenerateVideoNode.tsx

34
src/components/nodes/GenerateVideoNode.tsx

@ -1,6 +1,6 @@
"use client";
import React, { useCallback, useState, useEffect, useMemo } from "react";
import React, { useCallback, useState, useEffect, useMemo, useRef } from "react";
import { Handle, Position, NodeProps, Node, useReactFlow } from "@xyflow/react";
import { BaseNode } from "./BaseNode";
import { ModelParameters } from "./ModelParameters";
@ -8,6 +8,7 @@ import { useWorkflowStore } from "@/store/workflowStore";
import { GenerateVideoNodeData, ProviderType, SelectedModel, ModelInputDef } from "@/types";
import { ProviderModel, ModelCapability } from "@/lib/providers/types";
import { ModelSearchDialog } from "@/components/modals/ModelSearchDialog";
import { useToast } from "@/components/Toast";
// Video generation capabilities
const VIDEO_CAPABILITIES: ModelCapability[] = ["text-to-video", "image-to-video"];
@ -188,6 +189,17 @@ export function GenerateVideoNode({ id, data, selected }: NodeProps<GenerateVide
</button>
), []);
// Track previous status to detect error transitions
const prevStatusRef = useRef(nodeData.status);
// Show toast when error occurs
useEffect(() => {
if (nodeData.status === "error" && prevStatusRef.current !== "error" && nodeData.error) {
useToast.getState().show("Video generation failed", "error", true, nodeData.error);
}
prevStatusRef.current = nodeData.status;
}, [nodeData.status, nodeData.error]);
return (
<>
<BaseNode
@ -294,8 +306,8 @@ export function GenerateVideoNode({ id, data, selected }: NodeProps<GenerateVide
<Handle
type="source"
position={Position.Right}
id="image"
data-handletype="image"
id="video"
data-handletype="video"
/>
{/* Output label */}
<div
@ -346,6 +358,22 @@ export function GenerateVideoNode({ id, data, selected }: NodeProps<GenerateVide
</svg>
</div>
)}
{/* Error overlay when generation failed */}
{nodeData.status === "error" && (
<div className="absolute inset-0 bg-red-900/70 rounded flex flex-col items-center justify-center gap-1">
<svg
className="w-6 h-6 text-red-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span className="text-red-400 text-xs font-medium">Generation failed</span>
<span className="text-red-400/70 text-[10px]">See toast for details</span>
</div>
)}
<div className="absolute top-1 right-1">
<button
onClick={handleClearVideo}

Loading…
Cancel
Save