mirror of
https://github.com/PR0M3TH3AN/Artstr-Studio.git
synced 2026-11-05 21:20:40 +00:00
Adds docs/PPTX_IMPORT_FEATURE.md as the canonical plan for the next big arc: a phased editable .pptx importer that lands PowerPoint decks as editable Artstr deck JSON. Key decisions baked in: - Images and unsupported objects (charts / SmartArt / tables / video) import as placeholder image layers pointing at a hardcoded URL (postimg.cc for now). Original PowerPoint media filenames carry over into the layer name so the user can correlate placeholders with their source deck. - fflate (~10 KB) vendored as src/vendor/fflate.min.js. JSZip is too heavy for the single-file ethos. - Importer code lives in src/pptx-importer.js as an IIFE that exposes window.ArtstrPptxImporter. The Import PPTX button dynamically injects both scripts on first click, so the main index.html bundle does not grow for the 90 % of users who never import a PPTX. - Notes folded into Phase 2 alongside text (single extra relationship lookup, Presenter Mode already renders slide.notes). - No Blossom / NIP-96 prereq, no base64 bloat, no publish-size guard. Imported decks are normal Artstr deck payloads with remote URLs. - Import-only for this arc. PPTX export (Artstr -> .pptx) is a separate later arc with its own complexity. TODO.md gets a Drafted-but-unbuilt entry pointing at the new spec.
234 lines
12 KiB
Markdown
234 lines
12 KiB
Markdown
# Artstr Studio — TODO
|
||
|
||
Running list of deferred work. Detailed specs for the larger items live in
|
||
`docs/`. Each entry notes scope and where the spec is (if any).
|
||
|
||
## Adam's working list
|
||
|
||
_(Empty — see "Shipped (recent)" below for the items that just
|
||
landed. Drop new items in here as they come up.)_
|
||
|
||
## QR code layer — remaining phases
|
||
|
||
Phases A and B shipped (the `qr` layer type: data, error-correction level,
|
||
quiet zone, module / background colors, transparent background, renders
|
||
on every surface + canvas export, JSON round-trip; plus "Insert npub" and
|
||
"Insert share link" buttons under the QR data field).
|
||
|
||
- **Phase C — visual polish.** Optional center logo overlay and rounded
|
||
modules. Riskier: a logo eats into the error-correction budget, so it
|
||
should nudge the ECC level up. Skippable.
|
||
|
||
## Editor / tool UX
|
||
|
||
Small editor-usability improvements — no spec doc; scoped here.
|
||
|
||
Shipped: on-canvas drag-resize handles for every layer type, text-box
|
||
resize that never rescales the point size, the expanded Text tool panel
|
||
(font / size / color / alignment / bold / italic), a collapsible sidebar
|
||
toggle that fits the early-web aesthetic. Add new editor-UX items below.
|
||
|
||
## Profile pages — deferred polish
|
||
|
||
(Core profile pages at `/u/<npub>` already shipped.)
|
||
|
||
- Make author chips clickable in the **community thread view** (comments and
|
||
reposts) — currently only feed-card and preview-meta author chips route to
|
||
`openProfilePage`.
|
||
- **About-text clamp** — long bios overflow the profile header; clamp to ~4
|
||
lines with a "Show more" toggle.
|
||
- **Profile-grid pagination** — an author with 100+ designs renders them all
|
||
at once; cap the initial render and add a "Show more" pager.
|
||
|
||
## Edit-published-designs — deferred polish
|
||
|
||
(Core edit-in-place via NIP-33 replaceable semantics already shipped.)
|
||
|
||
- Replace the remaining `confirm()` calls in the edit / publish flow with the
|
||
styled in-app modal pattern, for consistency with the close-project and
|
||
publish-confirm modals.
|
||
- "Editing a previously-deleted design" warning — if the user opens Edit on a
|
||
design they had tombstoned with a kind-5, warn that publishing will
|
||
republish it.
|
||
|
||
## Pixel art — future polish
|
||
|
||
- **`pixelsB64` size-fallback encoder.** The spec calls for each frame
|
||
to store whichever is smaller: `pixels` (RLE pairs) or `pixelsB64`
|
||
(base64 of the raw `Uint8Array` of indices). Only RLE is implemented
|
||
today. For noisy / photo-pixelized content with many palette colours,
|
||
base64 is ~5× smaller — a 24-frame 64×64 sprite tested at 785 KB
|
||
RLE would drop to ~150 KB. Worth shipping alongside a live event-size
|
||
readout in the editor (soft warn at 50% of relay budget, hard block
|
||
at 90%) so users see the budget before publish.
|
||
|
||
## Drafted-but-unbuilt features
|
||
|
||
Each has a full spec in `docs/`.
|
||
|
||
- **PPTX import** — `docs/PPTX_IMPORT_FEATURE.md`. Phased editable
|
||
importer that converts a `.pptx` package into an Artstr deck.
|
||
Images and unsupported objects (charts, SmartArt, tables, video)
|
||
land as placeholder image layers pointing at a hardcoded URL;
|
||
user replaces each placeholder by editing the layer's src. No
|
||
Blossom prereq, no base64 bloat, decks publish to Nostr normally.
|
||
fflate vendored bundle + a lazy-loaded `src/pptx-importer.js`
|
||
module so the main app weight doesn't grow.
|
||
- **Artstr Stacks** — `docs/STACKS_FEATURE.md`. Interactive fullscreen
|
||
page/card stacks (HyperCard for Nostr) — the Slide Deck extended with
|
||
layer actions and an interactive viewer.
|
||
- **Badges (NIP-58)** — `docs/BADGES_FEATURE.md`. Award / display Nostr
|
||
badges on profile pages.
|
||
- **Collections (NIP-51 sets)** — `docs/COLLECTIONS_FEATURE.md`. Let users
|
||
organize favorite community templates into named sets.
|
||
|
||
## Premium-templates polish
|
||
|
||
The premium-encrypted-designs arc shipped in 2026-05; see
|
||
`docs/PREMIUM_DESIGNS_FEATURE.md` for the canonical spec. Open
|
||
follow-ups worth their own work:
|
||
|
||
- **Phase 4 E2E test matrix** — real-money round-trip through CoinOS:
|
||
publish premium → unlock from another browser → vault sync. Plus
|
||
the edge-case matrix from §19 item 4 of the spec (wallet budget
|
||
exhausted, platform fail after creator paid, partial-pay resume,
|
||
missing lud16, cache wipe → relay fast-path).
|
||
- **Confirm()-style modals** — the unlock confirm and a few other
|
||
premium-related prompts still use native `confirm()`. Replace with
|
||
the styled in-app modal pattern.
|
||
- **Future-proofing** — when an epoch's soft-gate pepper gets reverse-
|
||
engineered we'll ship a new epoch. The infra is in place; the
|
||
rotation playbook should land as a SECURITY.md when we do it.
|
||
|
||
## Phase-3+ work on shipped features
|
||
|
||
- **Private (encrypted) publishing — Phases 3 & 4.**
|
||
`docs/PRIVATE_PUBLISHING_FEATURE.md`. Phases 1 (private-to-me) and
|
||
2 (toggle public ⇄ private) shipped in commit `3e6e89e`. Still
|
||
unbuilt: Phase 3 (share with selected pubkeys) and Phase 4 (NIP-59
|
||
gift-wrap metadata privacy + Blossom/NIP-96 offload for oversized
|
||
encrypted blobs).
|
||
|
||
## Shipped (recent)
|
||
|
||
- **Premium encrypted designs — static soft-gate + NWC split-zap +
|
||
purchase vault.** Spec lives in `docs/PREMIUM_DESIGNS_FEATURE.md`.
|
||
Creators tick "Premium encrypted" + a soft-gate ack in the publish
|
||
modal, set a minimum sat amount; we AES-256-GCM encrypt the
|
||
payload (HKDF over an obfuscated per-epoch pepper + per-design
|
||
salt + the event coordinate as AAD), render a watermarked low-res
|
||
JPEG preview embedded in the envelope, and emit the §5.1 tag set
|
||
with two zap-split tags (creator 70 % / platform 30 %).
|
||
Consumers see a gradient-stroked card + ⚡ PREMIUM ribbon with an
|
||
"Unlock for N sats" CTA on all three import paths (feed card,
|
||
preview pane Use/Fork, preview pane Save JSON). Unlock fires both
|
||
pay_invoice legs in parallel over NWC, derives the soft-gate key
|
||
locally on receipt confirmation, decrypts in place with a reveal
|
||
animation. Cross-device sync via a NIP-44 self-encrypted purchase
|
||
vault (kind-30078 `d=artstr:purchase-vault:v1`) that auto-splits
|
||
into per-item events when over 40 KB. Address-tolerant unlock
|
||
lookup so edit-in-place doesn't invalidate prior purchases.
|
||
Hydrates on Nostr login with a "Restored N unlocks ✓" toast.
|
||
Soft-gate framing is honest in every UI surface: it raises
|
||
friction against drive-by scraping, NOT strong DRM. Foundation
|
||
layers (noble bundle, NWC client + wallet settings UI with
|
||
CoinOS-first onboarding, platform-fee dual-zap orchestrator, NWC-
|
||
default Lightning tips, login-method picker, profile dropdown
|
||
menu with View Profile / Settings / Logout, the Settings modal
|
||
itself, the new Premium tab + mobile-friendly browser layout)
|
||
all shipped as part of the same arc. ~30 commits on the
|
||
`zap-gated` branch, merged into main 2026-05.
|
||
- **Pixel-art dropdowns — no more sidebar clipping.** The pixel-editor
|
||
resize-grid and PNG-export menus were `position: absolute; right: 0`
|
||
inside their toolbar wrap. When the toolbar wrapped and the trigger
|
||
button landed at the left of its row, the menu slid leftward under
|
||
the main sidebar. Switched both menus to `position: fixed` with a
|
||
JS-placed coord that anchors to the button's right edge by default,
|
||
flips to its left edge if anchoring right would clip past the
|
||
sidebar (sidebar's actual right edge, not just the viewport),
|
||
and clamps inside the viewport on both sides. Also auto-closes any
|
||
open menu on window resize to avoid stranded fixed-position remnants.
|
||
- **Top-right action strip — permanent, never wraps.** Pulled the
|
||
canvas-size readouts and the undo / redo pair out of the topbar's
|
||
flex flow and pinned them in a fixed strip directly under the Nostr
|
||
widget, right-anchored, with `flex-wrap: nowrap`. Order: canvas-size
|
||
pills on the left, undo / redo on the right (so undo / redo hug the
|
||
viewport edge). The topbar's right padding now tracks the wider of
|
||
the Nostr widget or the strip via the existing
|
||
`--nostr-widget-space` var, so the project title never slides under
|
||
it.
|
||
- **Click canvas background → deselect.** The existing #sheet click
|
||
handler missed clicks in the gutter between sheet edge and
|
||
previewShell edge; added a #previewShell handler.
|
||
- **Crop marks for Custom Art / Slide canvases.** New `.canvasCrops`
|
||
corner marks inside .sheet, scoped to those template modes. The
|
||
existing showCrops / printCrops toggles drive screen + print
|
||
visibility (relaxed from cover-only to a new `.crops-toggle`
|
||
class).
|
||
- **Strip selection chrome from PDF Print / JPEG-fallback output.**
|
||
Dead `body.exporting` CSS rules were renamed to actually match the
|
||
class JS sets. Wired both the regular printBtn flow and the
|
||
JPEG-PDF flow to set the class. Two-class split (`body.exporting`
|
||
for chrome-stripping in either flow, `body.export-print` for the
|
||
heavier container-isolation only the JPEG-PDF flow does) avoids the
|
||
blank-print regression that a single class caused.
|
||
- **Custom Art: match canvas to image's natural dimensions.** New
|
||
"Match canvas to image size" button on the image-layer panel (Custom
|
||
Art mode only; Slide is 16:9 locked). Loads the image via
|
||
loadImageWithCors, clamps to CUSTOM_ART_MAX, pushes one undo entry.
|
||
- **JPEG export — rich text rendering (P2).** Canvas-based engine
|
||
that walks the layer's HTML into styled runs (bold/italic/underline,
|
||
bullets, numbered lists, line breaks), lays them out with
|
||
ctx.measureText + word wrap, and draws each item with its own font
|
||
+ underline. Dispatches to plain `fillText` when no inline marks
|
||
are present. SVG-foreignObject was tried first; it taints the
|
||
canvas in Chromium so we built the run-layout engine instead.
|
||
- **Independent-axis corner-node resize.** Corner handles default to
|
||
independent axes (each axis follows its own drag delta); Shift+drag
|
||
locks aspect (Figma / Photoshop / Keynote convention). The sidebar
|
||
🔒 toggle still governs typed W/H input cascades.
|
||
- **JPEG export — DPI / quality selector (P4 polish).** 96/150/300 dpi
|
||
presets in a dropdown next to the Export JPEG button.
|
||
- **JPEG export — one-click direct rasterizer (P1).** Replaces the
|
||
print-to-PDF-then-re-pick flow for Cover, Disc sheet, Jewel,
|
||
Disc design, Custom Art, and Slide canvases. The infrastructure
|
||
was already 90% built (drawLayerToCanvas + four canvas-type
|
||
rasterizers existed but were never wired to any entry point);
|
||
P1 added the missing Custom-Art rasterizer + the orchestrator
|
||
that picks the right rasterizer per templateMode, pre-flights
|
||
CORS via the existing _exportFailedImages set, and falls back to
|
||
the print modal when any image can't be embedded directly.
|
||
|
||
- **Slide deck PDF export** — multi-page PDF, one page per slide. The
|
||
existing Print / Save PDF button is context-aware: in the Deck Builder
|
||
it builds a hidden print-only container with one page per slide (themed
|
||
via `composeSlideForDeck`, each page sized to the preview's native
|
||
dimensions so the slide fills the page exactly) and emits one PDF via
|
||
`window.print()`. Inside a single-slide editor, the button still prints
|
||
just that slide.
|
||
- **Copy / paste transform consistency** — paste now computes a single
|
||
group bounding box across all clipboard items, applies one shared scale
|
||
(only shrinks, never enlarges) and one shared translation, so cross-
|
||
target paste keeps every layer's relative position and size to the
|
||
others intact.
|
||
- **Pixel-editor colour picker** — ported the OS native `<input type="color">`
|
||
over from the vector tools (same swatch styling; opens the OS picker with
|
||
its built-in eyedropper on click). Removed the Screen-Capture-API screen-
|
||
eyedropper workaround (~170 lines of dead code). Palette swatches and
|
||
the in-canvas eyedropper tool now sync the picker too, so grabbing a
|
||
palette colour as the starting point for a tweaked variant just works.
|
||
|
||
- **Pixel Art** — `docs/PIXEL_ART_FEATURE.md`. Phases A–D all shipped:
|
||
embedded `pixelart` layer + standalone `casewrap-pixelart` design,
|
||
PNG / sprite-sheet / GIF export, drawing tools (line / rect / ellipse,
|
||
flip / rotate, grid resize), animation (multi-frame timeline, playback,
|
||
onion-skin), image → pixelize, and animated previews in every preview
|
||
surface. Undo / redo integrated with the top-level toolbar.
|
||
- **Pixel editor layout expansion** — addressed by the collapsible
|
||
sidebar (gives both the pixel and vector editors a lot more breathing
|
||
room when needed).
|
||
- **Print / Save event ID wrapping** — the event-id `<dd>` already uses
|
||
`overflow-wrap: anywhere; word-break: break-word`, so no horizontal
|
||
scroll.
|
||
- **TMDB auto-fill cleanup** — `docs/TMDB_AUTOFILL_FEATURE.md` removed.
|