# ppt-live-editor integration review

Reviewed on 31 October 2026 for the Documents Generator Tools **Create SCORM** project type.

- Repository: https://github.com/ymankh/ppt-live-editor
- Inspected branch: `main`
- Inspected commit: `49f36a2d2f1472fdd1d08925a0c59068c8b58414`
- Local read-only checkout: `out/research/ppt-live-editor/` (ignored by this repository).
- Scope: source review and the repository's supplied screenshots. No dependency installation, candidate application execution, candidate tests, or integration changes were performed.

## Recommendation

**Yes: this is a promising foundation for the slide-authoring engine in Create SCORM.** Its React/TypeScript canvas, rich text, element model, geometry, rendering, layers, animation engine, and undo/redo cover more presentation-editing functionality than our current prototype.

Keep the current Laravel application responsible for authentication, projects, organizations, assets, permissions, revisions, and SCORM generation. Keep the existing question, assessment, media, and H5P components and their data contracts. Adapt the presentation engine to those boundaries rather than adopting its standalone application and ASP.NET backend wholesale.

This is a source-based feasibility conclusion. Performance, Arabic rendering, integration effort, and LMS behavior still require an isolated working integration and tests.

## Shared repository map

Paths below are relative to the candidate repository.

| Area | Source | What it does / how we would use it |
| --- | --- | --- |
| Standalone application | `frontend/src/App.tsx` | BrowserRouter, editor, project library, player, presenter routes. Our application keeps control of routing. |
| Workspace shell | `frontend/src/features/editor/Editor.tsx`, `Workspace.tsx`, `Toolbar.tsx`, `PropertiesPanel.tsx`, `LayersPanel.tsx` | Header/menu actions, resizable panels, inspector and layers. Reuse selected surfaces with our navigation, branding, translations, and responsive rules. |
| Canvas and gestures | `frontend/src/features/canvas/SlideCanvas.tsx`, `useCanvasGestures.ts` | Move, resize, rotate, drawing, multi-selection, marquee, grouping, snapping, pan/zoom. Strong reuse candidate. |
| Geometry | `frontend/src/lib/geometry.ts` | Bounds, rotated positions, resizing, snapping, and alignment calculations. Strong reuse candidate. |
| Document model | `frontend/src/types/model.ts` | Presentation, slide, rich-text, shape, line, image, table and chart types; fills, backgrounds, animation and transition data. Needs a versioned mapping from our prototype document. |
| Store and history | `frontend/src/store/editor.ts`, `store/view.ts` | Zustand state, Immer patch history, transactions, selection, saves. Adapt persistence and store ownership. |
| Shared rendering | `frontend/src/features/renderer/SlideRenderer.tsx`, `RichText.tsx`, `ChartRenderer.tsx` | DOM/SVG rendering used by editor, thumbnails and other outputs. Preserve a shared renderer to reduce preview differences. |
| Rich-text editing | `frontend/src/features/renderer/TextEditor.tsx` | TipTap rich text with text alignment, style and highlight support. Integrate Arabic direction and existing fonts. |
| Backgrounds and element appearance | `frontend/src/features/editor/PropertyFields.tsx`, `components/common/PropertyInputs.tsx` | Fills, gradients, outlines, shadows, numeric fields, color picker. Useful controls, with app-specific styling/localization. |
| Layouts and themes | `frontend/src/lib/defaults.ts`, `features/theme/` | Presentation layouts and visual themes. Our guided learning-course blueprints remain a separate layer. |
| Images and assets | `frontend/src/features/images/`, `features/persistence/repository.ts` | Image ingress, blob/asset references and API URLs. Replace with project-scoped Laravel asset handling. |
| Playback and animation | `frontend/src/features/presenter/Player.tsx`, `SlidePreview.tsx`, `animations.ts` | Presentation builds and transitions, including per-element effects. Reuse through a course-runtime adapter. |
| Import and export | `frontend/src/features/export/` | Project archive, basic PPTX import, native PPTX output, PDF/PNG raster export, schema validation. No SCORM exporter was found. |
| Backend | `backend/Folio.Api/` | ASP.NET Core 10 controllers and SQLite documents/assets. Keep our Laravel backend instead. |
| Development orchestration | `apphost/`, `aspire.config.json` | .NET Aspire local orchestration. Not required when extracting the frontend engine into our existing app. |
| Tests | Frontend `*.test.ts(x)` and `e2e/*.spec.ts` | Source includes geometry, store/history, export, renderer, persistence, authoring, layers and panel tests. Their presence is not evidence that they pass here. |

## Feature fit

| Requested capability | Source finding | Integration decision |
| --- | --- | --- |
| Rich text, fonts and sizes | TipTap content plus element typography and text editing | Reuse, with Arabic direction/font checks |
| Shapes, lines and images | Explicit model and renderers, including image masks/crop/filter fields | Reuse supported controls and document types |
| Tables and charts | Model, inspector and renderers exist | Optional additions to Create SCORM |
| Movement and selection | Transient geometry, pointer interactions, multi-selection and snapping | Reuse engine; benchmark in our workspace |
| Undo/redo | Immer forward/inverse patches and transactions | Reuse with our project lifecycle |
| Layers, lock/hide and arrangement | Source and supplied screenshot demonstrate implemented surfaces | Reuse/adapt UI |
| Element animations | Entrance/emphasis/exit categories and click/previous-item triggers | Requires integration with learner navigation and existing media/question playback |
| Guided course templates | Generic presentation layouts exist; course-specific guidance is absent | Build our learning blueprint generator above the engine |
| Questions and assessment groups | No equivalent course assessment system found | Retain our existing feature |
| H5P activities | No H5P integration found in application source | Retain our existing feature |
| SCORM tracking/resume/completion | No SCORM API, manifest or resume integration found in application source | Retain/extend our existing package builder and runtime |
| Arabic and RTL | No dedicated Arabic localization or explicit canvas direction configuration found in inspected code; physical left/right CSS is used | Add localization, explicit LTR physical canvas coordinates, RTL text/layout behavior, and browser tests |
| Phone workspace | Resizable horizontal panels have minimum sizes of 180 px, 420 px and 240 px | Add a mobile layout; do not infer phone support from desktop functionality |

## Performance findings

### Current Create SCORM prototype

A local, isolated 25-slide / 20-elements-per-slide browser fixture measured:

- One simulated 36-step drag: **36 full-draft JSON serializations and 36 synchronous localStorage writes**, plus 36 observed thumbnail source updates.
- A 24-sample color change: **24 full-draft serializations, 24 storage writes, 24 structured clones and 24 thumbnail updates**.
- The local trace did not record long tasks, so these counts identify unnecessary work rather than proving a particular frame rate on the user's device.

Relevant current sources are `element-canvas.tsx` (parent document update on pointer move), `page.tsx` (immediate draft serialization/storage and thumbnail generation), and `slide-editor.tsx` (full-slide history snapshots for color updates), under `app/prototypes/scorm-create/`.

### Candidate architecture

- `useCanvasGestures.ts` keeps live move/resize/rotate geometry in `transient` state and commits document changes at gesture end. This avoids saving a whole course on every pointer move.
- `SlideRenderer.tsx` memoizes `ElementView`.
- `store/editor.ts` uses Immer patches for history, keeps up to 200 entries, serializes save requests, and debounces autosave by 650 ms. An older save finishing does not automatically mark a newer edit saved.
- `ColorField` holds a local picker draft and commits on picker close or input blur. This avoids a full document mutation for every picker movement, but the source does not provide continuous committed slide-color updates during that picker drag. A smooth live slide preview should use transient color state plus one committed history edit.
- It still performs React state updates during gestures, and the main editor subscribes to the whole document. Complex-slide performance must be measured; no candidate frame-rate or speedup has been demonstrated here.

The candidate contains useful performance patterns. Those patterns can also improve our current editor independently, if we defer integration.

Baseline artifact: ignored `out/native-authoring/performance-baseline.json`. No performance fix was applied during this review.

## Integration architecture

```mermaid
flowchart TD
  A[Create SCORM project type] --> B[Our course workspace and guided templates]
  B --> C[Adapted Folio slide editor engine]
  B --> D[Existing questions and assessment groups]
  B --> E[Existing media and H5P editors]
  C --> F[Native presentation document]
  D --> G[Stable course-slide identities]
  E --> G
  F --> G
  F --> H[Laravel document and asset adapter]
  H --> I[Existing project access and revision controls]
  F --> J[Native-slide learner renderer]
  D --> K[Existing SCORM runtime and tracking]
  E --> K
  J --> K
```

Keep activities/media/questions outside the presentation engine's shape array. Link them to stable course-slide IDs. This preserves their existing editing, completion and scoring behavior.

## Required adapters and decisions

1. **Document boundary:** introduce an explicit native document format/engine discriminator and migration version. Both projects currently use `version: 1`, but their schemas are different.
2. **Identity:** retain our project and course-slide IDs. The candidate's generic string IDs can contain our UUIDs; avoid regenerating slide identities when switching engines or themes.
3. **Geometry:** configure the engine to our logical slide dimensions, or perform one explicit conversion. Its default is 1920 × 1080; our current prototype is 1280 × 720. Existing learning-overlay percentages must remain aligned.
4. **Element mapping:** our plain text becomes TipTap JSON; `kind` becomes the candidate's element/shape discriminant; flat color fields become fill/stroke objects; opacity changes from 0–100 to 0–1. Our animation times are milliseconds; candidate animation playback uses seconds. Map supported values and report unsupported values rather than silently dropping them.
5. **Persistence:** replace the candidate's concrete HTTP repository calls with our authenticated API client and project-scoped save/load operations. The existing repository interface helps describe the boundary, but the store currently imports concrete functions; this is not already a plug-in integration.
6. **Multiple project tabs:** the candidate exports a singleton Zustand document store, and has module-level save queue/timer/clipboard state. Refactor ownership for isolated per-project instances before mounting multiple editors, or deliberately support one native editor at a time with save/close guards.
7. **Assets:** map blob/asset keys and URLs to our private project assets. Export must resolve assets into self-contained package files; signed authoring URLs must not be left in offline SCORM.
8. **UI:** reuse canvas and interaction logic while adapting the shell, styles, theme tokens, icons, Arabic strings and accessibility. Its `index.css` includes Tailwind/shadcn global styles and a global theme/font; importing all of it can affect our existing app. Its strings object also stores CSS classes, routes and model discriminants, so it cannot be translated wholesale as display text.
9. **Learning runtime:** integrate element rendering and animation progression with slide entry/leave, media pause/resume, question overlays, completion, and SCORM restore. A standalone presentation player's slide links/click builds must not bypass sequential course navigation or required activities.
10. **Guided templates:** our blueprint generator should create native presentation slides plus author guidance and learning-activity drafts. Generic presentation layouts alone do not provide the course guidance discussed earlier.

## SCORM output choices

### Static first integration

The candidate's raster exporter can generate PNG/JPEG slide artwork. Our current `ScormPackageBuilder` accepts non-rendered PNG/JPG/SVG course-slide assets, so this offers a relatively direct packaging path alongside existing activities/media/questions.

Tradeoff: rasterization freezes native text/shapes/charts into images and does not retain element animations as independently animated objects.

### Interactive integration

For the requested animated slide editor, preserve the native presentation document and bundle a thin version of its renderer/animation code into our existing SCORM runtime. Include fonts/styles/assets locally, and connect slide lifecycle and animation builds to our learner navigation.

This best matches the requested behavior, but needs a dedicated runtime/export implementation and Moodle acceptance tests. Exporting a `.pptx` and converting it again would reintroduce the conversion dependency the new project type is intended to remove.

## Authentication and reuse boundaries

- The candidate backend's `LocalCurrentUserProvider` returns a hardcoded local identity. Its project endpoints are not a replacement for our user/organization authorization and revision controls.
- No `LICENSE`, `COPYING`, or `NOTICE` file was detected in the inspected repository tree. Confirm the right to reuse the repository's code before incorporating it; dependency licenses also need checking for distribution.
- Candidate package versions are broadly within our React 19 / Vite 8 family, but it adds TipTap, Zustand, Immer, Base UI/shadcn, dnd-kit, charts, and other dependencies. Reconcile versions and lazy-load native authoring rather than upgrading unrelated application dependencies automatically.

## Suggested implementation sequence

1. Pin the reviewed source and confirm reuse rights. Put the engine behind the existing Create SCORM route with our shell and a repository adapter; preserve the current native draft for rollback.
2. Demonstrate one native course with text, image, shape, rich text, an existing question, media item and H5P activity. Save/reopen through our app while retaining stable slide IDs.
3. Add Arabic/RTL and responsive workspace behavior; measure large-slide drag and color editing against the current baseline. Verify one undo step and one debounced save per completed gesture.
4. Connect guided course blueprints and migrate existing prototype documents with content-preservation checks.
5. Integrate the native renderer/animations into self-contained SCORM output, then test in the target Moodle environment.

Acceptance includes drag/resize/rotate/group, rich text and Arabic shaping, layers, cancellation, undo/redo, save/reopen, denied access, stale revisions, separate project tabs, private assets, desktop/mobile alignment, course activity placement, offline package assets, animations on revisit, SCORM resume/completion, and existing PowerPoint-project regressions.

## Verification limits

The candidate repository was cloned and its source, package manifests, supplied screenshot, test files and integration boundaries were inspected. Its build, tests, .NET services, browser behavior and exports were **not run**. No integration code or application dependencies were changed. Only this assessment document was added to the application repository.
