Browse Source

feat(quick-25): integrate useVideoAutoplay into 5 video nodes

- GenerateVideoNode: remove autoPlay, add ref={videoAutoplayRef}
- VideoTrimNode: add ref={videoAutoplayRef} (no autoPlay to remove)
- VideoStitchNode: remove autoPlay, add ref={videoAutoplayRef}
- EaseCurveNode: remove autoPlay, add ref={videoAutoplayRef}
- OutputNode: remove autoPlay from inline video, add ref={videoAutoplayRef}
- OutputNode lightbox video: unchanged (keeps autoPlay as intended)
handoff-20260429-1057
shrimbly 4 months ago
parent
commit
90b47991fe
  1. 4
      src/components/nodes/EaseCurveNode.tsx
  2. 4
      src/components/nodes/GenerateVideoNode.tsx
  3. 4
      src/components/nodes/OutputNode.tsx
  4. 4
      src/components/nodes/VideoStitchNode.tsx
  5. 3
      src/components/nodes/VideoTrimNode.tsx

4
src/components/nodes/EaseCurveNode.tsx

@ -7,6 +7,7 @@ import { useWorkflowStore } from "@/store/workflowStore";
import { EaseCurveNodeData } from "@/types";
import { checkEncoderSupport } from "@/hooks/useStitchVideos";
import { useVideoBlobUrl } from "@/hooks/useVideoBlobUrl";
import { useVideoAutoplay } from "@/hooks/useVideoAutoplay";
type EaseCurveNodeType = Node<EaseCurveNodeData, "easeCurve">;
@ -19,6 +20,7 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
const edges = useWorkflowStore((state) => state.edges);
const removeEdge = useWorkflowStore((state) => state.removeEdge);
const videoBlobUrl = useVideoBlobUrl(nodeData.outputVideo ?? null);
const videoAutoplayRef = useVideoAutoplay(id, selected);
// Check encoder support on mount
useEffect(() => {
@ -182,9 +184,9 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
{nodeData.outputVideo ? (
<div className="relative w-full h-full">
<video
ref={videoAutoplayRef}
src={videoBlobUrl ?? undefined}
controls
autoPlay
loop
muted
className="absolute inset-0 w-full h-full object-contain rounded-lg"

4
src/components/nodes/GenerateVideoNode.tsx

@ -13,6 +13,7 @@ import { useToast } from "@/components/Toast";
import { getVideoDimensions, calculateNodeSizePreservingHeight } from "@/utils/nodeDimensions";
import { ProviderBadge } from "./ProviderBadge";
import { useVideoBlobUrl } from "@/hooks/useVideoBlobUrl";
import { useVideoAutoplay } from "@/hooks/useVideoAutoplay";
import { getModelPageUrl, getProviderDisplayName } from "@/utils/providerUrls";
import { useInlineParameters } from "@/hooks/useInlineParameters";
import { InlineParameterPanel } from "./InlineParameterPanel";
@ -54,6 +55,7 @@ export function GenerateVideoNode({ id, data, selected }: NodeProps<GenerateVide
const [isBrowseDialogOpen, setIsBrowseDialogOpen] = useState(false);
const [isLoadingCarouselVideo, setIsLoadingCarouselVideo] = useState(false);
const videoBlobUrl = useVideoBlobUrl(nodeData.outputVideo ?? null);
const videoAutoplayRef = useVideoAutoplay(id, selected);
// Inline parameters infrastructure
const { inlineParametersEnabled } = useInlineParameters();
@ -646,10 +648,10 @@ export function GenerateVideoNode({ id, data, selected }: NodeProps<GenerateVide
{nodeData.outputVideo ? (
<>
<video
ref={videoAutoplayRef}
key={nodeData.videoHistory?.[nodeData.selectedVideoHistoryIndex || 0]?.id}
src={videoBlobUrl ?? undefined}
controls
autoPlay
loop
muted
className="w-full h-full object-cover"

4
src/components/nodes/OutputNode.tsx

@ -7,6 +7,7 @@ import { useCommentNavigation } from "@/hooks/useCommentNavigation";
import { useWorkflowStore } from "@/store/workflowStore";
import { OutputNodeData } from "@/types";
import { useVideoBlobUrl } from "@/hooks/useVideoBlobUrl";
import { useVideoAutoplay } from "@/hooks/useVideoAutoplay";
type OutputNodeType = Node<OutputNodeData, "output">;
@ -21,6 +22,7 @@ export function OutputNode({ id, data, selected }: NodeProps<OutputNodeType>) {
const isRunning = useWorkflowStore((state) => state.isRunning);
const [showLightbox, setShowLightbox] = useState(false);
const previousEdgeCountRef = useRef<number | null>(null);
const videoAutoplayRef = useVideoAutoplay(id, selected);
// Determine if content is audio
const isAudio = useMemo(() => {
@ -149,11 +151,11 @@ export function OutputNode({ id, data, selected }: NodeProps<OutputNodeType>) {
>
{isVideo ? (
<video
ref={videoAutoplayRef}
src={videoBlobUrl ?? undefined}
controls
loop
muted
autoPlay
playsInline
className="w-full h-full object-cover"
onClick={(e) => e.stopPropagation()}

4
src/components/nodes/VideoStitchNode.tsx

@ -7,6 +7,7 @@ import { useWorkflowStore } from "@/store/workflowStore";
import { VideoStitchNodeData } from "@/types";
import { checkEncoderSupport } from "@/hooks/useStitchVideos";
import { useVideoBlobUrl } from "@/hooks/useVideoBlobUrl";
import { useVideoAutoplay } from "@/hooks/useVideoAutoplay";
type VideoStitchNodeType = Node<VideoStitchNodeData, "videoStitch">;
@ -20,6 +21,7 @@ export function VideoStitchNode({ id, data, selected }: NodeProps<VideoStitchNod
const isRunning = useWorkflowStore((state) => state.isRunning);
const removeEdge = useWorkflowStore((state) => state.removeEdge);
const videoBlobUrl = useVideoBlobUrl(nodeData.outputVideo ?? null);
const videoAutoplayRef = useVideoAutoplay(id, selected);
// Check encoder support on mount
useEffect(() => {
@ -560,9 +562,9 @@ export function VideoStitchNode({ id, data, selected }: NodeProps<VideoStitchNod
{nodeData.outputVideo && nodeData.status !== "loading" && (
<div className="relative flex-1 min-h-0">
<video
ref={videoAutoplayRef}
src={videoBlobUrl ?? undefined}
controls
autoPlay
loop
muted
className="w-full h-full object-contain rounded"

3
src/components/nodes/VideoTrimNode.tsx

@ -7,6 +7,7 @@ import { useWorkflowStore } from "@/store/workflowStore";
import { VideoTrimNodeData } from "@/types";
import { checkEncoderSupport } from "@/hooks/useStitchVideos";
import { useVideoBlobUrl } from "@/hooks/useVideoBlobUrl";
import { useVideoAutoplay } from "@/hooks/useVideoAutoplay";
type VideoTrimNodeType = Node<VideoTrimNodeData, "videoTrim">;
@ -29,6 +30,7 @@ export function VideoTrimNode({ id, data, selected }: NodeProps<VideoTrimNodeTyp
// Track whether user wants to see source or output video
const [showOutput, setShowOutput] = useState(false);
const videoAutoplayRef = useVideoAutoplay(id, selected);
// Keep a ref to endTime so the metadata callback reads fresh state
const endTimeRef = useRef(nodeData.endTime);
@ -267,6 +269,7 @@ export function VideoTrimNode({ id, data, selected }: NodeProps<VideoTrimNodeTyp
<div className="flex-1 min-h-0 relative">
{previewUrl ? (
<video
ref={videoAutoplayRef}
key={previewUrl}
src={previewBlobUrl ?? undefined}
controls

Loading…
Cancel
Save