Browse Source

fix: auto-resize EaseCurve node on tab switch, rename handle labels to Settings

- Node height adjusts between 480px (editor) and 320px (video) on tab switch
- Default to video tab when settings are inherited from parent
- Rename "Ease In"/"Ease Out" handle labels to "Settings"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 5 months ago
parent
commit
64fb0f3c7c
  1. 41
      src/components/nodes/EaseCurveNode.tsx

41
src/components/nodes/EaseCurveNode.tsx

@ -1,7 +1,7 @@
"use client"; "use client";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Handle, Position, NodeProps, Node } from "@xyflow/react"; import { Handle, Position, NodeProps, Node, useReactFlow } from "@xyflow/react";
import { BaseNode } from "./BaseNode"; import { BaseNode } from "./BaseNode";
import { useCommentNavigation } from "@/hooks/useCommentNavigation"; import { useCommentNavigation } from "@/hooks/useCommentNavigation";
import { useWorkflowStore } from "@/store/workflowStore"; import { useWorkflowStore } from "@/store/workflowStore";
@ -44,19 +44,33 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
const isRunning = useWorkflowStore((state) => state.isRunning); const isRunning = useWorkflowStore((state) => state.isRunning);
const edges = useWorkflowStore((state) => state.edges); const edges = useWorkflowStore((state) => state.edges);
const removeEdge = useWorkflowStore((state) => state.removeEdge); const removeEdge = useWorkflowStore((state) => state.removeEdge);
const { setNodes } = useReactFlow();
const [activeTab, setActiveTab] = useState<"editor" | "video">("editor"); const [activeTab, setActiveTab] = useState<"editor" | "video">("editor");
const [showPresets, setShowPresets] = useState(false); const [showPresets, setShowPresets] = useState(false);
const presetsRef = useRef<HTMLDivElement>(null); const presetsRef = useRef<HTMLDivElement>(null);
// Auto-resize node height when switching tabs
const EDITOR_HEIGHT = 480;
const VIDEO_HEIGHT = 320;
const switchTab = useCallback((tab: "editor" | "video") => {
setActiveTab(tab);
const height = tab === "editor" ? EDITOR_HEIGHT : VIDEO_HEIGHT;
setNodes((nodes) =>
nodes.map((n) =>
n.id === id ? { ...n, style: { ...n.style, height } } : n
)
);
}, [id, setNodes]);
// Auto-switch to Video tab when processing completes // Auto-switch to Video tab when processing completes
const prevOutputRef = useRef(nodeData.outputVideo); const prevOutputRef = useRef(nodeData.outputVideo);
useEffect(() => { useEffect(() => {
if (!prevOutputRef.current && nodeData.outputVideo) { if (!prevOutputRef.current && nodeData.outputVideo) {
setActiveTab("video"); switchTab("video");
} }
prevOutputRef.current = nodeData.outputVideo; prevOutputRef.current = nodeData.outputVideo;
}, [nodeData.outputVideo]); }, [nodeData.outputVideo, switchTab]);
// Check encoder support on mount // Check encoder support on mount
useEffect(() => { useEffect(() => {
@ -145,6 +159,13 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
}, [edges, id]); }, [edges, id]);
const isInherited = inheritedEdge !== null; const isInherited = inheritedEdge !== null;
// Default to video tab when inherited
useEffect(() => {
if (isInherited) {
switchTab("video");
}
}, [isInherited, switchTab]);
const handleBreakInheritance = useCallback(() => { const handleBreakInheritance = useCallback(() => {
if (inheritedEdge) { if (inheritedEdge) {
removeEdge(inheritedEdge.id); removeEdge(inheritedEdge.id);
@ -202,7 +223,7 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
Video Out Video Out
</div> </div>
{/* Ease In (target, left, 75%) */} {/* Settings In (target, left, 75%) */}
<Handle <Handle
type="target" type="target"
position={Position.Left} position={Position.Left}
@ -215,10 +236,10 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
className="absolute text-[10px] font-medium whitespace-nowrap pointer-events-none text-right" className="absolute text-[10px] font-medium whitespace-nowrap pointer-events-none text-right"
style={{ right: "calc(100% + 8px)", top: "calc(75% - 7px)", color: "rgb(190, 242, 100)" }} style={{ right: "calc(100% + 8px)", top: "calc(75% - 7px)", color: "rgb(190, 242, 100)" }}
> >
Ease In Settings
</div> </div>
{/* Ease Out (source, right, 75%) */} {/* Settings Out (source, right, 75%) */}
<Handle <Handle
type="source" type="source"
position={Position.Right} position={Position.Right}
@ -231,7 +252,7 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
className="absolute text-[10px] font-medium whitespace-nowrap pointer-events-none" className="absolute text-[10px] font-medium whitespace-nowrap pointer-events-none"
style={{ left: "calc(100% + 8px)", top: "calc(75% - 7px)", color: "rgb(190, 242, 100)" }} style={{ left: "calc(100% + 8px)", top: "calc(75% - 7px)", color: "rgb(190, 242, 100)" }}
> >
Ease Out Settings
</div> </div>
</> </>
); );
@ -315,7 +336,7 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
hasError={nodeData.status === "error"} hasError={nodeData.status === "error"}
commentNavigation={commentNavigation ?? undefined} commentNavigation={commentNavigation ?? undefined}
minWidth={340} minWidth={340}
minHeight={480} minHeight={VIDEO_HEIGHT}
> >
{renderHandles()} {renderHandles()}
@ -328,7 +349,7 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
? "text-lime-300 border-b-2 border-lime-300" ? "text-lime-300 border-b-2 border-lime-300"
: "text-neutral-400 hover:text-neutral-300" : "text-neutral-400 hover:text-neutral-300"
}`} }`}
onClick={() => setActiveTab("editor")} onClick={() => switchTab("editor")}
> >
Editor Editor
</button> </button>
@ -338,7 +359,7 @@ export function EaseCurveNode({ id, data, selected }: NodeProps<EaseCurveNodeTyp
? "text-lime-300 border-b-2 border-lime-300" ? "text-lime-300 border-b-2 border-lime-300"
: "text-neutral-400 hover:text-neutral-300" : "text-neutral-400 hover:text-neutral-300"
}`} }`}
onClick={() => setActiveTab("video")} onClick={() => switchTab("video")}
> >
Video Video
</button> </button>

Loading…
Cancel
Save