Commit Graph

282 Commits

Author SHA1 Message Date
Psychotoxical 7cd0eaf9e1 Merge pull request #190 from kveld9/feat/playlist-csv-import
feature: spotify CSV playlist import
2026-04-15 18:09:27 +02:00
Psychotoxical 9383a6f6ed feat(radio): forward ICY StreamTitle to MPRIS metadata
When a radio stream is active, push the station name to MPRIS on start
and forward ICY StreamTitle updates (radio:metadata events) so the OS
now-playing overlay stays in sync. Skips ad metadata (is_ad flag) and
suppresses position ticks for radio streams (no meaningful duration).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 18:05:14 +02:00
Psychotoxical 624bd6bff7 fix(i18n): add common.play key to all 8 locales (fix for PR #186)
The AlbumHeader and PlaylistDetail play buttons use t('common.play') which
was missing — 'Reproducir' would have appeared as fallback in all languages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 18:05:14 +02:00
Psychotoxical 67f02def43 Merge pull request #186 from kveld9/redesign/albums-playlists-headers
redesign/albums playlists headers
2026-04-15 18:02:16 +02:00
kveld9 56d025f150 added context menu to search panel songs 2026-04-15 12:36:32 -03:00
kveld9 602811908b translations 2026-04-15 12:21:13 -03:00
kveld9 fc90617e9c some fixes 2026-04-15 11:50:44 -03:00
kveld9 a44581e5d6 new feature: import spotify playlist with .csv 2026-04-15 11:19:31 -03:00
kveld9 eb061bd9de fix album tracklist column picker cutoff and scroll containment issues 2026-04-14 23:27:57 -03:00
Maxim Isaev 6533991e7d feat(cli): expand remote player, opaque play id, tray without libindicator
Add CLI commands for stop, shuffle, repeat, mute, star, rating, reload,
server list/switch, and Subsonic search; publish extra snapshot fields and
server/search JSON for tooling. Single `play <id>` resolves track, album,
or artist; artists play a shuffled full discography.

Guard Linux tray creation with catch_unwind when Ayatana/AppIndicator .so
is missing. Harden bash completion against zsh sourcing (compopt). Narrow
AudioEngine field visibility to silence private_interfaces warnings.
2026-04-15 01:47:46 +03:00
Maxim Isaev c75297fcf6 feat(cli): completions, library/audio commands, server switcher
Embed bash and zsh completion scripts and add a `completions` subcommand.
Extend the player CLI (library, audio device, instant mix) and surface
`music_library` in snapshots. Add a shared active-server switcher in the
header and locales; instant mix can reseed the queue from CLI and UI.
2026-04-15 01:47:46 +03:00
Psychotoxical 19b7c8ec06 fix(favorites): correct post-merge issues from PR #184
- btn-sm: add global .btn-sm modifier to theme.css (was only scoped inside device-sync)
- year filter: exclude songs without year metadata when filter is active
- showing count: only render "X of Y" label when a filter is actually active

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 22:38:41 +02:00
kveld9 c3ebc9b951 some fixes 2026-04-14 17:38:08 -03:00
Psychotoxical 117be0d85e Merge pull request #184 from kveld9/feat/ux-redesign-favorites
feat: ux redesign favorites -- sortable columns, gender filter, age range filter, new columns.
2026-04-14 22:34:18 +02:00
kveld9 7ceaf4d5f2 merge branch 'main' into redesign 2026-04-14 17:29:57 -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
kveld9 5340d696cf new design 2026-04-14 17:26:02 -03:00
kveld9 6996dacdf7 sortable columns, gender filter, age range filter, new columns. 2026-04-14 16:49:06 -03:00
Psychotoxical 798812d5ef customization: 8 new themes have been implemented
customization: 8 new themes have been implemented
2026-04-14 21:47:51 +02:00
Psychotoxical 9f4c7382aa feat: add 3 visual toggles (cover art background, playlist cover photo, show bitrate)
feat: add 3 visual toggles (cover art background, playlist cover photo, show bitrate)
2026-04-14 21:47:48 +02:00
Psychotoxical d34de09673 feat(device-sync): overhaul Device Sync page
- New two-panel layout with live album search (search3, 300ms debounce)
  and 10 random albums when search is empty — replaces full paginated load
- Pre-sync summary modal: shows files to add/delete, net change, available
  space; Proceed button disabled when space is insufficient
- calculate_sync_payload now filters already-synced tracks (path exists on
  device) so add_bytes/add_count reflect the true delta
- Space check accounts for pending deletions: addBytes > availableBytes + delBytes
- Separate deviceSyncJobStore for ephemeral job progress state
- Removable drive detection + auto-poll every 5 s via sysinfo
- Desired-state diff: de-selecting a synced source stages it for deletion
  instead of silently removing it
- Status badges (Synced / Pending / Deletion) with matching row highlights
- Live-Search badge () and Zufallsalben section label (⇌) in album browser
- Status summary row height aligned with search field (52 px)
- i18n: all new keys added to all 8 locales (en/de/fr/nl/nb/zh/ru/es)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 21:37:35 +02:00
kveld9 9a9be253e3 8 new themes have been implemented 2026-04-14 14:40:23 -03:00
kveld9 38e59d7a5e feat: add 3 visual toggles (cover art background, playlist cover photo, show bitrate) 2026-04-14 14:21:48 -03:00
Psychotoxical 915f0143f7 fix(ssl): strip trailing slash in getBaseUrl + trust OS certificate store for HTTPS streaming
Fixes two bugs reported in #178:

- getBaseUrl() now strips trailing slashes from server URLs, consistent
  with restBaseFromUrl(). A trailing slash caused double-slash stream URLs
  (//rest/stream.view) which Caddy rejects. Trailing slash also caused
  browsing to return 0 results. Fix manually ported from PR #179 by kveld9.

- reqwest now loads the OS native certificate store in addition to
  Mozilla's webpki roots (rustls-tls-native-roots feature). Fixes HTTPS
  streaming failures where the server certificate is signed by a local CA
  (e.g. Caddy internal CA) that is trusted in the system keychain but not
  in Mozilla's root store.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 18:16:08 +02:00
Psychotoxical 17a5c92174 feat(device-sync): USB/SD card sync page (WIP)
Adds a new Device Sync page for transferring music from Navidrome to
USB drives or SD cards. Sidebar entry is hidden by default.

- Four new Tauri commands: sync_track_to_device, compute_sync_paths,
  list_device_dir_files, delete_device_file
- Filename template engine with cross-platform path sanitization
- 4-concurrent-worker download, live progress via device:sync:progress event
- Persistent source list (albums/playlists/artists) with checkbox deletion
- Expandable artist tree in browser panel (per-album selection)
- i18n: DE + EN complete; other locales have stub keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 00:02:13 +02:00
Psychotoxical cbf72c7eba chore(about): add cucadmuh PR #176 to contributors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 21:54:02 +02:00
cucadmuh 4207455440 fix(audio): Linux output device selection and watcher (#176)
* fix(audio): stabilize Linux output device picker and watcher

Keep pinned ALSA/cpal device ids stable when enumeration omits the active
sink or returns an equivalent name. Stop Linux device-watcher from clearing
the pin based on missing list entries; macOS and Windows still treat repeated
absence as unplugged. Settings refresh flow calls canonicalize and refetches
the list; add i18n for the out-of-list device label.

* fix(settings): sort audio output devices by label

cpal enumeration order is arbitrary; order the dropdown by readable label
and place the current OS default device first among concrete outputs.
2026-04-13 21:48:21 +02:00
Psychotoxical 9983d13122 chore(about): add kilyabin PR #175 to contributors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 20:48:13 +02:00
kilyabin 1b55e88cd5 fix(fullscreen-player): stop mesh blob and portrait animations in no-compositing mode (#175)
In software compositing (WEBKIT_DISABLE_COMPOSITING_MODE=1), WebKit renders
entirely on the CPU. The mesh blob animations were not covered by the
no-compositing overrides: blob-a occupies 130×130% of the viewport, so each
frame the CPU had to composite a surface larger than the screen. On high-DPI
displays (e.g. 8K) this drops the fullscreen player to ~10 FPS.

- Stop mesh blob pan animations (static gradients are preserved)
- Stop portrait drift animation (filter was already removed)
- Remove box-shadow from the seekbar played bar (its width changes on every
  playback tick; in software mode each change triggers a box-shadow repaint)
2026-04-13 20:46:56 +02:00
Psychotoxical 27ea221130 chore(about): update contributors, remove feature tagline, limit changelog to 3
- Add missing contributions: cucadmuh (PR #144, #167, #173, #174),
  kveld9 (PR #168), nisarg-78 (PR #115)
- Remove aboutFeatures tag line from all 8 locales (too dynamic to maintain)
- Changelog section now shows only the 3 most recent versions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 20:23:22 +02:00
cucadmuh 9cd4743d1c feat(settings): audio output device picker (labels, OS default, live refresh) (#173)
* feat(settings): clearer audio device labels for duplicate ALSA names

Show HDMI outputs as "Card (HDMI n)" from hdmi:DEV indices; include PCM and
optional subdevice for hw/plughw/sysdefault; label other ALSA plugins with
iface and PCM. When labels still collide, append a structured hint
(iface · card · PCM) instead of only truncating the raw device string.

* feat(settings): improve audio output device picker

Parse ALSA-style ids into clearer labels (HDMI with DEV index, PCM/subdevice
for hw/plughw/sysdefault). Disambiguate colliding labels; share stderr
suppression for Linux device enumeration.

Add audio_default_output_device_name and tag the matching list entry as the
current system output (i18n). While the Audio tab is open, refresh list and
mark on audio:device-changed and audio:device-reset without toggling the
refresh spinner. Show an error toast if listing devices fails.
2026-04-13 20:13:22 +02:00
cucadmuh e75fda168e fix(folder-browser): arrow navigation only without modifiers (#174)
Skip column/list arrow handling when any modifier is down. Detect modifiers
via nativeEvent and getModifierState (WebKit/WebView), and match arrow keys
by both key and code. On row buttons, preventDefault for plain arrows only
to avoid native focus/scroll stealing navigation. Filter field ArrowDown uses
the same modifier check.
2026-04-13 20:13:10 +02:00
Psychotoxical ec021516c7 fix(audio): device-reset false positive + stderr noise + i18n tooltip
- Device watcher requires 3 consecutive misses (~9 s) before triggering
  audio:device-reset, preventing false positives when ALSA temporarily
  hides a busy device from output_devices() enumeration
- Add stderr suppression to open_stream_for_device_and_rate (last source
  of ALSA terminal noise on Linux)
- Fix tooltip showing raw key 'common.refresh' — replaced with
  settings.audioOutputDeviceRefresh (added to all 8 locales)
- Device switch restarts track from beginning (no seek-back)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 19:00:36 +02:00
Psychotoxical 82e1b458f3 fix(audio): clean up ALSA device names for display on Linux
Raw ALSA names like "sysdefault:CARD=U192k" are replaced with
readable labels ("U192k") in the device dropdown. The underlying
value stays unchanged so rodio can still open the correct device.

Covers: sysdefault, hw, plughw, iec958, front, surround prefixes.
Names without ALSA structure (pipewire, pulse, default) are kept as-is.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:46:53 +02:00
Psychotoxical fc7a5815ef feat(audio): add refresh button for device list in Settings
The module-level cache prevented newly connected USB audio devices
from appearing in the dropdown. Replace with a manual refresh button
(RotateCcw icon, spins while loading) next to the dropdown.

Device enumeration now runs on every Audio tab open and on explicit
refresh. ALSA stderr noise is already suppressed by the dup2 guard,
so re-enumeration is silent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:38:58 +02:00
Psychotoxical 1cf5faff21 fix(audio): suppress ALSA stderr noise during device enumeration
Device watcher (3 s loop) and audio_list_devices both called
cpal output_devices(), triggering ALSA to probe unavailable backends
(JACK, OSS, dmix) and spam stderr with error messages.

Fix: redirect fd 2 to /dev/null for the duration of each enumeration
on Unix via libc dup/dup2 + RAII guard. Also add a module-level
cache in Settings.tsx so audio_list_devices is only invoked once
per app session instead of on every Audio tab activation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:30:24 +02:00
Psychotoxical 16cb4f5a6f feat(audio): audio output device selection (closes #169)
Adds the ability to choose which audio output device Psysonic plays
through — useful for USB DACs, dedicated soundcards, and multi-device setups.

Rust (audio.rs):
- open_stream_for_device_and_rate(device_name, rate): opens a named
  device by cpal name, falls back to system default if not found
- AudioEngine.selected_device: persists the chosen device across
  stream reopens so hi-res rate switches stay on the right device
- audio_list_devices: Tauri command — returns all output device names
- audio_set_device: Tauri command — switches device immediately,
  drops old sinks, emits audio:device-changed
- start_device_watcher: now handles two cases:
    1. No pinned device + system default changed → reopen on new default
    2. Pinned device disappeared (DAC unplugged) → clear selected_device,
       fall back to system default, emit audio:device-reset

Frontend:
- authStore: audioOutputDevice (string | null), persisted
- playerStore: applies stored device on cold start
- App.tsx: listens to audio:device-reset, clears authStore device
  and restarts playback on the fallback device
- Settings → Audio tab: device dropdown at top (above Hi-Res and EQ),
  uses CustomSelect (portal-based, styled), all 8 locales
- CustomSelect: added disabled prop

Note: exclusive mode (WASAPI exclusive, CoreAudio exclusive) is out
of scope for now.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:20:23 +02:00
Psychotoxical 9b22327bb0 fix(login): clarify that https:// URLs are accepted in server URL field (#171)
https:// was already supported by the code (startsWith('http') check) but
the placeholder text only showed bare host:port examples, giving no hint
that a full URL with protocol is valid.

- Updated serverUrlPlaceholder in login namespace (all 8 locales) to show
  https://music.example.com as the domain example
- Added settings.serverUrlPlaceholder i18n key (all 8 locales) and wired it
  into AddServerForm — previously the placeholder was a hardcoded English string

Closes #171

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:59:19 +02:00
Psychotoxical dba89cc4e4 fix(offline): replace blocking overlay with slim banner; add server settings link (#170)
When offline with no cached content, the full-screen OfflineOverlay blocked
all navigation including Settings, making it impossible to fix a broken
server config. Replace it with the same slim banner used in offline-cache mode.

- OfflineBanner now handles both cases: cache (existing) and no-cache (new)
- No-cache banner shows server name and a direct link to Settings → Server tab
- OfflineOverlay component is no longer used (import removed from App.tsx)
- All 8 locales: added offlineNoCacheBanner and serverSettings keys

Fixes #170

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:52:17 +02:00
Psychotoxical 91d4cb58b8 feat: playlist management enhancements & UX improvements (#168)
- Multi-selection for Albums, Artists, Playlists with context menu bulk-add
- Collapsible playlist section in sidebar
- Infinite scroll on Artists page (IntersectionObserver)
- Submenu flip-up on viewport overflow
- Remove from Playlist in context menu
- All 8 locales synced

Fixes applied:
- title= → data-tooltip on playlist toggle button (CLAUDE.md)
- Hardcoded Spanish aria-label → i18n (sidebar.expandPlaylists/collapsePlaylists)
- AddToPlaylistSubmenu fetches playlists on first open if store empty

Co-Authored-By: kveld9 <kveld9@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:37:50 +02:00
Psychotoxical 083c5f62cb fix(pr168): title→data-tooltip, i18n playlist toggle, cold-start playlist fetch
- Replace title= with data-tooltip on sidebar playlist expand button (CLAUDE.md)
- Replace hardcoded Spanish aria-label strings with i18n keys (sidebar.expandPlaylists / collapsePlaylists) across all 8 locales
- AddToPlaylistSubmenu now fetches playlists on first open if store is empty (regression fix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:33:56 +02:00
kveld9 592a479c30 fixed some bugs 2026-04-12 20:43:31 -03:00
Maxim Isaev 6439200e95 feat(keybindings): in-app modifier chords; fix seek shortcut units
Persist chords as ctrl/alt/shift/super plus key code; legacy single-key
bindings still match without modifiers. Settings capture uses buildInAppBinding;
App uses matchInAppBinding and skips chords also registered as global shortcuts.
Share MODIFIER_KEY_CODES and formatBinding with global shortcut formatting.

Fix seek-forward/backward hotkeys: seek() expects 0-1 progress, not seconds.
2026-04-13 01:01:50 +03:00
kveld9 9cb1471170 chore: apply stashed changes 2026-04-12 17:55:13 -03:00
kveld9 94323e91fa fixed bugs 2026-04-12 17:53:52 -03:00
kveld9 bef6941a2b feat: add multi-selection and context menu for playlist management 2026-04-12 17:53:52 -03:00
Psychotoxical fee454da5d fix(folder-browser): correct --bg-base to --bg-app in filter bar; add cucadmuh PR #165
--bg-base is undefined — sticky filter bar would have rendered transparent.
Also added PR #165 to cucadmuh's contributions in Settings About.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 18:44:40 +02:00
Psychotoxical a765bcd5d0 feat(themes): add Vision Dark & Vision Navy colorblind-safe themes (closes #166)
Purple & Gold palette (Deuteranopia / Protanopia / Tritanopia safe).
Vision Dark: near-black #0D0B12 + Gold #FFD700 (~14.7:1 WCAG AAA).
Vision Navy: deep navy #0A1628 + Gold #FFD700 (~14.5:1 WCAG AAA).
New 'Accessibility' group in ThemePicker.
Removed stale theme count from aboutFeatures across all locales.

This is an initial step toward colorblind accessibility — color variables
alone cannot cover all CVD use cases. Structural improvements (secondary
indicators, pattern/shape cues) are still needed in future iterations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 18:44:29 +02:00
Psychotoxical 7e50c7af40 feat(folder-browser): per-column filter keyboard flow
feat(folder-browser): per-column filter keyboard flow
2026-04-12 18:41:08 +02:00
Maxim Isaev a12d6a4015 feat(folder-browser): add per-column filter and queue append hotkey flow
Add Ctrl+F filtering for the active Folder Browser column with keyboard handoff between filter and rows, and clear right-side filters when parent selection changes.

When pressing Shift+Enter on a filtered track list, append visible tracks to the queue instead of replacing the current queue.
2026-04-12 14:08:36 +03:00