Commit Graph
100 Commits
Author SHA1 Message Date
vicrodh d474a55d70 lore(changelog): auth changes
Updating docs for tag release.
2026-04-05 09:39:51 -06:00
vicrodh 223dbf553e fix(security): override esbuild to 0.25.x (CVE in <= 0.24.2)
svelte-i18n pins esbuild ^0.19.2 which is vulnerable. Override to
0.25.x resolves dependabot alert #2. Build verified.

cc
2026-04-04 21:18:33 -06:00
vicrodh 12b8b3491a fix(auth): disable basic auth in bootstrap and legacy commands
Bootstrap no longer attempts email/password login — only OAuth token
restore. v2_manual_login and v2_auto_login now return immediately with
deprecation errors. Users with old saved credentials will see the
login screen instead of hitting Qobuz's deprecated endpoint.

cc
2026-04-04 21:13:41 -06:00
vicrodh 7588a4804a feat(ui): add system browser OAuth link in login view
Secondary link-style option below the main OAuth button. Opens the
user's default browser (Firefox, Chrome, etc.) instead of the Tauri
WebView. Useful for password managers and saved sessions.

i18n keys added to all 5 locales.

cc
2026-04-04 21:05:36 -06:00
vicrodh 648f690a0b feat(auth): add system browser OAuth login and extract shared finalize_oauth_login
Refactor: shared finalize_oauth_login() handles code exchange, CoreBridge
injection, session activation, and token persistence. Frontend-agnostic,
reusable by GUI, TUI, and headless clients.

New command: v2_start_system_browser_oauth spawns a local axum listener,
opens the user's default browser for Qobuz OAuth, and captures the
redirect code automatically.

cc
2026-04-04 21:03:11 -06:00
vicrodh a8e6d151dc fix(security): remove sensitive values from log lines flagged by CodeQL
session_uuid and user_id removed from log output entirely.
CodeQL does not recognize custom sanitizer functions as sufficient.

cc
2026-04-04 20:38:09 -06:00
vicrodh d79eb8e1a8 feat(ui): add Lock Output Device toggle for JACK/DAW routing (#263)
PipeWire-only setting, disabled when DAC Passthrough is active.
i18n keys added to all 5 locales.

cc
2026-04-04 12:12:08 -06:00
vicrodh 83e43949b7 feat(audio): add skip_sink_switch option for JACK/DAW routing (#263)
When enabled, skips pactl set-default-sink on stream creation.
Preserves external audio routing (JACK, qjackctl, Reaper).
Mutually exclusive with DAC passthrough.

cc
2026-04-04 12:08:22 -06:00
vicrodh e4e40b21e0 docs: add release notes for v1.2.2
cc
2026-04-04 11:28:05 -06:00
vicrodh ea2280f848 chore: update codename to Bye bye plain auth
cc
2026-04-04 11:19:52 -06:00
vicrodh ee019851ef chore: bump version to 1.2.2
cc
2026-04-04 11:15:15 -06:00
vicrodh a3dc3a28ee Merge remote-tracking branch 'origin/pre-release' into pre-release 2026-04-04 11:10:13 -06:00
Victor RH 4aed668bbb Merge pull request #255 from vicrodh/dependabot/cargo/src-tauri/pre-release/tempfile-3.27.0
chore(deps): bump tempfile from 3.26.0 to 3.27.0 in /src-tauri
2026-04-04 11:04:16 -06:00
Victor RH 5e3d824f5f Merge pull request #256 from vicrodh/dependabot/npm_and_yarn/pre-release/svelte-check-4.4.6
chore(deps-dev): bump svelte-check from 4.4.5 to 4.4.6
2026-04-04 11:04:14 -06:00
Victor RH 9e2fa8943e Merge pull request #258 from vicrodh/dependabot/cargo/src-tauri/pre-release/env_logger-0.11.10
chore(deps): bump env_logger from 0.11.9 to 0.11.10 in /src-tauri
2026-04-04 11:04:12 -06:00
Victor RH b05d0773a9 Merge pull request #259 from vicrodh/dependabot/cargo/src-tauri/pre-release/uuid-1.23.0
chore(deps): bump uuid from 1.22.0 to 1.23.0 in /src-tauri
2026-04-04 11:04:10 -06:00
Victor RH 2c75ee776c Merge pull request #264 from afonsojramos/macos-config-compat
fix(macos): gate Linux graphics CLI flags and crash handler
2026-04-04 10:57:41 -06:00
Victor RH 8c484075d1 Merge pull request #266 from afonsojramos/use-released-coreaudio
fix(deps): use released coreaudio-rs and notify-rust instead of forks
2026-04-04 10:57:39 -06:00
vicrodh e66117fbc4 feat(auth): remove basic auth login, OAuth only
Qobuz no longer accepts basic auth. Remove email/password fields,
manual login handler, and "Remember me" checkbox from LoginView.
OAuth browser login is now the sole authentication method.

cc
2026-04-04 10:39:51 -06:00
vicrodh 34a18093d0 fix: restore albumId/artistId on session resume for player bar navigation
setCurrentTrack during session restore was missing albumId and artistId,
causing Go to Album / Go to Artist clicks to silently fail until a new
track was played. Also restore isLocal, source, and parental_warning for
full parity with the normal playback path.

Closes #252

cc
2026-04-02 11:54:02 -06:00
vicrodh 3ac7073b9c feat(qobuz): migrate login_with_token to V2 crates
Add login_with_token to QobuzClient and QbzCore for restoring
sessions from saved OAuth tokens. Previously only existed in
the legacy client.

cc
2026-04-02 07:47:45 -06:00
vicrodh 211f45a557 fix(favorites): bulk make offline now actually downloads tracks
handleBulkMakeOffline was calling v2_cache_favorite_track which only
saves metadata to the favorites cache. Replaced with
cacheTracksForOfflineBatch which triggers the real offline download.

cc
2026-04-01 17:39:51 -06:00
Victor RH e56b0cbb6a Merge pull request #238 from afonsojramos/fix/macos-x86-build
fix(macos): enable x86_64 cross-compilation
2026-04-01 16:29:13 -06:00
Victor RH 38c5512507 Merge pull request #250 from afonsojramos/macos-tray-settings-audit
feat(settings): use menu bar terminology and hide redundant tray settings on macOS
2026-04-01 16:22:08 -06:00
Victor RH 00e76471d0 Merge pull request #249 from afonsojramos/macos-immersive-drag-bar
fix: make immersive mode window draggable on macOS
2026-04-01 16:22:05 -06:00
Victor RH bd7e5cbe9a Merge pull request #248 from afonsojramos/cmd-comma-settings
feat: add Cmd+, keyboard shortcut to open settings
2026-04-01 16:22:03 -06:00
vicrodh 35d0ff39f0 chore: remove unused github.svg (replaced by simple-icons in PR #237)
cc
2026-03-31 20:27:29 -06:00
Victor RH 1b10f6c132 Merge pull request #246 from afonsojramos/feat/macos-rich-notifications-pr
feat(macos): add album artwork to notifications
2026-03-31 20:27:23 -06:00
Victor RH 4b988a6c61 Merge pull request #245 from afonsojramos/fix/macos-hide-linux-settings
fix(macos): hide Linux-only settings and fix content padding
2026-03-31 20:27:16 -06:00
Victor RH 4a8f2e5562 Merge pull request #244 from afonsojramos/fix/macos-gate-idle-inhibit
fix(macos): gate idle_inhibit module for Linux only
2026-03-31 20:27:09 -06:00
Victor RH b2f75cc85c Merge pull request #239 from afonsojramos/feat/macos-deep-link
feat(macos): add deep link support for qobuzapp:// URLs
2026-03-31 20:27:02 -06:00
Victor RH fbac26ad34 Merge pull request #237 from afonsojramos/fix/lucide-github-icon
fix: replace removed Github icon with simple-icons
2026-03-31 20:26:36 -06:00
Victor RH eed692a852 Merge pull request #236 from afonsojramos/feat/coreaudio-device-probing
feat(macos): add CoreAudio device probing and sample rate switching
2026-03-31 20:26:29 -06:00
vicrodh 1e019becfd fix: resolve correct artist and country for MusicBrainz metadata
Three fixes:
- resolve_artist now prefers exact name matches over highest score,
  fixing "The Warning" resolving to "Fates Warning" (score=100 but
  wrong name vs score=97 exact match)
- resolve_area_country now returns ISO country code alongside name,
  fixing flag display (was showing US flag for German artists)
- country_code updated in location metadata for correct flag rendering

cc
2026-03-31 17:23:00 -06:00
vicrodh 1953774d03 fix: resolve birth country from area hierarchy instead of MB country field
Add resolve_area_country() that walks the MB area hierarchy up to
the country level (e.g., Frankfurt -> Hessen -> Germany).

Use it in v2_musicbrainz_get_artist_metadata to get the real birth
country instead of MB's "country" field (which is where the artist
is active, not where they were born).

Hans Zimmer now shows "Frankfurt am Main, Germany" and clicking
the location shows German composers, not American ones.

cc
2026-03-31 17:17:01 -06:00
vicrodh 305cffa08e fix: don't append country to birth location display
MB's country field is where the artist is active, not where they
were born. When begin_area exists (city-level), display only the
city name to avoid incorrect attribution (e.g., Hans Zimmer born
in Frankfurt showing "United States").

cc
2026-03-31 16:57:13 -06:00
vicrodh f702622e0e fix: correct artist birth/formation location display order
Two bugs in location_discovery.rs:
- Display format was "Country, City" instead of "City, Country"
- Country was derived from area (where artist is active) instead
  of country code (where artist was born/formed)

Hans Zimmer now shows "Frankfurt am Main, Germany" instead of
"United States, Frankfurt am Main"

Closes #235

cc
2026-03-31 16:54:07 -06:00
vicrodh d19c142d4f fix: switch log upload to paste.rs (dpaste.org returns 403/405)
paste.rs accepts raw POST body and returns URL directly.
Simpler API, no expiration config needed.

cc
2026-03-31 16:45:07 -06:00
vicrodh 527d63ca2c fix: migrate log upload from 0x0.st to dpaste.org
0x0.st disabled uploads. Switch to dpaste.org with 15-day expiry.
Use form POST instead of multipart, update all 5 locale files.

cc
2026-03-31 16:43:28 -06:00
vicrodh a87e35d167 fix: restore MPRIS metadata and playback context on session resume
- Send track metadata to MPRIS on session restore so playerctl
  shows title/artist/album immediately after app restart
- Persist playback context (album, playlist, etc.) to localStorage
  on session save and restore it on startup
- Add buffer_progress to frontend PlaybackEvent type

Closes #240

cc
2026-03-31 16:33:07 -06:00
vicrodh 6acd843891 feat: add streaming buffer progress indicator to seekbar
Show a subtle buffer progress bar in the seekbar when streaming
tracks (before they are fully cached). The bar disappears once
the track is fully buffered.

Backend: expose buffer_progress from BufferedMediaSource through
SharedState -> PlaybackEvent -> playerStore.
Frontend: render .seekbar-buffer bar behind the playback fill.

cc
2026-03-31 16:02:07 -06:00
vicrodh 18403bba73 fix: single ESC exits both immersive overlay and window fullscreen
closeFullScreen() now also exits window fullscreen so the user
doesn't need to press ESC twice.

cc
2026-03-31 15:42:41 -06:00
vicrodh b315b23b61 fix: F11 fullscreen toggle and ESC exit work globally
F11 now toggles window fullscreen from anywhere in the app, not just
inside the immersive player. ESC exits window fullscreen when no UI
overlays are open.

Closes #202

cc
2026-03-31 15:34:27 -06:00
vicrodh 84b54ed2ce chore: fix SSH commit signing after Gentoo migration
cc
2026-03-31 15:25:28 -06:00
Victor RH e229bbd7c3 Merge pull request #223 from vicrodh/dependabot/cargo/src-tauri/pre-release/lofty-0.23.3
chore(deps): bump lofty from 0.18.2 to 0.23.3 in /src-tauri
2026-03-31 09:11:39 -06:00
Victor RH b9572b3c2e Merge pull request #218 from vicrodh/dependabot/cargo/src-tauri/pre-release/axum-0.8.8
chore(deps): bump axum from 0.7.9 to 0.8.8 in /src-tauri
2026-03-30 21:46:12 -06:00
Victor RH 1e4ce38258 Merge pull request #224 from vicrodh/dependabot/cargo/src-tauri/pre-release/souvlaki-0.8.3
chore(deps): bump souvlaki from 0.7.3 to 0.8.3 in /src-tauri
2026-03-30 21:39:20 -06:00
Victor RH f9c32a25a9 Merge pull request #225 from vicrodh/dependabot/cargo/src-tauri/pre-release/rand-0.10.0
chore(deps): bump rand from 0.8.5 to 0.10.0 in /src-tauri
2026-03-30 20:59:16 -06:00
Victor RH 0ce54c3f10 Merge pull request #222 from vicrodh/dependabot/npm_and_yarn/pre-release/lucide-svelte-1.0.1
chore(deps): bump lucide-svelte from 0.562.0 to 1.0.1
2026-03-30 13:47:23 -06:00
Victor RH 7db3ecfae9 Merge pull request #221 from vicrodh/dependabot/npm_and_yarn/pre-release/svelte-5.55.0
chore(deps-dev): bump svelte from 5.54.0 to 5.55.0
2026-03-30 13:31:08 -06:00
Victor RH 1b0ccd7e3e Merge pull request #220 from vicrodh/dependabot/cargo/src-tauri/pre-release/image-0.25.10
chore(deps): bump image from 0.25.9 to 0.25.10 in /src-tauri
2026-03-30 13:31:05 -06:00
Victor RH 69d6356746 Merge pull request #214 from vicrodh/dependabot/npm_and_yarn/picomatch-4.0.4
chore(deps-dev): bump picomatch from 4.0.3 to 4.0.4
2026-03-30 13:31:02 -06:00
Victor RH 2053b2e798 Merge pull request #230 from AdamArstall/bugfix/external/scroll-restoration
Fix scroll restoration for virtualized containers on back/forward navigation
2026-03-30 13:29:19 -06:00
Victor RH ae67d63899 Merge pull request #226 from GwendalBeaumont/refactor/external/i18n-interpolation
feat(i18n): add translation strings to views
2026-03-30 13:06:54 -06:00
Victor RH e6ea2b483c Merge pull request #198 from vicrodh/dependabot/cargo/src-tauri/rustls-webpki-0.103.10 2026-03-24 20:17:12 -06:00
Victor RH 3b2cd1addd Merge pull request #188 from vicrodh/dependabot/cargo/src-tauri/pre-release/qrcode-generator-5.0.0
chore(deps): bump qrcode-generator from 4.1.9 to 5.0.0 in /src-tauri
2026-03-19 17:24:26 -06:00
Victor RH 23811367af Merge pull request #186 from vicrodh/dependabot/npm_and_yarn/pre-release/svelte-check-4.4.5
chore(deps-dev): bump svelte-check from 4.3.5 to 4.4.5
2026-03-19 17:24:24 -06:00
Victor RH 2c06d1163b Merge pull request #189 from vicrodh/dependabot/npm_and_yarn/pre-release/sveltejs/vite-plugin-svelte-7.0.0
chore(deps-dev): bump @sveltejs/vite-plugin-svelte from 5.1.1 to 7.0.0
2026-03-19 17:21:08 -06:00
Victor RH ef4ee640b1 Merge pull request #191 from vicrodh/dependabot/cargo/src-tauri/pre-release/rcgen-0.14.7
chore(deps): bump rcgen from 0.12.1 to 0.14.7 in /src-tauri
2026-03-19 17:21:05 -06:00
Victor RH 9cf7657be7 Merge pull request #193 from vicrodh/dependabot/cargo/src-tauri/pre-release/ashpd-0.13.8
chore(deps): bump ashpd from 0.13.3 to 0.13.8 in /src-tauri
2026-03-19 17:21:03 -06:00
Victor RH eb82bc8920 Merge pull request #190 from vicrodh/dependabot/cargo/src-tauri/pre-release/tauri-2.10.3
chore(deps): bump tauri from 2.10.2 to 2.10.3 in /src-tauri
2026-03-19 17:21:01 -06:00
Victor RH 8adcd67702 Merge pull request #192 from vicrodh/dependabot/cargo/src-tauri/pre-release/uuid-1.22.0
chore(deps): bump uuid from 1.21.0 to 1.22.0 in /src-tauri
2026-03-19 17:20:58 -06:00
Victor RH 5ec74a5beb Merge pull request #184 from vicrodh/dependabot/npm_and_yarn/pre-release/typescript-5.9.3
chore(deps-dev): bump typescript from 5.6.3 to 5.9.3
2026-03-19 17:20:56 -06:00
Victor RH 38fab9f7c9 Merge pull request #187 from vicrodh/dependabot/npm_and_yarn/pre-release/vitest-4.1.0
chore(deps-dev): bump vitest from 4.0.17 to 4.1.0
2026-03-19 17:20:54 -06:00
Victor RH f5e7187251 Merge pull request #185 from vicrodh/dependabot/npm_and_yarn/pre-release/svelte-5.54.0
chore(deps-dev): bump svelte from 5.53.6 to 5.54.0
2026-03-19 17:20:50 -06:00
Victor RH ee1459a0f1 Update funding information in FUNDING.yml 2026-03-14 21:07:43 -06:00
vicrodh 616fab281d fix(flatpak): correct fabricated commit hash in screenshot URLs
The metainfo.xml had a fake full hash (cff32e5d47f3b44568af9...) that
returned 404 on raw.githubusercontent.com. Replace with the real commit
hash (cff32e5da7) where screenshots exist.
2026-03-04 00:31:05 -06:00
vicrodh d431581f16 fix(notifications): normalize ashpd artwork icon payload
Normalize notification artwork to square PNG (max 512x512, <=4 MiB) before sending Icon::Bytes via ashpd portal, so album art renders reliably without legacy fallback.\n\ncx
2026-03-03 23:31:31 -06:00
vicrodh 70adee9f16 fix(notifications): restore album artwork via native D-Bus path
The XDG portal notification spec's icon field doesn't support inline
album artwork the way freedesktop Notifications does with image-path.

Dual-path approach:
- Native (non-Flatpak): use org.freedesktop.Notifications D-Bus
  interface directly with image-path hint for album artwork
- Flatpak (sandboxed): use ashpd portal (Flathub requirement)

Uses ashpd::is_sandboxed() for detection and ashpd's re-exported
zbus for the direct D-Bus call, avoiding extra dependencies.
2026-03-03 22:46:43 -06:00
vicrodh d3cad99bd9 fix(notifications): send artwork as bytes instead of file URI
The XDG portal was not displaying album artwork when passed as a
file:// URI (showed KDE default icon instead). Send artwork as
Icon::Bytes so the portal receives the image data directly.
2026-03-03 22:41:08 -06:00
vicrodh 69aed4e1ad feat(notifications): migrate from notify-rust to ashpd XDG Portal
Replace direct D-Bus notifications (notify-rust) with XDG Desktop
Portal notifications (ashpd) for Flathub compliance. Portal
notifications use the app's .desktop file identity and don't require
--talk-name=org.freedesktop.Notifications permission.

- Replace notify-rust dep with ashpd (linux-only, tokio+notification)
- Use NotificationProxy for portal-based notifications
- Use stable ID "track-now-playing" to replace instead of stacking
- Convert artwork path to file:// URI via ashpd::Uri
- Graceful fallback when portal is unavailable
2026-03-03 22:25:59 -06:00
vicrodh b15a375e23 feat(immersive): add 3-mode background system (Full/Lite/Off)
Replace binary blur toggle with a 3-option dropdown. Full mode uses
the existing WebGL2 shader, Lite mode renders a pre-blurred static
image animated with CSS transforms (compositor-driven, immune to
Wayland frame callback stutter), and Off mode shows a solid color.

Includes config migration from disableBlurBackground to backgroundMode,
updated composition profiles, and i18n for all 4 locales.

Closes #127
2026-03-02 13:18:55 -06:00
vicrodh 00675de6b8 feat(snap): add snap sandbox detection and welcome modal wiring
Detect when QBZ runs inside a Snap sandbox (via SNAP env var) and show
a one-time welcome modal with required plug connection commands. Adds a
Snap Sandbox section in Settings with copyable commands, mirroring the
existing Flatpak pattern.

Backend: snap.rs module, DB table snap_welcome_shown, V2 commands.
Frontend: updatesService, +page.svelte modal queue, SettingsView section.
2026-03-02 11:10:50 -06:00
vicrodh 8529477778 feat(immersive): polish tunnel depth and artwork-driven line palette
cx
2026-03-02 01:06:55 -06:00
vicrodh 5930f599d6 feat(immersive): refine tunnel curve occlusion behavior
cx
2026-03-02 00:55:38 -06:00
vicrodh 5492e8115e feat(immersive): refine neon and tunnel panel visuals
cx
2026-03-02 00:50:45 -06:00
vicrodh 47f80149d5 feat(playlists): add custom artwork and folder sidebar visibility controls
cx
2026-03-01 22:09:43 -06:00
vicrodh ec3ecb35b2 fix(flatpak): restore pipewire stream matching and tray icon access
cx
2026-03-01 20:18:17 -06:00
vicrodh afe086e6fd fix(ci): stabilize rc releases and version flatpak artifact
cx
2026-03-01 19:34:24 -06:00
vicrodh 0f28fd8979 fix: add mpris plug to root snapcraft.yaml
The packaging/snap/ copy already had the mpris plug but the root
snapcraft.yaml was missing it, preventing MPRIS media controls
from working in the Snap package.
2026-03-01 19:07:00 -06:00
vicrodh cb4708770c fix: sync local flatpak manifest with flathub PR changes
Remove broad filesystem permissions, add PipeWire :ro access,
drop --own-name (auto-granted since MPRIS name contains appid).
2026-03-01 19:06:25 -06:00
vicrodh b49d0b3e3b chore(release): bump version to 1.1.19-rc-1
cx
2026-03-01 18:59:24 -06:00
vicrodh 55a1ef25e6 fix(ui): polish mini/immersive layout and queue favorite behavior
cx
2026-03-01 18:56:23 -06:00
vicrodh 9c6265abd8 fix(linux): default main window to opaque for shutdown stability
cx
2026-03-01 17:21:49 -06:00
vicrodh 75254d26a9 fix(linux): apply WebKit EGL shutdown stability workarounds
cx
2026-03-01 17:13:42 -06:00
vicrodh b95edec754 fix(shutdown): avoid forced exit(0) during main window close
cx
2026-03-01 16:55:16 -06:00
vicrodh d72eac3c1e fix: search album/artist grid collapses to single column on keystroke
When typing in the search bar, new results cause the virtual scroll
container to remount. The ResizeObserver was stale (watching the old
destroyed element) and containerWidth reset to 0, causing gridCols
to default to 1. Two fixes: cache the last known column count so
width=0 uses the previous layout, and reconnect the ResizeObserver
whenever the container element changes.
2026-03-01 16:38:38 -06:00
vicrodh 63521e920b fix: Escape on empty search input blurs focus
First Escape clears the search text, second Escape when input is
already empty removes focus from the input. Applied to both the
sidebar and titlebar search inputs for keyboard-driven navigation.
2026-03-01 16:33:33 -06:00
vicrodh eabeb3959f fix: move multi-select button to header in WeeklySuggestView
The CheckSquare button was next to the search bar instead of in the
header actions alongside Play/Shuffle/Save, inconsistent with DailyQ,
FavQ and TopQ views. Moved it to the header and removed orphaned CSS.
2026-03-01 16:22:26 -06:00
vicrodh 7753d2520e fix: multi-select add to playlist sends all tracks in one call
The broken views called onTrackAddToPlaylist in a loop (once per
selected track), causing each call to overwrite the previous track
IDs in the playlist modal. Only the last track survived. Now all 6
views collect IDs first and call onBulkAddToPlaylist once with the
full array.

Views fixed: ArtistDetailView, AlbumDetailView, LabelView,
FavoritesView, WeeklySuggestView, PlaylistDetailView.
2026-03-01 16:19:12 -06:00
vicrodh 1054e71768 fix: populate downloaded_format_ids in all purchase endpoints
v2_purchases_get_all and v2_purchases_get_by_type only set the
downloaded boolean but never populated downloaded_format_ids, so
check marks disappeared after app restart. Now both use
get_downloaded_purchase_formats() and build the format map, matching
the behavior already present in v2_purchases_get_album.

Fixes #119
2026-03-01 16:11:04 -06:00
vicrodh f9e9d58e81 fix: add-to-library uses album folder instead of root destination
When downloading a purchased album to ~/Music, the "Add to Local
Library" button was adding ~/Music (the entire music directory) instead
of the specific album folder like ~/Music/Artist/Album/.

After the first track downloads, extract the album-level folder from
the returned file path and update the stored destination. This ensures
only the downloaded album gets added to the library. Fixes #117.
2026-03-01 15:47:01 -06:00
vicrodh 683f97a5d5 fix: deduplicate albums with quality subfolders in local library
The library scanner's album_root_dir() only knew to skip disc folders
(Disc 1, CD2, etc.) when resolving the album directory. Files stored
in quality subfolders like artist/album/FLAC 24-bit - 96 kHz/track.flac
caused each encoding variant to appear as a separate album card.

Add is_encoding_folder() to detect common audio format directory names
(FLAC, MP3, AAC, WAV, etc.) and make album_root_dir() skip past both
encoding and disc subdirectories, handling chained nesting too.

Fixes the workaround from #116.
2026-03-01 15:40:22 -06:00
vicrodh c2f2888312 feat: add cancel button for purchase album downloads
Allow users to cancel an in-progress album download. The current track
finishes but no further tracks are started. A cancel button appears in
the progress bar during download, and a cancelled state shows how many
tracks completed. Closes #133.
2026-03-01 14:14:47 -06:00
vicrodh 8fef723ced fix: eliminate dead space in Customize Shortcuts modal
Switch from CSS grid to CSS multi-column layout so categories pack
tightly top-to-bottom instead of creating large empty rows when
columns have uneven heights.
2026-03-01 14:09:17 -06:00
vicrodh 976e5226b4 feat: add miniplayer keyboard shortcuts and fix X button behavior
Add Shift+M toggle shortcut for mini player mode (main and mini window).
Add 1-5 number keys for surface switching (micro/compact/artwork/queue/lyrics)
in mini player context. Add playback shortcuts (Space, Ctrl+Arrow) to mini
player window. Fix X button to close app (or hide to tray) instead of
duplicating the Expand button behavior. Closes #134.
2026-03-01 14:04:18 -06:00
vicrodh 0f1f6b3716 fix: amplify ambient shader motion for visible animation
Previous shader was too subtle — drift, rotation, and breathing were
imperceptible with the smooth 8x8 texture. Now with much larger values:
- Drift: 0.05 -> 0.20 max (Lissajous with two frequencies)
- Scale breathing: 2% -> 12% range
- Rotation: 0.86deg -> 5deg range
- Added warm/cool color shifting over time
- Stronger vignette pulsing and brightness breathing

Safe because the 8x8-sourced texture has zero structure to reveal.
2026-03-01 13:30:18 -06:00
vicrodh db5d9182f2 fix: use 8x8 downscale instead of CSS blur to destroy artwork structure
CSS filter:blur() may not work reliably in all WebView environments,
leaving artwork structure visible as rectangular artifacts. New
approach: draw the full artwork at 8x8 resolution (64 pixels) where
no structure can physically survive, then scale up to 128x128 with
high-quality bilinear smoothing. One optional blur pass for polish.
2026-03-01 13:29:48 -06:00
vicrodh e5955a8f91 fix: replace multi-layer ambient shader with single-layer approach
The 3-layer parallax shader created visible rectangular artifacts on
dark/uniform artwork. Each layer sampled at different scale/offset,
and the spatial weighting transitions between layers showed as
geometric seams regardless of offset magnitude.

New shader uses a single texture sample with organic Lissajous drift,
gentle rotation, scale breathing, pulsing vignette, and vertical tint.
The pre-blurred texture handles the visual complexity — the shader
just adds subtle life without geometric artifacts.
2026-03-01 13:24:30 -06:00
vicrodh 10d395a89e fix: preserve dark artwork mood in ambient background
Two issues caused visible dark rectangles on simple/dark artwork:

1. Texture normalization always mapped to [30-240] regardless of source
   brightness. For dark artwork (Metallica), this amplified noise 5x and
   turned a dark album into a light gray background. Now uses
   brightness-aware blending: dark artwork gets gentle lift (preserves
   mood), colorful artwork gets full normalization.

2. Shader layer offsets were too large (up to 20% of texture), causing
   visible layer boundaries where each sampling layer showed different
   parts of the amplified texture. Reduced offsets by ~60% and tightened
   scale ranges for smoother parallax.
2026-03-01 13:22:05 -06:00