jevstrudel.git / website / src / jev / parties.mjs

The live listening parties, for the listening tab (LiveParties.jsx), from GET /jev/parties (worker/src/party.ts): each party's song, people, whether its host is there and since when. A party whose host shows themselves (the lobby's "show me here") is listed to join: its entry carries an id the room answers with its name for (GET /jev/parties/<id>), and joining is the ordinary guest join (joinParty, party.mjs), which plays the song from this page's own build. An unlisted party is only described.

8import { joinParty, PARTIES_PATH } from './party.mjs';
10const ID = /^[0-9a-f]{64}$/;
11const SONG = /^[a-z0-9-]{1,64}\/[a-z0-9-]{1,64}$/;

Only the fields the directory sends, checked.

14export function partyOf(p) {
15  if (!p || typeof p !== 'object') return null;
16  return {
17    id: typeof p.id === 'string' && ID.test(p.id) ? p.id : null,
18    song: typeof p.song === 'string' && SONG.test(p.song) ? p.song : null,
19    people: Number.isInteger(p.people) && p.people > 0 ? p.people : 0,
20    host: p.host === true,
21    since: typeof p.since === 'number' ? p.since : null,
22  };
23}
25export async function loadParties(fetcher = fetch) {
26  const res = await fetcher(PARTIES_PATH, { headers: { Accept: 'application/json' } });
27  if (!res.ok) throw new Error(`the site answered ${res.status}`);
28  const body = await res.json();
29  return (Array.isArray(body.parties) ? body.parties : []).map(partyOf).filter((p) => p && p.people > 0);
30}

Join a listed party: its room, from the room itself, then as a guest.

33export async function joinListed(id, fetcher = fetch, join = joinParty) {
34  if (!ID.test(id)) throw new Error('not a listed party');
35  const res = await fetcher(`${PARTIES_PATH}/${id}`, { headers: { Accept: 'application/json' } });
36  if (res.status === 404) throw new Error('this party is over, or no longer listed');
37  if (!res.ok) throw new Error(`the site answered ${res.status}`);
38  const { room } = await res.json();
39  if (typeof room !== 'string') throw new Error('the party did not say where it is');
40  join(room);
41}