Wrap all Tor library interactions in try-catch blocks so that failures
in the Tor service (JNI, control connection, bind/unbind) are logged
and gracefully degrade to TorServiceStatus.Off instead of crashing
the entire app.
https://claude.ai/code/session_019JDZMTvVdJyc9z2WmoAimv
The visual transformation for message edit fields now processes nostr:npub1...,
nostr:nprofile1..., and @nprofile1... mentions in addition to the existing @npub1...
pattern. Both UrlUserTagOutputTransformation (new API) and UrlUserTagTransformation
(old API) are updated to resolve these to user display names.
https://claude.ai/code/session_012ijrLmft5PjcQ64zDwXJWj
Replace typed consume() overloads that simply forwarded to
consumeRegularEvent() or consumeBaseReplaceable() with direct calls
in the when dispatch block. This removes ~600 lines of boilerplate
without changing behavior.
https://claude.ai/code/session_017dM6dt1on3g3yhWSi69Pwq
When a user hits Quote, the new post screen opens with the nostr URI
pre-filled but the cursor was at the end (after the URI). This moves
the cursor to the beginning so the user can immediately start typing
their commentary.
https://claude.ai/code/session_01RPseKC9GJ8hs3GGBR85ezw
When events share the same createdAt timestamp, the tiebreaker sort by id
must be ascending to produce a stable, deterministic order. Fixed several
locations that either had no secondary sort, used descending id sort, or
used .reversed() which incorrectly flipped both sort directions.
https://claude.ai/code/session_01RvuyPf1x9wLf2DCgsSXLGz
Add a new notification channel for reactions (kind 7 events) so users
get notified when someone reacts to their posts. Follows the same
pattern as zap notifications with deduplication, time-window filtering,
and grouped summaries.
https://claude.ai/code/session_01J9rAA4oeFEfNcYD6GoJqqt
Enable the message field to receive images/GIFs from Android's keyboard
using Compose Foundation's contentReceiver API. When content is received,
it's routed through the existing selectImage flow for upload.
https://claude.ai/code/session_019GfY3MtCPcYn3wqTHCMSNu
The external signer registration logic was failing when the signer was
wrapped in a `NostrSignerWithClientTag`. Fix by:
1. Updating `ListenToExternalSignerIfNeeded` to unwrap the signer if it's
a `NostrSignerWithClientTag` containing an `IActivityLauncher`
2. Using the unwrapped launcher for intent registration and response handling
3. Renaming the intent callback to `intentLauncher` to avoid shadowing the `ActivityResultLauncher` variable
Use Channel(UNLIMITED) as a lock-free send queue and AtomicBoolean with
atomic exchange for the isSending flag, eliminating all synchronized blocks
while maintaining thread safety via a double-check pattern.
https://claude.ai/code/session_01KLRz7FJgWRtgCcZe3qD1VX