feat: Image and Editable slides side by side #98
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "development_pptx_mockup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Brings the image (PNG) slide-generation pipeline back alongside the new
HTML (Editable) pipeline so both coexist — the user picks a style when
creating a deck and can switch it per slide or for the whole deck. The two
pipelines live side by side; generation dispatches to the right one by each
slide's resolved render mode.
User-facing names: Image (AI-rendered picture) and Editable (WYSIWYG
HTML). Internally
RenderMode { Image, Html }.Highlights
hashing.rs): per-sliderender_modeoverride + per-deckdefault_render_mode(defaults toHtml, so existing decks are unchanged —guarded by a backward-compat test).
resolve_render_mode()resolves slide → deck default.generator.rs,deck.rs):generate_slide/fix_slide_image,slide_generate_image/deck_generate_image, spell-check.slide_generate_auto/deck_generate_autoroute each slide tothe image or HTML pipeline by mode (mixed decks supported, parallel with a
shared metadata lock). CLI
generate slide|deckauto-dispatch; server submitsthese mode-agnostically.
slide.generateAsync/deck.generateAsyncadded;the
*Html*RPC names kept as aliases..png/.html/.mdperslide. Restoring a version now syncs the slide's mode to the restored artifact;
the UI warns when rolling back to a different style.
PPTX wraps image slides as a full-bleed picture through the same dom-to-pptx path.
switch, restored image/thumbnail routes, image thumbnails in the grid, and the
rollback warning.
slide_generate/deck_generate/*_set_render_modebindings.Also includes a preceding commit: single image-slot regeneration from the WYSIWYG editor.
Backward compatibility
Existing decks (metadata without the new keys) resolve to Editable exactly as
before. Render mode is deliberately excluded from the staleness input hash;
mode-change setters clear generation markers so a flipped slide re-renders.
Testing
cargo test -p hero_slides_lib— 111 pass, incl.test_render_mode_backward_compat.lab build --release --restart; services running, newadmin JS served, RPC dispatch verified.
🤖 Generated with Claude Code
Adds a parallel HTML generation path alongside the existing PNG pipeline: - generator.rs: generate_slide_html() — calls text model, returns a self-contained 1920×1080 HTML document with inline CSS and image-slot placeholder divs (data-image-slot="true") for visual regions - deck.rs: slide_generate_html() and deck_generate_html() public API - CLI: hero_slides generate html <collection/deck> [--force] - Server: deck.generateHtmlAsync / JobLogs / JobStatus RPC methods backed by the new GenerateHtml job kind - Routes: GET /api/.../slides/{slide}/html serves the HTML file - RPC slide.list: has_html field alongside existing has_png - present.html: viewer now renders HTML slides in a scaled <iframe> (1920×1080 with CSS transform scale-to-fit); falls back to PNG when only that exists; both formats coexist per-slide Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>Replaces the broken per-slide export + hand-rolled zip merge with a single exportToPptx([...]) call over all slides at once, letting PptxGenJS generate a well-formed multi-slide PPTX natively. The merge had three bugs that caused PowerPoint's repair dialog: - patch_content_types used line-by-line filtering but PptxGenJS writes minified single-line XML, stripping everything after the XML header - zip directory entries (ppt/media/) passed the media filter, trimmed to "", and replace("", filename) corrupted the rels XML - presentation rels had duplicate rId conflicts between non-slide rels (theme, notesMaster, presProps) and the newly added slide rels New flow: blank loader page served over local HTTP → inject dom-to-pptx CDN once → N iframes (one per slide, same origin) → exportToPptx([roots]) → single PPTX. Gradient pre-processing applied per iframe before export. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>- `needs_validation` now checks `html.contains("<svg")` only; the `|| html.contains("data-image-slot")` branch that caused slot stripping is removed - Add `strip_diagram_labels` — string-scanning heuristic that removes `position:absolute` elements with <5 words of text within 200px of any image slot, without touching slot elements themselves - Integrate `strip_diagram_labels` into the pipeline after the validation pass and before `extract_image_slot_descriptions` - Add `info!` slot-count logs after each pipeline stage for regression visibility - Remove Violation #3 (DIAGRAM LABEL ANNOTATIONS) from `system_validate_slide.md`; renumber remaining violations #95Remove all PNG image generation and the associated PNG spell-check path, leaving HTML as the sole slide output format. The visual-critique pass (HTML screenshot → AI fix) replaces the old PNG spell-check workflow. Removed: - `generate_slide()` and `fix_slide_image()` from generator.rs - `deck_generate()`, `slide_generate()`, `slide_generate_with_selection()`, `spell_check_and_fix()`, `slide_spell_check_fix()` from deck.rs - `submit_generate_{deck,slide}_job`, `handle_{deck,slide}_generate_async`, and all PNG job-status/logs shims from jobs/generate.rs - `JobKind::GenerateSlide` and `JobKind::GenerateAll`; added `JobKind::Critique` so visual-critique gets its own debounce key - `slide.generate`, `deck.generate`, `*Async`, `*JobStatus`, `*JobLogs` (PNG) and `slide.spellCheckAsync` RPC dispatch arms - PNG image-serving routes (`serve_slide_image`, `serve_slide_thumbnail`, `serve_slide_version_{image,thumbnail}`) from admin routes - `GenerateSub::Deck`, `GenerateSub::Slide`, `SpellCheck` CLI commands from main.rs - `slide_generate`, `deck_generate` Rhai bindings; updated Rhai tests - Unused `write_resize_marker` and `image_ref_kind` helpers Also: - PPTX export now triggers a browser download via new `serve_deck_pptx_download` route (`GET /api/collections/{col}/decks/{dk}/export/pptx`) - dashboard.js triggers <a download> after successful PPTX job Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>Restores the image (PNG) generation pipeline alongside the HTML (Editable) pipeline so both coexist. Adds a per-slide render mode and a per-deck default (RenderMode{Image,Html}, default Html for backward compat), with generation dispatching to the right pipeline by resolved mode. - hashing: RenderMode enum, SlideMetaEntry.render_mode, GlobalMeta .default_render_mode, resolve_render_mode + backward-compat test - generator: restore generate_slide / fix_slide_image / write_resize_marker - deck: slide_generate_image / deck_generate_image (image pipeline), slide_generate_auto / deck_generate_auto (per-slide mode dispatch), spell_check restore, render-mode setters; slide_restore_version now syncs + returns the restored artifact's mode - server: slide.generateAsync / deck.generateAsync (Html aliases kept), slide.setRenderMode, deck.setDefault/AllRenderMode; deck.get exposes render_mode + default_render_mode; deck.create takes default_render_mode; jobs submit mode-agnostic 'generate slide/deck' (CLI resolves mode) - cli: generate deck/slide (auto), spell-check - export: pdf + pptx handle mixed decks (image slides embed PNG) - admin: restored image/thumbnail routes; grid image thumbnails; deck-create style picker; per-slide + whole-deck style switch; rollback warning when restoring a different-style version - rhai: slide_generate / deck_generate / *_set_render_mode bindings Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>a5a3812621to63f98d51f7Tested on a real mixed deck (local deploy, build #187)
Duplicated
sample_deck→ set 2 slides to Image, left 3 as Editable:generate deckrendered the 2 image slides as PNG (Gemini) and skipped the 3 unchanged Editable slides:generated: 2, skipped: 3.deck.getreports correct per-sliderender_mode;generated_count= 5/5 across both artifact types.slides.pdf= 5 pages, image slides embedded directly (2752×1536) + Editable slides browser-rendered (1920×1080).v001.htmlandv002.png.slide.restoreVersionof an HTML snapshot on an image slide returnsrestored_mode: "html"and flips the slide back to Editable (UI warns before this).sample_deck(metadata without render-mode keys) resolves to Editable, unchanged.Fixed during testing (commit
63f98d5): generation now removes the other mode's stale live artifact soarchive_versionsnapshots the correct one.⚠️ Pre-existing issue (not from this PR)
PPTX export fails with
hero_browser response: error decoding response body— and it fails identically on the pure-HTMLsample_deck, so it's a pre-existing problem in the dom-to-pptx / hero_browser path, independent of the Image/Editable work. PDF export is unaffected. Worth a separate look.