Commit Graph

106 Commits

Author SHA1 Message Date
cucadmuh a6cc2e2ad4 perf(linux): WebKit probe, throttled progress IPC, snapshot playback UI (#452)
* feat(linux): optional native GDK for Nix gdk-session

Introduce PSYSONIC_ALLOW_NATIVE_GDK so main skips the default GDK_BACKEND=x11
pin when the Nix gdk-session wrapper sets the flag. Remove GDK_BACKEND from
the npm tauri:dev script so it does not override nix develop defaults.

* fix(ui): portal server switch menu above sidebar

Main column stacks below the sidebar (layout z-index), so an in-tree dropdown
could never win over the left nav. Render the menu via createPortal to
document.body with fixed coordinates, matching the library scope picker.

* feat(perf): add mainstage probe controls and cut WebKit repaint load

Add a dedicated performance probe surface for mainstage/home toggles and wire Linux CPU diagnostics to isolate expensive UI paths. Tune waveform drawing and Home artwork clipping/windowing so visible content loads immediately while reducing WebKit compositor pressure during playback.

* fix(perf): stop hero rotation when section is off-screen

Gate hero auto-rotation and backdrop crossfade by real viewport visibility using the actual scrolling ancestor. This prevents periodic 10-second CPU spikes from hidden hero updates while preserving normal behavior when the hero is visible.

* fix(perf): isolate player progress updates from mainstage diagnostics

Add probe toggles for PlayerBar waveform and live progress UI updates to confirm playback progress churn as the main CPU driver.
Restore Home artwork quality defaults and keep visual-degradation modes opt-in via debug flags only.

* fix(hero): resume background and autoplay after viewport return

Re-check hero visibility on focus/visibility changes and add a short recovery poll while off-screen so missed scroll/RAF events cannot leave hero animation paused.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(perf): decouple playback progress from mainstage compositing pressure

Throttle audio progress delivery and route live seekbar timing through a lightweight progress channel to cut focus-time WebKit CPU spikes.
Add focused diagnostics in Performance Probe and restore hero/waveform behavior so visuals remain stable while profiling.

* fix(debug): open performance probe with Ctrl+Shift+D

Replace logo-triggered opening with a keyboard shortcut and keep logo purely decorative to avoid accidental probe activation.

* docs(changelog): document experiment/performance probe and playback work

Add an [Unreleased] section for the performance probe, throttled audio
progress IPC, snapshot-based live UI updates, WaveformSeek scheduling
over the same canvas bar renderer, Hero/Home rail fixes, and Linux/Nix
GDK dev ergonomics.

* perf(linux): add WebKit probe, throttle progress IPC, snapshot playback UI

Ship Performance Probe (Ctrl+Shift+D), Rust-throttled audio:progress, a
playback progress snapshot channel with coarse Zustand timeline commits,
Linux /proc CPU readout for the probe, Hero and Home rail artwork fixes,
Tracks SongRail windowing parity, MPRIS cleanup, gated perf counters, and
WaveformSeek paused-seek correctness. Documented in CHANGELOG for PR #452.

* docs(changelog): fold perf work into 1.45.0 and refresh date

Drop the separate 1.45.1 heading; keep PR #452 notes under 1.45.0 Added and
set the section date to 2026-05-04. Restore the safety preface before the
versioned sections.

* docs(changelog): order 1.45.0 Added entries by PR number

Sort the 1.45.0 release notes so subsections follow ascending PR id (390
through 452), with PR #452 last.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-04 20:06:49 +03:00
github-actions[bot] dd73e2b36b chore(release): bump main to 1.45.0-dev (#375)
* chore(release): bump main to 1.45.0-dev

* chore(nix): sync npmDepsHash with package-lock.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-30 02:41:53 +03:00
cucadmuh 42c6b2274d chore(release): prepare 1.44.0 dev version and aur tag source (#346)
* chore(release): prepare 1.44.0 dev version and aur tag source

Set the app version to 1.44.0-dev in package manifests and update the AUR source tag template to app-v$pkgver while keeping pkgver on the current stable release.

* chore(nix): sync npmDepsHash with package-lock.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-28 23:34:03 +03:00
Frank Stellmacher 402120143e chore(release): bump to 1.44.0-rc1 (#339)
CHANGELOG entry covers everything merged on top of v1.43.0:
LUFS loudness normalization, Orbit multi-user listen-together,
Now-Playing dashboard, Tracks library hub, Lucky Mix, sleep-timer
ring UI, Genres tag-cloud, queue undo/redo, settings refactor +
perf suite, plus the usual fixes.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:02:51 +02:00
Frank Stellmacher 67d51a0975 revert: roll back flatpak packaging experiment (#271 + follow-ups) (#297)
Reverts #271, #292, #293, #294, #295, #296.

The flatpak CI pipeline itself works end-to-end, but the installed bundle
surfaced three separate manifest issues during smoke-test on Wayland+NVIDIA:

1. GDK_BACKEND is not set, so without an X11 display in the sandbox GTK
   aborts with "Failed to initialize GTK".
2. libayatana-appindicator3 is not bundled in the GNOME 47 runtime, so
   libappindicator-sys panics the main thread.
3. The release binary is compiled via \`cargo build --release\` rather than
   \`cargo tauri build\`, so the \`custom-protocol\` feature is off and
   Tauri falls back to devUrl — the window opens but shows
   "Could not connect to localhost".

Rolling back so main stays on 1.43.0. A follow-up on the original PR
tracks the fixes needed before re-attempting.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 22:50:06 +02:00
Frank Stellmacher 2476c2197d chore(release): bump to 1.43.2 (flatpak test retry) (#294)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 21:56:40 +02:00
Frank Stellmacher 114b58d128 chore(release): bump to 1.43.1 (flatpak test) (#292)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 21:47:59 +02:00
Frank Stellmacher 77598e10e9 chore(release): v1.43.0 (#225)
Co-authored-by: Psychotoxical <dev@psysonic.app>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 23:34:05 +02:00
Psychotoxical 9bcef81b22 chore(release): v1.42.1
Critical Windows bug-fix release.

Fixed
- Mini player no longer hangs the app on Windows (see 71fbc717): the
  second WebView2 is now pre-built in .setup() so the first open is a
  pure show/hide instead of a creation + minimize race. Windows is
  back on native window decorations for the mini and skips the main-
  window minimize/unminimize dance around show/hide.
- Mini player re-emits mini:ready on window focus so the snapshot from
  main arrives reliably on first open even when pre-create finished
  before main's bridge attached its listener.

Added
- "Preload mini player" toggle in Settings → General for Linux + macOS
  so those platforms can opt into the instant-open behaviour that
  Windows already has as a hang workaround.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 15:52:13 +02:00
Psychotoxical c17fc0f6ac chore(release): v1.42.0
Consolidates everything since v1.40.0 (public) into one coherent
release. v1.41.0 remains as an internal Draft on GitHub that was used
to verify the Cachix substituter pipeline and never went public — this
release folds its intended contents in and adds the mini-player feature
work, the player-bar time toggle (kveld9), the ReplayGain expand badge
and related UX polish on top.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 13:40:57 +02:00
Psychotoxical ab35ef5eb4 chore(release): v1.41.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 23:43:29 +02:00
Psychotoxical 98352bb656 chore(release): v1.40.0
Major release consolidating several months of work into a single coherent
version. The 1.34.x patch series accumulated many small features; 1.40.0
packages them up and signals the infrastructure milestone (macOS signing
+ notarization + auto-updater) clearly.

Highlights (see CHANGELOG for the full rundown):
- macOS builds are signed with a Developer ID certificate and notarized
  by Apple — no more Gatekeeper "unidentified developer" dialog
- In-app auto-update on macOS via the Tauri Updater plugin; polished
  modal with trust badges, restart countdown, and state-dependent buttons
- Linux WebKitGTK wheel scroll toggle (PR #207 by cucadmuh)
- Device Sync: user-configurable filename template replaced with a
  fixed cross-OS scheme; playlists now live in their own self-contained
  folders with sibling-referencing .m3u8; one-shot migration tool for
  existing sticks
- WCAG contrast audits for middle-earth and nucleo themes
- Contributors list in Settings → About updated (PRs #205, #206, #207)

Windows signing + Windows auto-updater are the remaining gap; 2.0.0 is
planned once both are active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:41:16 +02:00
Psychotoxical 36f0ef79fe chore(release): v1.34.23 — update-target for v1.34.22 auto-update test
No functional changes. Throwaway build to serve as the "latest" release
that v1.34.22 will find, download, verify, and install via the Tauri
Updater. Will be deleted once the updater round-trip is confirmed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 17:18:33 +02:00
Psychotoxical 939ed3d412 chore(release): v1.34.22 — fix truncated updater pubkey
A character was lost when the base64-encoded minisign public key was
transcribed into tauri.conf.json, producing a 41-byte decoded key
instead of the required 42 bytes. Every release built against that key
(v1.34.15 through v1.34.21) rejects any update manifest signature with
"Invalid encoding in minisign data". Replaced with the correct pubkey
read directly from ~/.tauri/psysonic-updater.key.pub.

v1.34.19 installed manually for testing cannot receive auto-updates
because the broken pubkey is baked into its binary; a fresh v1.34.22
install is required as the base for the updater test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 17:04:51 +02:00
Psychotoxical bddfd45086 chore(release): v1.34.21 — macOS updater UI fix + second test build
- AppUpdater.tsx: macOS now has a dedicated branch in the update modal —
  no architecture-specific DMG asset shown (the Tauri Updater picks the
  right platform from latest.json), clearer wording ("Downloads, verifies
  and installs automatically"), and the primary button reads "Install
  now" instead of "Download". Strings use defaultValue so locales without
  the key fall back to English until translations catch up.
- Test release for the updater pipeline; CHANGELOG entry asks users to
  ignore it. Will be deleted after the test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 16:05:02 +02:00
Psychotoxical 48c10e5619 chore(release): v1.34.20 — test build for auto-updater pipeline
Throwaway release to validate the macOS Tauri Updater end-to-end:
v1.34.19 (installed manually) → check() → latest.json → download +
install → relaunch. Contains no actual changes. CHANGELOG entry asks
users to ignore it; will be deleted after the test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 15:46:03 +02:00
Psychotoxical 216e6c957f ci(release): re-sign updater tarball after tauri-action's repack
tauri-action always re-packs Psysonic.app into .app.tar.gz after tauri
CLI finishes (regardless of includeUpdaterJson), so the .sig that tauri
CLI produces never matches the final tarball — and the sig tauri-action
was supposed to produce silently goes missing ("Signature not found for
the updater JSON. Skipping upload...").

Rather than fight the repack, sign the repacked tarball ourselves in a
follow-up step using `tauri signer sign` against the same private key
(from TAURI_SIGNING_PRIVATE_KEY), then upload the fresh .sig. tauri-
action still handles the DMG + .app.tar.gz upload; we only add the .sig.

Also removes an unused `std::rc::Rc` import in the vendored cpal patch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 15:31:17 +02:00
Psychotoxical 425addffa0 ci(release): disable tauri-action updater repack, upload .sig ourselves
Root cause: tauri-action runs a second "Packaging" pass after tauri CLI
finishes, which rewrites src-tauri/target/<target>/release/bundle/macos/
Psysonic.app.tar.gz with different bytes. The .sig produced by tauri CLI
no longer matches the new hash, so tauri-action silently deletes it —
leaving the directory with only .app and .app.tar.gz (no .sig for our
manifest generator to consume).

Fix: pass `includeUpdaterJson: false` to tauri-action so it skips the
repack + updater JSON upload entirely, then copy both the .app.tar.gz
and .app.tar.gz.sig produced by tauri CLI into the workspace root with
the expected asset names and `gh release upload` them.

Also disables build-linux and the Windows matrix entry during testing
to cut iteration time roughly in half.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 15:19:33 +02:00
Psychotoxical 43df830960 ci(release): debug .sig discovery, disable verify-nix during testing
- Replace the glob find for the .sig file with an explicit target-based
  path ($matrix → src-tauri/target/<target>-apple-darwin/release/bundle/
  macos/Psysonic.app.tar.gz.sig) and dump directory listings so we can
  see what tauri-action actually leaves behind if the path is wrong
- Skip verify-nix while we iterate fast on signing + updater (its auto-
  commits of flake.lock / npmDepsHash cause rebase friction on every
  release)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 15:08:56 +02:00
Psychotoxical 6ed41070a5 ci(release): upload updater .sig as release asset
tauri-action on macOS cross-target builds produces the .app.tar.gz.sig
locally but silently skips its upload ("Signature not found for the
updater JSON. Skipping upload..."), which caused generate-manifest to
abort on v1.34.15 because the .sig asset was absent.

New step after tauri-action locates the .sig under src-tauri/target/*/
release/bundle/macos/ and uploads it as Psysonic_aarch64.app.tar.gz.sig
or Psysonic_x64.app.tar.gz.sig — the exact filenames generate-update-
manifest.js expects.

Also bumps version to 1.34.16.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 14:46:58 +02:00
Psychotoxical 061c96a89f chore(release): v1.34.15
- feat(updater): macOS auto-update via Tauri Updater

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 14:29:11 +02:00
Psychotoxical fb927c5a2e chore(release): v1.34.14
- feat(linux): WebKitGTK smooth/linear wheel scroll toggle (PR #207 by cucadmuh)
- ci(release): Apple Developer ID signing + notarization for macOS
- fix(themes): WCAG contrast audits for middle-earth + nucleo
- docs(contributors): PRs #205, #206, #207 in Settings About

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 13:31:46 +02:00
kilyabin 4f188be792 feat: fonts with cyrillic support 2026-04-18 02:16:57 +04:00
Psychotoxical d79de7904d chore(release): bump version to 1.34.13
Adds YouLyPlus karaoke lyrics + static-only lyrics toggle, collapses
the advanced Discord options under one header, and ships the real
macOS microphone-prompt fix (cpal patch forcing DefaultOutput on all
output streams).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 22:37:25 +02:00
Psychotoxical d18646de23 chore(release): bump version to 1.34.12
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 19:20:40 +02:00
Psychotoxical 442ed9d191 feat(device-sync): manifest, cancel, font picker + sync status fix
- Write psysonic-sync.json to device after sync/deletions; auto-import
  on folder select when localStorage is empty (cross-platform handoff)
- Add cancel button during active sync: AtomicBool flag per job,
  tasks bail after acquiring semaphore, cancelled state in UI
- Fix sync status staying "pending": normalize template path separators
  to OS separator (Windows: '/' → '\') so compute_sync_paths and
  list_device_dir_files produce matching strings for Set comparison
- Add Geist and JetBrains Mono as variable fonts; font picker collapsible
- Fix device mount detection on Windows: removable drive letters (E:\)
  were incorrectly skipped alongside system roots; strip \?\ prefix
  from canonicalized paths before mount-point comparison

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 22:59:27 +02:00
Psychotoxical 2384b73908 fix(post-merge #190): restore public-toggle in PlaylistEditModal, move @types/papaparse to devDeps
- PlaylistEditModal footer lost the isPublic toggle in the CSV import PR;
  restore it alongside the new Cancel button
- @types/papaparse is a type-only package — belongs in devDependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 18:10:19 +02:00
kveld9 a44581e5d6 new feature: import spotify playlist with .csv 2026-04-15 11:19:31 -03:00
Psychotoxical 795701a447 chore(release): bump version to 1.34.11
- Changelog for v1.34.11 (Opus, Device Sync, community themes, SSL fix)
- Contributors updated in Settings About (PR #181, #182, #183)
- Version bumped to 1.34.11 in package.json, tauri.conf.json, Cargo.toml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 22:28:15 +02:00
Psychotoxical 58f99ae846 chore: bump version to 1.34.11-dev 2026-04-13 22:25:49 +02:00
Psychotoxical 01f71cf50c chore(release): bump version to 1.34.10
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 22:21:07 +02:00
Psychotoxical da1cc91ff1 fix(deps): bump @tauri-apps/plugin-fs to ^2.5.0 and plugin-dialog to ^2.7.0
Rust crates resolved to newer minor versions; npm pins were behind,
causing CI version-mismatch error on tauri build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 12:49:07 +02:00
Psychotoxical 4a2baaf87d chore: bump version to 1.34.9
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 12:38:48 +02:00
Psychotoxical 649f5223b4 chore: bump version to 1.34.8
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 17:06:19 +02:00
Psychotoxical 9671f89a48 chore: bump version to 1.34.7, add changelog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:28:54 +02:00
Psychotoxical 4e3efa3814 feat: self-host fonts via @fontsource-variable, remove Google Fonts CDN
Replaces all Google Fonts CDN references (index.html preconnect/stylesheet
and theme.css @import) with local @fontsource-variable npm packages.
All 10 UI fonts now bundle as WOFF2 into dist/assets/ — app renders
correctly without any internet connection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 13:23:48 +02:00
Psychotoxical 9b239892ef chore: bump version to 1.34.6, add changelog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:36:59 +02:00
Psychotoxical 3643a78cd6 perf: drastically reduce background API requests to Navidrome (v1.34.5)
- NowPlaying polling: only active while dropdown is open + respects
  Page Visibility API — was firing every 10s unconditionally (~8.6k req/day)
- Connection check interval: 30s → 120s (4× reduction)
- Queue sync debounce: 1.5s → 5s (prevents burst on rapid skip)
- Rating prefetch: add 7-minute in-memory TTL cache for artist/album
  ratings — repeated random album loads no longer re-fetch known ratings

Fixes server log flooding reported by users behind reverse proxies (Traefik).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:04:03 +02:00
Psychotoxical dbb53bfa70 release: bump to v1.34.4
Song ratings in context menu + player bar, entity ratings (PR #130),
5 new seekbar styles, custom Linux title bar, album multi-select,
mix rating filter, top-rated stats, compilation filter, scroll reset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 11:13:23 +02:00
Psychotoxical 78beb699a7 chore: bump version to 1.34.3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 20:36:01 +02:00
Psychotoxical 9319c40fde feat(fs-player): adaptive dynamic accent color from album cover
Extracts the most vibrant pixel from an 8×8 downscaled album cover via
the Canvas API and applies it as --dynamic-fs-accent on the .fs-player
root element.  All accent-colored FS player elements use
var(--dynamic-fs-accent, var(--accent)) as fallback so the theme accent
is restored automatically when the FS player closes.

Elements updated:
- .fs-track-title (color + text-shadow)
- .fs-btn.active, .fs-btn-heart.active/:hover
- .fs-btn-play and :hover (background + box-shadow)
- .fs-seekbar-played (background + box-shadow)
- .fs-mesh-blob-a/-b (radial-gradient via color-mix at 14%/8% opacity)
- .fs-art-wrap box-shadow glow (color-mix at 70% opacity)
- MicVocal lyrics-toggle inline style

Color safety: WCAG 4.5:1 contrast against near-black FS background
enforced by progressively lightening in HSL space (ensureContrast).

Pure math functions unit-tested with vitest (28 tests, 0 deps beyond
vitest itself).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 19:14:20 +02:00
Psychotoxical 47490072ef chore: bump version to 1.34.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:52:34 +02:00
Psychotoxical 390e6e788d chore: bump version to 1.34.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 22:59:32 +02:00
Psychotoxical 50ac1b8284 feat: v1.34.0 — Mobile UI Early Preview, Russian 2, macOS network fix
Co-authored-by: kilyabin <kilyabin@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 12:46:13 +02:00
Psychotoxical 8cd4cdcd64 feat: v1.33.0 — Fullscreen Player redesign, Norwegian, configurable preload
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 02:00:48 +02:00
Psychotoxical 9be0d8dfa9 feat: v1.32.0 — The Big Easter Update
Internet Radio full release (HTML5 engine, card UI, RadioDirectoryModal,
cover upload), Backup/Restore, Albums year filter, Statistics Library
Insights (playtime/genres/formats), Playlist cover upload, resizable
tracklist columns for Playlists & Favorites, crossfade fine control,
Settings Storage tab redesign, various fixes and UI polish.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 19:34:26 +02:00
Psychotoxical c873880a26 feat: v1.31.0 — AutoEQ, resizable tracklist columns, Discord Listening type, layout fixes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 02:04:14 +02:00
Psychotoxical c365140870 feat: v1.30.0 — Discord RPC, offline bulk download, artist images, lazy loading, crossfade fix
- Discord Rich Presence (opt-in) — requested by @Bewenben (#49)
- Bulk offline download for playlists and artist discographies — requested by @Apollosport (#54)
- Offline Library filter tabs: All / Albums / Playlists / Discographies with artist grouping
- Artist images on Artists overview (opt-in, off by default) — reported by @Apollosport (#53)
- Image lazy loading via IntersectionObserver (300px margin) across all pages
- Fix: crossfade no longer triggers on manual track skip — reported by @netherguy4 (#35)
- Fix: playlist offline cache now stored as single entry (not per-album)
- Fix: image cache AbortController no longer blocks IDB writes
- Update toast: experimental auto-update hint + GH download link always visible (Win/Mac)
- Queue tech strip: genre removed
- Facebook theme: contrast, opaque badge/back button, queue tab labels
- "Save discography offline" label (was "Download discography")
- Fix: clearing empty playlists via updatePlaylist.view (Axios empty array workaround)
- starredOverrides propagated to AlbumDetail, Favorites, RandomMix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 14:53:41 +02:00
Psychotoxical a932e7c2db chore: bump to v1.29.0 — release prep
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 22:24:41 +02:00
Psychotoxical 95283d792b feat: v1.28.0 — Infinite Queue, Start Radio, Single-click Play, Performance
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 17:40:39 +02:00