music: per-device now-playing (browser vs phone)
Key music_now_playing on (user_id, device) instead of user_id alone so the
browser ('web') and phone ('' default) each keep their own resume snapshot
instead of sharing one row. Sidecar /now-playing threads device (?device=,
default '') through get/set/clearNowPlaying; the web client tags its calls
?device=web. Phone unchanged → '' bucket, inherits the existing row.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -98,9 +98,9 @@ const asKeys = (v: unknown): string[] | null =>
|
||||
// GET /favorites { tracks[], albums[], artists[] } (keys, newest first).
|
||||
// POST /favorites { kind, key } add (idempotent). kind ∈ track|album|artist.
|
||||
// DELETE /favorites?kind=&key= remove.
|
||||
// GET /now-playing last snapshot, or null.
|
||||
// PUT /now-playing { homePath, dir?, title?, artist?, album?, durationSec?, positionSec? } upsert.
|
||||
// DELETE /now-playing clear.
|
||||
// GET /now-playing[?device=] last snapshot for that device, or null. device '' = default/phone, 'web' = browser.
|
||||
// PUT /now-playing[?device=] { homePath, dir?, title?, artist?, album?, durationSec?, positionSec? } upsert.
|
||||
// DELETE /now-playing[?device=] clear that device's snapshot.
|
||||
// GET /playlists [{ id, name, count, createdAt, updatedAt }] (recent first).
|
||||
// POST /playlists { name } create → 201 row; 409 if name taken.
|
||||
// GET /playlists/:id { id, name, items:[keys], … }; 404 if not the user's.
|
||||
@@ -341,14 +341,17 @@ const server = Bun.serve({
|
||||
}
|
||||
|
||||
if (P === '/now-playing') {
|
||||
if (m === 'GET') return json(await getNowPlaying(uid));
|
||||
// Per-client resume state: `?device=` tags the caller ('' = default/phone, 'web' = the browser)
|
||||
// so each keeps its own now-playing instead of sharing one row. Missing → '' (back-compat).
|
||||
const device = url.searchParams.get('device') ?? '';
|
||||
if (m === 'GET') return json(await getNowPlaying(uid, device));
|
||||
if (m === 'PUT') {
|
||||
const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;
|
||||
if (typeof b.homePath !== 'string' || !b.homePath)
|
||||
return json({ error: 'homePath required' }, { status: 400 });
|
||||
const str = (v: unknown) => (typeof v === 'string' ? v : undefined);
|
||||
const num = (v: unknown) => (typeof v === 'number' && Number.isFinite(v) ? v : undefined);
|
||||
await setNowPlaying(uid, {
|
||||
await setNowPlaying(uid, device, {
|
||||
homePath: b.homePath,
|
||||
dir: str(b.dir),
|
||||
title: str(b.title),
|
||||
@@ -360,7 +363,7 @@ const server = Bun.serve({
|
||||
return json({ ok: true });
|
||||
}
|
||||
if (m === 'DELETE') {
|
||||
await clearNowPlaying(uid);
|
||||
await clearNowPlaying(uid, device);
|
||||
return json({ ok: true });
|
||||
}
|
||||
return new Response('Method not allowed', { status: 405 });
|
||||
|
||||
Reference in New Issue
Block a user