Commit Graph

880 Commits

Author SHA1 Message Date
Psychotoxical 51c118806e feat(fullscreen): track name on top, large & bold; artist name below, small
Swap DOM order and styles in the info cluster:
- fs-track-title: clamp(28px,4.5vw,68px) / weight 900 / var(--accent) — primary
- fs-artist-name: clamp(13px,1.5vw,22px) / weight 400 / 55% opacity — secondary
- fs-cluster gap: 12px → 8px (denser hierarchy)
- fs-meta: margin-top: 4px for breathing room after artist name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:44:32 +02:00
Psychotoxical fc653941c2 fix(lyrics): allow line wrapping in fullscreen lyrics overlay
Increase slot height from 3.6vh → 6vh (CSS + JS factor 0.036 → 0.06)
so that long lyric lines can wrap onto a second line without being clipped.

Fixed height on .fs-lyric-line is kept intentional — rail math requires
uniform slots. 2 wrapped lines at 2vh font / 1.4 line-height = 5.6vh,
comfortably inside the 6vh slot. font-size adjusted from 2.2vh → 2vh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:36:06 +02:00
Psychotoxical 8add62a502 perf(lyrics): fix CPU spikes during lyric transitions; fix release workflow
CSS: remove `font-weight` from transition list on `.fs-lyric-line` — it
triggers layout reflow on every animation frame when the active line changes.
Replaced with `transform: scaleX(1.015)` on `.fsl-active` (compositor-only).
Added `contain: layout style` to `.fs-lyrics-overlay` to isolate reflows.

Cargo.lock: update for thread-priority crate (added in previous audio commit).

CI: replace delete-asset workaround with `updaterJsonKeepUniversal: false`
to prevent tauri-action from uploading a latest.json with wrong signature.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:30:32 +02:00
Psychotoxical 44287a7ceb feat(audio): bit-perfect hi-res playback + underrun hardening (opt-in alpha)
Safe mode (default): all audio outputs at 44.1 kHz, rodio resamples
internally. Maximum stability out of the box.

Hi-Res mode (alpha toggle): stream opens at the file's native sample rate
(e.g. 88.2/96/192 kHz) for bit-perfect output.

Rust (audio.rs):
- open_stream_for_rate(): CPAL queries device supported configs, finds
  exact rate match or falls back to highest available / device default.
- create_engine() thread: ThreadPriority::Max (silently ignored without
  CAP_SYS_NICE), loop handles rate-switch requests, PIPEWIRE_LATENCY
  scales with rate (8192 frames for >48 kHz ≈ 93 ms quantum), keeps
  PULSE_LATENCY_MSEC in sync.
- audio_play(): hi_res_enabled param gates effective_rate (44100 vs
  native); stream re-opens only when needed; 150 ms PipeWire settle +
  500 ms sink pre-fill (pause→append→sleep→play) for hi-res tracks.
- audio_chain_preload(): hi_res_enabled param; rate-mismatch bail skipped
  in safe mode so gapless chains always work at 44.1 kHz.
- SizedDecoder MSS buffer: 4 MB (was 512 KB) to reduce Symphonia read
  overhead on high-bitrate hi-res files.
- thread-priority crate added to Cargo.toml.

Frontend:
- authStore: enableHiRes (bool, default false) + setEnableHiRes.
- playerStore: hiResEnabled passed to all audio_play /
  audio_chain_preload invoke calls.
- Settings → Audio tab: "Native Hi-Res Playback" toggle with Alpha
  badge and stability warning, i18n for all 7 languages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:20:07 +02:00
cucadmuh 0f3033d84e feat: add hot playback cache (queue prefetch, alpha)
Ephemeral on-disk cache for upcoming queue tracks. Adds Rust commands (download/delete/purge), hotCacheStore with LRU eviction, serial prefetch worker, playback gate, and Settings UI. Disabled by default.

- fix: boundary check before file delete in delete_hot_cache_track
- fix: remove stale languageRu2 key from ru.ts
- fix: restore accidentally removed lyricsServerFirst/fsLyricsToggle/lyricsSource* strings in ru.ts
2026-04-07 10:52:26 +02:00
Psychotoxical d73f348339 feat: v1.34.1 — fullscreen lyrics overlay, FsArt crossfade, lyrics toggle, contributor updates
- FullscreenPlayer: synced lyrics overlay (5-line rail, mask fade, click-to-seek)
- FullscreenPlayer: FsArt crossfade component with onLoad pattern, 300px art, next-track pre-fetch
- FullscreenPlayer: MicVocal lyrics toggle button next to heart (persisted in authStore)
- FullscreenPlayer: idle system — only close button auto-hides, cluster+seekbar always visible
- LyricsPane: refactored to use shared useLyrics hook (no double-fetch with FS overlay)
- authStore: showFullscreenLyrics field (default true)
- i18n: fsLyricsToggle key added to all 7 locales; ru2.ts removed (merged into ru.ts)
- Settings: Contributors updated (nisrael, cucadmuh, kilyabin); logout moved to Server tab as btn-danger
- theme.css: btn-danger style added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:00:33 +02:00
Psychotoxical ff950efb0c feat(settings): add nisrael to contributors, update cucadmuh/kilyabin, move logout button
- Add nisrael (Nightfox themes PR #114, rustls-tls fix PR #112)
- Update cucadmuh with gapless manual skip fix (PR #119)
- Update kilyabin with RU locale improvements (PR #120) and auto-install script (PR #121)
- Move logout button from System tab to Server tab — styled as btn-danger (outlined red)
- Add .btn-danger CSS class to theme.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 22:54:27 +02:00
Psychotoxical 4ef21d6d78 i18n(ru): apply translation improvements from PR #120
Manually merged kilyabin's Russian locale improvements (more natural phrasing
throughout) while preserving keys added after #120 was opened: fsLyricsToggle,
lyricsServerFirst/Desc, lyricsSourceServer/Lrclib.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 22:46:41 +02:00
Psychotoxical 1197c1f916 feat: album cover art in Discord Rich Presence via iTunes Search API
Fetches album artwork from the iTunes Search API and passes the URL
directly to Discord's large_image field. Subsonic cover URLs require
auth and can't be used by Discord directly.

- 3-strategy search: exact quoted → relaxed → track title fallback
- 1-hour in-memory cache per artist|album key
- iTunes search runs in tokio::task::spawn_blocking (reqwest::blocking
  must not run on the Tokio async executor)
- artwork_cache wrapped in Arc<Mutex<...>> for cross-thread sharing
- Fallback to the pre-uploaded "psysonic" asset when no match found
- Cargo.toml: blocking feature alongside rustls-tls

Co-Authored-By: kilyabin <kilyabin@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:30:22 +02:00
Psychotoxical b448c2bc82 fix(queue): revert auto-scroll target back to queueIndex+1
The queue-current-track section already shows the active track above the
list. Scrolling to queueIndex+1 (next track) is the correct behavior —
it keeps the upcoming tracks in view, not the already-visible current one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:23:55 +02:00
cucadmuh 6226383762 i18n(ru): refine Russian locale using phrasing from ru2
Co-authored-by: Psychotoxical <dev@psysonic.app>
2026-04-06 19:13:47 +02:00
nisarg 13a8f696d0 fix: queue auto-scroll to current track and fix re-renders
* stop queue panel from constant rerendering

* add queueHeader type

* fix(queue): move hook before early return, fix auto-scroll target

- usePlayerStore must be called before conditional return (Rules of Hooks)
- Auto-scroll to songs[queueIndex] not [queueIndex+1] — current track,
  not the next one

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Psychotoxical <dev@psysonic.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:11:03 +02:00
Nils Israel 64e0948904 feat: integrate nightfox.nvim themes into Open Source Classics
* feat: integrate nightfox.nvim themes into Open Source Classics

Agent-Logs-Url: https://github.com/nisrael/psysonic/sessions/410b9047-62de-4c0b-a6bc-1dc6f8247164

Co-authored-by: nisrael <66925+nisrael@users.noreply.github.com>

* i18n: add Nightfox to theme FAQ in de + zh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: nisrael <66925+nisrael@users.noreply.github.com>
Co-authored-by: Psychotoxical <dev@psysonic.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:09:39 +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
Maxim Isaev 83c36de091 feat(i18n): Russian locale and translations in src/locales
- Add Russian UI strings with idiomatic phrasing and plural forms
- Split en/de/fr/nl/zh/nb strings into src/locales/*.ts for maintainability
- Register ru in i18n and Settings language picker
- Add languageRu to all locales; extend English help (supported languages)

Made-with: Cursor
2026-04-06 11:08:40 +03: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
zz55zz 939abace35 Added Norwegian language
Added Norwegian language
2026-04-05 13:15:22 -08: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 67f31b0700 fix: include InternetRadio.tsx (referenced in App.tsx router) 2026-04-04 02:09:19 +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 463b7483fd fix: wrap next/previous in arrow functions to satisfy MouseEventHandler type 2026-04-03 15:00:36 +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 7263d93d42 feat: v1.29.0 — Radio fast-start, seek fix, OGG, error toasts, contributors
Incorporates PRs #38 (nisarg-78), #42 #43 #44 (JulianNymark) with fixes:

Audio / Playback
- Artist Radio starts immediately from fast getTopSongs (local library);
  getSimilarSongs2 (Last.fm) enriches queue in background — no more wait
- Fix seek audio glitch: EqualPowerFadeIn only resets to zero-gain on
  seeks to track start (<100 ms); all other seeks resume at unity gain
- OGG/Vorbis container support via symphonia-format-ogg (PR #42)
- Human-readable audio error messages in SizedDecoder (PR #44)
- Audio playback errors shown as themed toast notifications (PR #43)

Queue / Radio
- Infinite Queue: proactive load of 5 tracks (was 25) when ≤2 remain
- Radio: proactive reload at ≤2 remaining tracks, independent of
  Infinite Queue setting — radio no longer stops at last track
- Fix: clicking Start Radio multiple times no longer stacks duplicates
- Fix: Start Radio on artist keeps current song playing
- Manual tracks always appear before Radio, Radio before Auto-added
- Queue separators: "— Radio —" and "— Auto —" dividers
- Fix: radio proactive load now works even when songs lack artistId
  (uses currentRadioArtistId module var as fallback)

UI / UX
- Click synced lyrics lines to seek (PR #38)
- Volume scroll wheel on volume slider (PR #38)
- Lyrics: active / completed / upcoming visual states (PR #38)
- Shared toast utility (src/utils/toast.ts) replaces inline toast fn
- Auto-updater: relaunch_after_update Rust command exits first to
  release single-instance lock before spawning new process

About / Credits
- nisarg-78 and JulianNymark added to contributors (since v1.29.0)
- netherguy4 added as Special Thanks for feature ideas and feedback
- i18n: aboutSpecialThanksLabel in all 5 languages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 22:17:55 +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
Psychotoxical 0b5db172bd chore: bump to v1.27.2 — bugfix release
- fix: Radio from context menu passed artist name as ID to getSimilarSongs2 (closes #29)
- fix: CI Windows NSIS upload — tauri-action no longer searches missing bundle/msi/
- fix: Linux/AUR ring linker error — use cc instead of rust-lld via .cargo/config.toml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 10:38:26 +02:00
Psychotoxical 55e7cb835b feat: v1.27.0 — In-App Auto-Update, Configurable Home, Icon Consistency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 02:14:57 +02:00
Psychotoxical d8da511a8f fix: v1.26.1 — hero/album/playlist background flickering
Background of Hero carousel, Album Detail and Playlist Detail was
flickering for up to 20 seconds on first visit. useCachedUrl with
fallbackToFetch=true returned the raw server URL immediately, causing
a double render — once with the HTTP URL and again when the blob was
ready. Fixed by passing fallbackToFetch=false in all three locations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 21:20:15 +02:00
Psychotoxical 434ee0ecf1 feat: v1.26.0 — Bulk Select, Song Info, Favorite Button, Recently Played
### Added
- Favorite/Star button in player bar (requested by @halfkey)
- Bulk multi-select for album tracklist and playlist detail (add to playlist, remove from playlist)
- Song Info modal via right-click context menu (metadata: format, bitrate, sample rate, bit depth, channels, file size, path, replay gain)
- Recently Played section on Home page
- "Show activity in Now Playing" opt-in toggle in Settings → Behavior

### Fixed
- Queue cover art not updating on track change (useCachedUrl/CachedImage reset on cacheKey change)
- FullscreenPlayer background flickering (FsBg preloads image before layer transition)
- Playlist card delete confirmation visual (size expansion + pulse animation)
- Gruvbox Light Soft: back button and badge invisible against light background

### Changed
- buildStreamUrl: removed unused suffix parameter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 20:57:57 +02:00
Psychotoxical e65c476a76 fix: v1.25.1 — Opus playback, single-instance enforcement
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 13:45:37 +02:00
Psychotoxical 560349819f feat: v1.25.0 — Tray Icon, Minimize to Tray, Sidebar Customization
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 09:46:41 +02:00
Psychotoxical c67d606f89 feat: v1.24.0 — Playlist Management, native sample rate playback
- Full playlist feature: overview grid, detail page with hero collage,
  tracklist DnD, song search, suggestions, context menu submenu
- Audio: disable all app-level resampling — every track plays at its
  native sample rate (target_rate always 0 in audio_play + chain_next)
- Fix: playlist hero bg flicker (memoize buildCoverArtUrl calls)
- Fix: input focus double-border (search-input → .input class)
- Polish: redesigned playlist search panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:14:15 +02:00
Psychotoxical 43c656dfc3 feat: v1.23.0 — Advanced Search, Genre Mix overhaul, Playlist append, Contributors table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:56:59 +02:00
Psychotoxical 3d03b8d5a1 merge: PR #9 — Replay Gain fix (trbn1) + conflict resolution
Merges songToTrack() helper and audio_update_replay_gain Tauri command
from @trbn1 without losing v1.22.0 DnD/queue-management work:

- All track construction sites use songToTrack() for correct replay gain
- psy-drag system (mouse-event DnD) preserved across all components
- enqueueAt() position-aware insertion preserved in QueuePanel
- updatePlaylist / smart-save / active-playlist tracking preserved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:07:29 +02:00
Psychotoxical d6f6e6466c feat: v1.22.0 — Queue Management, DnD Overhaul, Seek & Waveform Fixes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:14:59 +02:00
trbn 95cdbc7fc7 fix: replay gain not applying to tracks
Replay gain was not working because track objects were created manually without
including replay gain metadata from the Subsonic API response.

Changes:
- Add songToTrack() helper function to properly map SubsonicSong to Track with
  replayGainTrackDb, replayGainAlbumDb, and replayGainPeak fields
- Add audio_update_replay_gain Tauri command for dynamic volume recalculation
  when replay gain settings change mid-playback
- Add updateReplayGainForCurrentTrack() to recalculate volume when toggling
  replay gain setting
- Fetch fresh track data on cold resume (app relaunch) to ensure replay gain
  values are current from server
- Update all files that create track objects to use songToTrack()

Fixes issue where toggling replay gain ON/OFF or changing between track/album
mode had no effect on currently playing or newly played tracks.
2026-03-30 19:11:33 +02:00
Psychotoxical 42863877f6 fix: close seek-flash race window after debounce expires
PR #7 blocked stale Rust progress ticks during the 100 ms debounce
window but lifted the guard exactly when invoke('audio_seek') went out.
The engine can still emit 1–2 ticks with the old position before the
seek takes effect.  Add seekTarget: once the debounce fires, record the
requested time and keep ignoring progress until current_time is within
2 s of that target, then clear it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:28:48 +02:00
Psychotoxical 7ed0fa4914 Merge branch 'pr-8' into test/pr-7-8 2026-03-30 17:24:18 +02:00
Joshua Bassett 4f8e7d7bc7 fix: stabilize waveform seekbar width when player time changes
Add min-width to .player-time elements so they don't resize when the
displayed time string changes length (e.g. "9:59" → "10:00"). Not all
fonts support the tabular-nums font-variant, so without a min-width the
time elements can change size and cause the waveform seekbar to
continuously resize as playback progresses.

Also align the elapsed time to the right and duration to the left so
they sit flush against the waveform edges.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:17:50 +11:00
Joshua Bassett bb56269cd1 fix: prevent waveform seekbar flashing back to old position on seek
When clicking/dragging the waveform seekbar, the playback position would
briefly flash back to the previous position before snapping to the new
one.

The seek function optimistically updates the store with the target
position immediately but debounces the actual audio_seek IPC call by
100ms. During that window, audio:progress events from the Rust backend
continue to arrive carrying the old playback position, overwriting the
optimistic update and causing the visual flash.

The fix skips incoming audio:progress events while a seek debounce is
pending, since the store already holds the correct target position. Once
the debounce fires and audio_seek is sent to the backend, progress
events resume normally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:59:55 +11:00
Psychotoxical 29a4363dca feat: v1.21.0 — What's New Modal, 3 New Themes (Beta), Artist Column, Powerslave Blue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 21:48:40 +02:00
Psychotoxical e1d27798eb feat: v1.20.0 — FLAC Seek Fix, Genres, Genre Filter, Chinese, W10 Theme
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 18:04:01 +02:00
jiezhuo a1b3022140 Add Chinese language 2026-03-28 22:04:13 +08:00
Psychotoxical b6fb66c46d feat: v1.19.0 — NSIS Installer, Tray Removed, Storage Warning, Theme Polish
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:56:35 +01:00
Psychotoxical 936e548f40 feat: v1.18.0 — Offline Mode (Beta), MPRIS Seek, 2 New Themes, Perf Fixes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:17:09 +01:00
Psychotoxical b67c198227 fix: player bar CSS + Windows media keys HWND (v1.17.2)
- layout: overflow:hidden on .app-shell + min-height:0 on sidebar/main/queue
  prevents player bar from being pushed off-screen when window is resized
  below OS minHeight constraint (ignored by some Linux WMs)
- lib.rs: pass main window HWND to souvlaki PlatformConfig on Windows so
  SMTC hooks into the existing Win32 message loop instead of creating its
  own — fixes media keys on Windows without crashing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 18:15:25 +01:00
Psychotoxical 6bdd6f3a59 feat: v1.17.0 — Media Keys, 3 New Themes, Perf Fixes, Contrast Audit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 21:30:13 +01:00
Psychotoxical d62bffd082 feat: v1.16.0 — 15 New Themes, W98 Overhaul, Aqua Quartz Polish
New themes: Aqua Quartz (Mac OS X Aqua, skeuomorphic), Spider-Tech,
T-800, B-Runner, Hill Valley 85, TetraStack, Turtle Power, Insta,
ReadIt, The Book (new Social Media group), W3.1, Jayfin (Jellyfin).

W98 rebuilt from scratch: authentic #d4d0c8 warm-gray, full 4-layer
3D bevel on all panels/buttons (raised/sunken on press), title bar
gradient on song name, navy progress fill, 16px styled scrollbar.

Aqua Quartz: all button variants now jelly-styled, blue Source List
sidebar with white pill nav, aluminium pinstripe background.

Theme Picker: groups and themes sorted alphabetically, Mediaplayer
group renamed, Pandora/Order of the Phoenix/Imperial Sith removed.

Fix: AlbumDetail genre propagation, W98 accordion active state,
Aqua Quartz sidebar labels, W98 connection indicator contrast.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:54:57 +01:00
Psychotoxical ff706104ab fix: propagate genre in AlbumDetail track constructions
Play All, Enqueue All, and single-song play in AlbumDetail were
building Track objects without genre/starred fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:57:17 +01:00
Psychotoxical 3effad0830 feat: v1.15.0 — Genre Strip, Lyrics Accent, Sidebar Button fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 18:47:32 +01:00
Psychotoxical 361e9cfdb3 feat: v1.14.0 — Critical Buffer Fix, Gapless/Crossfade stable, UX polish
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 23:00:55 +01:00