Audit outcome for the two suspected "double-prompt" Amber flows:
• Image upload — CONFIRMED already a single signature. BlossomUploader
(even at the pinned 0.47.1) signs one kind-24242 auth event and reuses
it across all servers via Promise.any, so uploads = 1 Amber prompt. No
change needed.
• DM / crew-chat send — the multiple prompts are protocol-inherent and
MUST NOT be optimized away: NIP-17 seals+signs once per recipient (and
to self); a Cordn crew message signs an author proof then encrypts once
per roster member. Reducing the count would weaken confidentiality or
authorship. So instead of a code shortcut we add transparency.
New <AmberApprovalHint>: a tiny heads-up shown ONLY to interactive
(Amber) signers before an inherently multi-approval action, telling them
how many Approve screens to expect and that it's normal. Renders nothing
for silent signers (extension/nsec/bunker), where the ops are invisible.
Wired into:
• CrewChat composer — count derived from transport + roster size
(Cordn: roster+1; NIP-17: roster*2).
• ConversationPage (1:1 DM) composer — 4 approvals (encrypt+sign to the
recipient and to yourself).
Dependencies: reviewed the full manifest; deliberately left unchanged.
Every upgrade candidate is either on the critical crypto/Nostr/payments
path (nostrify, nostr-tools, cashu, bitcoinjs, noble, scure — pinned for
safety) or a documented major bump (lucide v1, react 19, react-router 7)
with breaking changes and no user-facing benefit. No security advisories
force a change, and caret ranges already pull safe patch/minor updates.
"It must work" wins over churn.
Bumps to 1.2.20 (Android versionCode 10220 auto-derived).
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
useConversations reported unreadCount: 0 for everything, so the inbox never
showed new messages. Add a lightweight, reliable unread signal:
- useDMRead: per-conversation, per-user last-read timestamps in localStorage
(local-only; compares against the inner rumor's real created_at, not the
fuzzed gift-wrap time, so it's accurate).
- DirectMessagesPage: a conversation is unread when its latest message is from
the other person and newer than last-read — rendered as a red dot, bolder
name, brighter preview text, and a subtle highlighted card.
- ConversationPage: opening a chat marks it read up to the newest message, so
the dot clears on return (each page mounts fresh, so no stale state).
Scope: kept to the Messages page. Deliberately did NOT add a global nav badge,
which would require background-decrypting all gift wraps on every page — the
same heavy cost avoided for the crew bell.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Root cause: NUser's extension signer exposes .nip44 as a getter that calls
.nostr (window.nostr) and THROWS when the extension isn't present. Any
synchronous access during render crashes the whole tree — the actual culprit
was useStash's `isEncryptionAvailable: !!user?.signer?.nip44` in its return
object, evaluated every render even when logged out.
- Add src/lib/signerCapabilities.ts: hasNip44/hasNip04 helpers that determine
capability via login type + direct window.nostr probe (no throwing getter).
- useStash: use the helper for hasNip44 + isEncryptionAvailable
- useDirectMessages: replace all render-path `enabled: !!user?.signer?.nip44`
with a pre-computed nip44Available across all 4 conversation hooks
- CrewChat, CrewRequestToJoin, ConversationPage, DirectMessagesPage,
ContactsPage: use the safe helper in render/guard paths
Async accesses (inside queryFn/callbacks) are left as-is — they reject
gracefully within react-query and never crash render.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
The entire skate-spots codebase was accidentally copied into src/src/ and
public/public/ instead of src/ and public/ directly. This left the real
src/ directory as blank MKStack template stubs, explaining why the landing
page showed the default template instead of SkateSpots.
Changes made:
- Copied all files from src/src/ up to src/ (App.tsx, AppRouter.tsx, main.tsx,
all pages, components, hooks, contexts, lib, i18n, test)
- Copied all files from public/public/ up to public/ (images, manifest, etc.)
- Deleted src/src/ and public/public/ nested directories
- Removed HelloWorld.tsx template stub from pages/
- Retained the previously fixed index.css (Tailwind v3 directives)
Full skate-spots feature set is now active:
- All 30+ routes (map, events, spots, coaches, marketplace, wallet, etc.)
- NWCProvider, LanguageProvider, PWAInstallPrompt, AmberCallbackHandler
- Skate community relays (goskatespots.nostr1.com, wotr.relatr.xyz, etc.)
- Outfit Variable font, Amber pre-check in main.tsx
- All hooks (useSkateSpots, useCoaches, useZaps, etc.)
- i18n support (en/es)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 22:18:28 +07:00
Renamed from src/src/pages/ConversationPage.tsx (Browse further)