Commit Graph

96 Commits

Author SHA1 Message Date
Jure
c8d2b05440 Bump to v0.4.0 — Phase 3: image lightbox, bookmarks, discover, language filter, UI polish v0.4.0 2026-03-14 18:00:28 +01:00
Jure
af8a364e28 Bump to v0.3.1 — Phase 2 complete, AUR package, feed tab fix v0.3.1 2026-03-14 16:31:18 +01:00
Jure
ef35f20688 Persist feed tab across navigation — back button returns to correct tab
Feed tab (Global/Following) moved from local state to UI store so it
survives thread/profile navigation. Fixed hardcoded "feed" in openThread
calls to pass currentView instead.
2026-03-14 16:23:51 +01:00
Jure
3ca73a8b01 Bump to v0.3.0 — instant post/reply feedback
Published notes now appear in the feed immediately. Thread replies
show up without waiting for the relay round-trip. Includes all
v0.2.9 fixes (image paste, sent zaps, reply-to clickable, feed
refresh on login).
v0.3.0
2026-03-13 19:40:14 +01:00
Jure
7c10423b4a Show published note in feed immediately after posting 2026-03-13 18:08:40 +01:00
Jure
176cbe8ae3 Bump to v0.2.9 — image upload fix, sent zaps, clickable reply-to, feed refresh v0.2.9 2026-03-13 15:46:43 +01:00
Jure
17304a2432 Fix image upload: use Tauri HTTP plugin to bypass WebView fetch restrictions 2026-03-13 15:44:44 +01:00
Jure
1d4ab27d08 Make reply-to @name clickable to open profile separately from thread 2026-03-13 12:38:49 +01:00
Jure
93963de28d Fix sent zaps: query kind 9735 receipts with #P tag instead of ephemeral kind 9734 2026-03-13 11:17:45 +01:00
Jure
7746e31051 Navigate to feed and refresh after login with new account 2026-03-13 10:59:29 +01:00
Jure
aef7cdf658 Use GitHub noreply email in PKGBUILD maintainer field 2026-03-13 10:26:55 +01:00
Jure
bbf6291567 Bump to v0.2.8 — enable keyring platform backends (keychain was a no-op) v0.2.8 2026-03-13 10:22:34 +01:00
Jure
8e0d92c893 Bump to v0.2.7 — multi-account persistence fix v0.2.7 2026-03-13 09:04:36 +01:00
Jure
56cf0bae4d Fix multi-account restore and switch after restart
- restoreSession pre-loads all nsec accounts from keychain into signer
  cache at startup, not just the active one
- switchAccount updates state to target account on failure instead of
  leaving UI stuck on previous account
- AccountSwitcher shows re-login prompt when account has no signer
- store_nsec now logs warnings instead of silently swallowing errors
2026-03-12 16:14:23 +01:00
Jure
f33d78ebcf Update PKGBUILD to 0.2.6 and add it to release checklist 2026-03-12 15:43:53 +01:00
Jure
6ee02eb586 Bump to v0.2.6 — add createUpdaterArtifacts for updater signing
Tauri 2 requires bundle.createUpdaterArtifacts: true to produce .sig
files and updater zip/tar.gz archives. Without it, TAURI_SIGNING_PRIVATE_KEY
is ignored and latest.json is never generated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.2.6
2026-03-12 15:30:45 +01:00
Jure
cc05a80433 Bump to v0.2.5 — fix updater signing key (regenerate without password)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.5
2026-03-12 13:27:38 +01:00
Jure
4e06aa2d00 Bump to v0.2.4 — retrigger with signing key set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.4
2026-03-12 12:44:35 +01:00
Jure
0b02f34338 Document release procedure in CLAUDE.md — version bump before tagging, includeUpdaterJson
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 12:26:03 +01:00
Jure
7ca0e804f1 Bump to v0.2.3 — add includeUpdaterJson: true to fix latest.json generation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.3
2026-03-12 12:21:44 +01:00
Jure
9b6ba35dac Update release notes for v0.2.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.2
2026-03-12 11:56:06 +01:00
Jure
9d54bfb22f Bump to v0.2.2 — version files forgotten before tagging
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 11:54:59 +01:00
Jure
351667c1f0 Drop Intel macOS build — macos-13 runner no longer available on GitHub
Apple Silicon (macos-latest) is sufficient for current Mac user base.
Intel can be revisited if demand arises.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 11:19:18 +01:00
Jure
2c874de790 Bump to v0.2.1 — Batch 3 playtest fixes + auto-updater fix
- Fix: repost + quote buttons added to RootNote in ThreadView (Issue A)
- Fix: switchAccount no longer silently goes read-only when nsec keychain
  entry is missing — nsec accounts stay logged out so the login button
  handles recovery; loginType field added to SavedAccount (Issue B)
- Fix: macos-12 runner replaced with macos-13 in release.yml — macos-12
  was deprecated by GitHub, causing macOS jobs to never run, which
  prevented latest.json from being assembled and broke the auto-updater
  for every user since v0.1.5
- Bump Cargo.toml version (was stuck at 0.1.10)
- Release notes updated with v0.2.1 + v0.2.0 Phase 2 changelog
- README: Windows unsigned installer note added
- ROADMAP: NIP-05 monetization added to brainstorm backlog

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.1
2026-03-12 11:17:33 +01:00
Jure
fd1e5cac44 Fix copyright attribution in README and About page
Show full "MIT License — Copyright (c) 2026 Jure Sršen" in both
places to match the LICENSE file exactly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 20:41:42 +01:00
Jure
3a196cb9a0 Bump to v0.2.0 — Phase 2: Engagement & Reach
Four features shipped in this release:

- Feed reply context: replies show "↩ replying to @name" above the
  note content; clicking fetches and opens the parent thread

- NIP-65 outbox model: fetchUserRelayList + publishRelayList +
  fetchUserNotesNIP65 in client.ts; profile notes fetched via the
  author's write relays; "Publish relay list to Nostr" button in
  Settings (kind 10002)

- Notifications: new store (notifications.ts) + NotificationsView;
  🔔 sidebar nav item with unread badge; DM nav item also shows
  unread conversation count; badges clear on open/select

- Keyboard shortcuts: useKeyboardShortcuts hook + HelpModal;
  n=compose, /=search, j/k=feed nav with ring highlight,
  Esc=back, ?=help overlay

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.0
2026-03-11 20:39:30 +01:00
Jure
181233796b Bump to v0.1.10 — Bitcoin QR to right edge on Support page
Use justify-between on the QR section so Lightning address sits flush
left and Bitcoin address sits flush right, making them visually
impossible to confuse when scanning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.10
2026-03-11 20:02:30 +01:00
Jure
fdb7aab9d1 Bump version to v0.1.9 — fix account switch read-only bug (root cause)
Root cause: switchAccount fetched the nsec from the OS keychain on every
switch. Any keychain failure (timeout, Windows Credential Manager quirk,
no entry yet) silently fell through to loginWithPubkey → read-only mode.

Fix: cache each NDKPrivateKeySigner in-memory (_signerCache map) the
moment loginWithNsec succeeds. switchAccount checks the cache first;
the OS keychain is now only consulted at startup (restoreSession). Signers
are pure crypto objects with no session state — safe to reuse indefinitely.

Verified with a 9-switch stress test across 3 accounts (A1→A2→A3→A1→
A2→A1→A3→A2→A1): hasSigner=true and correct pubkey on every switch.

Also adds dev tooling:
- src/lib/tauri-dev-mock.ts: localStorage-backed keychain + SQLite stubs
  so the frontend can run in a plain browser for Playwright testing
- src/main.tsx: import mock first in DEV mode (no-op in production)
- test/gen-accounts.mjs: generates 3 deterministic test keypairs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.9
2026-03-11 15:11:03 +01:00
Jure
cdf1a0b4a2 Bump version to v0.1.8 — Windows playtest fixes
- Fix switchAccount: check signer was set after loginWithNsec before
  returning; fall back to loginWithPubkey on silent failure; always
  navigate to feed after switch to clear stale UI
- Fix profile edit button: hidden in read-only (npub) mode; read-only
  badge shown in profile header to make state visible
- Sidebar: show version number (v0.1.8) below WRYSTR brand, auto-tracked
  from package.json — no more hardcoding
- Support page: increase QR code gap (gap-8 → gap-16) to prevent
  accidentally scanning the wrong address
- ROADMAP: add language/alphabet feed filter to Phase 3 backlog

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.8
2026-03-11 13:39:30 +01:00
Jure
dba930ae29 Update README and ROADMAP for v0.1.7
README: add v0.1.7 features (per-account NWC, image paste, new account
tab, conditional zap, etc.), update "Up next" to Phase 2, add GitHub
Sponsors to Support table.

ROADMAP: mark Phase 1 complete, move all shipped items to changelog
(v0.1.3–v0.1.7), Phase 2 is now the active target.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:31:35 +01:00
Jure
c0608a18fe Fix CI: remove invalid "updater" bundle target + update release notes
"updater" is not a valid Tauri 2.x bundle target — the auto-updater
is configured as a plugin, not a bundle format. This was causing
exit code 1 on all three platforms for the v0.1.6 build.

Also updates release notes in the workflow for v0.1.7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.7
2026-03-11 12:26:41 +01:00
Jure
e8ad01117b Bump version to 0.1.7 — Windows playtest fixes
Critical:
- NWC wallet now stored per-account (wrystr_nwc_<pubkey>); switching
  accounts loads the correct wallet automatically
- Clear NDK signer before account switch to prevent race where old
  account could sign outgoing events
- LoginModal: add "New account" tab to create a fresh keypair inline
  (same flow as onboarding, with nsec copy + confirmation checkbox)
- ThreadView: add like + zap action row to the root note (was missing)

UX:
- Zap button now conditional on lud16/lud06 (NoteCard, ProfileView,
  RootNote) — no zap button shown for profiles without Lightning
- Remove "200 notes" counter from sidebar footer
- AccountSwitcher: larger active account avatar (w-8), name more
  prominent; sign-out/remove moved into dropdown only

Quick wins:
- AboutView: add GitHub Sponsors link
- ComposeBox: paste image from clipboard → uploads via nostr.build,
  inserts URL at cursor with "uploading image…" status

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:19:48 +01:00
Jure
7d68b1fa6f Bump version to 0.1.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.6
2026-03-10 22:44:03 +01:00
Jure
0fba49c812 Switch Linux packaging from AppImage to deb + rpm + PKGBUILD
AppImage library bundling causes cascading compatibility failures on
rolling-release distros (Arch, mesa 26+): libwayland-egl conflicts
break EGL, removing it cascades into GLib version mismatches, and so
on. Native packages sidestep this entirely.

- tauri.conf.json: targets now ["deb","rpm","nsis","msi","dmg","updater"]
  — no AppImage
- release.yml: drop LINUXDEPLOY_EXCLUDELIST workaround (no longer needed);
  update install instructions in release body
- PKGBUILD: added for Arch/Manjaro users; builds from source via git tag;
  desktop entry sets WEBKIT_DISABLE_DMABUF_RENDERER=1 (required on Wayland)
- README: install table updated with distro-specific commands

Arch users: build from source with PKGBUILD or `npm run tauri build`.
Ubuntu/Debian/Fedora/openSUSE: install the .deb or .rpm from Releases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 22:43:54 +01:00
Jure
b1647d7a20 Fix Linux AppImage blank window on mesa 26+ / Arch / modern distros
The AppImage bundled libwayland-egl.so.1 from ubuntu-22.04 which is
incompatible with mesa 26's EGL implementation, causing:
  "Could not create default EGL display: EGL_BAD_PARAMETER. Aborting..."

Fix: exclude all libwayland-* libs from the AppImage via LINUXDEPLOY_EXCLUDELIST
so the app always uses the system's Wayland libraries. The dev binary
already worked correctly since it uses system libs directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 22:28:03 +01:00
Jure
708c54b2a3 Merge pull request #1 from hoornet/hoornet-patch-1
Update Liberapay username in FUNDING.yml
2026-03-10 22:05:35 +01:00
Jure
2fe95473a3 Add Support section to README so #support anchor works
Fixes broken "Zap the developer" link in GitHub release notes.
Includes Lightning, Bitcoin, Ko-fi, and in-app zap instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 22:04:01 +01:00
Jure
3e3532d47d Update Liberapay username in FUNDING.yml 2026-03-10 21:57:28 +01:00
Jure
98f5d70024 Bump version to 0.1.5 + update release notes (Phase 1 complete)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.5
2026-03-10 21:05:42 +01:00
Jure
5659f18099 Add auto-updater (Phase 1 #4)
- tauri-plugin-updater + tauri-plugin-process registered (Rust + npm)
- Updater endpoint: github.com/hoornet/wrystr/releases/latest/download/latest.json
- Ed25519 signing keypair generated; public key in tauri.conf.json;
  private key added to TAURI_SIGNING_PRIVATE_KEY GitHub secret
- Release workflow passes TAURI_SIGNING_PRIVATE_KEY env var so
  tauri-action signs artifacts and generates latest.json manifest
- useUpdater hook: checks for updates 5 s after startup (silent on
  error); exposes available, version, install(), dismiss()
- UpdateBanner: dismissible top-of-app bar shown when an update is
  available — "Update & restart" downloads, installs, and relaunches

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 21:00:14 +01:00
Jure
4cde2fe4c7 Add quoted note inline preview (Phase 1 #3)
- fetchNoteById(eventId): fetches a single event by ID
- NoteContent: note1 and nevent1 (kind 1) references now parsed as
  "quote" segment type instead of plain mention text
- QuotePreview component: lazily fetches the referenced note, renders
  a bordered card with author avatar + name + truncated content;
  click navigates to the thread view
- Quote cards rendered as a block below the note text, consistent with
  how images/videos are handled
- naddr1 (kind 30023) and other nevent kinds still open via the
  existing article/njump.me handler

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:46:08 +01:00
Jure
af5e04f963 Add zap counts on notes (Phase 1 #2)
- fetchZapCount(eventId): fetches kind 9735 receipts for an event,
  parses millisat amounts from embedded zap request description tags,
  returns { count, totalSats }
- useZapCount hook: session-cached, same pattern as useReactionCount
- NoteCard: zap button shows " N sats" when total > 0, falls back
  to " zap" when no zaps yet; stats row shown for logged-out users
  displaying ♥ and  counts when non-zero

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:43:54 +01:00
Jure
ab7af96c45 Add long-form article reader (Phase 1 #1, NIP-23)
- fetchArticle(naddr): fetches kind 30023 by d-tag + author pubkey
- fetchAuthorArticles(pubkey): for future profile articles tab
- ArticleView: cover image, title, italic summary, author row (avatar +
  name + date), tag pills, full markdown body (DOMPurify sanitized),
  zap author button in header and footer, copy nostr: link, njump.me
  fallback on fetch error
- prose-article CSS: reader-optimised typography (15px base, 1.8 line
  height, h2 border, styled blockquote/code/pre/links/images)
- NoteContent: naddr1 clicks for kind 30023 now open ArticleView
  instead of falling through to njump.me
- openArticle(naddr) added to UI store with previousView tracking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:42:13 +01:00
Jure
f0cb9a97bb Restructure roadmap into Phase 1/2/3 with release gates between phases
Phase 1 (OpenSats priority): article reader, zap counts, quoted note
preview, auto-updater.

Phase 2 (engagement): notifications, NIP-65 outbox, reply context,
keyboard shortcuts.

Phase 3 (polish): NIP-17 DMs, image lightbox, bookmarks, follow
suggestions, UI polish.

Also documents all shipped features through v0.1.x and captures the
brainstorm backlog (WOT, NIP-23 depth, NIP-46).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:38:17 +01:00
Jure
6464ba2a79 Add Direct Messages — NIP-04 encrypted DMs (roadmap #13)
Nostr layer:
- fetchDMConversations: fetches all kind-4 events to/from the user
  (both directions in parallel), deduplicates, newest-first
- fetchDMThread: fetches both directions for a specific conversation,
  sorted oldest-first for display
- sendDM: NIP-04 encrypts content via NDK signer, publishes kind 4
- decryptDM: decrypts regardless of direction (ECDH shared secret is
  symmetric — always pass the other party to signer.decrypt)

UI (DMView):
- Two-panel layout: conversation list (w-56) + active thread
- ConvRow: avatar, name, time; shows "🔒 encrypted" preview to avoid
  decrypting the whole inbox on load
- MessageBubble: decrypts lazily on mount; mine right-aligned,
  theirs left-aligned; shows "Could not decrypt" on failure
- ThreadPanel: loads full thread, auto-scrolls to bottom, re-fetches
  after send; Ctrl+Enter to send
- NewConvInput: start a new conversation by pasting an npub1 or hex
  pubkey; validates and resolves before opening thread
- Read-only (npub) accounts see a clear "nsec required" message

Navigation:
- ✉ messages added to sidebar nav
- openDM(pubkey) in UI store → navigates to dm view with pending pubkey
- ProfileView: "✉ message" button in action row opens DM thread

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:29:05 +01:00
Jure
65d103f252 Bump version to 0.1.4 + update release notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.4
2026-03-10 20:22:48 +01:00
Jure
d72dfe56d8 Search improvements — NIP-50 relay detection + smarter zero-results (roadmap #12)
- relayInfo.ts: checkNip50Support fetches NIP-11 relay info (Accept:
  application/nostr+json) and checks supported_nips for 50; results
  cached per session with 4s timeout; getNip50Relays checks all relays
  in parallel

- SearchView: relay NIP-50 support checked on mount in the background
  and shown as context in the idle state ("N of M relays support
  full-text search") and in zero-results states

- Zero results for full-text search now shows:
  - relay NIP-50 count (or "none of your relays support full-text")
  - prominent "Search #<query>" one-click button to retry as hashtag

- Tabs (notes / people) now always rendered after any search, not only
  when both result types are non-empty — makes the UI consistent

- Per-tab zero-results explanations: people tab explains NIP-50
  requirement when no relay supports it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:21:22 +01:00
Jure
abd38a4edd Add profile helpers for newcomers (roadmap #11)
Image upload (ImageField):
- "upload" button next to profile picture and banner URL fields
- Opens native file picker (accept="image/*"), uploads to nostr.build
  free hosting via their v2 API, auto-fills the URL on success
- Shows inline error if upload fails; URL field still editable manually

NIP-05 verification (Nip05Field):
- Replaces the plain nip05 text field
- Debounced live check (900ms): fetches /.well-known/nostr.json?name=...
  and compares the returned pubkey against the logged-in user's pubkey
- Status badges: checking… / ✓ verified / ✗ pubkey mismatch / ✗ not found
- "How to get verified ↗" link to nostr.how guide

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:18:18 +01:00
Jure
288abdc180 Sidebar improvements (roadmap #10)
- sidebarCollapsed now persisted to localStorage — remembered across sessions
- Explicit ‹/› toggle button always visible in the header; no longer
  requires knowing to click the WRYSTR wordmark
  - Expanded: WRYSTR on left, ‹ collapse button on right
  - Collapsed: centered › expand button fills the header
- Write article (✦) now visible in collapsed mode as icon-only with
  tooltip, consistent with the rest of the nav
- Nav items have title tooltip in collapsed mode for discoverability
- Status footer: collapsed shows just the connection dot with tooltip;
  expanded shows dot + online/offline text + note count as before

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:41:16 +01:00
Jure
faaf8ac4a4 Bump version to 0.1.3 + update README and release notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.3
2026-03-10 19:37:57 +01:00