github Psychotoxical/psysonic app-v1.45.0-rc.3
Psysonic v1.45.0-rc.3

pre-release5 hours ago

Added

Audio Preview — Rust Preview Engine and Tracklist Rollout

By @Psychotoxical, PRs #392, #394

Psysonic now has a native Rust-powered preview engine for tracklist previews. Instead of using a separate HTML5 audio path, previews run through a parallel rodio sink on the existing output stream, with dedicated Tauri commands and engine events for preview start, progress and end.

When a preview starts, the main player pauses and only resumes automatically if it was playing beforehand. Starting normal playback, radio playback, resume or stop actions cancels any active preview first, so preview audio and main playback cannot overlap.

The new preview UI is rolled out across the main tracklist surfaces:

  • Albums
  • Playlist detail including suggestions
  • Favorites
  • Artist detail top tracks
  • Random Mix genre and filtered-song lists

Track numbers now stay stable on hover, while dedicated inline Play and Preview buttons handle playback actions from the title cell. Active playing rows keep the equalizer bars, including on hover; active paused rows fall back to a static accent-colored track number. SongRow is intentionally left untouched in this pass.

Settings → Audio now includes a preview section with a master toggle, configurable start position, configurable duration and per-location toggles. Users can keep previews enabled on discovery-heavy surfaces while hiding them on owned-content views. The preview progress ring follows the configured duration automatically.

Preview state is mirrored through a new previewStore, giving the UI one reliable source of truth for preview progress, active state and the currently previewing track metadata.

While a preview is playing, the player bar mirrors the previewed track with cover, title, artist, a dedicated Preview label and an accent top border. Actions that would otherwise target the queued track, such as rating, fullscreen hint and album/artist links, are suppressed during preview playback.

The main play button also reflects preview state with a stop-style preview control and progress ring. Its behavior matches the inline preview buttons: stopping the preview resumes the main player only if it was already playing before. The smaller Stop button uses silent preview stop semantics, cancelling the preview and leaving the main player paused so Stop always means silence.

Spacebar stops an active preview, media keys are ignored during previews, and tray actions cancel the preview before continuing with the requested player action.

Play Next in the context menu now uses a double-chevron icon, making it visually distinct from the Preview button.

The feature includes updated i18n coverage across all supported locales, including the new player-bar preview labels.

Tray — Now Playing Tooltip and Localized Menu Labels

By @Psychotoxical, PR #395, closes #383

The system tray now reflects the current playback state more clearly. On Windows and macOS, the tray tooltip shows the currently playing track as Artist – Title on play, pause and track changes, falling back to Psysonic when nothing is playing.

On Linux, where AppIndicator does not expose a hover-tooltip API, the same now-playing text is shown as a disabled entry at the top of the tray menu instead.

Tray menu labels are now localized across all supported languages, including Play/Pause, Next/Previous, Show/Hide, Exit and the Linux-only empty-state label. The frontend updates the tray labels on startup and whenever the app language changes, without rebuilding the tray icon.

Themes — Kanagawa, Atom One and 1984 Palettes

By @Psychotoxical, PR #390

Open Source Classics gains three new theme families: Kanagawa, Atom One and 1984, adding nine new themes in total.

  • Kanagawa: Wave, Dragon and Lotus
  • Atom One: Dark and Light
  • 1984: Default, Cyberpunk, Light and Orwell

Each theme defines the full token set, including background, accent, text, Catppuccin compatibility, waveform, status and select-arrow tokens. This lets login, queue sidebar and subpages inherit the palette cleanly without component-specific overrides.

The theme picker now groups Open Source Classics by family with dedicated family headings. Theme scheduler dropdown labels are also family-prefixed, making it clearer which palette family a scheduled theme belongs to.

Sidebar Discovery Indicators

By @cucadmuh, PR #397

Sidebar navigation now includes a dedicated unread indicator for New Releases, with persistence per server/library scope and delayed mark-as-seen behavior after opening the New Releases page.

Albums added within the last 48 hours now receive a localized New badge in both album cards and album detail header.

Adaptive Header Controls

By @cucadmuh, PR #397

The top header behavior was reworked for narrow widths: search, Live and Orbit controls now compress in a deterministic order with improved stability in edge-width ranges.

Waveform Wheel Seeking

By @cucadmuh, PR #397

Waveform mouse-wheel seeking now uses fixed step-based jumps with debounce smoothing for more predictable navigation and less jitter during rapid scrolling.

Queue — Drag Outside to Remove

By @cucadmuh, PR #420

You can remove a track from the play queue by dragging its row outside the queue sidebar (main window) or outside the mini player’s queue list. Drop targets still support reordering when you release inside the queue area.

The drag ghost shows a trash affordance only while the cursor is outside the queue bounds; inside the queue it behaves as a normal reorder drag. The mouse-event psy-drop path now carries cursor coordinates so removal can be detected when the drop target is not the queue panel itself.

Statistics — Shareable Top-Albums Card

By @Psychotoxical, PR #425

Statistics page can now export your most-played albums as a shareable PNG, accessible via a share icon next to the Most Played Albums section header. Three aspect ratios for different platforms (Story 9:16, Square 1:1, Twitter Card 16:9), three grid sizes (3×3, 4×4, 5×5), with each cover carrying a thin info strip showing rank + play count.

The card pulls the wordmark and accent color directly from the active theme, so a Catppuccin export looks Catppuccin and a Nord export looks Nord. Cover art reuses the existing IndexedDB cache, so no extra Subsonic round-trips on repeat exports. The header label is hardcoded English ("Top Albums") so a shared image stays legible to followers regardless of their language.

Saving uses the native OS save dialog — no silent dump into Downloads, the user picks the path each time. Data source is local-only (Subsonic getAlbumList(frequent)); Last.fm is intentionally not used. There is no time-window selector because Navidrome's API exposes only cumulative play counts, not per-event play history.

Queue Panel — Position Counter, Tri-State Duration Toggle, Collapsible Now Playing, EQ Indicator

By @kveld9, PR #419

The queue panel got a sweep of UX refinements. The header now shows the current position as (N/M) next to the queue title for at-a-glance context.

The clickable duration label in the header rotates through three modes per click instead of two: total queue time, remaining time, and estimated end-of-queue clock time (e.g. · 02:10). ETA updates every 30 seconds, is formatted in the user's locale, and is visually highlighted with the accent colour while playing.

A new chevron next to the queue title collapses the Now Playing section and queue toolbar, and the collapsed state is persisted across restarts, so users who treat the queue as a pure list can keep it that way.

The currently playing row in the queue list is now indicated by animated equalizer bars to the left of the track title; the bars freeze in place when playback is paused. The previous small play icon next to the title is removed since the EQ bars carry the same signal more clearly.

Shortcuts — Action Registry, Dynamic CLI Help, New Input Targets

By @cucadmuh, PR #435

Shortcut, keyboard, global-hotkey, mini-window and CLI inputs are now all routed through one TypeScript action registry — a single source of truth for what an action does, how it's labelled, and which input transports can fire it. CLI --player help is generated dynamically from the registry, so command coverage stays in sync with the action set automatically.

Nine new input actions were added (requested by zunoz on Discord): start search, start advanced search, toggle sidebar, mute, open / toggle equalizer, toggle repeat, open Now Playing, show lyrics, favorite current track. Help is bound to F1 by default and hidden from the Settings input list; existing users get the F1 binding back-filled into their persisted keybindings on next launch.

Translations for the new action labels follow in a separate i18n nachhol-PR (de, fr, nl, zh, nb, ru, es).

Fixed

  • Settings → Audio no longer blanks the app on macOS (Issue #382, PR #384, by @Psychotoxical): Fixed a macOS-only crash where opening Settings → Audio could turn the whole app into a blank window. The Equalizer canvas now waits until it has valid layout dimensions before drawing, and redraws automatically once the section is visible.

  • Polish (PR #397, by @cucadmuh): multiple branch-local interaction fixes around sidebar drag/drop behavior, Live dropdown layering, queue-resize handle behavior during scroll/overlay-scrollbar interaction, and now-playing narrow-layout stability.

  • Track preview audio in sync with progress ring; huge files no longer abort (Issue #421, PR #423, by @Psychotoxical): Previews used to start audio about 25 % into the preview window on mid-track starts because Sink::try_seek ran in parallel with sink.append while the 30 s take_duration cap was already counting wall-clock from append. The seek now runs on the bare source before append, and the progress-ring animation only starts once the engine actually emits audio:preview-start — a small loading spinner is shown during the download/decode/seek warmup. The preview HTTP-client timeout was raised from 30 s to 5 min, so multi-hundred-megabyte Hi-Res files no longer abort the download mid-fetch.

  • Windows playback stutter under GPU load (Issue #334, PR #426, by @Psychotoxical): Audio could stutter and crackle on Windows whenever another app put GPU/CPU pressure on the system (browser, 3D apps, games). The WASAPI render thread is now promoted to MMCSS "Pro Audio" via AvSetMmThreadCharacteristicsW, so it survives priority contention from competing graphics work. Reproed and validated under a Half-Life parallel-load stresstest. Companion mitigations for high-GPU situations: cosmetic UI animations now pause when the window loses OS focus, and a new Reduce animations toggle in Settings → Appearance caps animated seekbar styles (pulsewave, particletrail, liquidfill, retrotape) to 30 fps for users on GPU-constrained machines (off by default).

  • Linux dev — sidebar and main content invisible after HMR (PR #434, by @Psychotoxical): The data-app-blurred="true" CSS rule introduced in #426 used a * selector to pause every animation while the window was unfocused. On WebKitGTK + no-compositing this triggered a stale rendering bug after Vite hot-reloads — the sidebar and main content stayed unpainted until any user interaction nudged a re-render. The rule now targets only the concrete heaviest infinite animations (eq bars, marquees, now-playing dot pulse, fullscreen mesh blob / portrait, .spin); release builds are unchanged in behaviour.

Don't miss a new psysonic release

NewReleases is sending notifications on new releases.