exp(orbit): iterative refinements

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-23 16:56:28 +02:00
parent 2b97a7b01e
commit 11dddf6290
14 changed files with 444 additions and 75 deletions
+13 -2
View File
@@ -63,11 +63,22 @@ export function useOrbitGuest(): void {
return;
}
// Kicked: transition into `ended` phase but with a different
// errorMessage so the UI can show the right copy.
// Kicked / soft-removed: transition into the error phase with a
// matching errorMessage so the UI can pick the right copy.
const me = useAuthStore.getState().getActiveServer()?.username;
if (me && state.kicked.includes(me)) {
useOrbitStore.getState().setError('kicked');
return;
}
// Soft-remove: only react to markers strictly newer than our own join
// time, otherwise a stale marker from a prior session-life would
// immediately bounce us out on rejoin.
if (me && state.removed && state.removed.length > 0) {
const joinedAt = useOrbitStore.getState().joinedAt ?? 0;
const hit = state.removed.find(r => r.user === me && r.at > joinedAt);
if (hit) {
useOrbitStore.getState().setError('removed');
}
}
};
+19 -1
View File
@@ -12,6 +12,7 @@ import {
} from '../utils/orbit';
import {
orbitOutboxPlaylistName,
ORBIT_PLAY_QUEUE_LIMIT,
type OrbitState,
type OrbitQueueItem,
} from '../api/orbit';
@@ -125,7 +126,24 @@ export function useOrbitHost(): void {
}
// 4) Overlay the host's live playback snapshot.
const next: OrbitState = { ...afterShuffle, ...snapshotPlayerPatch(base.host) };
const playerLive = usePlayerStore.getState();
const upcoming = playerLive.queue.slice(playerLive.queueIndex + 1);
// Map track id → original suggester (if any). State's `queue` carries
// every suggestion we've ever seen this session, so it's the right
// attribution source even after the track has been merged into the
// host's player queue.
const suggesterByTrack = new Map<string, string>();
for (const q of afterShuffle.queue) suggesterByTrack.set(q.trackId, q.addedBy);
const playQueue = upcoming.slice(0, ORBIT_PLAY_QUEUE_LIMIT).map(t => ({
trackId: t.id,
addedBy: suggesterByTrack.get(t.id) ?? base.host,
}));
const next: OrbitState = {
...afterShuffle,
...snapshotPlayerPatch(base.host),
playQueue,
playQueueTotal: upcoming.length,
};
// 5) Commit locally + push remote.
useOrbitStore.getState().setState(next);