Video handles/edges/labels were inconsistent — using white, green, blue,
and hardcoded purple across different files. Standardize all to pink and
use the CSS variable var(--handle-color-video) for labels. Also adds the
missing .react-flow__handle[data-handletype="video"] CSS rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update all 18 node files to use the centralized HandleLabel component.
Labels now fade in/out with a 150ms opacity transition instead of
mounting/unmounting (pop-in). ~430 lines removed across 18 files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add useShowHandleLabels hook that combines node selection state with
React Flow's useConnection to show handle labels only when relevant,
reducing visual clutter on the canvas.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflicts in 4 executor files by combining develop's
runWithFallback structure with feature branch's client-side polling.
Both capabilities are now integrated: executors use runWithFallback
for model redundancy, and pollGenerateTask for long-running Kie tasks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- OutputGalleryNode: add aria-label to gallery tile buttons so screen
readers can identify video tiles (images already had alt via
AdaptiveGalleryThumbnail)
- OutputGalleryNode: add nodeData.imageRefs and nodeData.videoRefs to
removeMedia dependency array so splice operates on current refs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- OutputGalleryNode: splice imageRefs/videoRefs alongside images/videos
in removeMedia to keep arrays in lockstep
- TutorialOverlay: track and clean up actionCompleted advance timeout
via advanceTimeoutRef to prevent stale nextTutorialStep after skip
- TutorialOverlay: track and clean up populate-content nested timeouts
via populateTimeoutIds ref to prevent post-teardown state mutations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- OutputGalleryNode: replace hardcoded .png/.mp4 download with shared
downloadMedia utility for correct MIME-based extensions
- OutputNode: wrap downloadMedia call in try/catch to prevent unhandled
rejection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Restore FTUX production logic (remove testing override)
- Fix generate3dExecutor clearOutput field and add modelId validation
- Remap startLevel index after loop partitioning in executeWorkflow
- Add missing mockTutorialExecution dep in FloatingActionBar
- Reset settingsTab to "primary" when fallbackModel is removed
- Clear orphaned fallbackParameters when removing fallback model
- Fix OutputGalleryNode removeMedia to splice single item, not all duplicates
- Add data-tutorial="save-button" to untitled save button in Header
- Move data-tutorial to layout-producing element in BaseNode
- Hydrate FTUXApiKeysStep localKeys from providerSettings
- Remove broken docs URL from ftuxStore tutorial steps
- Add error handling in loadTutorialSampleImage
- Fix mediaStorage ref array misalignment in outputGallery hydration
- Make OutputGalleryNodeData.videos optional to match usage
- Remove unused fitView destructuring from WorkflowCanvas
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The video stitch node was only copying video tracks from source clips,
silently discarding any embedded audio. Now extracts and concatenates
audio from source videos when no external audio node is connected.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds a toolbar button that extracts all gallery items (images and videos) into
individual input nodes, stacked vertically to the right of the gallery node.
New nodes are auto-selected for easy repositioning.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Renders low-resolution JPEG thumbnails (256px, q=0.6) in nodes when
zoomed out (effective width < 300px), swapping to full resolution when
zoomed in. Thumbnails are generated eagerly and cached in memory.
- New utility: imageThumbnail.ts (offscreen canvas downscaling)
- New cache: thumbnailCache.ts (ephemeral Map-based cache)
- New hook: useAdaptiveImageSrc (zoom-aware src selector)
- Integrated into all image-bearing nodes (GenerateImage, ImageInput,
Output, Annotation, SplitGrid, VideoFrameGrab, OutputGallery, GLBViewer)
- Lightbox/modal views always use full resolution
https://claude.ai/code/session_01MvD1n4QeXutgwUpKJuDGHa
- Create OutputGalleryNode.tsx with BaseNode wrapper
- Single image input handle (type target, id image)
- Real-time image collection from connected nodes (imageInput, annotation, nanoBanana)
- 3-column scrollable thumbnail grid with nowheel for scroll isolation
- Full-screen lightbox via createPortal with:
- Left/right arrow navigation
- Download button (saves as gallery-image-N.png)
- Close button (X icon, top-right)
- Click backdrop to close
- Keyboard support (Escape, ArrowLeft, ArrowRight)
- Image counter display (N / Total)
- Empty state placeholder when no images connected
- Fix validation.ts: add outputGallery dimensions and createDefaultNodeData case
- Build passes with zero errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>