Commit Graph

6 Commits

Author SHA1 Message Date
Jörg Lohrer 54eb0b62cb feat: cc0-badge im footer + impressum auf cc0 umstellen
Footer zeigt jetzt CC0-Badge (Heart+Zero inline SVG, monochrom via
currentColor) statt "© Jörg Lohrer". Impressum entsprechend von
CC BY-SA auf CC0 umgestellt, mit freundlichem Hinweis, dass
Namensnennung erwünscht, aber nicht rechtlich erforderlich ist.

"Nostr-basiert" im Footer jetzt Link zum GitHub-Repo (Making-of).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 16:19:21 +02:00
Jörg Lohrer 10e455a078 spa: startseite + archiv + impressum + menü + assets für cutover
Startseite (+page.svelte) komplett überarbeitet:
  - Hero mit lokalem Profilbild (WebP aus static/, schneller als
    kind:0-roundtrip), Begrüßung "Hi Willkommen auf meinem Blog 🤗",
    About/Website aus kind:0
  - Social-Icons-Leiste (Nostr/Mastodon/Bluesky/LinkedIn/ORCID/Mail)
    als inline-SVG, monochrom via currentColor, hover färbt blau
  - Nostr-Icon von satscoffee/nostr_icons (outline, CC0), die anderen
    stilisiert als vereinfachte Brand-Icons
  - Neueste 5 Posts + Archiv-Link

Archiv-Route (/archiv/): alle Posts, nach Jahr gruppiert.

Impressum (/impressum/): static-page, rendert content/impressum.md
(via vite ?raw-import), bleibt aus nostr-feeds draußen. Frontmatter-
parser toleriert trailing-spaces auf --- zeilen.

Menü im Layout: sticky header mit brand + 3 links (Home, Archiv,
Impressum), aktiv-state via akzent-farbe. Footer mit © + Impressum
+ "Nostr-basiert"-hinweis.

Assets: profilbild und favicons aus dem hugo-static (repo-root) nach
app/static/ übernommen, favicon-links in app.html ergänzt.

NIP-05: .well-known/nostr.json in app/static angelegt mit CORS-header
via .htaccess, damit "joerglohrer@joerg-lohrer.de" nach cutover
verifizierbar bleibt.

E2E-Tests angepasst an neue hero/navigation-struktur, 29/29 unit + 4/4
e2e grün.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:35:05 +02:00
Jörg Lohrer 3ad1a72d84 spa: kommentar-author klickbar (njump) + external-client-links am post
Zwei Erweiterungen, die Community-Interaktion an Nostr-native Clients
auslagern statt in der SPA nachzubauen:

1. ReplyItem-Header ist jetzt ein <a href=https://njump.me/<npub>
   target=_blank>. Klick auf Avatar/Name öffnet das vollständige
   Profil des Kommentar-Authors mit allen Events.
2. Neue ExternalClientLinks.svelte zwischen Reactions und Composer:
   dezente Box mit "In Nostr-Client öffnen" — drei Links (Habla,
   Yakihonne, njump) über naddr, damit Leser Thread-Replies,
   Reactions, Teilen dort nutzen können, wo die volle Nostr-Social-
   Layer läuft.

Nostr-Helper erweitert:
- buildNpub(hex) — npub1…-Bech32-Encoding
- buildNjumpProfileUrl(hex) — njump.me/<npub>
- externalClientLinks({pubkey, kind, identifier}) — Liste der drei
  etablierten Langform-Viewer mit naddr1…-URLs.

npm run check: 0 errors, 611 files. Deploy live.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 18:04:23 +02:00
Jörg Lohrer eb400a8a6a spa: avatar + name für kommentar-authoren via kind:0-profil
- loadProfile(pubkey?) akzeptiert jetzt optional einen Pubkey, default
  weiterhin AUTHOR_PUBKEY_HEX.
- Neuer profileCache.ts: sessionsweiter Cache, Promise-Memoization —
  paralleles Nachladen derselben Pubkey teilt dieselbe Request.
- ReplyItem lädt das kind:0-Profil des Kommentar-Authors on mount,
  zeigt Avatar (32px rund) + display_name/name. Fallback bei fehlendem
  Profil: Pubkey-Hex-Prefix (wie bisher).
- Home-Page nutzt getProfile(AUTHOR_PUBKEY_HEX) statt loadProfile()
  direkt — gleicher Cache, kein doppeltes Fetchen.

npm run check: 0 errors. E2E 3/3 grün. Deploy live.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 17:58:44 +02:00
Jörg Lohrer 3b0f059cea spa(phase 5, tasks 26-32): reactions, replies, nip-07 kommentare, e2e
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>
2026-04-15 17:51:57 +02:00
Jörg Lohrer feb336fc5b spa(phase 3, tasks 15-22): routing, komponenten, home, postview
Phase 3 komplett:
- Task 15: LoadingOrError-Komponente (loading/error-states, Habla-Fallback)
- Task 16: app.html mit CSS-Variablen (light/dark), Base-Typography
- Task 17: +layout.svelte mit Container + bootstrapReadRelays onMount
- Task 18: ProfileCard-Komponente (Avatar, Name, About, NIP-05, Website)
- Task 19: PostCard-Komponente (Thumbnail + Titel/Summary/Datum), responsive
- Task 20: +page.svelte als Home (Profil + Liste, Promise.all für beides)
- Task 21: PostView-Komponente (Titel, Meta, Cover, Summary, Markdown-Body)
- Task 22: [...slug]/+page.ts+svelte — Catch-all-Route mit Legacy-301-Redirect

Alle $props()-abhängigen Werte via $derived() (Svelte-5-Runes-Konformität).

npm run check: 0 errors, 0 warnings, 592 files. npm run build grün.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 17:39:24 +02:00