managarten/apps/cards
Till JS 82db4eb794 feat(cards-web): Anki import carries images + audio along
Closes the gap from the first Anki-import pass: media files are now
uploaded alongside the cards instead of stripped.

Pipeline:
  • parse.ts: read the .apkg's `media` JSON manifest, build a
    filename → ZIP-entry map (Anki names files numerically; the
    manifest is the original-name lookup table). Returned alongside
    decks/cards as parsed.mediaByFilename.
  • import.ts: collectMediaRefs() walks every card field, gathers
    distinct <img src=…> and [sound:…] references — orphan media
    bundled in the .apkg are ignored. Referenced files upload to
    mana-media in 4 parallel workers, returning a filename → URL map.
  • parse.sanitizeAnkiHtml() now takes that map: <img src="X"> →
    <img src="<url>" alt="" />, [sound:Y] → <audio controls
    preload="metadata" src="<url>"/>. The remaining-tag stripper has
    a negative lookahead for img/audio/video/source so the new tags
    survive.
  • CardFace already renders <img>/<audio> via @mana/cards-core's
    DOMPurify config (the image/audio attachments commit added the
    allowlist), so the freshly-imported cards just work in the
    learn session.

UI:
  • AnkiImport gains an "uploading-media" stage with X / N progress
    bar between preview and card creation.
  • Preview now shows the media count, copy promise updated from
    "Bilder/Audio bleiben raus" to "Bilder + Audio werden mit
    übernommen".
  • Result block reports `N Medien übernommen · M fehlgeschlagen`.

Phase-2 ideas: per-user media scoping in mana-media; verify-then-
upload via /media/hash/:sha256 to skip duplicates from re-imports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 14:25:43 +02:00
..
apps/web feat(cards-web): Anki import carries images + audio along 2026-05-07 14:25:43 +02:00
GUIDELINES.md feat(cards): Phase-1 Spinoff — standalone cards.mana.how + cards-core extraction 2026-05-07 01:20:43 +02:00
package.json feat(cards): Phase-1 Spinoff — standalone cards.mana.how + cards-core extraction 2026-05-07 01:20:43 +02:00
README.md feat(cards): Phase-1 Spinoff — standalone cards.mana.how + cards-core extraction 2026-05-07 01:20:43 +02:00

Cards

Spaced-repetition flashcards on cards.mana.how.

Phase-1 standalone web app. The frontend lives here; data, auth, and sync are shared with the rest of the Mana stack:

  • Auth: mana-auth (SSO), *.mana.how
  • Sync: mana-sync, app-id cards
  • Storage: mana_platform.cards.* (Postgres, RLS)

The same cards data backs the mana built-in Cards module at mana.how/cards. Schema changes ship to both frontends together — see apps/cards/GUIDELINES.md.

Layout

apps/cards/
├── apps/
│   └── web/        # SvelteKit 2 + Svelte 5 — the Phase-1 surface
├── GUIDELINES.md   # Project rules (read first)
└── README.md

apps/cards/apps/mobile/ and any production apps/cards/apps/landing/ will land in Phase 2/3.

Quick start

pnpm install
pnpm --filter @cards/web dev      # cards.mana.how on http://localhost:5180