Commit Graph

10125 Commits

Author SHA1 Message Date
Vitor Pamplona 4df78340b6 Merge pull request #1879 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-19 15:41:16 -04:00
davotoula ae5f76e018 Merge branch 'main-upstream' into claude/strip-file-metadata-sVIEd 2026-03-19 20:38:57 +01:00
Crowdin Bot f8d6ac7900 New Crowdin translations by GitHub Action 2026-03-19 19:38:07 +00:00
Vitor Pamplona cee4291ba9 Merge pull request #1878 from vitorpamplona/claude/event-sync-screen-sYGtN
Claude/event sync screen
2026-03-19 15:36:38 -04:00
Vitor Pamplona fd5e8dcca0 Merge pull request #1877 from vitorpamplona/claude/nip17-dm-migration-qxDbT
Deprecate NIP-04 and always use NIP-17 for DM sending
2026-03-19 15:25:38 -04:00
Vitor Pamplona ad53bff8e3 Final touches to remove nip04 dms 2026-03-19 15:23:48 -04:00
Vitor Pamplona f75971fc6a Merge pull request #1876 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-19 13:31:51 -04:00
Crowdin Bot 2f60697b28 New Crowdin translations by GitHub Action 2026-03-19 16:43:50 +00:00
Vitor Pamplona 3f4e265dc0 Brings the creation of Zap Polls back. 2026-03-19 12:40:14 -04:00
Claude 695d3c7a23 feat: deprecate NIP-04 DM sending, always use NIP-17
NIP-04 encryption for sending DMs is now deprecated. All new messages
are sent using NIP-17 (gift-wrapped sealed messages). Reading NIP-04
messages remains supported for backward compatibility.

When a recipient lacks both a DM relay list (kind 10050) and NIP-65
inbox relays, the send button is disabled and a warning is shown
explaining that messages cannot be delivered.

Changes:
- ChatNewMessageState: Remove nip17/requiresNip17 toggles, add
  recipientsMissingDmRelays state, always send via NIP-17
- ChatNewMessageViewModel: Always use NIP-17, remove NIP-04 send
  paths, add recipient relay status checking
- ToggleNip17Button -> Nip17Indicator: Replace toggle with static
  NIP-17 indicator (always on)
- PrivateMessageEditFieldRow: Show warning when recipients lack
  DM relay lists, hide message input
- ChatFileSender: sendAll() always uses NIP-17
- Desktop ChatPane: Remove NIP-17 toggle, show relay warning
- ChatroomView: Reactively check recipient DM relay availability

https://claude.ai/code/session_01T7QhUW9cZogk4DxDXbbbJJ
2026-03-19 15:22:13 +00:00
Vitor Pamplona 185fd96802 Merge branch 'main' into claude/strip-file-metadata-sVIEd 2026-03-19 10:06:20 -04:00
Vitor Pamplona 0f4555cfaa Merge pull request #1875 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-19 09:58:46 -04:00
Crowdin Bot 5903af2229 New Crowdin translations by GitHub Action 2026-03-19 13:56:12 +00:00
Vitor Pamplona 29db4ca0e3 Merge pull request #1825 from vitorpamplona/claude/event-sync-screen-sYGtN
Add Event Sync feature to redistribute events across relays
2026-03-19 09:54:26 -04:00
Vitor Pamplona 78ffb9fce4 Merge branch 'main' into claude/event-sync-screen-sYGtN 2026-03-19 09:54:20 -04:00
Vitor Pamplona 30f862cf26 Increase max parallel to 50 2026-03-19 09:50:50 -04:00
Vitor Pamplona ab81b2a71d Improving calendar debug 2026-03-19 09:50:31 -04:00
Vitor Pamplona ec29a47dc4 More debugging information 2026-03-19 09:34:52 -04:00
Vitor Pamplona 98578de840 Merge pull request #1874 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-03-19 08:51:23 -04:00
Crowdin Bot 311bbe19cf New Crowdin translations by GitHub Action 2026-03-19 12:45:49 +00:00
Vitor Pamplona 3f841c94ec Merge pull request #1873 from nrobi144/feat/desktop-media
feat(desktop): Full media parity — images, video, audio, encrypted DMs, upload, lightbox
2026-03-19 08:44:21 -04:00
nrobi144 5b2f2ca42b feat(chats): per-message encryption badge — lock for NIP-17, lock-open for NIP-04
Show a small lock icon next to the timestamp on each DM message:
- NIP-17 (ChatMessageEvent, ChatMessageEncryptedFileHeaderEvent): filled
  lock in primary color — relay can't see sender/recipient
- NIP-04 (PrivateDmEvent): open lock in muted gray — legacy encryption,
  metadata visible to relays

Matches Android's IncognitoBadge pattern. Both NIP-04 and NIP-17 messages
in the same 1-on-1 conversation produce identical ChatroomKeys, so they
merge into one conversation — the badge is the only way to tell them apart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:23:06 +02:00
nrobi144 f3e55f9958 fix(chats): handle ChatMessageEncryptedFileHeaderEvent in GiftWrap unwrap
The GiftWrap inner event handler only processed ChatMessageEvent (kind 14)
and ReactionEvent. ChatMessageEncryptedFileHeaderEvent (kind 15) was
silently dropped, so encrypted file attachments never appeared in DMs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:11:46 +02:00
nrobi144 35b58e489b feat(chats): right-click context menu on encrypted files — download + forward
Right-click on encrypted file attachments in DMs now shows a context menu:
- "Save to disk" — decrypts and saves via native file dialog
- "Forward" — placeholder callback for forwarding to another conversation

Also caches decrypted bytes (not just image bitmap) so save doesn't
re-download. Non-image files also get decrypted on load for save support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:06:26 +02:00
nrobi144 d9848b868b feat(chats): always show attach button, auto-force NIP-17 with snackbar
- Attach button always visible in DM input (not gated on NIP-17 mode)
- Drag-and-drop always enabled
- When files are attached in NIP-04 mode, auto-switches to NIP-17
  with snackbar: "Switched to NIP-17 — file attachments require
  encrypted messaging"
- NIP-17 toggle remains for manual control

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:02:05 +02:00
nrobi144 9187bf448f fix(chats): pass compactMode through RootContent — single-pane keeps split
compactMode was hardcoded in the Messages branch of RootContent, which is
shared between deck and single-pane. Now compactMode is a RootContent
parameter: deck passes true, single-pane defaults to false.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:53:03 +02:00
nrobi144 0184ebad11 fix(test): disambiguate mock upload call after ByteArray overload
The new ByteArray upload overload on DesktopBlossomClient made the
positional any() mock call ambiguous. Specify explicit type parameters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:51:22 +02:00
nrobi144 e06287acb3 feat(chats): stacked messages layout in deck columns
In multi-deck mode, Messages column now uses stacked navigation instead
of side-by-side split pane. Full-width contact list OR full-width chat —
clicking a conversation navigates to chat, back arrow returns to list.

Single-pane mode keeps the existing split layout (280dp list + flex chat).

Changes:
- Add compactMode param to DesktopMessagesScreen (default false)
- Extract SplitMessagesContent and CompactMessagesContent composables
- Add onBack callback to ChatPane with back arrow in header
- Remove hardcoded 280dp from ConversationListPane (caller controls width)
- Pass compactMode=true from deck RootContent

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:49:36 +02:00
nrobi144 598256639b fix(chats): share single DesktopIAccount across deck — DMs now visible
DeckColumnContainer was creating its own DesktopIAccount (and ChatroomList)
for the Messages column, while Main.kt created a separate one for DM relay
subscriptions. Events were added to one ChatroomList but the UI read from
the other, so DMs never appeared.

Fix: thread the single iAccount from Main.kt through DeckLayout →
DeckColumnContainer → RootContent → DesktopMessagesScreen. Removed the
duplicate DesktopIAccount and DmSendTracker creation from RootContent.

Audited all other deck column types — no similar instance duplication found.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:31:27 +02:00
nrobi144 24d4073b9b feat(media): encrypted file sharing in desktop DMs (NIP-17 Phase 6)
Add full send + receive encrypted media support in desktop DM chat:
- Paperclip attach button and drag-and-drop in ChatPane (NIP-17 mode only)
- AES-GCM encryption before upload to Blossom server
- ChatMessageEncryptedFileHeaderEvent (kind 15) wrapped in GiftWrap
- sendNip17EncryptedFile() added to IAccount interface and implementations
- DesktopUploadOrchestrator.uploadEncrypted() with proper encrypted hash
- DesktopBlossomClient ByteArray upload overload for encrypted blobs
- LRU cache in EncryptedMediaService to avoid re-downloading
- Error handling: retry on failure, disable send during upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:53:36 +02:00
Vitor Pamplona 3e3adaff10 Finalizes the RelaySync utility 2026-03-18 17:35:05 -04:00
Vitor Pamplona e57023cad9 Fix: Filters onCannotConnect to the relays that sent a req 2026-03-18 17:34:50 -04:00
davotoula 7bfc35e04d Fixes Applied
Code reuse
  - Extracted remuxTracks() helper to deduplicate video/audio remux loop (~40 lines)
  - Extracted stripAfterCompression() to deduplicate identical blocks in upload()/uploadEncrypted()
  - Replaced 8 identical showStrippingFailureDialog() copy-pastes with shared SuspendableConfirmation utility
  Privacy
  - 4 metadata ViewModels now error on strip failure instead of silently uploading unstripped media
  Efficiency
  - Eliminated temp input file copy for video/audio — MediaExtractor reads URIs directly
  Bug fixes
  - Fixed Long.toInt() overflow for MP3 files >2GB
  - Fixed MP3 temp file leak on exception and null InputStream paths
  Cleanup
  - Mutex field and wrapping the suspendCancellableCoroutine in mutex.withLock. Concurrent callers now queued
  - Converted MetadataStripper from class to object (stateless)
  - Moved StrippingFailureState from service layer to UI as generic ConfirmationCallbacks
2026-03-18 20:59:46 +01:00
davotoula 0cf256e5b2 Merge branch 'main-upstream' into claude/strip-file-metadata-sVIEd 2026-03-18 19:32:43 +01:00
davotoula bfc04497d6 Profile picture upload fails with an error instead of silently uploading unstripped media when stripping fails 2026-03-18 19:25:57 +01:00
davotoula eb13bab738 fix grammar 2026-03-18 18:31:34 +01:00
davotoula 97e6206244 fix persisted account preference 2026-03-18 18:31:07 +01:00
davotoula a7ac30493c Extension mismatch fix
Temp file leak fix
2026-03-18 18:25:31 +01:00
davotoula 49c8423be5 moving the stripping decision after compressIfNeeded 2026-03-18 18:20:01 +01:00
davotoula 127079ede3 - Hide privacy toggle when video compression is selected (compression
already handles metadata stripping)
- Pass stripMetadata=false when toggle is hidden for compressed video
- Hide compression quality for audio and other non-compressible media types
- refactor
2026-03-18 13:54:15 +01:00
nrobi144 c90bf8f610 feat(media): add Note/Picture post type selector; fix gallery crash
- Post type toggle (Note vs Picture/kind 20) in compose dialog, only
  shown when image files are attached. Text input disabled in picture mode.
- Fix LazyVerticalGrid crash in GalleryTab: bounded height via
  fillParentMaxHeight() when nested inside LazyColumn.
- Phase 1 testing plan: all pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:42:44 +02:00
nrobi144 cf17dea53f feat(media): add Note/Picture post type selector in compose dialog
When images are attached, a Note/Picture toggle appears letting the user
publish as kind 20 (PictureEvent) instead of kind 1. Text input is
disabled in picture mode. Selector only shows for image file types.
Updates testing plan: Phase 1 all pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:37:48 +02:00
nrobi144 1d1d32da0e feat(media): add server selector to compose dialog; update testing plan
Server selector dropdown appears when files are attached, letting the
user choose which Blossom server to upload to. Updates testing plan:
Phase 2 & 3 all pass, Phase 9 audio tested with volume bug tracked.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:26:47 +02:00
nrobi144 836e024bd7 feat(media): use VLC :start-volume for initial audio; document volume bug
Passes :start-volume media option to VLC on play. Removes polling/delay
volume hacks. Documents 9.7 volume bug in testing plan — VLC ignores
initial volume on macOS, needs further investigation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:26:52 +02:00
nrobi144 f0c80f3c7c fix(media): delay volume enforcement — VLC audio output not ready at playing event
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:34:36 +02:00
nrobi144 11b9fdad80 fix(media): enforce volume on playback start — VLC resets volume on new media
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:30:57 +02:00
nrobi144 2a6087af27 feat(media): global media player — persistent playback across navigation
Media playback now survives navigation. A GlobalMediaPlayer singleton owns
VLC players and exposes StateFlows. Composables are thin viewports.
NowPlayingBar has full controls (volume, mute, save, fullscreen).
GlobalFullscreenOverlay renders video fullscreen above all screens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:27:13 +02:00
davotoula 20ab105e44 feat: add metadata stripping failure dialog to all upload ViewModels
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 11:12:36 +01:00
davotoula c0632e17bd feat: add onStrippingFailed callback to upload orchestrators
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 10:51:30 +01:00
davotoula 9ce1ff3e63 feat: plumb stripMetadata from UI through ViewModels to upload orchestrators
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 10:50:16 +01:00