Neue Komponenten unter $lib/components/:
- Reactions.svelte: lädt kind:7-Aggregation via loadReactions, rendert
Chips mit Emoji + Count. +/- werden zu 👍/👎 gemappt.
- ReplyItem.svelte: einzelner Kommentar mit Author-Npub-Prefix + Datum.
- ReplyList.svelte: lädt kind:1-Replies, merged mit optimistic-Props
(dedup per id), sortiert chronologisch.
- ReplyComposer.svelte: Textarea + Senden-Button. Nutzt NIP-07-Wrapper
(getPublicKey, signEvent), baut kind:1-Event mit a/e/p-Tags, pusht
via pool.publish() zu allen Read-Relays. Fehlertolerant: zeigt
Hinweis, wenn NIP-07-Extension fehlt.
Integration in PostView: Reactions, Composer, ReplyList unterhalb des
Artikel-Bodys. Optimistisches Reply-Pattern: Composer.onPublished
pushed signed event in PostView-local $state, ReplyList merged mit
fetched events.
Playwright-E2E:
- playwright.config.ts mit Dev-Server-Auto-Start
- home.test.ts: Profil + Beitragsliste sichtbar
- post.test.ts: Titel + Body + Legacy-URL-Redirect
Alle 3 E2E-Tests grün. npm run check: 600 files, 0 errors.
Deploy live auf svelte.joerg-lohrer.de (Phase 5 inklusive).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- loadPostsByTag(tagName): client-seitige Filterung der Post-Liste
(case-insensitive). #t-Filter wird nicht von allen Relays zuverlässig
unterstützt — wir laden alles und filtern lokal.
- /tag/[name]/+page.ts+svelte: neue Tag-Route, Breadcrumb zurück zur
Übersicht, #tagName als H1, dieselbe PostCard-Darstellung wie Home.
- Tag-Chips in PostView sind bereits klickbar (aus Task 21).
npm run check: 0 errors. Deploy live auf svelte.joerg-lohrer.de.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
window.nostr-Proxy für Alby/nos2x/Flamingo-Extensions. Fehlertolerant:
bei fehlender Extension ODER User-Ablehnung returnen die Helper null,
damit UI klar "bitte Extension installieren"-Hinweise zeigen kann
statt zu crashen.
UnsignedEvent/SignedEvent als explizite Types — werden ab Task 29
(ReplyComposer) für NIP-07-signierte kind:1-Kommentare genutzt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
loadReactions(dtag) sammelt kind:7-Events mit #a-Filter auf den
Post, gruppiert nach content (emoji oder +/-), zählt und sortiert
nach Häufigkeit. Leerer content wird als + interpretiert (NIP-25-
Konvention für Like-Default).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fügt `loadReplies(dtag)` an loaders.ts an. Filter `#a` auf das
addressable-Event-Format "30023:<pubkey>:<dtag>" findet alle kind:1
Replies auf den Post. Sortiert aufsteigend (älteste zuerst).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Eigene `new Marked({...})`-Instanz statt globaler `marked.use()`-Mutation
— schützt andere Module vor Konfigurationsleckage, schärft Spec §3
("lokale Ersetzbarkeit").
- SSR-Guard: `renderMarkdown` wirft in Non-DOM-Umgebungen eine
Fehlermeldung statt stumm unsicher durchzulaufen. SPA hat `ssr=false`,
Vitest läuft in jsdom — Guard ist Early-Fail für versehentliche
Node-Aufrufe.
- `ADD_ATTR: ['target', 'rel']` entfernt — war ein No-Op, weil Marked
diese Attribute nicht einfügt. Link-Attribut-Hardening kommt später,
wenn externe Links tatsächlich `target="_blank"` bekommen sollen.
- Code-Block-Test prüft zusätzlich `class="hljs"` (Regression-Anker
für Custom-Renderer).
- Erweiterte XSS-Matrix: onerror, onclick, iframe, data:text/html,
vbscript:, svg+script — relevant für spätere Reply-Darstellung.
14/14 Tests grün.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- JSDoc zu NaddrArgs, buildNaddr, buildHablaLink (Stil konsistent mit config.ts).
- Neue Tests: ohne relays (Default-`?? []`-Pfad), unterschiedliche Inputs
erzeugen unterschiedliche Links (Guard gegen konstanten Rückgabewert).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- decodeURIComponent in try/catch (malformed URI encoding crasht
den SPA-Boot-Path nicht mehr, returned stattdessen null).
- JSDoc präzisiert: erwartet nur Pfad ohne Query/Fragment.
- Neue Tests: malformed %E0 → null, leerer dtag → null,
round-trip Legacy → canonical.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- FALLBACK_READ_RELAYS als `as const` tuple (kein mutables Array).
- BOOTSTRAP_RELAY als erster Eintrag referenziert statt dupliziert.
- Präzisere JSDoc zu HABLA_BASE (klarmacht, dass /a/ baked-in ist).
- Timeout-Kommentare trennen soft (per-Relay) vs. hard (Page-Budget).
Code-Quality-Nitpicks aus Task 3 Review adressiert. npm run check grün.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>