Commit Graph

9728 Commits

Author SHA1 Message Date
Vitor Pamplona e66e5e28c1 Merge branch 'main' into claude/auto-load-transactions-scroll-KC8of 2026-03-17 11:48:21 -04:00
Vitor Pamplona c027e70c8b Merge pull request #1849 from vitorpamplona/claude/file-encryption-toggle-PwA8W
Add encrypted file upload with fallback option for NIP17 chats
2026-03-17 11:45:25 -04:00
Vitor Pamplona 30b785eec9 Merge branch 'main' into claude/file-encryption-toggle-PwA8W 2026-03-17 11:45:17 -04:00
Vitor Pamplona 4770f1eb90 Fixes sending url without cipher. 2026-03-17 11:43:24 -04:00
Claude 034cc0ab6d feat: move downloadFromRelay pagination logic to Quartz library
Extract the paginated relay download into a reusable INostrClient
extension (NostrClientDownloadFromRelayExt.kt) in the Quartz
commonMain accessories package. Uses Channel-based event collection
for KMP compatibility (no JVM-only atomics).

EventSyncViewModel.downloadFromRelay now delegates to the Quartz
extension, keeping the ViewModel thin.

Add NostrClientDownloadFromRelayTest integration test against
wss://nos.lol with Filter(kinds = [MetadataEvent.KIND], limit = 10)
to verify paginated downloads return correctly-typed events.

https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX
2026-03-17 15:34:17 +00:00
Claude bb32962f7d fix: prevent infinite loading spinner on wallet transactions screen
- Convert filteredTransactions from cold Flow to StateFlow via stateIn()
  to ensure reliable state updates with collectAsState()
- Add 30s timeout to NWC requests (fetchBalance, fetchTransactions,
  loadMoreTransactions) so loading state resets if wallet doesn't respond

https://claude.ai/code/session_01CdNY7qYDRHJr1jhAFvVgzj
2026-03-17 15:29:37 +00:00
Vitor Pamplona e0dc4edf7a Merge branch 'main' into claude/event-sync-screen-sYGtN 2026-03-17 11:21:54 -04:00
nrobi144 d70b13ef33 fix(media): properly constrain video height within NoteCard
Replace aspectRatio modifier with BoxWithConstraints that manually
calculates height from aspect ratio and clamps it to the max height
constraint. Video now stays within its allocated space in the card,
so controls are accessible and content below is not overlapped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:09:40 +02:00
Vitor Pamplona 45e0dc9bd5 renames class and other small changes 2026-03-17 11:02:30 -04:00
nrobi144 fbde0052a8 fix(media): video respects max height, stays within NoteCard bounds
Remove fillMaxWidth before aspectRatio so the caller's heightIn(max)
constraint is respected. Video now sizes to fit within the NoteCard
without overlapping the author header or overflowing the card.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:56:42 +02:00
nrobi144 9a19148da8 fix(media): stable hover controls, fix text cutoff
- Single hover zone on entire video — no more flickering from competing
  zones. Play button always visible when paused, bottom controls appear
  on hover (works in fullscreen too)
- Media height capped to 50% of window (min 200dp) so post text is
  never pushed off-screen by large media

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:51:44 +02:00
nrobi144 248f38cc47 fix(media): zone-based video controls — play always visible, controls on hover
- Center play button always visible when paused
- Pause button appears on center hover when playing
- Bottom controls bar only appears when hovering the bottom area
- Controls also show when paused for discoverability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:32:08 +02:00
nrobi144 e9249c924c fix(media): only show video controls on hover
Controls (play button, seek bar, volume) are hidden by default and
appear when the mouse enters the video area. They auto-hide 2s after
the mouse leaves.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:27:57 +02:00
nrobi144 bce6c12ab3 feat(media): video thumbnails in feed via VLC first-frame extraction
Add VideoThumbnailCache that grabs the first rendered frame from VLC
and caches it in memory. Videos in the feed now show a thumbnail
preview instead of a blank background before the user clicks play.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:12:16 +02:00
Vitor Pamplona baa55ab7f9 reverts to amber's session start 2026-03-17 09:55:56 -04:00
nrobi144 89f39fa77e feat(search): show images and media in search results
Replace plain-text NotePreviewCard with full NoteCard in search results
so images, videos, and author avatars are visible inline without having
to open the note.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:40:48 +02:00
nrobi144 d091084064 fix(media): resize media to fit visible window, never truncate text
- Remove maxLines/TextOverflow from RichTextContent so post text is
  never truncated
- Media height = window height minus 200dp chrome, so each image/video
  fits in the visible area without scrolling
- Use ContentScale.Fit for images to scale down while keeping aspect
  ratio instead of filling width and overflowing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:33:54 +02:00
nrobi144 bdd1feae3e fix(ui): show full post text, scrollable profile header with floating bar
- Remove maxLines=10 on post text so content is never truncated
- Profile header/card/tabs now scroll with content instead of staying
  sticky — scrolls away naturally as you browse posts
- Floating compact header (back + avatar + name) slides in when
  scrolling up and the full header is out of view

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:26:20 +02:00
Vitor Pamplona 9bf3086230 Make the session-start executable by default 2026-03-17 09:25:33 -04:00
Vitor Pamplona 345a569115 Merge pull request #1867 from vitorpamplona/claude/add-apk-pr-comments-gR7m7
Add direct APK download link and PR comments to benchmark workflow
2026-03-17 09:01:12 -04:00
nrobi144 2aa84c98ad fix(media): cap feed media height to 70% of window height
Replace hardcoded 400.dp max with window-relative height so media
(images and videos) never overflow the visible area and controls
are always accessible without scrolling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:53:58 +02:00
nrobi144 dffb996335 fix(media): immersive fullscreen via GraphicsDevice, separate view mode buttons
Replace WindowPlacement.Fullscreen (macOS maximize-only) with
GraphicsDevice.setFullScreenWindow() for true exclusive fullscreen that
hides menu bar and dock. Split single cycling view mode button into two
distinct toggles (theater + fullscreen). Hide all navigation chrome
(sidebar, nav rail, dividers, arrows, overlay menus) during fullscreen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:49:39 +02:00
davotoula f10387025d spotlessApply 2026-03-17 07:27:56 +01:00
nrobi144 7d3d633e03 feat(media): bundle VLC, lazy video player, fullscreen with seek continuity
- Bundle VLC via ir.mahozad.vlc-setup plugin (all plugins for network playback)
- BundledVlcDiscoverer (Win/Linux) and MacOsVlcDiscoverer for bundled VLC discovery
- Lazy player activation — no VLC calls during composition, only on play click
- Pre-init VLC on background thread at startup
- Video controls: seek slider, volume, mute, fullscreen (two-row layout, no clipping)
- Buffering indicator (CircularProgressIndicator) while loading
- ActiveMediaManager enforces single-player — pauses others when new video plays
- Fullscreen passes seek position so lightbox resumes from current playback point
- LightboxOverlay renders videos (DesktopVideoPlayer) or images (ZoomableImage)
- Gitignore downloaded VLC binaries (appResources/{linux,macos,windows}/)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 07:23:42 +02:00
Claude dbf5d6954c fix: revert to artifact zip download, PR comment only
Use upload-artifact with artifact-id for direct zip download URL.
Remove prerelease approach and commit comments.

https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf
2026-03-17 04:08:30 +00:00
Claude 706d282681 fix: direct APK download via prerelease asset, PR comment only
- Upload APK as a GitHub prerelease asset for direct .apk download
  (no zip wrapping like artifacts)
- Remove commit comment, only comment on open PRs
- Clean up existing release with same tag before creating

https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf
2026-03-17 04:05:33 +00:00
Claude 61dc903e9a fix: use artifact ID for direct download URL instead of nightly.link
Use the artifact-id output from upload-artifact to construct a direct
GitHub artifact download URL. No third-party service needed — the URL
points to the artifact on GitHub which triggers a download when clicked.

https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf
2026-03-17 04:03:18 +00:00
Vitor Pamplona 13da04e9f1 Merge pull request #1868 from vitorpamplona/claude/fix-missing-plugin-adHgr
Fix proxy bypass and improve code formatting
2026-03-16 23:51:49 -04:00
Claude 6bc927147c fix: use nightly.link for direct APK download without auth
GitHub artifact URLs require authentication and don't provide direct
file downloads. nightly.link proxies artifact downloads, giving a
direct download link that works for anyone without GitHub login.

https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf
2026-03-17 03:47:47 +00:00
nrobi144 cd7ee69f50 feat(media): add imeta tags on upload and drag-and-drop
- Build IMetaTag (NIP-92) from upload metadata (mime, sha256, dim, blurhash, size)
- Use TextNoteEvent.build directly with tag initializer for imeta injection
- Add drag-and-drop file support via Compose DragAndDropTarget
- Filter dropped files by media extension whitelist
- Visual border highlight on drag-over state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 adecc35721 feat(media): wire profile gallery tab and lightbox
- Add Notes/Gallery PrimaryTabRow to UserProfileScreen
- Subscribe to PictureEvent (kind 20) for gallery grid
- Wire GalleryTab composable with image click callbacks
- Wire LightboxOverlay for full-screen image viewing
- Pass onImageClick to FeedNoteCard in notes tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 7773844d2f feat(media): wire encrypted media, server settings, and server preferences
- ChatPane: display ChatFileAttachment for encrypted file header events
- DesktopPreferences: add blossom server list persistence
- Settings: add MediaServerSettings section above relay settings
- ComposeNoteDialog: use preferred blossom server from preferences

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 e654d48cdf fix(media): code review — dead code removal, perf fixes, bug fixes
- Remove unused: MediaAspectRatioCache, VideoPlayerState, resetZoom,
  onDoubleClick, delete/headUpload/createDeleteAuth, encryptAndUpload,
  EncryptedUploadResult, unused options params, formatAudioTime dupe
- Fix VlcjPlayerPool.release() accumulating stale event listeners
- Fix SaveMediaAction FileDialog running on IO instead of EDT
- Pre-allocate video frame ByteArray to avoid ~240MB/s GC pressure
- Pool audio players in VlcjPlayerPool instead of factory-per-instance
- Remove listener in onDispose before returning player to pool
- Fix acquire() race condition by moving poll inside synchronized
- Reduce memory cache to 15%/256MB with weak references
- Parallelize server health checks
- Remove redundant Content-Type/Content-Length headers
- Deduplicate BlurHashFetcher bitmap conversion via bufferedImageToSkiaBitmap
- Hoist audioExtensions to top-level constant, rename allMediaUrls
- Remove nonfunctional Save button and dead decryptedBytes state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 d5facd90df test(media): add 49 unit tests for media upload, encryption, and server services
Coverage for DesktopMediaMetadata, DesktopUploadTracker, DesktopMediaCompressor,
DesktopBlossomClient (MockK), DesktopUploadOrchestrator (MockK + mockkObject),
ServerHealthCheck, and AESGCM encrypt/decrypt round-trip.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 dfaca39528 feat(media): inline audio playback with VLCJ no-video mode
Phase 9: AudioPlayer composable using VLCJ --no-video factory,
play/pause/seek controls, NoteCard splits audio from video URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 4450aacdf9 feat(media): Blossom server management settings with health checks
Phase 8: MediaServerSettings UI for add/remove/reorder Blossom servers,
ServerHealthCheck with 5s timeout HEAD requests, status indicators.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 ca4e51afa9 feat(media): NIP-68 picture display and profile gallery grid
Phase 7: PictureDisplay composable for kind 20 events with image-first
layout, GalleryTab with adaptive grid of thumbnails, lightbox support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 f0acbb1934 feat(media): encrypted media service for NIP-17 DM file sharing
Phase 6: AESGCM encrypt/decrypt for DM file attachments, Blossom
upload of encrypted files, ChatFileAttachment composable with
auto-decrypt for images and file type display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 1a2dc9efac feat(media): lightbox overlay with zoom, gallery navigation, and save
Phase 5: Full-screen lightbox overlay with mouse wheel zoom + pan,
left/right gallery carousel, keyboard shortcuts (Esc/arrows/Ctrl+S),
save to disk via FileDialog. Images in NoteCard are clickable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 405601463e feat(media): VLCJ video playback with DirectRendering and player pool
Phase 4: VLCJ player pool (max 3 instances), DirectRendering via
CallbackVideoSurface → Skia Bitmap → Compose Image. Video controls
with auto-hide, seek, play/pause. Graceful fallback when VLC missing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 2181407647 feat(media): desktop upload UX with file picker, clipboard paste, and attachment row
Phase 3: Native file dialog, AWT clipboard paste handler, media
attachment UI with thumbnails, and ComposeNoteDialog media integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 443f7c6a09 feat(media): Phase 2 — Desktop Blossom upload client
- DesktopBlossomClient: PUT /upload, DELETE, HEAD /upload (BUD-06)
- DesktopBlossomAuth: kind 24242 auth with base64 Nostr header
- DesktopMediaMetadata: SHA-256, dimensions, blurhash via ImageIO
- DesktopMediaCompressor: lossless EXIF stripping (Commons Imaging)
- DesktopUploadOrchestrator: strip EXIF → metadata → auth → upload
- DesktopUploadTracker: StateFlow-based upload state tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
nrobi144 212dda40ca feat(media): Phase 0+1 — Coil3 image loading + inline images in notes
- DesktopImageLoaderSetup: Coil3 with explicit memory cache (25% heap,
  max 512MB), persistent disk cache (OS-appropriate paths), SVG decoder
- DesktopBlurHashFetcher: blurhash placeholder images via Skia Bitmap
- DesktopBase64Fetcher: base64 data: URI image decoding
- SkiaGifDecoder: GIF first-frame rendering via Skia Codec
- MediaAspectRatioCache: thread-safe LruCache for aspect ratios
- NoteCard: inline AsyncImage for image URLs, stripped from text
- Added coil-compose, coil-okhttp, coil-svg, vlcj, commons-imaging,
  androidx-collection deps to desktopApp

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:44:33 +02:00
Claude 883a2f995e style: apply ktlint formatting fixes
https://claude.ai/code/session_01HeWiRdKDTnMGfEBUegk3d1
2026-03-17 03:43:19 +00:00
Claude 1c4f9769b1 fix: session-start hook fails silently when dl.google.com is blocked
The Claude Code web egress proxy does not include dl.google.com in its
allowlist, causing the session-start hook to abort entirely (due to
set -euo pipefail) when Android SDK downloads fail. This cascading
failure also prevented local.properties creation and ANDROID_HOME export.

Additionally, JAVA_TOOL_OPTIONS contains nonProxyHosts entries for
*.google.com and *.googleapis.com, which causes the JVM to bypass the
proxy for Google Maven, resulting in connection failures.

Changes:
- Remove set -euo pipefail; use per-section error handling instead
- Fix JAVA_TOOL_OPTIONS: strip *.google.com from nonProxyHosts
- Fix no_proxy: remove *.google.com and *.googleapis.com entries
- Move local.properties and env exports before SDK download section
- Make SDK downloads non-fatal with clear warning messages
- Install standalone ktlint as fallback for spotlessApply
- Create spotless-apply wrapper script for proxy-blocked environments
- Update Stop hook to fall back to spotless-apply when Gradle fails

https://claude.ai/code/session_01HeWiRdKDTnMGfEBUegk3d1
2026-03-17 03:43:10 +00:00
Claude af12d13d67 fix: use artifact-url output for direct APK download link
The manually constructed URL was invalid. Use the artifact-url output
from upload-artifact which provides the correct download URL.

https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf
2026-03-17 03:34:53 +00:00
Claude 39e15a8929 feat: comment benchmark APK link on open PRs
Add PR commenting to the build-benchmark-apk workflow. When a build
completes, it now finds any open PR for the branch and posts a comment
with a direct download link to the benchmark APK artifact.

https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf
2026-03-17 03:23:00 +00:00
Claude 866dfca710 fix: rename _transactions to allTransactions to fix ktlint backing-property-naming
The backing property _transactions no longer has a matching public
property since it was replaced by filteredTransactions.

https://claude.ai/code/session_01CdNY7qYDRHJr1jhAFvVgzj
2026-03-17 03:07:57 +00:00
Vitor Pamplona 73d1e39587 Merge branch 'main' into claude/auto-load-transactions-scroll-KC8of 2026-03-16 23:03:09 -04:00
Claude 11950dc4f4 feat: add transaction filter for zaps vs non-zaps on wallet screen
Adds filter chips (All / Zaps / Non-Zaps) to the transactions list.
Zap transactions are identified by having nostr metadata. The filter
is applied client-side via a combined Flow in WalletViewModel.

https://claude.ai/code/session_01CdNY7qYDRHJr1jhAFvVgzj
2026-03-17 02:55:16 +00:00