Slideshow Editor Redesign
Goal
Redesign the slideshow editor into a timeline-first workflow while keeping the current backend render pipeline (BullMQ + ffmpeg) stable.
This redesign focuses on:
- better visual sequencing for slides and clips;
- simple soundtrack preview controls (play/stop);
- customizable slideshow cover strategy;
- optional generated cover with title/subtitle and layout editor.
Current implementation status (May 2026)
- Render pipeline: slideshow MP4 export uses the dedicated BullMQ queue
gallery-slideshow(QueueNames.GALLERY_SLIDESHOW), not the genericexportsqueue. Canonical routing rules:docs/AGENTS_BACKEND.md§ BullMQ: exports queue and workers and.cursor/rules/backend-bullmq-queues.mdc. - Persistence: slideshow settings on
gallery_slideshowsinclude export quality, output format locks, audio source/presets, segment crossfade, export window, frame fit, and cover fields; values are normalized when persisting and when enqueueing render jobs so worker payloads stay consistent. - Editor: timeline-first UX (
@xzdarcy/react-timeline-editor) with hybrid editing for program slides:IMAGE,VIDEO, andGRAPHIC(Konva-style editor JSON + optional raster). Intro (opening) and ending blocks are represented on the timeline with configurable durations and layout specs (SlideshowImageLayoutSpecv2 for image layouts). - Delivery surfaces: owner preview, public gallery, and client portal gallery detail pages reuse shared presentation building blocks and the published slideshow video when a rendered asset exists.
- Data contract: source of truth for payloads is OpenAPI — see
openapi/components/galleries.yaml(GallerySlideshow,GallerySlideshowSlide,GallerySlideshowCoverMode, etc.) and generated client types. - Migrations (Liquibase):
- 0266 —
changes/0266_migrate_slideshow_covers_to_graphic_slides: legacy opening/ending cover data migrated intoGRAPHICslides where applicable (historicalstudioBookendtagging during migration). - 0267 —
changes/0267_strip_graphic_studio_bookend_tag: removes deprecatedstudioBookendkeys fromgraphic_editor_dataforGRAPHICslides. Client code also strips this key when normalizing editor payloads (scrubStudioBookendFromGraphicEditorDataingallery-editor-slideshow/shared.ts).
- 0266 —
Related docs
- GALLERIES_SHARING_PLAN.md — direct shares, basket downloads, public/portal access modes, and owner download notifications when work spans slideshow plus delivery.
- GALLERIES_LIBRARY_PLAN.md — owner gallery library and session decoupling; entry points for
/galleriesvs session tab.
Technology Decision
Chosen base: @xzdarcy/react-timeline-editor
Reference: xzdarcy/react-timeline-editor
Reasoning:
- lightweight and focused on timeline editing UX;
- easier integration with existing React screen architecture;
- lower migration risk than full “all-in-one” video editor stacks.
Deferred option: designcombo/react-video-editor
Reference: designcombo/react-video-editor
This option is intentionally deferred because it introduces a much larger editor framework (multi-track app shell, broader rendering model) than needed for the current product stage.
Player Policy
- Audio preset preview: native
<audio>controlled by one icon button (play/stop). - Render preview video: native
<video controls>for now. - No external video player dependency unless we need advanced features later (chapters, analytics, custom skins, plugins).
Cover strategy (implemented)
Slideshow poster / cover behavior is driven by coverMode on GallerySlideshow:
API value (GallerySlideshowCoverMode) | Product behavior |
|---|---|
OPENING_SHOT | Use the opening segment of the program (first timeline frame after intro handling in render). |
GENERATED | Use the generated cover path: title/subtitle, text items, optional image layers, background, overlays — edited in the cover studio and stored on the slideshow (see coverLayoutSpec, coverTextItems, coverImageLayers, etc. on GallerySlideshow). |
Note: Earlier design drafts referred to AUTO / ASSET / GENERATED as distinct enums. The shipped contract is the two-valued enum above; choosing a specific gallery still image as the only poster without the generated editor is not exposed as a separate third mode in the API.
Generated cover (requirements met in API)
- Inputs: slideshow
title/subtitle(and ending fields where relevant), text items with positioning, optional style theme / palette usage in the editor; - Output: normalized layout + optional rendered raster / storage keys depending on flow; public/owner URLs resolved where applicable (
coverImageUrl, storage-backed assets); - Layout presets and safe text regions are handled via layout spec kinds and the cover stage dimensions helpers on the frontend (
getCoverStageDimensions, etc.).
Key GallerySlideshow fields for covers (non-exhaustive)
See OpenAPI for the full schema. Important groups:
- Mode & framing:
coverMode,coverFramingMode,coverDurationSeconds,coverBackgroundColor,coverOverlayColor,coverOverlayOpacity. - Generated editor:
coverLayoutSpec,coverTextItems,coverImageLayers,coverImageZoom,coverImageOffsetX/coverImageOffsetY,coverImageSuppressed,coverEditorBackgroundImageUrl. - Ending:
endingCoverLayoutSpec,endingCoverTextItems,endingCoverTemplate, duration and brand/web fields.
Rollout plan
Phase 1 (done)
- Simplify audio preview controls to one play/stop icon button;
- replace video preview player by native
<video>.
Phase 2 (done)
- Timeline editor integrated with slide mapping;
- drag/reorder and in-place duration edits for still images;
- support for GRAPHIC program slides and hybrid organizer/studio modes.
Phase 3 (done)
- Cover mode selector aligned with API:
OPENING_SHOT|GENERATED; - generated cover editing (layout + text + layers) persisted via owner slideshow APIs;
- published poster / playback surfaces use the same presentation primitives as the owner (see sharing/public docs).
Phase 4 (continuous improvement)
- UX polish (keyboard shortcuts, snapping, micro-copy) as needed;
- automated checks: Vitest for pure layout/cover helpers (
slideshow-layout-spec,gallery-editor-slideshow/shared); - optional stack-level E2E for delivery (
frontend/e2e/gallery-slideshow-delivery.spec.ts) whenE2E_*slideshow env vars are set.
Acceptance criteria
- Editor supports quick sequencing without opening multiple panels;
- soundtrack preview is one-click play/stop;
- cover can be customized (including generated mode) without external tools;
- public gallery and client portal show the configured slideshow cover and video consistently with owner preview.