chore(orbit): session-start polish

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-24 10:35:50 +02:00
parent fe7dc7af54
commit f8bcd57ed4
7 changed files with 100 additions and 3 deletions
+29 -1
View File
@@ -5,10 +5,11 @@ import {
deletePlaylist,
getPlaylist,
getPlaylists,
getSong,
} from '../api/subsonic';
import { useAuthStore } from '../store/authStore';
import { useOrbitStore } from '../store/orbitStore';
import { usePlayerStore } from '../store/playerStore';
import { usePlayerStore, songToTrack } from '../store/playerStore';
import {
makeInitialOrbitState,
orbitOutboxPlaylistName,
@@ -505,6 +506,33 @@ export async function suggestOrbitTrack(trackId: string): Promise<void> {
await updatePlaylist(outboxPlaylistId, nextIds, songs.length);
}
/**
* Host: add a track to the active Orbit session directly, skipping the
* outbox/approval loop guests go through. The track lands in the host's
* own play queue immediately and is attributed to the host in the
* session's suggestion history. Host-authored queue items are filtered
* out of the tick-merge pipeline so the host-tick doesn't re-insert the
* same track once it notices the new entry in `OrbitState.queue`.
*/
export async function hostEnqueueToOrbit(trackId: string): Promise<void> {
const store = useOrbitStore.getState();
if (store.role !== 'host' || !store.state || !store.sessionPlaylistId) {
throw new Error('Not hosting an active Orbit session');
}
const song = await getSong(trackId);
if (!song) throw new Error('Track not found');
const track = songToTrack(song);
usePlayerStore.getState().enqueue([track]);
const item: OrbitQueueItem = { trackId, addedBy: store.state.host, addedAt: Date.now() };
const next: OrbitState = { ...store.state, queue: [...store.state.queue, item] };
store.setState(next);
try { await writeOrbitState(store.sessionPlaylistId, next); }
catch { /* best-effort; next host-tick will push the merged state anyway */ }
}
// ── Host-side outbox sweep ──────────────────────────────────────────────
interface OutboxSnapshot {