feat(orbit): sync the host's track-transition settings to guests (#1158)

* feat(orbit): mirror host track-transition settings into the session

Each client previously used its own local crossfade / gapless / AutoDJ
settings, so guests blended tracks differently from the host and drifted
out of sync — the exact drift the Catch-Up button exists to paper over.

Add an optional OrbitSettings.transitions (crossfade enabled/secs/trim,
AutoDJ smooth-skip, gapless), additive on the wire so older sessions
simply omit it. The host seeds its own prefs at start and refreshes them
every tick, so a mid-session change propagates. Guests snapshot their own
prefs on join, adopt the host's for the session (idempotent — no setState
churn / audio-sync re-fire when unchanged), and restore their own on
leave. Applying via authStore.setState reuses the existing authSyncListener
path to the Rust engine, so no new IPC. Without the Hot cache a guest's
AutoDJ blend degrades gracefully via the existing byte-preload fallback.

Add a bridge module with unit tests for read/apply/save/restore.

* feat(orbit): lock guest transition controls during a session

Since a guest now mirrors the host's track-transition settings (re-applied
every read tick), their own controls would visibly fight the sync. Disable
them while a guest is in a live session and explain why.

Settings -> Audio -> Track transitions greys out the mode picker, seconds
slider and smooth-skip toggle with a "controlled by the Orbit host" note;
the queue toolbar's Gapless / Crossfade / AutoDJ quick-toggles get the same
disabled state and tooltip. Host controls are untouched. New i18n key added
across all locales.

* docs(changelog): add Orbit transition sync (1158)
This commit is contained in:
Psychotoxical
2026-06-22 16:44:20 +02:00
committed by GitHub
parent a4fbd45d5d
commit 9b03949f34
21 changed files with 281 additions and 5 deletions
+22
View File
@@ -116,6 +116,21 @@ export interface OrbitState {
export const ORBIT_SHUFFLE_INTERVAL_PRESETS_MIN = [1, 5, 10, 15, 30] as const;
export type OrbitShuffleIntervalMin = typeof ORBIT_SHUFFLE_INTERVAL_PRESETS_MIN[number];
/**
* Host's playback-transition preferences, mirrored into the session so guests
* blend tracks the same way the host does (otherwise each client uses its own
* local transition settings, re-introducing the drift the Catch-Up button
* exists to fix). Optional on the wire — a session hosted by a build that
* predates transition sync simply omits it, and guests keep their own.
*/
export interface OrbitTransitionSettings {
crossfadeEnabled: boolean;
crossfadeSecs: number;
crossfadeTrimSilence: boolean;
autodjSmoothSkip: boolean;
gaplessEnabled: boolean;
}
export interface OrbitSettings {
/** Guest suggestions go straight into the host's play queue. */
autoApprove: boolean;
@@ -127,6 +142,13 @@ export interface OrbitSettings {
* field fall back to 15 via `effectiveShuffleIntervalMs`.
*/
shuffleIntervalMin?: OrbitShuffleIntervalMin;
/**
* Host's track-transition prefs (crossfade / gapless / AutoDJ), refreshed
* every host tick from the host's own playback settings. Guests adopt these
* for the session and restore their own on leave. Optional: absent on
* pre-transition-sync sessions.
*/
transitions?: OrbitTransitionSettings;
}
export const ORBIT_DEFAULT_SETTINGS: OrbitSettings = {