- 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>
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>
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>
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>
- 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>
- 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>
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>
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>
- 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>
- 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>
- 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>
- 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>
- 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>
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>
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>
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>
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>
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>
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>
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>
* 'main' of https://github.com/vitorpamplona/amethyst:
New Crowdin translations by GitHub Action
drawerGesturesEnabled is true whenever the drawer is in transition (target != current)
Split the logic between onPreScroll and onPostScroll
New Crowdin translations by GitHub Action
New Crowdin translations by GitHub Action
Unnecessary ?. / ?: / !! on non-null Missing @OptIn annotations Parameter name mismatches Icons.Filled.* / Icons.AutoMirrored.* No cast needed / remove inline LocalLifecycleOwner import fix NIP-51 name() → title() Chess gameId → startEventId Nullable DecimalFormat safe calls DelicateCoroutinesApi opt-in
use 50/50 split for pager vs dock zones
fix: allow swipe-to-close when drawer is open on pager screens