From 2c874de790c59ee57160d59f1ebd2d3cf765417d Mon Sep 17 00:00:00 2001 From: Jure <44338+hoornet@users.noreply.github.com> Date: Thu, 12 Mar 2026 11:17:33 +0100 Subject: [PATCH] =?UTF-8?q?Bump=20to=20v0.2.1=20=E2=80=94=20Batch=203=20pl?= =?UTF-8?q?aytest=20fixes=20+=20auto-updater=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .github/workflows/release.yml | 15 +++++++++- README.md | 2 ++ ROADMAP.md | 9 ++++++ package.json | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/components/thread/ThreadView.tsx | 41 +++++++++++++++++++++++++++- src/stores/user.ts | 13 +++++++-- 8 files changed, 78 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab0906a..d3aa40f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: args: '' - platform: macos-latest args: '--target aarch64-apple-darwin' - - platform: macos-12 + - platform: macos-13 args: '--target x86_64-apple-darwin' runs-on: ${{ matrix.platform }} @@ -66,6 +66,19 @@ jobs: Cross-platform Nostr desktop client — polished UI, deep Lightning integration, first-class long-form writing. + > **Windows note:** The installer is not yet code-signed. Windows SmartScreen will show an "Unknown publisher" warning — click "More info → Run anyway" to install. + + ### New in v0.2.1 + - **Fix: repost + quote in thread view** — thread view now shows repost and quote buttons on the root note (they were already on feed notes but were missing in threads) + - **Fix: login persistence after Windows update** — nsec accounts whose keychain entry was lost after an OS update now stay logged out (login button visible) instead of silently becoming read-only + + ### New in v0.2.0 — Phase 2: Engagement & Reach + - **Feed reply context** — replies show "↩ replying to @name" above the note; click to open the parent thread + - **NIP-65 outbox model** — reads kind 10002 relay lists so you see notes from people who publish to their own relays; "Publish relay list to Nostr" button in Settings + - **Notifications view** — 🔔 sidebar nav item; lists recent mentions with unread badge; badge clears on open + - **DM unread badge** — messages nav item shows count of conversations with new messages; clears when conversation is opened + - **Keyboard shortcuts** — `n` focus compose, `/` focus search, `j`/`k` navigate feed with highlight, `Esc` go back, `?` help overlay + ### New in 0.1.7 - **Per-account Lightning wallet** — NWC connection is now stored per account; switching accounts loads the correct wallet automatically - **New account creation in-app** — "Add account" now has a "New account" tab that generates a fresh keypair (no need to go through onboarding again) diff --git a/README.md b/README.md index 74396c1..4e7c87c 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Grab the latest release from the [Releases page](https://github.com/hoornet/wrys | macOS (Apple Silicon) | `aarch64.dmg` | open and drag to Applications | | macOS (Intel) | `x86_64.dmg` | open and drag to Applications | +**Windows note:** The installer is not yet code-signed. Windows SmartScreen will show an "Unknown publisher" warning — click "More info → Run anyway" to install. + ## Features **Identity & accounts** diff --git a/ROADMAP.md b/ROADMAP.md index 5df4682..b1b31df 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -96,10 +96,19 @@ Bugs found during testing are fixed before Phase N+1 starts. A release is cut be - Sign events via a remote signer (Nsecbunker, Amber, etc.) - Would complete the multi-account story for users who don't want nsec in keychain +### NIP-05 monetization (Phase 4 idea) +- Offer a paid "Verified NIP-05 name" service (e.g. name@wrystr.app) +- Would need a backend + domain; Wrystr talks to it; users pay sats via Lightning +- Free tier: self-hosted as today; paid tier: managed registration + --- ## What's already shipped +### v0.2.1 — Batch 3 playtest fixes +- **Fix: repost + quote in thread view** — root note in thread view now shows repost and quote buttons (parity with feed cards) +- **Fix: login persistence after Windows update** — nsec accounts with a lost keychain entry now stay logged out (login button visible) instead of silently going read-only + ### v0.2.0 — Phase 2: Engagement & Reach - **Feed reply context** — replies show "↩ replying to @name" above the note; click to open the parent thread - **NIP-65 outbox model** — reads kind 10002 relay lists so you see notes from people who publish to their own relays; profile notes fetched via their write relays; "Publish relay list to Nostr" button in Settings diff --git a/package.json b/package.json index 85ed934..2c71f5a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "wrystr", "private": true, - "version": "0.2.0", + "version": "0.2.1", "type": "module", "scripts": { "dev": "vite", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 6d36267..492a1ca 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wrystr" -version = "0.1.10" +version = "0.2.1" description = "Cross-platform Nostr desktop client with Lightning integration" authors = ["hoornet"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 85dc717..719a4e7 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Wrystr", - "version": "0.2.0", + "version": "0.2.1", "identifier": "com.hoornet.wrystr", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/components/thread/ThreadView.tsx b/src/components/thread/ThreadView.tsx index 137ec6c..0df39ee 100644 --- a/src/components/thread/ThreadView.tsx +++ b/src/components/thread/ThreadView.tsx @@ -5,7 +5,8 @@ import { useUserStore } from "../../stores/user"; import { useProfile } from "../../hooks/useProfile"; import { useReactionCount } from "../../hooks/useReactionCount"; import { useZapCount } from "../../hooks/useZapCount"; -import { fetchReplies, publishReaction, publishReply, getNDK } from "../../lib/nostr"; +import { fetchReplies, publishReaction, publishReply, publishRepost, getNDK } from "../../lib/nostr"; +import { QuoteModal } from "../feed/QuoteModal"; import { shortenPubkey, timeAgo } from "../../lib/utils"; import { NoteContent } from "../feed/NoteContent"; import { NoteCard } from "../feed/NoteCard"; @@ -27,6 +28,9 @@ function RootNote({ event }: { event: NDKEvent }) { }); const [liking, setLiking] = useState(false); const [showZap, setShowZap] = useState(false); + const [reposting, setReposting] = useState(false); + const [reposted, setReposted] = useState(false); + const [showQuote, setShowQuote] = useState(false); const hasLightning = !!(profile?.lud16 || profile?.lud06); const handleLike = async () => { @@ -44,6 +48,17 @@ function RootNote({ event }: { event: NDKEvent }) { } }; + const handleRepost = async () => { + if (reposting || reposted) return; + setReposting(true); + try { + await publishRepost(event); + setReposted(true); + } finally { + setReposting(false); + } + }; + return (
@@ -79,6 +94,21 @@ function RootNote({ event }: { event: NDKEvent }) { > {liked ? "♥" : "♡"}{reactionCount !== null && reactionCount > 0 ? ` ${reactionCount}` : liked ? " liked" : " like"} + + {hasLightning && (
); } diff --git a/src/stores/user.ts b/src/stores/user.ts index 5e49995..6e951fd 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -13,6 +13,7 @@ export interface SavedAccount { npub: string; name?: string; picture?: string; + loginType?: "nsec" | "pubkey"; } // In-memory signer cache — survives account switches within a session. @@ -98,7 +99,7 @@ export const useUserStore = create((set, get) => ({ _signerCache.set(pubkey, signer); // Update accounts list - const accounts = upsertAccount(get().accounts, { pubkey, npub }); + const accounts = upsertAccount(get().accounts, { pubkey, npub, loginType: "nsec" }); persistAccounts(accounts); set({ pubkey, npub, loggedIn: true, loginError: null, accounts }); @@ -142,7 +143,7 @@ export const useUserStore = create((set, get) => ({ const npub = nip19.npubEncode(pubkey); // Update accounts list - const accounts = upsertAccount(get().accounts, { pubkey, npub }); + const accounts = upsertAccount(get().accounts, { pubkey, npub, loginType: "pubkey" }); persistAccounts(accounts); set({ pubkey, npub, loggedIn: true, loginError: null, accounts }); @@ -229,7 +230,13 @@ export const useUserStore = create((set, get) => ({ // Keychain unavailable } if (!succeeded) { - await get().loginWithPubkey(pubkey); + const account = get().accounts.find((a) => a.pubkey === pubkey); + if (account?.loginType === "pubkey") { + // Deliberately read-only (npub) account — correct behavior + await get().loginWithPubkey(pubkey); + } + // else: nsec account whose keychain entry was lost. + // Stay logged out; user sees AccountSwitcher "login" button to re-enter nsec. } // Always land on feed to avoid stale UI from previous account's view useUIStore.getState().setView("feed");