Aller au contenu principal

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 generic exports queue. Canonical routing rules: docs/AGENTS_BACKEND.md § BullMQ: exports queue and workers and .cursor/rules/backend-bullmq-queues.mdc.
  • Persistence: slideshow settings on gallery_slideshows include 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, and GRAPHIC (Konva-style editor JSON + optional raster). Intro (opening) and ending blocks are represented on the timeline with configurable durations and layout specs (SlideshowImageLayoutSpec v2 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 into GRAPHIC slides where applicable (historical studioBookend tagging during migration).
    • 0267 — changes/0267_strip_graphic_studio_bookend_tag: removes deprecated studioBookend keys from graphic_editor_data for GRAPHIC slides. Client code also strips this key when normalizing editor payloads (scrubStudioBookendFromGraphicEditorData in gallery-editor-slideshow/shared.ts).
  • 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 /galleries vs 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_SHOTUse the opening segment of the program (first timeline frame after intro handling in render).
GENERATEDUse 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) when E2E_* 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.