Commit Graph

9995 Commits

Author SHA1 Message Date
Crowdin Bot 68f58c3b8d New Crowdin translations by GitHub Action 2026-03-15 15:06:39 +00:00
Vitor Pamplona 0380927f7e fromJsonTo calls throw, they should always be wrapped if we want null results. 2026-03-15 11:05:40 -04:00
Vitor Pamplona 2c91fdea15 Avoids using format to write hex-encoded strings. 2026-03-15 11:03:50 -04:00
Claude 764c2241ca refactor: integrate relay event counts into each ViewModel
Move count query logic from separate RelayEventCountViewModel into each
relay list's own ViewModel. BasicRelaySetupInfoModel now manages counts
via countFilters() override. Nip65RelayListViewModel gets its own count
infrastructure for home (outbox) and notification (inbox) relay lists.
Simplify AllRelayListScreen by removing 7 extra count ViewModels and
their LaunchedEffects.

https://claude.ai/code/session_016158D5mq5BygS1uBbLNbsA
2026-03-15 15:02:09 +00:00
Claude b1723a5dfb feat: add relay event count stats to AllRelay settings screen
Use NostrClient's NIP-45 COUNT queries to show how many events each
relay stores, with filters specific to each relay role:
- Outbox: events authored by the user
- Inbox: events where the user is p-tagged
- DM Inbox: DM events (kind 4, 1059) tagging the user
- Private Home: events authored by the user
- Proxy: total event count
- Search: total event count
- Indexer: kind 0 and kind 10002 counts separately
- Broadcast: no count (as specified)

https://claude.ai/code/session_016158D5mq5BygS1uBbLNbsA
2026-03-15 14:41:19 +00:00
Claude 997a59dc23 feat: add file encryption toggle for encrypted DMs with retry on failure
Add an "Encrypt files" toggle (default: on) to the file upload dialog in
NIP-17 encrypted DMs. When encrypted upload fails, show an informative
dialog explaining that many servers don't accept encrypted files on free
accounts, with an option to retry without encryption. The retry dialog
warns that without encryption anyone with the link can see the content.

https://claude.ai/code/session_012xvKzHrZPq3ZTAzBN2LvrR
2026-03-15 14:30:26 +00:00
Claude aecbcb68a5 feat: per-relay recv/new counts and OK-true acceptance tracking
ViewModel:
- MAX_ACTIVITY_LOG raised to 5000
- Remove activeRelays from LiveSyncActivity (active relay chips removed)
- Add eventsAccepted: Int to CompletedRelayInfo
- Add totalEventsAccepted: Int to SyncState.Done
- Register IRelayClientListener on account.client for the duration of
  the sync to intercept OkMessage(success=true) from destination relays
- sourceRelayOfEvent map attributes each forwarded event to the relay
  it was first seen on; ConcurrentHashMap.remove() ensures the first
  OK true is counted exactly once per event (dedup across dest relays)
- acceptedCountPerRelay accumulates per-source-relay accepted counts,
  read at onRelayComplete time
- downloadFromPool.onEvent changed to (Event, NormalizedRelayUrl) to
  carry the source relay into runSync routing logic

Screen:
- Remove ActiveRelaysCard and ActiveRelayChip composables + preview
- Remove animation imports (no longer needed)
- ActivityLogRow now shows two right-hand columns per relay:
    recv N  — events received from that source relay
    new N   — events accepted as new by destination relays (highlighted
               in primary color when > 0)
- DoneCard now shows three lines:
    Forwarded N events to destination relays.
    M events accepted as new by destination relays.  ← key headline
    Completed in N seconds.

Strings: event_sync_done_body replaced by done_sent / done_accepted /
done_duration; event_sync_reading_from and events_found_log removed;
log_recv and log_new added.

https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-15 14:19:08 +00:00
David Kaspar a21e38f428 Merge pull request #1847 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-15 11:53:03 +00:00
Crowdin Bot 7999010390 New Crowdin translations by GitHub Action 2026-03-15 11:51:55 +00:00
David Kaspar 00fb924dbb Update README with build instructions and requirements
Added instructions for full build and requirements.
2026-03-15 11:50:24 +00:00
davotoula f28fdd8404 Convert between flag types
spotlessApply
2026-03-14 21:39:27 +01:00
David Kaspar f3aafd3884 Merge pull request #1845 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-14 20:26:58 +00:00
Crowdin Bot 2df98c456a New Crowdin translations by GitHub Action 2026-03-14 20:04:41 +00:00
David Kaspar 21bf8a343a Merge pull request #1844 from davotoula/update-translations
update cz, pt, de, sv
2026-03-14 20:03:08 +00:00
David Kaspar caee58da55 Add migrations.xml to .gitignore 2026-03-14 20:02:48 +00:00
davotoula 64bf1d5090 update cz, pt, de, sv 2026-03-14 21:00:31 +01:00
Vitor Pamplona ee449f78f4 Merge pull request #1843 from davotoula/bugfix-multiple-spinners-on-upload
Bugfix: multiple spinners on upload
2026-03-14 14:10:22 -04:00
David Kaspar 9d14a2d840 Merge pull request #1842 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-14 17:30:32 +00:00
davotoula 795da8cf1b Block Add to message button while uploading 2026-03-14 18:00:36 +01:00
davotoula 1fc0ba8628 refactor:
extract MediaUploadTracker with common methods

bugfixes:
 ChatFileUploadState.canPost() was missing isUploadingFile check
 ChatNewMessageViewModel.cancel() was never resetting upload flags
 Double-reset in ChatFileUploader and ChannelNewMessageViewModel
2026-03-14 18:00:36 +01:00
davotoula 42542159d4 bugfix: remove dead code
bugfix: ChannelNewMessageViewModel canPost checks wrong state
2026-03-14 18:00:36 +01:00
davotoula c290a1c779 - SelectFromGallery and SelectFromFiles now accept an enabled param separate from isUploading
- All ViewModels track isUploadingFile alongside isUploadingImage, set via hasNonMedia()
  - All screen call sites pass source-specific flags so only the initiating button spins
  - canPost() methods block posting during file uploads too
  - ChatNewMessageViewModel delegates to ChatFileUploadState (fixes pre-existing dead state)
  - cancel() methods reset both flags in all ViewModels
2026-03-14 17:59:35 +01:00
Claude a49a0ac9ae feat: add @Preview composables to EventSyncScreen
One ThemeComparisonColumn preview per card — renders both dark and light
themes stacked — covering all independently previewable composables:

  SyncProgressCardPreview  — mid-sync progress (312/1024 relays, 4821 sent)
  PausedCardPreview        — paused state with relay/event counts
  DoneCardPreview          — completed run (18K events, 187s)
  ErrorCardPreview         — configuration error message
  ActiveRelaysCardPreview  — 5-relay FlowRow with pulsing chips
  DestinationRelaysCardPreview — all three sections (outbox/inbox/DM)
  ActivityLogCardPreview   — mixed log: found events + empty/unreachable

https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-14 16:16:36 +00:00
Claude 6aacaa7d41 fix: remove event sync section item from AllRelayListScreen
https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-14 15:51:41 +00:00
Crowdin Bot 0dce9542fb New Crowdin translations by GitHub Action 2026-03-14 15:41:38 +00:00
Vitor Pamplona 42574f302c updates change log 2026-03-14 11:39:02 -04:00
Vitor Pamplona d4ae3411c7 spotless 2026-03-14 11:36:58 -04:00
Vitor Pamplona 6739e66bd3 Merge pull request #1828 from vitorpamplona/claude/implement-nip47-wallet-Fjcds
Implement NIP-47 Wallet Connect protocol with full method support
2026-03-14 11:32:51 -04:00
Claude 78c66b00eb fix: align arrow icons to 40dp to match user picture size
https://claude.ai/code/session_01JFogiwyR4CPVP8cRznqahJ
2026-03-14 15:29:28 +00:00
Claude b7dd460734 feat: live relay activity UI for event sync screen
ViewModel now emits a LiveSyncActivity StateFlow alongside the existing
SyncState, carrying:
  - activeRelays: which relays are currently being queried
  - recentCompletions: last 100 completed relays with event counts
  - outboxTargets / inboxTargets / dmTargets: destination relay sets

downloadFromPool gains onRelayStart/onRelayComplete(relay, eventsFound)
callbacks; downloadFromRelay returns Int (total events across all pages).
Tracking uses ConcurrentHashMap.newKeySet + synchronized ArrayDeque for
thread safety across 50 concurrent workers.

Screen adds three new live cards:
  ActiveRelaysCard  — FlowRow of chips with a shared pulsing dot
                      animation (one InfiniteTransition for all chips)
  DestinationRelaysCard — Outbox / Inbox / DMs sections, color-coded
                          using primary / secondary / tertiary
  ActivityLogCard   — fixed-height (260dp) inner-scrollable list;
                      filled dot + count for active relays, muted for
                      empty/unreachable ones; K/M formatting for counts

String resources updated: event_sync_batch_of → event_sync_relays_progress,
paused_body copy updated to relay language; 7 new strings added.

https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-14 15:26:12 +00:00
Vitor Pamplona 03e1c32757 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-14 11:20:33 -04:00
Claude 84035f887a feat: parse NIP-47 transaction metadata for sender/recipient display
Add NwcTransactionMetadata parser that extracts comment, payer_data,
recipient_data, and nostr zap data from the untyped metadata field.
The transaction list UI now shows the Nostr user profile picture and
name for zap senders/recipients, falls back to payer name/email or
lightning address, and displays comment when it differs from description.

https://claude.ai/code/session_01JFogiwyR4CPVP8cRznqahJ
2026-03-14 15:18:53 +00:00
Claude 666c795c93 fix: use correct cancellation checks in suspend functions
isActive is a CoroutineScope extension and has no CoroutineScope
receiver in plain suspend fun bodies (runSync, downloadFromRelay).

- runSync catch block: split into CancellationException (rethrow) +
  Exception, removing the invalid isActive guard entirely
- downloadFromRelay while loop: while(isActive) -> while(true) with
  coroutineContext.ensureActive() as the first statement, which works
  in any suspend fun and throws CancellationException when cancelled

The isActive import is kept for the supervisorScope lambda in
downloadFromPool, where a CoroutineScope receiver is in scope.

https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-14 15:03:45 +00:00
Claude 2fd623a97d fix: wallet screen showing "No wallet connected" on first open
The WalletViewModel.init() was called inside LaunchedEffect (async),
but hasWalletSetup() was checked synchronously during the first
composition frame—before init had run. Moved init to run synchronously
during composition and made hasWalletSetup a reactive StateFlow so the
UI updates when wallet state changes.

https://claude.ai/code/session_01JFogiwyR4CPVP8cRznqahJ
2026-03-14 14:30:54 +00:00
Vitor Pamplona 120981f8c4 spotless apply 2026-03-14 10:18:16 -04:00
Vitor Pamplona 493fe05ac4 Fixes missing parameter 2026-03-14 10:18:08 -04:00
Claude 5905926d4a feat: sliding window relay pool replaces fixed batch chunks
Instead of waiting for all 50 relays in a batch to finish before
starting the next 50, a Semaphore(MAX_CONCURRENT_RELAYS) keeps the
concurrency window full at all times: the moment one relay is fully
exhausted it releases the semaphore and the next relay starts.

Each relay is handled by downloadFromRelay(), which paginates
independently (until cursor) until the relay returns no events.
supervisorScope ensures a single relay failure does not cancel
the rest of the pool.

Dedup sets and event counter are now thread-safe (ConcurrentHashMap
key sets, AtomicLong) since workers fire concurrently.

SyncState.Running/Paused fields renamed:
  chunkIndex/totalChunks -> relaysCompleted/totalRelays
  nextChunkIndex         -> nextRelayIndex

https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-14 13:44:48 +00:00
Claude 1841e47c5c feat: add high-level Nip47Client and Nip47Server APIs for NIP-47
Simplifies the NWC developer experience by providing Nip47Client (for
wallet client apps) and Nip47Server (for wallet service backends) that
handle URI parsing, signer creation, event building, filter construction,
and response decryption. Updates README with quick-start examples.

https://claude.ai/code/session_01JFogiwyR4CPVP8cRznqahJ
2026-03-14 11:39:17 +00:00
David Kaspar 43914c0f09 Merge pull request #1841 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-14 11:19:39 +00:00
Crowdin Bot 4fc97f21c5 New Crowdin translations by GitHub Action 2026-03-14 11:10:01 +00:00
David Kaspar dcf1e4e39b Add Claude Code local settings to .gitignore 2026-03-14 11:08:34 +00:00
David Kaspar a6d5944bf3 Fix JSON formatting in settings.json 2026-03-14 09:01:55 +00:00
David Kaspar f2391e698a Merge pull request #1839 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-14 05:06:48 +00:00
Crowdin Bot f9f4e7716d New Crowdin translations by GitHub Action 2026-03-14 05:06:26 +00:00
David Kaspar ce3f9bec5c Merge pull request #1838 from davotoula/update-translations
update cz, pt, de, sv
2026-03-14 05:04:49 +00:00
davotoula 3f1e826a10 update cz, pt, de, sv 2026-03-14 06:00:21 +01:00
Claude 580678eed8 feat: add server-side event builders and NIP-47 README for quartz
Adds missing server-side capabilities to the NIP-47 quartz module:

- LnZapPaymentResponseEvent.createResponse(): builds encrypted response
  events (kind 23195) for wallet services to reply to client requests
- NwcNotificationEvent.createNotification(): builds encrypted notification
  events (kind 23197) for wallet services to push payment notifications

Creates comprehensive README.md documenting the full NIP-47 API with
code examples for both wallet client and wallet service implementations,
covering URI parsing, request/response building, encryption, notifications,
error handling, transaction states, and caching.

https://claude.ai/code/session_01JFogiwyR4CPVP8cRznqahJ
2026-03-14 04:25:27 +00:00
Claude 4b76c70c29 feat: add NIP-47 wallet interface with balance, send, receive, and transactions
Adds an Alby Go-inspired wallet interface accessible from the left drawer menu.
Uses existing NWC connection from zap settings to communicate with the wallet
via NIP-47 methods (get_balance, get_info, pay_invoice, make_invoice, list_transactions).

New files:
- WalletViewModel: manages wallet state and NWC requests
- WalletScreen: balance display with send/receive action buttons
- WalletSendScreen: paste BOLT-11 invoice and pay
- WalletReceiveScreen: create invoice with QR code display
- WalletTransactionsScreen: scrollable transaction history

Also adds generic sendNwcRequest() to NwcSignerState and Account for
sending arbitrary NIP-47 requests beyond just pay_invoice.

https://claude.ai/code/session_01JFogiwyR4CPVP8cRznqahJ
2026-03-14 03:52:41 +00:00
Claude cf922a064b feat: Strip sensitive metadata from media files before upload
Adds a MetadataStripper that removes GPS location, camera info, timestamps,
and other sensitive EXIF/metadata from images, videos, and audio files before
uploading. This protects user privacy by default.

- Creates MetadataStripper using AndroidX ExifInterface for images and
  MediaMuxer for video/audio remuxing
- Adds "Strip location metadata" toggle to all upload dialogs (NewMediaView,
  ChatFileUploadDialog) so users can disable stripping per upload
- Persists the setting in AccountSettings (stripLocationOnUpload, default true)
- Integrates stripping into UploadOrchestrator before compression
- Covers all upload paths: media posts, DM attachments, channel uploads,
  profile pictures, list/channel metadata images

https://claude.ai/code/session_01974zpAMSRD9GeqBt9ax6XD
2026-03-14 03:50:34 +00:00
Claude 0fe721f426 feat: Add markdown long-form post screen (NIP-23)
Add a new post screen specialized for writing and publishing long-form
content events (kind 30023) with markdown support. Includes:

- MarkdownPostViewModel with title, summary, cover image, and markdown
  body fields, draft support, and LongTextNoteEvent creation
- MarkdownPostScreen with Edit/Preview tabs, monospace editor, markdown
  preview using existing RenderContentAsMarkdown, and media upload that
  inserts markdown image syntax
- Navigation route (Route.NewMarkdownPost) and AppNavigation entry
- String resources for the new screen

https://claude.ai/code/session_012pBNvnWtVtQ6aKSheWJUDt
2026-03-14 03:44:46 +00:00