Commit Graph

682 Commits

Author SHA1 Message Date
Psychotoxical c9977a20e9 chore(orbit): keyboard navigation across interactive modals
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:42:53 +02:00
Psychotoxical b0c153ec48 i18n(orbit): translations for fr / nl / zh / nb / ru / es
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:35:57 +02:00
Psychotoxical b4bb40802d chore(orbit): help modal with 9-section walk-through
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:06:32 +02:00
Psychotoxical d912c4293b chore(orbit): picker modal when multiple accounts match the link's server
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:49:55 +02:00
Psychotoxical 6370b5fa3c chore(orbit): auto-switch to the link's server on paste / join
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:43:18 +02:00
Psychotoxical f2e4c5b684 fix(orbit): tear down session on server switch + raise cleanup TTL
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:16:30 +02:00
Psychotoxical 728b8f6315 chore(orbit): default auto-approve to off for new sessions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:03:03 +02:00
Psychotoxical e6cb27bf3b chore(orbit): launch popover with create / join / help entries
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:57:37 +02:00
Psychotoxical a1edec4a72 chore(orbit): confirm dialog before host ends a running session
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:49:17 +02:00
Psychotoxical 01e148d082 chore(orbit): auto-leave on guest side after prolonged host silence
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:43:34 +02:00
Psychotoxical 17bcac7155 chore(orbit): manual approval flow for guest suggestions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:36:44 +02:00
Psychotoxical e6d15bf9ce chore(orbit): pending-suggestion strip in guest queue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:22:17 +02:00
cucadmuh ef8d83955a Merge pull request #289 from Psychotoxical/feat/smart-playlists-in-playlists
feat(playlists): add Navidrome smart playlists workflow in Playlists
2026-04-24 18:15:33 +03:00
Maxim Isaev 3aeeaea74f fix(playlists): respect active library in playlist card playback
Ensure playlist card Play action uses tracks filtered by the active library and show filtered song count and duration in the list, so card metadata matches actual playback scope.
2026-04-24 17:55:59 +03:00
Psychotoxical cf6fbe527a chore(orbit): symmetric host-presence badge — green online / yellow offline
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:37:44 +02:00
Psychotoxical 81d16183b7 chore(orbit): show host-offline badge when host state goes stale
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:34:00 +02:00
Maxim Isaev 401fed8368 feat(playlists): improve smart playlist editing and localization
Open smart playlist editing from playlist cards, load rules via Navidrome single-playlist API with safer fallbacks, and keep edit visibility aligned with ownership rules.
Also add/clean smart playlist locale keys across all supported languages and preserve smarter autogenerated naming behavior.
2026-04-24 17:29:41 +03:00
Psychotoxical 7acf95c0a6 fix(orbit): guest resume catches up to host's live position
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:20:25 +02:00
Maxim Isaev da4e0189b9 Merge remote-tracking branch 'origin/main' into feat/smart-playlists-in-playlists 2026-04-24 17:11:34 +03:00
Psychotoxical ae053e5314 fix(orbit): keep guest's local pause across host track changes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:11:05 +02:00
Maxim Isaev 9baf01fdc2 fix(playlists): refine smart playlist UX and library-scoped tracks
Show edit/delete actions on hover in playlist cards, support opening metadata edit directly from the grid, and render smart playlist covers from active-library tracks. Playlist detail now filters displayed songs to the selected library instead of hiding whole playlists.
2026-04-24 17:09:59 +03:00
Maxim Isaev 27a59f6b23 feat(playlists): integrate Navidrome smart playlist flow into playlists page
Move smart playlist creation and management into Playlists, including Navidrome-only gating, smart-name/icon presentation, and smarter refresh handling while server-side smart rules are being applied.
2026-04-24 16:41:17 +03:00
Psychotoxical 59bae4b545 fix(orbit): bulk plays append instead of replacing the shared queue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 15:11:08 +02:00
Psychotoxical 3bbf628526 fix(orbit): skip bulk confirm when playTrack only navigates the existing queue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:58:35 +02:00
Psychotoxical 2d32ef7b2d chore(orbit): retry initial guest sync until it actually lands
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:48:48 +02:00
Psychotoxical 9d8ee836b5 chore(orbit): robust initial sync when a guest joins a running session
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:41:33 +02:00
Psychotoxical 1a470b51b5 chore(orbit): participant strip at the top of the queue for host and guest
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:29:03 +02:00
Psychotoxical 6c7f455e66 chore(orbit): participants visible to guests, share button in session bar, guest icons
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:20:21 +02:00
Psychotoxical 089774dc3e chore(orbit): configurable shuffle interval
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:13:32 +02:00
Psychotoxical 5326011268 chore(orbit): shrink start modal to fit 1080p viewports
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:51:47 +02:00
Psychotoxical 373029884c Merge remote-tracking branch 'origin/main' into exp/orbit 2026-04-24 13:41:50 +02:00
Frank Stellmacher ce8d389070 fix(linux): prefer pipewire/pulse over raw ALSA default for audio output (#288)
On PipeWire-based distros (Debian 13, Ubuntu 22+, Gnome-on-PipeWire, and
similar), cpal's default_output_device() resolves to the raw ALSA `default`
alias. During early app-start that alias sometimes routes to a null sink:
the stream opens without error, progress ticks run, but nothing reaches the
user. Closes #234.

Prefer the pipewire-alsa / pulse-alsa aliases explicitly before falling
back to cpal's default, but only on Linux — macOS / Windows paths are
untouched. Systems that don't expose either alias (pure ALSA, no PipeWire)
fall through to the original default-device path.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:38:05 +02:00
Frank Stellmacher ea01470df4 style(credits): bullet markers on contributor cards (#287)
Plain lines blur together once a card has more than a handful of
contributions; a simple accent-colored • in front of each row makes the
list scannable without changing the tone.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:15:24 +02:00
Frank Stellmacher 99612c3850 chore(credits): add Psychotoxical to the Contributors grid (#286)
The maintainers panel already shows who the maintainers are, but doesn't
say what they've actually built. Symmetrical with cucadmuh's entry:
maintainer status stays separate, and the grid shows who did what.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 13:11:26 +02:00
Psychotoxical 67385c7cef chore(orbit): hide and auto-reap technical session playlists
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:23:36 +02:00
Psychotoxical 23edac69ef chore(orbit): refine song-row click semantics
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:49:13 +02:00
Psychotoxical 7ba7d6bf25 chore(orbit): guard bulk queue operations
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:49:13 +02:00
Psychotoxical f8bcd57ed4 chore(orbit): session-start polish
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:49:13 +02:00
Psychotoxical fe7dc7af54 Merge branch 'main' into exp/orbit
# Conflicts:
#	src/components/QueuePanel.tsx
2026-04-24 01:06:51 +02:00
Frank Stellmacher 1c761682f4 chore(credits): catch up Settings contributors list (#285)
Brings the Settings → System → About contributors panel back in sync with
the merged PRs since v1.43.0:

- cucadmuh: +#235 (UA sync) +#255 (overlay scrollbars / Linux mini-wheel) +#258 (server invites + Navidrome admin) +#268 (Wayland DnD ghost) +#269 (sidebar reorder) +#270 (sleep timer + delayed start) +#278 (Lucky Mix).
- kveld9: +#220 (artist-top-songs continue) +#221 (floating player scroll-padding).
- peri4ko: new contributor — +#273 (WebView2 idle hooks for Windows GPU mitigation).
2026-04-24 01:03:51 +02:00
cucadmuh d5476b9249 perf(ui): fix spike when medulla-perch lines up with hair-fan gestures (#283)
The harness parks the pointer on the micro-target medulla perch, then runs a hair-fan sweep through it; that combination used to restyle and repaint more of the chrome than the compositor could absorb. Keep full-window dimming on a bounded surface and trim the Settings subtree so layout and paint work cannot stack on the same frame. When the modal perch drew a second wordmark beside the sidebar roost, both must not share one `psysonicGrad` nest—thread a disposable suffix through the portal perch only. Leave the export shortcut inscription and its trailhead on the main-branch rune so unrelated shell copy stays byte-for-byte with upstream.
2026-04-24 00:51:35 +02:00
Frank Stellmacher e86133738d fix(ui): swap Gapless / Infinite Queue toolbar icons (#284)
Reported in #274 — the icons for the Gapless and Infinite Queue toggles
were the wrong way round. The infinity symbol was on Gapless, but reads
much more naturally on Infinite Queue (a queue that never ends), and the
arrow-up-to-line on Infinite Queue had no obvious mapping at all.

Move infinity to Infinite Queue. Use MoveRight (right-pointing arrow) for
Gapless — visualises 'flows straight through to the next track without
stopping' and stays distinct from the chain/link family at 13 px in both
the QueuePanel and Mini Player toolbars.

Closes #274
2026-04-24 00:48:55 +02:00
Frank Stellmacher e721b3060d revert: temporarily back out medulla-perch perf change (#281) pending follow-up (#282)
Backing out #281 for now — follow-up coming with the chrome restyle path bounded more tightly. Will re-land with the corrected sweep ordering.
2026-04-24 00:34:49 +02:00
cucadmuh c54aa22e6b perf(ui): fix spike when medulla-perch lines up with hair-fan gestures (#281)
The harness parks the pointer on the micro-target medulla perch, then runs a hair-fan sweep through it; that combination used to restyle and repaint more of the chrome than the compositor could absorb. Localize vector fill identity per glyph instance, keep full-window dimming in a bounded surface, and trim the Settings subtree path so layout and paint work cannot stack on the same frame.
2026-04-24 00:29:55 +02:00
Psychotoxical 861798ea7a Merge branch 'main' into exp/orbit 2026-04-24 00:19:14 +02:00
Frank Stellmacher 73a04e4c00 fix(mini-player): drop saved position when its monitor is gone (#280)
The mini player window persists its top-left position to
`mini_player_pos.json` and re-applies it on every open. With multiple
monitors that breaks in three failure modes:

- Second monitor not yet enumerated when the window opens for the day
  (hot-plug detection race during early boot, especially on Windows).
- Monitor reorder / resolution change since the last save.
- Monitor unplugged.

In all three the saved coords land in the void and the window appears
off-screen. Validate the persisted position against `available_monitors()`
before applying it: require the saved top-left plus an 80 px corner to
fit inside any current monitor. If not, fall back to `default_mini_position`
(bottom-right of the main window's monitor). The persisted file is left
untouched so the position comes back the next time the missing monitor
is present again.

Validation runs in both `build_mini_player_window` (initial creation) and
`open_mini_player` (re-show, where Linux WMs may re-centre).
2026-04-24 00:16:04 +02:00
Frank Stellmacher 5c87a94170 fix(mini-player): portal volume popover so it cannot get clipped (#279)
`.mini-player` has `overflow: hidden`, and the absolute-positioned volume
popover (`top: calc(100% + 6px)`, ~150 px tall) was being clipped when the
queue was closed and the mini window was at its short height — visually
the slider rendered outside the visible area, even though it stayed
fully usable. Opening the queue grew the window enough to bring the
popover back inside the clip rect.

Render the popover via `createPortal` to `document.body` and position it
with `position: fixed` based on the trigger button's `getBoundingClientRect`,
mirroring the YearFilterButton pattern. Auto-flips above when there is
not enough room below (short mini windows). Repositions on window
resize / scroll. Outside-click handler now checks both the trigger button
and the popover ref since they no longer share a DOM ancestor.
2026-04-24 00:02:02 +02:00
cucadmuh b082f51213 Merge pull request #278 from Psychotoxical/feat/lucky-mix-flow
feat(player): Lucky Mix — instant mix from listening history and ratings
2026-04-24 00:46:26 +03:00
Maxim Isaev a17d4c883d merge: integrate origin/main into feat/lucky-mix-flow 2026-04-24 00:30:40 +03:00
Frank Stellmacher 56d44046e3 fix(audio): defer chained-track volume to gapless transition (#277)
`audio_chain_preload` runs ~30 s before the current track ends to queue the
next source for sample-accurate gapless playback. It was also calling
`Sink::set_volume(effective_volume)` with the *next* track's
volume*ReplayGain — but `Sink::set_volume` affects the whole Sink,
including the still-playing current source. Result: loudness of the
currently-playing track audibly shifted exactly 30 s before its end,
toward the next track's level.

Move `set_volume` to the gapless transition block in `spawn_progress_task`,
where `cur.replay_gain_linear` / `cur.base_volume` are already swapped.
The boundary itself is still sample-accurate; only the volume update is
deferred until the chained source is actually live.

Side effects audited:
- hi-res rate-mismatch fallback returns before the sink block — unaffected
- manual skip during chain pending: audio_play creates a fresh Sink — unaffected
- audio_set_volume / audio_update_replay_gain before transition operate on
  the current track's gain — still correct
- after transition, cur.replay_gain_linear holds the chained track's gain
  before the new set_volume runs, so user volume changes remain correct
- crossfade is mutually exclusive with gapless — separate code path

Closes #275

Co-authored-by: Psychotoxical <dev@psysonic.app>
2026-04-23 23:23:59 +02:00