Commit Graph

29 Commits

Author SHA1 Message Date
Jure
fa1eb0d89b Make logged-out state visually obvious with top banner 2026-04-04 21:07:09 +02:00
Jure
ebf964980b Add V4V sidebar section with dashboard, settings, and history
- New V4V store with budget tracking, cap enforcement, and history
- Dashboard: live streaming status, per-episode + weekly budget bars, stats
- Settings: auto-enable toggle (guarded by caps), per-episode cap, weekly
  budget, default rate, info icons
- History: expandable list of past V4V episodes with recipient breakdowns
- Budget enforcement: streaming stops with toast when cap is hit
- Auto-streaming: starts automatically for V4V episodes when enabled
- Cap reached state: dashboard shows red card, ticker shows "(capped)"
- V4VIndicator: slimmed popup, AUTO badge, "open v4v" nav link
- Fix duplicate history entries on cap stop
2026-04-04 19:03:00 +02:00
Jure
ae5b9a444c Optimize rendering: memo, granular selectors, code splitting
- React.memo on NoteCard and ArticleCard to skip re-renders
- Granular Zustand selectors in Feed.tsx and NoteCard.tsx
- Lazy-load 19 views with React.lazy + Suspense boundary
2026-04-02 18:03:19 +02:00
Jure
5cbaa7b741 Rename Wrystr to Vega
Named after Jurij Vega (1754-1802), Slovenian mathematician who made
knowledge accessible through his logarithm tables. Rebrand before
OpenSats application (April 1).

- Product name, window title, identifiers, binary name all renamed
- Cargo package: wrystr -> vega, wrystr_lib -> vega_lib
- PKGBUILD: wrystr -> vega (new AUR package name)
- Release workflow: artifact names, release text updated
- README: new tagline referencing Jurij Vega
- DB migration: auto-renames wrystr.db -> vega.db on first launch
- Keyring service name kept as "wrystr" for backward compatibility
- localStorage keys kept as wrystr_* to preserve existing user data

Pending manual steps:
- Rename GitHub repo hoornet/wrystr -> hoornet/vega
- Create new AUR package vega-git, orphan wrystr-git
- Update local .desktop launcher
2026-03-30 21:14:02 +02:00
Jure
6da5f6a74c Move zoom from document root to main content area only
Sidebar now stays at fixed size regardless of font setting. Only the
content area (feed, settings, thread, articles, etc.) scales with the
font size preference. This prevents the sidebar from bloating and
eating into content space at larger zoom levels.
2026-03-25 16:34:55 +01:00
Jure
255faefbdc Add follows view with followers/following tabs and new follower badges
Followers tab fetches kind 3 events referencing the user, following tab
shows the contact list. Each row has avatar, NIP-05 badge, follow/unfollow
button, and "follows you" indicator. New follower notifications from the
background poller increment a sidebar badge that clears on view open.
2026-03-25 10:21:18 +01:00
Jure
ad028c7406 Bump to v0.9.3 — color themes, font size, settings polish
7 color themes (Midnight, Light, Catppuccin Mocha, Tokyo Night, Gruvbox,
Ethereal, Hackerman), font size presets (Small/Normal/Large/Extra Large),
collapsible muted accounts list, removed old sidebar connection indicator.
2026-03-24 12:16:08 +01:00
Jure
1f50afded7 Add subscription debug panel (Ctrl+Shift+D)
Hidden dev tool showing NDK uptime, live subscription status,
per-relay connection state, per-tab last-updated timestamps,
and recent feed diagnostics log. Polls every 2s while visible.
Closes with Ctrl+Shift+D, Escape, or X button.
2026-03-23 19:12:29 +01:00
Jure
ac4e39fcbf Add relay status badge, toast notifications, per-tab feed timestamps, relay UX improvements
- Relay status badge in feed header: shows connected/total relay count with
  color coding (green >75%, yellow 25-75%, red <25%), hover tooltip with
  per-relay status
- Toast notification system: transient messages for connection lost,
  reconnecting, relay reset, and back-online events
- Per-tab "last updated" relative timestamp in feed header (global,
  following, trending tracked independently)
- Consolidated all relay management into RelaysView (removed duplicate
  relay section from Settings); per-relay remove button on health cards
- Show all supported NIP badges on relay cards (was filtering to 11 notable)
- Tooltips on relay status dots explaining green/yellow/red/gray meaning
- Fix relay removal with trailing-slash URL normalization
- Fix stale health results lingering after relay removal
- Add acknowledgements section to README
2026-03-23 11:28:53 +01:00
Jure
04180cf186 Add podcast playback, Fountain.fm cards, V4V streaming, fix notifications
Podcast feature:
- Podcast discovery via Podcast Index API (trending + search)
- Persistent player bar with play/pause, seek, speed (1x/1.5x/2x), volume
- Audio persists across view navigation, resumes from saved position
- Fountain.fm URL detection in feed with rich playable cards
- "Play in Wrystr" button on inline audio blocks
- V4V streaming sats via NWC (LNURL-pay, 5min accumulation, split payments)
- Share what you're listening to (publish note with confirm)
- Space key toggles play/pause globally

Notification fixes:
- Per-notification read tracking (click to mark read) instead of mark-all-on-open
- Read notifications persist at 50% opacity, unread get accent border
- Always fetches last 7 days, keeps 15 most recent
- Filter out own replies from notifications
- Sidebar badge shows only unread count
2026-03-21 12:53:05 +01:00
Jure
c65ddb1c26 Fix test bugs: mute filtering, notification toggles, external links, emoji picker
- Fix mute button having no effect in Media Feed (missing filter)
- Fix notification toggle switches overlapping labels (sizing + shrink-0)
- Fix external links not opening in system browser (use Tauri opener plugin)
- Fix trending refresh showing no visual feedback (clear list on force refresh)
- Fix emoji reactions inaccessible behind WebKitGTK context menu (visible + button)
- Add emoji picker to compose box, inline reply, and thread reply
- New shared EmojiPicker component with categorized emoji groups
2026-03-20 15:32:57 +01:00
Jure
0bcbba6e8f Bump to v0.8.3 — trending feed, NIP-46 remote signer, media feed, profile media gallery 2026-03-20 12:45:58 +01:00
Jure
57630227e1 Add NIP-05 badges, hashtag pages, keyword muting, suggestion dismissal, notification poller
- Article cover: aspect-video replaces max-h-72 for consistent 16:9
- NIP-05 verification badge on note cards with 1-hour TTL cache
- Dedicated hashtag feed pages (clicking #tag opens live feed, not search)
- Keyword muting: word-boundary matching, applied across all feed views
- Follow suggestion dismissal: persistent "don't suggest again" per person
- Background notification poller (60s): mentions, zaps, new followers
- All notification types independently toggleable in settings
- Centralized notification firing (removed inline store notifications)
2026-03-20 12:09:11 +01:00
Jure
ef189932e6 Bump to v0.6.0 — article discovery, search, profile tab, reader polish
Article discovery feed with Latest/Following tabs, article search
(NIP-50 + hashtag for kind 30023), Notes/Articles tab on profiles,
reading time + bookmark + like buttons on article reader. Event
passed directly from card to reader to avoid relay re-fetch failures.
2026-03-17 21:47:24 +01:00
Jure
17011252d6 Preserve feed scroll position across navigation
Keep Feed component mounted (hidden via CSS) instead of unmounting
when navigating to threads/profiles/etc. Back button now returns to
the exact scroll position in the feed.
2026-03-15 19:44:10 +01:00
Jure
c8d2b05440 Bump to v0.4.0 — Phase 3: image lightbox, bookmarks, discover, language filter, UI polish 2026-03-14 18:00:28 +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>
2026-03-11 20:39:30 +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
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
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
16446573c4 Add zap history view (roadmap #9)
- fetchZapsReceived: kind 9735 filtered by #p tag (receipts)
- fetchZapsSent: kind 9734 filtered by authors (zap requests)
- ZapHistoryView: Received / Sent tabs with row count; header shows
  total sats in/out; each row: avatar, amount, counterpart name
  (clickable → profile), comment, time ago
- Receipt parsing: amount from embedded zap request in "description"
  tag (millisats → sats); sender from uppercase "P" tag with fallback
  to zap request pubkey
- Request parsing: amount from "amount" tag, recipient from "p" tag
-  zaps nav item added to sidebar between search and relays
- Logged-out fallback state with prompt to log in

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:32:44 +01:00
Jure
926a7cbdae Add About / Support page (roadmap #4)
- New 'about' view wired into sidebar nav (♥ support) and App.tsx
- Sections: in-app zap button (reuses ZapModal + NWC infra), Lightning
  address QR + copy, Bitcoin address QR + copy, Ko-fi link, GitHub link,
  version/tech credits footer
- QR codes rendered as SVG via react-qr-code (no canvas dependency)
- lightning: URI and bitcoin: URI formats for wallet-scannable QR codes
- Tasteful and non-nagging — lives in the nav, never pops up unprompted

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 18:16:54 +01:00
Jure
c84e5d3a3b Add onboarding flow for new users
- OnboardingFlow replaces app layout on first visit (no wrystr_pubkey in localStorage)
- Welcome screen: plain-language explanation of Nostr/keys, two paths
- Create path: NDKPrivateKeySigner.generate(), show npub with copy button
- Backup step: show nsec with danger styling, copy button, checkbox confirmation
  required before proceeding — login happens only after user confirms backup
- Login path: existing nsec or read-only npub, back button to welcome
- On complete: normal app layout shown; pubkey in localStorage acts as the flag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 17:55:27 +01:00
Jure
2370fc21f9 Add search view (NIP-50 + hashtag + people)
- searchNotes: NIP-50 full-text for text queries, #t tag filter for #hashtags
- searchUsers: NIP-50 kind 0 search for people
- SearchView with tabbed notes/people results, follow/unfollow inline
- Hashtag queries skip people search and use universal #t filter
- Graceful empty state explains NIP-50 relay support caveat
- Search added to sidebar nav (⌕)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 17:38:54 +01:00
Jure
bf1d68bb93 Add long-form article editor (NIP-23)
- ArticleEditor with title, markdown body, summary, cover image, tags
- write/preview toggle with markdown rendering via marked
- Auto-save draft to localStorage
- Publish as kind 30023 with NIP-23 tags (d, title, published_at, etc.)
- 'write article' button in sidebar when logged in
- Article preview prose styles in CSS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 19:04:43 +01:00
Jure
366731f9d7 Add thread view with replies
- Click note content to open thread view
- ThreadView shows root note, reply composer, and replies
- fetchReplies added to nostr lib (kind 1 #e filter)
- UI store gains openThread, goBack, previousView for navigation history
- Profile back button now returns to previous view correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:55:57 +01:00
Jure
5879a640df Add profile view with clickable names/avatars
- ProfileView shows avatar, bio, nip05, website, recent notes
- Clicking any name or avatar navigates to their profile
- Add fetchUserNotes to nostr lib (kind 1 by author)
- Add openProfile action + selectedPubkey to UI store
- Back button returns to feed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:48:05 +01:00
Jure
b75ccb7f46 Working feed: NDK + relay connection + live notes from Nostr
- Tailwind CSS + Zustand + NDK installed and configured
- Sidebar with feed/relays/settings navigation
- Global feed view with live notes from relays
- Profile fetching with caching and deduplication
- Relay connection with timeout handling
- Note cards with avatar, name, timestamp, content
- Dark theme, monospace, no-slop UI
- Devtools enabled for debugging
2026-03-08 14:54:04 +01:00
Jure
43e14f9f04 Scaffold Tauri 2.0 + React + TypeScript app 2026-03-08 14:28:25 +01:00