Commit Graph
1997 Commits
Author SHA1 Message Date
vicrodh bdde90fc0d feat(plex): persist hydrated quality metadata in cache
cx
2026-02-09 01:51:30 -06:00
vicrodh bf99a19eb3 fix(plex): hydrate track quality and show plex source indicator
cx
2026-02-09 01:47:24 -06:00
vicrodh ddf4142188 fix(appimage): pin WebKitGTK to 2.44.0-2 to prevent EGL crash
The AppImage EGL_BAD_PARAMETER crash is caused by how Tauri's
linuxdeploy bundles newer WebKitGTK versions (tauri-apps/tauri#11994).

Fix: pin WebKitGTK to 2.44.0-2 on ubuntu-24.04, matching the proven
fix from other Tauri apps (audioling#40, OmniKee).

Also revert runtime env var workarounds (LIBGL_ALWAYS_SOFTWARE,
default-off hardware accel) since the fix is at the build level.
Keep only the NVIDIA DMA-BUF workaround which is still needed.
2026-02-09 01:28:11 -06:00
vicrodh 228563454b feat(plex): checkpoint plex lan integration and quality sync
cx
2026-02-09 01:28:11 -06:00
vicrodh 52f2d9ded5 fix: force software rendering when hardware accel is disabled
WEBKIT_DISABLE_DMABUF_RENDERER alone is not enough — WebKit still calls
eglGetDisplay() for compositing and crashes with EGL_BAD_PARAMETER on
systems without working EGL (VMs, some driver combinations).

Setting LIBGL_ALWAYS_SOFTWARE=1 forces Mesa to use llvmpipe so the EGL
initialization succeeds through software rasterization.
2026-02-09 00:50:41 -06:00
vicrodh 3db93a00bf fix: disable WebKit hardware acceleration by default on Linux
EGL/DMA-BUF renderer crashes on many GPU/driver/compositor combinations,
not just NVIDIA. Default to software rendering for all GPUs and allow
opt-in via QBZ_HARDWARE_ACCEL=1.
2026-02-09 00:27:15 -06:00
vicrodh 0c3a2d15b1 fix: remove invalid artistId/onArtistClick props from AlbumCard usage
AlbumCard's Props interface doesn't include artistId or onArtistClick.
Remove these from VirtualizedFavoritesAlbumGrid to fix type error.
2026-02-08 21:33:07 -06:00
vicrodh 0c5c9f22ec perf: batch album download status checks
Change loadAllAlbumDownloadStatuses from Promise.all(all) to
chunked batches of 10 with setTimeout(0) between batches to
yield to the UI thread and prevent blocking during large
album collections.
2026-02-08 21:32:10 -06:00
vicrodh 5e970f9ca8 feat: add inline virtualization to SearchView results
Virtualize albums, tracks, and artists tabs with binary search
and absolute positioning. Each tab uses its own scroll container
with ResizeObserver for responsive grid columns. Load More buttons
render as virtual items at the bottom of each list.
2026-02-08 21:31:32 -06:00
vicrodh fda6449ec9 feat: integrate VirtualizedFavoritesAlbumGrid into FavoritesView
Replace 4 album render paths (grouped grid, grouped list,
ungrouped grid, ungrouped list) with single virtualized component.
Remove ~110 lines of duplicated album CSS now in component.
Enable no-outer-scroll for albums tab.
2026-02-08 21:27:24 -06:00
vicrodh d49eaf000f feat: add VirtualizedFavoritesAlbumGrid component
Binary search virtualization for favorite albums in both grid
and list modes. Grid uses AlbumCard with responsive columns,
list uses inline rows with QualityBadge. Supports grouping,
scroll-to-group, and all album action callbacks.
2026-02-08 21:25:59 -06:00
vicrodh 5f7a0ae57d feat: integrate VirtualizedFavoritesArtistList into sidepanel
Replace raw {#each} loops in artist sidepanel left column with
virtualized list component. Remove ticker animation state from
parent (now encapsulated in VirtualizedFavoritesArtistList).
Clean up unused CSS for artist-list-* classes.
2026-02-08 21:24:40 -06:00
vicrodh a0fbd5b7b4 feat: add VirtualizedFavoritesArtistList component
Binary search virtualization for artist sidepanel list.
Includes ticker animation for long names, group headers,
and scroll-to-group support. 64px row height, 10-item buffer.
2026-02-08 21:23:36 -06:00
vicrodh d042000a3d feat: integrate VirtualizedFavoritesArtistGrid into FavoritesView
Replace raw {#each} loops for artist grid (grouped + ungrouped)
with virtualized component. Artists now render only visible cards
in DOM, fixing 20-second UI freezes with large artist collections.
2026-02-08 21:22:44 -06:00
vicrodh af5704df7c feat: add VirtualizedFavoritesArtistGrid component
Binary search virtualization for favorite artists grid view.
Supports grouped/ungrouped modes, responsive columns via
ResizeObserver, scroll-to-group, and lazy image loading.
Part of issue #56 fix for 20-second UI freezes.
2026-02-08 21:21:45 -06:00
vicrodh 67f9d6a505 fix(appimage): disable WebKit GPU compositing to fully prevent EGL
GDK_BACKEND=x11 alone is not enough: WebKitGTK still initializes
EGL for GPU compositing under X11, and the bundled libEGL sees
WAYLAND_DISPLAY, tries the Wayland EGL platform, and aborts with
EGL_BAD_PARAMETER.

Add WEBKIT_DISABLE_COMPOSITING_MODE=1 which prevents WebKitGTK
from initializing EGL entirely. This flag caused ghost app on
native Wayland but is safe on X11 (which we force for AppImage).
2026-02-08 20:59:35 -06:00
vicrodh 76c24f48d3 fix(appimage): unconditionally force X11 on Wayland to prevent EGL crash
The previous workaround guarded the GDK_BACKEND override with
is_none(), so if the AppImage runtime or desktop session had already
set GDK_BACKEND=wayland, the fix was silently skipped.

AppImage builds have a fundamentally broken EGL stack on Wayland:
libEGL is present but incomplete, Mesa EGL loaders are missing,
and eglGetDisplay() returns EGL_BAD_PARAMETER with no possible
runtime fallback.

Changes:
- AppImage + Wayland now unconditionally sets GDK_BACKEND=x11,
  overriding any existing value
- Also sets QT_QPA_PLATFORM=xcb and WEBKIT_DISABLE_DMABUF_RENDERER=1
  in the same block for belt-and-suspenders safety
- Adds QBZ_FORCE_WAYLAND=1 escape hatch for power users
- Skips all other GDK/DMABUF logic when AppImage forced X11
- Simplifies NVIDIA DMA-BUF logic (no longer Wayland-gated)
- Does NOT affect RPM, DEB, Flatpak, or native builds
2026-02-08 20:17:20 -06:00
vicrodh 464b57d573 fix(favorites): prevent content from overlapping sticky alpha-index
Add z-index: 2 to .alpha-index so artist/album cards don't render
on top of the sticky jump-bar when scrolling.
2026-02-08 20:00:55 -06:00
vicrodh 05414eae37 perf(sidebar): virtualize playlist list to prevent UI freeze
Replace the non-virtualized playlist rendering in the Sidebar with
an inline virtual scroll implementation. Users with 500+ playlists
experienced 20-second UI freezes because all playlists were mounted
as DOM nodes simultaneously.

Now only ~20-30 visible items (plus buffer) are rendered at any time,
using absolute positioning with translateY and binary search for
efficient viewport calculation. Follows the existing
VirtualizedArtistList pattern.

Fixes #56
2026-02-08 19:44:16 -06:00
vicrodh 22055d15e4 fix(appimage): force X11 backend on Wayland to prevent EGL crash
WEBKIT_DISABLE_DMABUF_RENDERER alone is not enough: WebKitGTK's
Wayland platform init calls eglGetPlatformDisplay() in
PlatformDisplayWayland before any renderer decision, and the
AppImage's bundled EGL loader is incompatible with the host
Mesa/driver, causing EGL_BAD_PARAMETER abort.

Force GDK_BACKEND=x11 for AppImage + Wayland so WebKitGTK uses
GLX via XWayland instead of EGL, bypassing the crash entirely.
Users who want native Wayland can override with GDK_BACKEND=wayland.

Non-AppImage builds (Flatpak, RPM, DEB) are unaffected and continue
using native Wayland.

cc
2026-02-08 18:57:22 -06:00
vicrodh 09e0aa579a fix(wayland): rework EGL crash prevention for AppImage + Wayland
WEBKIT_DISABLE_COMPOSITING_MODE=1 was set automatically on Wayland
(both in the VM path and the general Wayland path), which caused a
"ghost app": process alive, tray/MPRIS initialized, but UI never
renders on Fedora + GNOME + Wayland.

Rework the defensive strategy:

- Remove WEBKIT_DISABLE_COMPOSITING_MODE from all automatic paths;
  gate it behind opt-in QBZ_WEBKIT_DISABLE_COMPOSITING=1
- Treat AppImage + Wayland as the primary condition (not VM-only):
  disable DMA-BUF renderer for AppImage on Wayland to prevent
  eglGetPlatformDisplay() EGL_BAD_PARAMETER abort
- Keep LIBGL_ALWAYS_SOFTWARE=1 scoped to VMs and QBZ_SOFTWARE_RENDER
- Keep NVIDIA + Wayland DMA-BUF mitigation unchanged
- Flatpak / RPM / DEB builds unaffected (no APPIMAGE env var)

Fixes: #59

cc
2026-02-08 17:09:27 -06:00
vicrodh 579477f21f ImmersivePlayer + panels: propagate original* and format props
Accept originalBitDepth, originalSamplingRate, and format in
ImmersivePlayer Props and pass them through to all 4 focus panels
(Coverflow, Static, Vinyl, Visualizer) and the inline QualityBadge
in split mode. This enables hardware-based downgrade detection in
all immersive views.
2026-02-08 16:28:52 -06:00
vicrodh 6794f00259 QualityBadge: hardware rate detection + custom tooltip
Poll get_hardware_audio_status every 2s to get the actual hardware
sample rate from /proc/asound. Compare decoded rate (kHz) vs
hardware rate (Hz) for real downgrade detection instead of relying
on originalSamplingRate which comes from the same decoder.

Replace native title attribute with custom tooltip (matching
AudioOutputBadges style) for the degraded state, showing source
rate, output rate, resampling warning, and settings fix hint.
2026-02-08 16:27:21 -06:00
vicrodh 659a5b7718 Add i18n keys for structured quality tooltip
Replace single degradedTooltip string with quality.tooltip.*
keys (source, output, resampled, fix) for the new custom tooltip
in QualityBadge. Updated all 4 locales (en, es, de, fr).
2026-02-08 16:26:31 -06:00
vicrodh 2040ab116c Add degraded quality tooltip explaining resampling and how to fix it 2026-02-08 15:55:53 -06:00
vicrodh 4df3fa52a4 Eradicate all t-as-lambda-param shadowing across codebase
Renamed t -> trk (or tab as contextually appropriate) in all
lambda/callback parameters across 6 files that import t from i18n.
This prevents vite-plugin-svelte CSS extraction failures (PostCSS
"Unknown word" errors) caused by t shadowing the i18n store.

Files: +page.svelte, PlaylistDetailView, FavoritesView,
TrackReplacementModal, Sidebar, SuggestionsPanel
2026-02-08 15:33:59 -06:00
vicrodh 386a66c905 Fix t-as-lambda shadowing i18n store in LocalLibraryTagEditorModal 2026-02-08 15:20:52 -06:00
vicrodh edaf6e442c Rework LogsModal: per-tab upload, URL display with copy, bug report hint
Upload is now per-tab (Terminal/Console separately). Each tab shows a
checkmark after upload. URL displayed inline with copy button. Help text
appears after first upload encouraging users to share both URLs.
2026-02-08 15:13:52 -06:00
vicrodh ff968456c8 Show uploaded log URL next to upload button in LogsModal 2026-02-08 15:10:38 -06:00
vicrodh 18d37765c1 Fix 0x0.st upload 403 by adding User-Agent header 2026-02-08 15:09:08 -06:00
vicrodh cdb58a0e08 Fix Toggle props for Force DMA-BUF (enabled/onchange, not checked/onChange) 2026-02-08 15:05:37 -06:00
vicrodh 363495cb15 Add Developer Mode section to Settings; fix Factory Reset always visible bug
Developer Mode: collapsible section (hidden from jump-nav) with Force DMA-BUF
toggle and View Logs button. LogsModal shows Terminal/Console tabs with
0x0.st upload. Console capture wraps console.log/warn/error/info.

Bugfix: Factory Reset row was outside {#if !storageCollapsed}, making it
always visible even when Storage section was collapsed.
2026-02-08 15:01:09 -06:00
vicrodh 2fda58b823 Add i18n keys for Developer Mode section in all 4 locales 2026-02-08 15:01:02 -06:00
vicrodh 3e4cc6921c Add developer settings backend, log capture system, and --reset-dmabuf CLI flag
Developer settings: SQLite-backed store for force_dmabuf toggle.
Logging: TeeWriter captures env_logger output to ring buffer;
log_startup() captures pre-logger startup messages.
Upload: multipart POST to 0x0.st for log sharing.
CLI: --reset-dmabuf flag resets force_dmabuf and exits for recovery.
2026-02-08 15:00:58 -06:00
vicrodh 03e4232cfc Fix EGL crash in VMs by auto-detecting virtual machines and forcing software rendering
Adds is_virtual_machine() detection (DMI product name, sys vendor,
hypervisor type) that triggers LIBGL_ALWAYS_SOFTWARE=1 to bypass
EGL hardware initialization entirely on VirtualBox, VMware, QEMU,
Xen, Hyper-V, and Parallels.

Also adds QBZ_SOFTWARE_RENDER=1 env var for users on real hardware
who experience transparent outlines or EGL failures (issue #59).
2026-02-08 14:37:15 -06:00
vicrodh 681d3e5dac Change playback defaults: gapless off, context icon off, stream uncached off
Aligns defaults with intended new-install and reset behavior:
- gapless_enabled: false (was true)
- show_context_icon: false (was true)
- stream_first_track: false (was true)
Updates DB migration defaults and frontend reset handler to match.
2026-02-08 14:13:06 -06:00
vicrodh bf370e5373 Move streaming settings to Playback section, add Reset Audio and Factory Reset
- Moves Stream Uncached Tracks, Initial Buffer Size, and Streaming Only
  from Audio section to Playback section
- Adds Reset Audio & Playback Settings button at bottom of Audio section
- Adds Delete All Application Data danger zone at bottom of Storage section
  with confirmation checkbox and secondary dialog
- Adds CSS for reset-btn, danger-zone, checkbox-label, factory-reset-btn
2026-02-08 14:09:35 -06:00
vicrodh 33d69ef3f3 Add i18n keys for reset audio, factory reset; move streaming keys to playback
Moves streamUncached, initialBuffer, streamingOnly and related keys
from settings.audio to settings.playback in all 4 locale files.
Adds reset audio/playback keys to settings.audio section.
Adds factory reset keys to settings.storage section.
2026-02-08 14:06:46 -06:00
vicrodh 2c0dc66b17 Add factory_reset Rust command
Tears down all per-user stores, clears credentials from keyring,
then removes ~/.local/share/qbz/, ~/.cache/qbz/, and ~/.config/qbz/.
Makes teardown_type_alias_state public for reuse.
2026-02-08 14:03:38 -06:00
vicrodh 2d94430c0a Add reset_audio_settings Rust command
Adds reset_all() to both AudioSettingsStore and PlaybackPreferencesStore.
The reset_audio_settings tauri command resets both audio and playback
preferences to their default values in a single call.
2026-02-08 14:00:52 -06:00
vicrodh 1a5b8ae428 fix(startup): scope client mutex locks and yield before download status checks
Applies the same fix pattern from issue #56 (search) to Home view commands.

Backend: scope client.lock().await to just the HTTP call in get_featured_albums,
get_album, get_track, get_artist_basic, and get_discover_index so concurrent
Tauri commands no longer serialize through a single lock.

Frontend: await tick() after setting section data before firing download status
checks, and add .catch() to prevent unhandled rejections from blocking the UI.
2026-02-08 13:38:25 -06:00
vicrodh ed4395392b fix(ui): fix artist-link button reset for proper ticker animation
Add display:block, font:inherit, appearance:none to ensure the button
renders identically to the div variant. Without font:inherit, buttons
use the UA stylesheet font-family which causes text width measurement
mismatches and breaks the overflow detection for the ticker.
2026-02-08 13:28:54 -06:00
vicrodh 74a1b12b3b fix(ui): revert badge to original padding, fix artist link overflow
Restore quality badge to original values (padding 4px 6px, no
line-height override). Fix artist-link button: replace all:unset with
targeted button resets and width:100% so the button is constrained by
its parent and overflow/text-overflow/ticker actually work.
2026-02-08 13:20:26 -06:00
vicrodh f1488489ce fix(ui): restore badge inner padding and add ticker to artist link
Set badge padding to 2px 6px with line-height 1.2 for proper text
breathing room. Add ticker scroll animation to the clickable artist
name on hover so long artist names scroll into view.
2026-02-08 13:12:41 -06:00
vicrodh 6b168f3118 fix(ui): correct quality badge dimensions — restore 90px width, reduce height
Revert min-width to 90px (was correct), set line-height: 1 and
padding: 1px 6px to actually reduce the badge height.
2026-02-08 13:10:56 -06:00
vicrodh f3be2b737f feat(ui): wire artist click through all views using AlbumCard
Pass artistId and onArtistClick to AlbumCard in HomeView, SearchView,
FavoritesView, LabelView, and AlbumDetailView. Add artistId to
AlbumCardData interface. Add onArtistClick prop to LabelView and wire
it from +page.svelte.
2026-02-08 13:10:02 -06:00
vicrodh f5d947e8f1 feat(ui): add clickable artist name to AlbumCard
Add artistId and onArtistClick props. When both are provided, the
artist name renders as a button with hover highlight that navigates
to the artist detail page independently of the card click.
2026-02-08 13:05:10 -06:00
vicrodh 25535eabe4 fix(ui): reduce quality badge height in AlbumCard
Reduce vertical padding from 4px to 2px, add explicit line-height: 1.2,
and revert min-width from 90px to 72px for more compact badges.
2026-02-08 13:04:29 -06:00
vicrodh 6b20355737 fix(tooltip): match data-sys-tooltip on subsequent hovers
After first hover, title is stripped and stored as data-sys-tooltip.
Subsequent hovers need to match [data-sys-tooltip] since [title] no
longer exists on the element.
2026-02-08 12:47:49 -06:00
vicrodh 969f2ba71c feat(ui): add global custom tooltip system replacing native title tooltips
Global event delegation intercepts pointerenter on [title] elements,
strips the native title attribute, and shows a styled tooltip matching
QBZ's visual language. Handles viewport edge clamping with
top/bottom/right/left fallback positioning.
2026-02-08 12:44:07 -06:00