@hadoku/watchparty-ui 0.45.14 → 0.45.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{AdminPanel-NqY9bqdB.js → AdminPanel-DQAQsKh3.js} +11 -11
- package/dist/chunks/{AdminPanel-NqY9bqdB.js.map → AdminPanel-DQAQsKh3.js.map} +1 -1
- package/dist/chunks/{MediaDrawer-DnJ2bjL7.js → MediaDrawer-CM-SiHns.js} +32 -32
- package/dist/chunks/{MediaDrawer-DnJ2bjL7.js.map → MediaDrawer-CM-SiHns.js.map} +1 -1
- package/dist/chunks/PlaylistPanel-DgRm9nsi.js +328 -0
- package/dist/chunks/PlaylistPanel-DgRm9nsi.js.map +1 -0
- package/dist/chunks/{Room-H5597D2i.js → Room-DgsMxWGJ.js} +1341 -1339
- package/dist/chunks/Room-DgsMxWGJ.js.map +1 -0
- package/dist/chunks/{index-BLeEknCO.js → index-Ip1nTIQR.js} +1930 -1857
- package/dist/chunks/index-Ip1nTIQR.js.map +1 -0
- package/dist/chunks/{submissionsApi-CL9vNf_o.js → submissionsApi-DZ3dGiaA.js} +6 -6
- package/dist/chunks/{submissionsApi-CL9vNf_o.js.map → submissionsApi-DZ3dGiaA.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/room-chrome.js +901 -831
- package/dist/room-chrome.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunks/PlaylistPanel-DKjA4zxR.js +0 -323
- package/dist/chunks/PlaylistPanel-DKjA4zxR.js.map +0 -1
- package/dist/chunks/Room-H5597D2i.js.map +0 -1
- package/dist/chunks/index-BLeEknCO.js.map +0 -1
package/dist/room-chrome.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { jsx as c, jsxs as _, Fragment as
|
|
2
|
-
import
|
|
3
|
-
import { themePrefs as
|
|
1
|
+
import { jsx as c, jsxs as _, Fragment as ce } from "react/jsx-runtime";
|
|
2
|
+
import Gt, { useState as R, useRef as z, useMemo as Q, useCallback as k, useEffect as D, createContext as qt, useContext as Dn, useSyncExternalStore as On, useId as Mn, useEffectEvent as Vt } from "react";
|
|
3
|
+
import { themePrefs as ie, Icon as Ln, THEMES as jn, useHadokuThemeOptional as Un } from "@wolffm/themes";
|
|
4
4
|
import { z as o } from "zod";
|
|
5
|
-
import { createCdnClient as
|
|
6
|
-
import { create as
|
|
7
|
-
import { createPrefsClient as
|
|
8
|
-
import { io as
|
|
9
|
-
import { createAvatarClient as
|
|
10
|
-
import { resolveIdentityReassert as
|
|
11
|
-
import { createPortal as
|
|
12
|
-
import { useCatalogueSearch as
|
|
13
|
-
const
|
|
14
|
-
function
|
|
15
|
-
return typeof e == "string" &&
|
|
16
|
-
}
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
5
|
+
import { createCdnClient as Fn, kindOfType as Hn, MAX_BYTES as $n, measureImage as Bn, filesFromClipboard as Gn, filesFromDrop as qn, CdnError as Ye } from "@wolffm/cdn-client";
|
|
6
|
+
import { create as Vn } from "zustand";
|
|
7
|
+
import { createPrefsClient as Kn, getDeviceId as Wn, DEVICE_ID_KEY as Yn } from "@wolffm/prefs-client";
|
|
8
|
+
import { io as zn } from "socket.io-client";
|
|
9
|
+
import { createAvatarClient as Xn, AvatarError as vt } from "@wolffm/prefs-client/avatar";
|
|
10
|
+
import { resolveIdentityReassert as Jn } from "@wolffm/rooms-protocol";
|
|
11
|
+
import { createPortal as Zn } from "react-dom";
|
|
12
|
+
import { useCatalogueSearch as Qn } from "@wolffm/cdn-client/react";
|
|
13
|
+
const Kt = "https://cdn.hadoku.me", Wt = /^[0-9a-f]{64}\.(?:png|jpe?g|gif|webp|avif)$/;
|
|
14
|
+
function tt(e) {
|
|
15
|
+
return typeof e == "string" && Wt.test(e);
|
|
16
|
+
}
|
|
17
|
+
const nt = 8080, Yt = 5173, er = "/watchparty/ws", zt = 500, tr = 1e3, W = 4, Xt = typeof process < "u" && process.env ? process.env : {};
|
|
18
|
+
Xt.PRODUCTION_UI_URL;
|
|
19
|
+
Xt.PRODUCTION_SERVER_URL;
|
|
20
|
+
const Ie = o.enum(["S", "A", "B", "C", "D", "F"]), St = 2e4, nr = 300;
|
|
21
21
|
o.object({
|
|
22
22
|
name: o.string().min(1).max(32).optional(),
|
|
23
23
|
sprite: o.string().min(1).max(32).optional(),
|
|
@@ -44,7 +44,7 @@ const w = {
|
|
|
44
44
|
// 'ready_state' here = playback-readiness gate (distinct from READY_EVENTS.STATE = "ready check" UX feature)
|
|
45
45
|
READY_STATE: "ready_state",
|
|
46
46
|
ERROR: "error"
|
|
47
|
-
},
|
|
47
|
+
}, rr = o.enum(["play", "pause", "seek", "load", "home"]), or = o.object({
|
|
48
48
|
framed: o.boolean(),
|
|
49
49
|
depth: o.number().int().nonnegative().max(10)
|
|
50
50
|
});
|
|
@@ -52,7 +52,7 @@ o.object({
|
|
|
52
52
|
room_key: o.string(),
|
|
53
53
|
name: o.string().min(1).max(32).optional(),
|
|
54
54
|
sprite: o.string().min(1).max(32).optional(),
|
|
55
|
-
embed:
|
|
55
|
+
embed: or.optional(),
|
|
56
56
|
/** Which media-delivery path this client resolved to ('range' | 'fragment').
|
|
57
57
|
* Optional so older clients still validate. Reported so a party's logs can be split by
|
|
58
58
|
* arm — without it an A/B rollout is unmeasurable, exactly as entry path was before
|
|
@@ -100,13 +100,13 @@ o.object({
|
|
|
100
100
|
});
|
|
101
101
|
o.object({
|
|
102
102
|
client_seq: o.number().int().positive(),
|
|
103
|
-
kind:
|
|
103
|
+
kind: rr,
|
|
104
104
|
to_ms: o.number().int().nonnegative().optional(),
|
|
105
105
|
media_id: o.string().optional()
|
|
106
106
|
// leader_id removed - not needed since set_leader control was removed
|
|
107
107
|
});
|
|
108
|
-
const
|
|
109
|
-
key: o.string().regex(
|
|
108
|
+
const Jt = o.object({
|
|
109
|
+
key: o.string().regex(Wt, "not a CDN image key"),
|
|
110
110
|
/**
|
|
111
111
|
* Intrinsic pixels, or **0 meaning "unknown"**.
|
|
112
112
|
*
|
|
@@ -119,8 +119,8 @@ const Wt = o.object({
|
|
|
119
119
|
* text went with it, with nothing said. Widening is backward compatible —
|
|
120
120
|
* every message already in history carries positive dimensions.
|
|
121
121
|
*/
|
|
122
|
-
w: o.number().int().nonnegative().max(
|
|
123
|
-
h: o.number().int().nonnegative().max(
|
|
122
|
+
w: o.number().int().nonnegative().max(St),
|
|
123
|
+
h: o.number().int().nonnegative().max(St),
|
|
124
124
|
/**
|
|
125
125
|
* Human-readable description, rendered as the `alt` text.
|
|
126
126
|
*
|
|
@@ -134,14 +134,14 @@ const Wt = o.object({
|
|
|
134
134
|
* value only, never as markup. Bounded so one message cannot carry a
|
|
135
135
|
* paragraph; the library's own titles run well under this.
|
|
136
136
|
*/
|
|
137
|
-
title: o.string().max(
|
|
137
|
+
title: o.string().max(nr).optional()
|
|
138
138
|
});
|
|
139
139
|
o.object({
|
|
140
|
-
text: o.string().max(
|
|
140
|
+
text: o.string().max(zt),
|
|
141
141
|
style: o.string().max(64).optional(),
|
|
142
|
-
images: o.array(
|
|
142
|
+
images: o.array(Jt).max(W).optional()
|
|
143
143
|
}).refine((e) => e.text.length > 0 || (e.images?.length ?? 0) > 0, { message: "message must carry text or at least one image" });
|
|
144
|
-
const
|
|
144
|
+
const ar = o.enum(["join", "leave", "media_change", "identity_change", "recap"]);
|
|
145
145
|
o.object({
|
|
146
146
|
id: o.string(),
|
|
147
147
|
client_id: o.string(),
|
|
@@ -154,11 +154,11 @@ o.object({
|
|
|
154
154
|
ts: o.number(),
|
|
155
155
|
// Optional so a client on an older bundle still validates a message that
|
|
156
156
|
// has none, and so system messages (which never carry images) stay unchanged.
|
|
157
|
-
images: o.array(
|
|
157
|
+
images: o.array(Jt).max(W).optional(),
|
|
158
158
|
isSystem: o.boolean().optional(),
|
|
159
|
-
systemType:
|
|
159
|
+
systemType: ar.optional()
|
|
160
160
|
});
|
|
161
|
-
const
|
|
161
|
+
const ir = o.object({
|
|
162
162
|
avg_download_rate_bps: o.number().nonnegative(),
|
|
163
163
|
buffered_ahead_ms: o.number().nonnegative(),
|
|
164
164
|
rtt_ms: o.number().nonnegative(),
|
|
@@ -200,7 +200,7 @@ const er = o.object({
|
|
|
200
200
|
* socket shows here as a growing number while everything else looks fine. */
|
|
201
201
|
pong_age_ms: o.number().int().nonnegative().optional(),
|
|
202
202
|
reported_at: o.number().int().nonnegative()
|
|
203
|
-
}),
|
|
203
|
+
}), sr = ir.extend({
|
|
204
204
|
client_id: o.string(),
|
|
205
205
|
name: o.string(),
|
|
206
206
|
sprite_id: o.string().nullable(),
|
|
@@ -211,10 +211,10 @@ const er = o.object({
|
|
|
211
211
|
stale_ms: o.number().int().nonnegative().optional()
|
|
212
212
|
});
|
|
213
213
|
o.object({
|
|
214
|
-
clients: o.array(
|
|
214
|
+
clients: o.array(sr),
|
|
215
215
|
server_ts: o.number().int().nonnegative()
|
|
216
216
|
});
|
|
217
|
-
const
|
|
217
|
+
const lr = o.object({
|
|
218
218
|
client_id: o.string(),
|
|
219
219
|
sprite_id: o.string().nullable(),
|
|
220
220
|
name: o.string(),
|
|
@@ -232,13 +232,13 @@ const nr = o.object({
|
|
|
232
232
|
video_ready_state: o.number().int().default(-1)
|
|
233
233
|
});
|
|
234
234
|
o.object({
|
|
235
|
-
clients: o.array(
|
|
235
|
+
clients: o.array(lr),
|
|
236
236
|
server_ts: o.number().int().nonnegative()
|
|
237
237
|
});
|
|
238
238
|
o.object({
|
|
239
239
|
media_id: o.string()
|
|
240
240
|
});
|
|
241
|
-
const
|
|
241
|
+
const rt = o.enum(["super_upvote", "upvote", "mid", "downvote"]), cr = o.object({
|
|
242
242
|
mediaId: o.string(),
|
|
243
243
|
displayName: o.string(),
|
|
244
244
|
// Enrichment fields — present for flat-playlist ingest output, absent for
|
|
@@ -249,11 +249,11 @@ const Ze = o.enum(["super_upvote", "upvote", "mid", "downvote"]), rr = o.object(
|
|
|
249
249
|
durationMs: o.number().optional(),
|
|
250
250
|
uploadDate: o.string().optional()
|
|
251
251
|
// YouTube upload date 'YYYY-MM-DD'; drives playlist order
|
|
252
|
-
}),
|
|
252
|
+
}), dr = o.enum(["basic", "vote"]), Zt = o.object({
|
|
253
253
|
id: o.string(),
|
|
254
254
|
name: o.string(),
|
|
255
|
-
type:
|
|
256
|
-
videos: o.array(
|
|
255
|
+
type: dr.default("vote"),
|
|
256
|
+
videos: o.array(cr),
|
|
257
257
|
cover: o.string().optional()
|
|
258
258
|
// media-relative path to the playlist cover image
|
|
259
259
|
});
|
|
@@ -262,28 +262,28 @@ o.object({ index: o.number().int().min(0) });
|
|
|
262
262
|
o.object({
|
|
263
263
|
playlistId: o.string(),
|
|
264
264
|
mediaId: o.string(),
|
|
265
|
-
vote:
|
|
265
|
+
vote: rt
|
|
266
266
|
});
|
|
267
267
|
o.object({ voterKey: o.string().min(1).max(128) });
|
|
268
268
|
o.object({ playlistId: o.string(), mediaIds: o.array(o.string()) });
|
|
269
269
|
o.object({
|
|
270
|
-
playlist:
|
|
270
|
+
playlist: Zt.nullable(),
|
|
271
271
|
activeIndex: o.number().int().nullable(),
|
|
272
|
-
myVotes: o.record(o.string(),
|
|
272
|
+
myVotes: o.record(o.string(), rt)
|
|
273
273
|
// mediaId -> VoteValue
|
|
274
274
|
});
|
|
275
|
-
const
|
|
275
|
+
const ur = o.object({
|
|
276
276
|
clientId: o.string(),
|
|
277
277
|
name: o.string(),
|
|
278
278
|
votedCount: o.number().int().nonnegative(),
|
|
279
279
|
totalVideos: o.number().int().nonnegative()
|
|
280
280
|
});
|
|
281
281
|
o.object({
|
|
282
|
-
progress: o.array(
|
|
282
|
+
progress: o.array(ur)
|
|
283
283
|
});
|
|
284
284
|
o.object({
|
|
285
|
-
playlist:
|
|
286
|
-
votes: o.record(o.string(), o.record(o.string(),
|
|
285
|
+
playlist: Zt,
|
|
286
|
+
votes: o.record(o.string(), o.record(o.string(), rt)),
|
|
287
287
|
// votes[clientId][mediaId]
|
|
288
288
|
names: o.record(o.string(), o.string()),
|
|
289
289
|
// clientId -> display name
|
|
@@ -291,50 +291,56 @@ o.object({
|
|
|
291
291
|
* (and so is gone from the live roster) still renders. Optional: older
|
|
292
292
|
* servers omit it and clients fall back to the roster. */
|
|
293
293
|
sprites: o.record(o.string(), o.string()).optional(),
|
|
294
|
+
/** clientId -> avatar picture URL, frozen at reveal like `sprites`. Only
|
|
295
|
+
* people who have a picture; everyone else shows their character. */
|
|
296
|
+
pictures: o.record(o.string(), o.string()).optional(),
|
|
294
297
|
/** True when this re-sends results after a voter was removed. A client whose
|
|
295
298
|
* reveal is closed ignores it, rather than having the popup reappear. */
|
|
296
299
|
update: o.boolean().optional()
|
|
297
300
|
});
|
|
298
|
-
const
|
|
301
|
+
const be = {
|
|
299
302
|
STATE: "playlist_state",
|
|
300
303
|
VOTE_PROGRESS: "playlist_vote_progress",
|
|
301
304
|
RESULTS: "playlist_results",
|
|
302
305
|
/** Server -> the removed voter: forget the ballot you hold in localStorage. */
|
|
303
306
|
VOTES_CLEARED: "playlist_votes_cleared"
|
|
304
|
-
},
|
|
307
|
+
}, Qt = o.object({
|
|
305
308
|
id: o.string(),
|
|
306
309
|
displayName: o.string(),
|
|
307
310
|
thumbnail: o.string().optional()
|
|
308
311
|
});
|
|
309
312
|
o.object({
|
|
310
|
-
items: o.array(
|
|
313
|
+
items: o.array(Qt)
|
|
311
314
|
});
|
|
312
|
-
const
|
|
313
|
-
o.object({ board:
|
|
314
|
-
const
|
|
315
|
+
const en = o.partialRecord(Ie, o.array(o.string()));
|
|
316
|
+
o.object({ board: en });
|
|
317
|
+
const mr = o.object({
|
|
315
318
|
mediaId: o.string(),
|
|
316
|
-
tier:
|
|
317
|
-
absoluteTier:
|
|
319
|
+
tier: Ie,
|
|
320
|
+
absoluteTier: Ie,
|
|
318
321
|
/** Tier level + within-row position. Integer part is the tier. */
|
|
319
322
|
score: o.number(),
|
|
320
323
|
/** The consensus mean that decided the tier. Never the displayed number. */
|
|
321
324
|
placementScore: o.number(),
|
|
322
325
|
subRankOffset: o.number(),
|
|
323
|
-
votes: o.record(o.string(),
|
|
326
|
+
votes: o.record(o.string(), Ie)
|
|
324
327
|
// opaque voterId -> the letter they gave
|
|
325
328
|
});
|
|
326
329
|
o.object({
|
|
327
|
-
items: o.array(
|
|
328
|
-
placed: o.array(
|
|
330
|
+
items: o.array(Qt),
|
|
331
|
+
placed: o.array(mr),
|
|
329
332
|
unrated: o.array(o.string()),
|
|
330
333
|
spread: o.number(),
|
|
331
334
|
nudged: o.boolean(),
|
|
332
335
|
names: o.record(o.string(), o.string()),
|
|
333
336
|
sprites: o.record(o.string(), o.string()),
|
|
337
|
+
/** Voter id -> avatar picture URL, for voters who have one. Optional so a
|
|
338
|
+
* browser on a newer bundle still reads an older server's board. */
|
|
339
|
+
pictures: o.record(o.string(), o.string()).optional(),
|
|
334
340
|
voterCount: o.number().int().nonnegative(),
|
|
335
|
-
myBoard:
|
|
341
|
+
myBoard: en
|
|
336
342
|
});
|
|
337
|
-
const
|
|
343
|
+
const fr = {
|
|
338
344
|
/** Broadcast to EVERY connected socket when anyone saves. Carries no board —
|
|
339
345
|
* it is a "re-fetch" ping, because the shared result is identical for all
|
|
340
346
|
* viewers but `myBoard` is not, and one payload cannot serve both. */
|
|
@@ -347,10 +353,10 @@ o.object({
|
|
|
347
353
|
ready: o.array(o.string())
|
|
348
354
|
// clientIds who have flagged ready
|
|
349
355
|
});
|
|
350
|
-
const
|
|
356
|
+
const pr = {
|
|
351
357
|
STATE: "ready_check_state"
|
|
352
358
|
// distinct from buffer-readiness 'ready_state'
|
|
353
|
-
},
|
|
359
|
+
}, tn = {
|
|
354
360
|
ACTIVE: "game_active",
|
|
355
361
|
// server -> room (the open game id; null = none)
|
|
356
362
|
SYNC: "game_sync"
|
|
@@ -362,7 +368,7 @@ o.object({
|
|
|
362
368
|
o.object({
|
|
363
369
|
gameId: o.string().nullable()
|
|
364
370
|
});
|
|
365
|
-
const
|
|
371
|
+
const hr = [
|
|
366
372
|
{
|
|
367
373
|
id: "fantasy",
|
|
368
374
|
characters: [
|
|
@@ -406,37 +412,37 @@ const cr = [
|
|
|
406
412
|
{ id: "mentor", color: "#e1e0dc" }
|
|
407
413
|
]
|
|
408
414
|
}
|
|
409
|
-
],
|
|
410
|
-
function
|
|
411
|
-
const t =
|
|
415
|
+
], ot = hr.flatMap((e) => e.characters), Le = ot.map((e) => e.id), gr = Object.fromEntries(ot.map((e) => [e.id, e.color])), yr = Object.fromEntries(ot.map((e) => [e.id, "rev" in e ? e.rev : 1]));
|
|
416
|
+
function br(e) {
|
|
417
|
+
const t = yr[e];
|
|
412
418
|
return `/media/sprites/square_${e}.png${t > 1 ? `?v=${t}` : ""}`;
|
|
413
419
|
}
|
|
414
|
-
function
|
|
415
|
-
return !!e &&
|
|
420
|
+
function at(e) {
|
|
421
|
+
return !!e && Le.includes(e);
|
|
416
422
|
}
|
|
417
|
-
const
|
|
418
|
-
function
|
|
419
|
-
return typeof e == "string" &&
|
|
423
|
+
const vr = 5e3, nn = { mode: "off", percent: 0 }, Sr = ["off", "on", "ab"];
|
|
424
|
+
function _r(e) {
|
|
425
|
+
return typeof e == "string" && Sr.includes(e);
|
|
420
426
|
}
|
|
421
|
-
function
|
|
422
|
-
const t = e && typeof e == "object" ? e : {}, n =
|
|
427
|
+
function wr(e) {
|
|
428
|
+
const t = e && typeof e == "object" ? e : {}, n = _r(t.mode) ? t.mode : nn.mode, r = Number(t.percent), a = Number.isFinite(r) ? Math.min(100, Math.max(0, Math.round(r))) : 0;
|
|
423
429
|
return { mode: n, percent: a };
|
|
424
430
|
}
|
|
425
|
-
function
|
|
431
|
+
function xr(e) {
|
|
426
432
|
let t = 2166136261;
|
|
427
433
|
for (let n = 0; n < e.length; n++)
|
|
428
434
|
t ^= e.charCodeAt(n), t = Math.imul(t, 16777619) >>> 0;
|
|
429
435
|
return t >>> 0;
|
|
430
436
|
}
|
|
431
|
-
function
|
|
437
|
+
function Ir(e, t, n) {
|
|
432
438
|
if (n === !0)
|
|
433
439
|
return "fragment";
|
|
434
440
|
if (n === !1)
|
|
435
441
|
return "range";
|
|
436
|
-
const r =
|
|
437
|
-
return r.mode === "on" ? "fragment" : r.mode === "off" || r.percent <= 0 ? "range" : r.percent >= 100 || t &&
|
|
442
|
+
const r = wr(e);
|
|
443
|
+
return r.mode === "on" ? "fragment" : r.mode === "off" || r.percent <= 0 ? "range" : r.percent >= 100 || t && xr(t) % 100 < r.percent ? "fragment" : "range";
|
|
438
444
|
}
|
|
439
|
-
const
|
|
445
|
+
const rn = o.enum(["url", "magnet", "upload"]), Cr = o.enum([
|
|
440
446
|
"pending",
|
|
441
447
|
"approved",
|
|
442
448
|
"fetching",
|
|
@@ -444,7 +450,7 @@ const Zt = o.enum(["url", "magnet", "upload"]), vr = o.enum([
|
|
|
444
450
|
"ready",
|
|
445
451
|
"rejected",
|
|
446
452
|
"failed"
|
|
447
|
-
]),
|
|
453
|
+
]), _t = {
|
|
448
454
|
pending: ["approved", "rejected"],
|
|
449
455
|
approved: ["fetching", "rejected", "failed"],
|
|
450
456
|
fetching: ["ingesting", "failed"],
|
|
@@ -453,12 +459,12 @@ const Zt = o.enum(["url", "magnet", "upload"]), vr = o.enum([
|
|
|
453
459
|
rejected: [],
|
|
454
460
|
failed: ["approved"]
|
|
455
461
|
};
|
|
456
|
-
Object.keys(
|
|
457
|
-
const
|
|
462
|
+
Object.keys(_t).filter((e) => _t[e].length === 0);
|
|
463
|
+
const Tr = o.object({
|
|
458
464
|
id: o.string().min(1),
|
|
459
465
|
/** Stable userId from whoami. Never the raw `X-User-Key`. */
|
|
460
466
|
ownerUserId: o.string().min(1),
|
|
461
|
-
kind:
|
|
467
|
+
kind: rn,
|
|
462
468
|
/** The magnet URI, the https URL, or the filetransfer binding id. */
|
|
463
469
|
source: o.string().min(1),
|
|
464
470
|
title: o.string().optional(),
|
|
@@ -473,7 +479,7 @@ const Sr = o.object({
|
|
|
473
479
|
* misroute the copy.
|
|
474
480
|
*/
|
|
475
481
|
series: o.string().optional(),
|
|
476
|
-
state:
|
|
482
|
+
state: Cr,
|
|
477
483
|
createdAt: o.number().int().nonnegative(),
|
|
478
484
|
updatedAt: o.number().int().nonnegative(),
|
|
479
485
|
/** Why it failed, or why an operator rejected it. */
|
|
@@ -481,19 +487,19 @@ const Sr = o.object({
|
|
|
481
487
|
/** Size once known. 0 means "known to be empty"; absent means "not yet known" —
|
|
482
488
|
* the same distinction `chatImages` draws for image dimensions. */
|
|
483
489
|
bytes: o.number().int().nonnegative().optional()
|
|
484
|
-
}),
|
|
490
|
+
}), Ar = 4096, on = 300, Er = 100;
|
|
485
491
|
o.object({
|
|
486
|
-
kind:
|
|
487
|
-
source: o.string().min(1).max(
|
|
488
|
-
title: o.string().min(1).max(
|
|
492
|
+
kind: rn,
|
|
493
|
+
source: o.string().min(1).max(Ar),
|
|
494
|
+
title: o.string().min(1).max(on).optional(),
|
|
489
495
|
/** Required for `kind: 'magnet'` by `checkSource`; ignored for `url`/`upload`. */
|
|
490
|
-
series: o.string().min(1).max(
|
|
496
|
+
series: o.string().min(1).max(Er).optional()
|
|
491
497
|
});
|
|
492
498
|
o.object({
|
|
493
|
-
reason: o.string().min(1).max(
|
|
499
|
+
reason: o.string().min(1).max(on).optional()
|
|
494
500
|
});
|
|
495
501
|
o.object({
|
|
496
|
-
submissions: o.array(
|
|
502
|
+
submissions: o.array(Tr)
|
|
497
503
|
});
|
|
498
504
|
o.object({
|
|
499
505
|
error: o.literal("submissions/quota_exceeded"),
|
|
@@ -502,26 +508,26 @@ o.object({
|
|
|
502
508
|
/** The cap that was applied, from the server's config. */
|
|
503
509
|
capBytes: o.number().int().nonnegative()
|
|
504
510
|
});
|
|
505
|
-
const
|
|
506
|
-
function
|
|
511
|
+
const kr = /^[a-z0-9][a-z0-9-]{0,31}$/, wt = "https://game-catalog.invalid";
|
|
512
|
+
function Pr(e) {
|
|
507
513
|
if (!e.startsWith("/") || e.startsWith("//") || /[\\\s]/.test(e) || [...e].some((t) => t.charCodeAt(0) < 32 || t.charCodeAt(0) === 127))
|
|
508
514
|
return !1;
|
|
509
515
|
try {
|
|
510
|
-
return new URL(e,
|
|
516
|
+
return new URL(e, wt).origin === wt;
|
|
511
517
|
} catch {
|
|
512
518
|
return !1;
|
|
513
519
|
}
|
|
514
520
|
}
|
|
515
|
-
const
|
|
521
|
+
const an = o.string().min(2).max(512).refine(Pr, {
|
|
516
522
|
message: "must be a root-relative path on the page origin (e.g. /cardtable/embed/x.js)"
|
|
517
|
-
}),
|
|
518
|
-
id: o.string().regex(
|
|
523
|
+
}), Nr = {
|
|
524
|
+
id: o.string().regex(kr),
|
|
519
525
|
name: o.string().min(1).max(64),
|
|
520
|
-
cover:
|
|
521
|
-
},
|
|
522
|
-
o.array(
|
|
523
|
-
const
|
|
524
|
-
source:
|
|
526
|
+
cover: an.optional()
|
|
527
|
+
}, Rr = o.object({ ...Nr, kind: o.literal("module"), url: an }).strict();
|
|
528
|
+
o.array(Rr).max(32).refine((e) => new Set(e.map((t) => t.id)).size === e.length, { message: "game ids must be unique" });
|
|
529
|
+
const it = o.enum(["anilist", "tmdb"]), Dr = o.object({
|
|
530
|
+
source: it,
|
|
525
531
|
/** The provider's own id, as a string (AniList and TMDB both use integers). */
|
|
526
532
|
id: o.string(),
|
|
527
533
|
title: o.string(),
|
|
@@ -542,11 +548,11 @@ const nt = o.enum(["anilist", "tmdb"]), Ar = o.object({
|
|
|
542
548
|
addable: o.boolean()
|
|
543
549
|
});
|
|
544
550
|
o.object({
|
|
545
|
-
results: o.array(
|
|
551
|
+
results: o.array(Dr),
|
|
546
552
|
/** Providers that answered. TMDB is absent when no token is configured. */
|
|
547
|
-
sources: o.array(
|
|
553
|
+
sources: o.array(it)
|
|
548
554
|
});
|
|
549
|
-
const
|
|
555
|
+
const Or = o.object({
|
|
550
556
|
id: o.string(),
|
|
551
557
|
url: o.string(),
|
|
552
558
|
title: o.string(),
|
|
@@ -554,35 +560,35 @@ const kr = o.object({
|
|
|
554
560
|
durationS: o.number().nullable(),
|
|
555
561
|
thumb: o.string().nullable()
|
|
556
562
|
});
|
|
557
|
-
o.object({ results: o.array(
|
|
563
|
+
o.object({ results: o.array(Or) });
|
|
558
564
|
o.object({
|
|
559
|
-
source:
|
|
565
|
+
source: it,
|
|
560
566
|
id: o.string().regex(/^\d{1,12}$/)
|
|
561
567
|
});
|
|
562
568
|
o.object({ series: o.string(), title: o.string() });
|
|
563
|
-
let
|
|
564
|
-
function
|
|
565
|
-
e.cdnBase && (
|
|
569
|
+
let ve = null, sn = Kt;
|
|
570
|
+
function Mr(e) {
|
|
571
|
+
e.cdnBase && (sn = e.cdnBase);
|
|
566
572
|
}
|
|
567
|
-
function
|
|
568
|
-
return
|
|
573
|
+
function ln() {
|
|
574
|
+
return sn.replace(/\/+$/, "");
|
|
569
575
|
}
|
|
570
|
-
function
|
|
571
|
-
const e =
|
|
572
|
-
return (!
|
|
576
|
+
function je() {
|
|
577
|
+
const e = ln();
|
|
578
|
+
return (!ve || ve.base !== e) && (ve = { base: e, client: Fn({ cdnBase: e }) }), ve.client;
|
|
573
579
|
}
|
|
574
|
-
function
|
|
575
|
-
return !
|
|
580
|
+
function Ne(e) {
|
|
581
|
+
return !tt(e) || !ln() ? null : je().urlFor(e);
|
|
576
582
|
}
|
|
577
|
-
function
|
|
583
|
+
function Lr(e) {
|
|
578
584
|
return e.kind === "file";
|
|
579
585
|
}
|
|
580
|
-
class
|
|
586
|
+
class cn extends Error {
|
|
581
587
|
constructor(t) {
|
|
582
588
|
super(t), this.name = "ChatImageUploadError";
|
|
583
589
|
}
|
|
584
590
|
}
|
|
585
|
-
function
|
|
591
|
+
function Ce(e) {
|
|
586
592
|
switch (e) {
|
|
587
593
|
case "unauthenticated":
|
|
588
594
|
return "Sign in to paste images";
|
|
@@ -602,88 +608,88 @@ function Ie(e) {
|
|
|
602
608
|
return "Image upload failed";
|
|
603
609
|
}
|
|
604
610
|
}
|
|
605
|
-
function
|
|
606
|
-
return e instanceof
|
|
611
|
+
function jr(e) {
|
|
612
|
+
return e instanceof Ye ? Ce(e.reason) : e instanceof cn ? e.message : "Image upload failed";
|
|
607
613
|
}
|
|
608
|
-
function
|
|
614
|
+
function Ur(e) {
|
|
609
615
|
const t = e.type.toLowerCase().split(";")[0].trim();
|
|
610
|
-
return t &&
|
|
616
|
+
return t && Hn(t) !== "image" ? Ce("unsupported-type") : e.size > $n.image ? Ce("too-large") : e.size === 0 ? Ce("invalid") : null;
|
|
611
617
|
}
|
|
612
|
-
function
|
|
613
|
-
return
|
|
618
|
+
function Fr(e) {
|
|
619
|
+
return Gn(e);
|
|
614
620
|
}
|
|
615
|
-
function
|
|
616
|
-
return
|
|
621
|
+
function Hr(e) {
|
|
622
|
+
return qn(e);
|
|
617
623
|
}
|
|
618
|
-
async function
|
|
619
|
-
const t = await
|
|
624
|
+
async function $r(e) {
|
|
625
|
+
const t = await Bn(e);
|
|
620
626
|
return { w: t?.width ?? 0, h: t?.height ?? 0 };
|
|
621
627
|
}
|
|
622
|
-
async function
|
|
623
|
-
const n = await
|
|
624
|
-
if (!
|
|
625
|
-
throw new
|
|
628
|
+
async function Br(e, t = {}) {
|
|
629
|
+
const n = await je().upload(e, { signal: t.signal });
|
|
630
|
+
if (!tt(n.key))
|
|
631
|
+
throw new cn("Image upload returned an unusable key");
|
|
626
632
|
return { key: n.key, deduplicated: n.deduplicated === !0 };
|
|
627
633
|
}
|
|
628
|
-
async function
|
|
634
|
+
async function Gr(e, t = {}) {
|
|
629
635
|
const n = [];
|
|
630
636
|
for (const r of e) {
|
|
631
637
|
if (r.kind === "remote") {
|
|
632
638
|
n.push({ key: r.key, w: r.w, h: r.h, ...r.title ? { title: r.title } : {} });
|
|
633
639
|
continue;
|
|
634
640
|
}
|
|
635
|
-
const { key: a } = await
|
|
641
|
+
const { key: a } = await Br(r.file, t);
|
|
636
642
|
n.push({ key: a, w: r.w, h: r.h });
|
|
637
643
|
}
|
|
638
644
|
return n;
|
|
639
645
|
}
|
|
640
|
-
function
|
|
646
|
+
function qr(e) {
|
|
641
647
|
return {
|
|
642
648
|
error: e instanceof Error ? e.message : String(e),
|
|
643
649
|
name: e instanceof Error ? e.name : typeof e,
|
|
644
|
-
reason: e instanceof
|
|
645
|
-
status: e instanceof
|
|
650
|
+
reason: e instanceof Ye ? e.reason : void 0,
|
|
651
|
+
status: e instanceof Ye ? e.status : void 0
|
|
646
652
|
};
|
|
647
653
|
}
|
|
648
|
-
const
|
|
649
|
-
function
|
|
650
|
-
let r = t.left -
|
|
651
|
-
r < X && (r = t.right + X), r = Math.min(r, n.width -
|
|
652
|
-
const a =
|
|
654
|
+
const ze = 240, X = 8, Vr = 28, dn = 240;
|
|
655
|
+
function Kr(e, t, n) {
|
|
656
|
+
let r = t.left - ze - X;
|
|
657
|
+
r < X && (r = t.right + X), r = Math.min(r, n.width - ze - X), r = Math.max(X, r);
|
|
658
|
+
const a = dn + Vr;
|
|
653
659
|
let i = e.top + e.height / 2 - a / 2;
|
|
654
660
|
return i = Math.min(i, n.height - a - X), i = Math.max(X, i), { left: r, top: i };
|
|
655
661
|
}
|
|
656
|
-
const
|
|
657
|
-
function
|
|
658
|
-
const [r, a] = R(""), i = z(null), s = z(null), l =
|
|
662
|
+
const un = "/dataplatform/api/memes", Wr = 120;
|
|
663
|
+
function Yr({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
664
|
+
const [r, a] = R(""), i = z(null), s = z(null), l = je(), { items: u, loading: h, error: f, hasMore: O, loadMore: M } = Qn(
|
|
659
665
|
l,
|
|
660
|
-
|
|
666
|
+
un,
|
|
661
667
|
r.trim()
|
|
662
|
-
),
|
|
668
|
+
), L = f?.reason ?? null, C = Q(() => {
|
|
663
669
|
const x = /* @__PURE__ */ new Set();
|
|
664
|
-
return
|
|
665
|
-
}, [
|
|
670
|
+
return u.filter((P) => x.has(P.key) ? !1 : (x.add(P.key), !0));
|
|
671
|
+
}, [u]), [p, v] = R(null), b = z(null), I = k(() => {
|
|
666
672
|
b.current !== null && (window.clearTimeout(b.current), b.current = null);
|
|
667
|
-
}, []), g =
|
|
673
|
+
}, []), g = k(() => {
|
|
668
674
|
I(), v(null);
|
|
669
|
-
}, [I]),
|
|
675
|
+
}, [I]), E = typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(hover: hover)").matches, N = k(
|
|
670
676
|
(x, P, T = !1) => {
|
|
671
|
-
const
|
|
672
|
-
if (!
|
|
673
|
-
const
|
|
677
|
+
const he = i.current;
|
|
678
|
+
if (!he) return;
|
|
679
|
+
const ge = () => v({
|
|
674
680
|
item: x,
|
|
675
|
-
...
|
|
681
|
+
...Kr(P.getBoundingClientRect(), he.getBoundingClientRect(), {
|
|
676
682
|
width: window.innerWidth,
|
|
677
683
|
height: window.innerHeight
|
|
678
684
|
})
|
|
679
685
|
});
|
|
680
|
-
I(), T ?
|
|
686
|
+
I(), T ? ge() : b.current = window.setTimeout(ge, Wr);
|
|
681
687
|
},
|
|
682
688
|
[I]
|
|
683
689
|
);
|
|
684
690
|
D(() => () => I(), [I]), D(() => {
|
|
685
|
-
|
|
686
|
-
}, [
|
|
691
|
+
L === "unavailable" && n?.();
|
|
692
|
+
}, [L, n]), D(() => {
|
|
687
693
|
s.current?.focus();
|
|
688
694
|
}, []), D(() => {
|
|
689
695
|
const x = (T) => {
|
|
@@ -695,7 +701,7 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
695
701
|
document.removeEventListener("keydown", x), document.removeEventListener("mousedown", P);
|
|
696
702
|
};
|
|
697
703
|
}, [e]);
|
|
698
|
-
const U =
|
|
704
|
+
const U = k((x) => {
|
|
699
705
|
t(x), e();
|
|
700
706
|
}, [t, e]), F = !h && !f && C.length === 0;
|
|
701
707
|
return /* @__PURE__ */ _(
|
|
@@ -732,13 +738,13 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
732
738
|
{
|
|
733
739
|
className: "m-2 p-2 text-center text-sm bg-danger-bg text-on-danger-bg rounded",
|
|
734
740
|
role: "alert",
|
|
735
|
-
"data-reason":
|
|
736
|
-
children:
|
|
741
|
+
"data-reason": L,
|
|
742
|
+
children: L === "unauthenticated" ? "Sign in to browse memes" : L === "forbidden" ? "Your account can't browse the meme library" : "Meme library is unavailable"
|
|
737
743
|
}
|
|
738
744
|
),
|
|
739
745
|
F && /* @__PURE__ */ c("p", { className: "p-4 text-center text-sm text-text-secondary", children: r.trim() ? `No memes match "${r.trim()}"` : "The meme library is empty" }),
|
|
740
746
|
C.length > 0 && /* @__PURE__ */ c("div", { className: "grid grid-cols-3 gap-1.5 sm:grid-cols-4", children: C.map((x) => {
|
|
741
|
-
const P =
|
|
747
|
+
const P = Ne(x.key);
|
|
742
748
|
return P ? /* @__PURE__ */ c(
|
|
743
749
|
"button",
|
|
744
750
|
{
|
|
@@ -747,7 +753,7 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
747
753
|
title: x.title,
|
|
748
754
|
"data-testid": "meme-result",
|
|
749
755
|
onMouseEnter: (T) => {
|
|
750
|
-
|
|
756
|
+
E && N(x, T.currentTarget);
|
|
751
757
|
},
|
|
752
758
|
onMouseLeave: g,
|
|
753
759
|
onFocus: (T) => N(x, T.currentTarget, !0),
|
|
@@ -768,11 +774,11 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
768
774
|
) : null;
|
|
769
775
|
}) }),
|
|
770
776
|
h && /* @__PURE__ */ c("p", { className: "p-2 text-center text-xs text-text-secondary", children: "Loading…" }),
|
|
771
|
-
|
|
777
|
+
O && !h && /* @__PURE__ */ c(
|
|
772
778
|
"button",
|
|
773
779
|
{
|
|
774
780
|
type: "button",
|
|
775
|
-
onClick:
|
|
781
|
+
onClick: M,
|
|
776
782
|
"data-testid": "meme-load-more",
|
|
777
783
|
className: "mt-2 w-full rounded border border-border-light py-1 text-xs text-text-secondary hover:text-text hover:border-primary",
|
|
778
784
|
children: "Load more"
|
|
@@ -781,15 +787,15 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
781
787
|
]
|
|
782
788
|
}
|
|
783
789
|
),
|
|
784
|
-
|
|
790
|
+
p && /* @__PURE__ */ _(
|
|
785
791
|
"div",
|
|
786
792
|
{
|
|
787
793
|
"data-testid": "meme-preview",
|
|
788
794
|
className: "fixed z-50 flex flex-col gap-1 rounded border border-border-light bg-bg-card p-1.5 shadow-2xl",
|
|
789
795
|
style: {
|
|
790
|
-
left:
|
|
791
|
-
top:
|
|
792
|
-
width:
|
|
796
|
+
left: p.left,
|
|
797
|
+
top: p.top,
|
|
798
|
+
width: ze,
|
|
793
799
|
/* The placement maths reserves exactly PREVIEW_PX of width.
|
|
794
800
|
Without border-box the padding and border sit OUTSIDE that
|
|
795
801
|
number and the box laps over the panel it is meant to sit
|
|
@@ -803,15 +809,15 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
803
809
|
/* @__PURE__ */ c(
|
|
804
810
|
"img",
|
|
805
811
|
{
|
|
806
|
-
src:
|
|
812
|
+
src: Ne(p.item.key) ?? void 0,
|
|
807
813
|
alt: "",
|
|
808
814
|
className: "block w-full rounded bg-bg object-contain",
|
|
809
|
-
style: { height: "auto", maxHeight:
|
|
815
|
+
style: { height: "auto", maxHeight: dn }
|
|
810
816
|
}
|
|
811
817
|
),
|
|
812
|
-
|
|
818
|
+
p.item.title && /* One line. A long title must not change the box height, because
|
|
813
819
|
the box height is what the placement maths clamped against. */
|
|
814
|
-
/* @__PURE__ */ c("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap text-center text-[10px] text-text-secondary", children:
|
|
820
|
+
/* @__PURE__ */ c("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap text-center text-[10px] text-text-secondary", children: p.item.title })
|
|
815
821
|
]
|
|
816
822
|
}
|
|
817
823
|
)
|
|
@@ -819,42 +825,42 @@ function Br({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
819
825
|
}
|
|
820
826
|
);
|
|
821
827
|
}
|
|
822
|
-
function
|
|
823
|
-
return e ? /* @__PURE__ */ c(
|
|
828
|
+
function zr({ open: e, ...t }) {
|
|
829
|
+
return e ? /* @__PURE__ */ c(Yr, { ...t }) : null;
|
|
824
830
|
}
|
|
825
|
-
const
|
|
826
|
-
serverOrigin: `http://localhost:${
|
|
831
|
+
const st = {
|
|
832
|
+
serverOrigin: `http://localhost:${nt}`,
|
|
827
833
|
defaultRoomKey: "dev-room",
|
|
828
|
-
cdnBase:
|
|
834
|
+
cdnBase: Kt
|
|
829
835
|
};
|
|
830
|
-
let
|
|
831
|
-
function
|
|
836
|
+
let Te = { ...st };
|
|
837
|
+
function Xr(e) {
|
|
832
838
|
const t = Object.fromEntries(
|
|
833
839
|
Object.entries(e).filter(([n, r]) => r !== void 0)
|
|
834
840
|
);
|
|
835
|
-
|
|
841
|
+
Te = { ...Te, ...t }, Mr({ cdnBase: Te.cdnBase });
|
|
836
842
|
}
|
|
837
|
-
function
|
|
838
|
-
return
|
|
843
|
+
function fe() {
|
|
844
|
+
return Te;
|
|
839
845
|
}
|
|
840
|
-
const
|
|
841
|
-
function
|
|
846
|
+
const Jr = qt(st);
|
|
847
|
+
function Zr(e) {
|
|
842
848
|
return e.serverOrigin?.replace(/\/$/, "") || "";
|
|
843
849
|
}
|
|
844
|
-
function
|
|
845
|
-
return
|
|
850
|
+
function mn() {
|
|
851
|
+
return Zr(fe());
|
|
846
852
|
}
|
|
847
|
-
const
|
|
848
|
-
function
|
|
849
|
-
return
|
|
853
|
+
const fn = qt(null);
|
|
854
|
+
function Qr() {
|
|
855
|
+
return Dn(fn);
|
|
850
856
|
}
|
|
851
|
-
const
|
|
857
|
+
const ne = {
|
|
852
858
|
ANON_KEY: "watchparty_preferences",
|
|
853
859
|
DEBUG_FLAG: "wp:debug",
|
|
854
860
|
REPORT_LOGS_FLAG: "wp:reportLogs",
|
|
855
861
|
voteKey: (e, t, n) => `watchparty_vote:${e}:${t}:${n}`
|
|
856
862
|
};
|
|
857
|
-
function
|
|
863
|
+
function Ue() {
|
|
858
864
|
try {
|
|
859
865
|
return globalThis.localStorage ?? null;
|
|
860
866
|
} catch {
|
|
@@ -863,22 +869,22 @@ function je() {
|
|
|
863
869
|
}
|
|
864
870
|
function B(e) {
|
|
865
871
|
try {
|
|
866
|
-
return
|
|
872
|
+
return Ue()?.getItem(e) ?? null;
|
|
867
873
|
} catch {
|
|
868
874
|
return null;
|
|
869
875
|
}
|
|
870
876
|
}
|
|
871
|
-
function
|
|
877
|
+
function lt(e, t) {
|
|
872
878
|
try {
|
|
873
|
-
const n =
|
|
879
|
+
const n = Ue();
|
|
874
880
|
return n ? (n.setItem(e, t), !0) : !1;
|
|
875
881
|
} catch {
|
|
876
882
|
return !1;
|
|
877
883
|
}
|
|
878
884
|
}
|
|
879
|
-
function
|
|
885
|
+
function eo() {
|
|
880
886
|
try {
|
|
881
|
-
const e =
|
|
887
|
+
const e = Ue();
|
|
882
888
|
if (!e) return [];
|
|
883
889
|
const t = [];
|
|
884
890
|
for (let n = 0; n < e.length; n++) {
|
|
@@ -890,51 +896,51 @@ function Yr() {
|
|
|
890
896
|
return [];
|
|
891
897
|
}
|
|
892
898
|
}
|
|
893
|
-
function
|
|
899
|
+
function Re(e) {
|
|
894
900
|
try {
|
|
895
|
-
|
|
901
|
+
Ue()?.removeItem(e);
|
|
896
902
|
} catch {
|
|
897
903
|
}
|
|
898
904
|
}
|
|
899
|
-
function
|
|
905
|
+
function to(e) {
|
|
900
906
|
const t = B(e);
|
|
901
907
|
return t === null ? null : t === "true" ? !0 : t === "false" ? !1 : null;
|
|
902
908
|
}
|
|
903
|
-
const
|
|
904
|
-
let
|
|
905
|
-
function
|
|
906
|
-
|
|
909
|
+
const pn = /* @__PURE__ */ new Map();
|
|
910
|
+
let hn = !1;
|
|
911
|
+
function Fe(e, t) {
|
|
912
|
+
pn.set(e, t), hn && gn(e, t);
|
|
907
913
|
}
|
|
908
|
-
function
|
|
909
|
-
|
|
910
|
-
for (const [e, t] of
|
|
914
|
+
function no() {
|
|
915
|
+
hn = !0;
|
|
916
|
+
for (const [e, t] of pn) gn(e, t);
|
|
911
917
|
}
|
|
912
|
-
function
|
|
918
|
+
function gn(e, t) {
|
|
913
919
|
typeof window > "u" || (window[e] = t);
|
|
914
920
|
}
|
|
915
|
-
const
|
|
916
|
-
let
|
|
917
|
-
const
|
|
918
|
-
let
|
|
919
|
-
function
|
|
920
|
-
|
|
921
|
+
const se = [], ro = 500;
|
|
922
|
+
let Ae = [], Xe = null;
|
|
923
|
+
const oo = 1e3, ao = 200;
|
|
924
|
+
let Je = null;
|
|
925
|
+
function yn(e) {
|
|
926
|
+
Je = e;
|
|
921
927
|
}
|
|
922
|
-
function
|
|
923
|
-
return B(
|
|
928
|
+
function bn() {
|
|
929
|
+
return B(ne.REPORT_LOGS_FLAG) === "true";
|
|
924
930
|
}
|
|
925
|
-
function
|
|
931
|
+
function io() {
|
|
926
932
|
if (typeof window > "u") return !1;
|
|
927
933
|
if (window.__WP_DEBUG__ || new URLSearchParams(window.location.search).get("debug") === "true") return !0;
|
|
928
|
-
const t = B(
|
|
934
|
+
const t = B(ne.DEBUG_FLAG);
|
|
929
935
|
return t !== null && t !== "false";
|
|
930
936
|
}
|
|
931
|
-
function
|
|
932
|
-
const e = B(
|
|
937
|
+
function so() {
|
|
938
|
+
const e = B(ne.DEBUG_FLAG);
|
|
933
939
|
if (!e || e === "true") return null;
|
|
934
940
|
const t = e.split(",").map((n) => n.trim().toLowerCase()).filter(Boolean);
|
|
935
941
|
return t.length > 0 ? new Set(t) : null;
|
|
936
942
|
}
|
|
937
|
-
function
|
|
943
|
+
function lo() {
|
|
938
944
|
return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
|
|
939
945
|
hour12: !1,
|
|
940
946
|
hour: "2-digit",
|
|
@@ -943,24 +949,24 @@ function no() {
|
|
|
943
949
|
fractionalSecondDigits: 3
|
|
944
950
|
});
|
|
945
951
|
}
|
|
946
|
-
function
|
|
947
|
-
|
|
952
|
+
function co(e) {
|
|
953
|
+
se.push(e), se.length > ro && se.shift();
|
|
948
954
|
}
|
|
949
|
-
const
|
|
955
|
+
const He = {
|
|
950
956
|
debug: "color: #64748b; font-weight: normal;",
|
|
951
957
|
warn: "color: #f59e0b; font-weight: bold;",
|
|
952
958
|
error: "color: #ef4444; font-weight: bold;",
|
|
953
959
|
category: "color: #3b82f6; font-weight: bold;",
|
|
954
960
|
time: "color: #6b7280; font-weight: normal;"
|
|
955
961
|
};
|
|
956
|
-
function
|
|
962
|
+
function uo(e) {
|
|
957
963
|
try {
|
|
958
964
|
return JSON.stringify(e);
|
|
959
965
|
} catch {
|
|
960
966
|
return "[unserializable]";
|
|
961
967
|
}
|
|
962
968
|
}
|
|
963
|
-
function
|
|
969
|
+
function ct(e, t, n, r, a, i, s) {
|
|
964
970
|
const l = {
|
|
965
971
|
level: e,
|
|
966
972
|
category: a,
|
|
@@ -968,47 +974,47 @@ function at(e, t, n, r, a, i, s) {
|
|
|
968
974
|
data: s,
|
|
969
975
|
timestamp: Date.now()
|
|
970
976
|
};
|
|
971
|
-
if (
|
|
972
|
-
if (!
|
|
973
|
-
const f =
|
|
977
|
+
if (co(l), (n || bn()) && xt(l), !r) {
|
|
978
|
+
if (!io()) return;
|
|
979
|
+
const f = so();
|
|
974
980
|
if (f && !f.has(a.toLowerCase())) return;
|
|
975
981
|
}
|
|
976
|
-
const
|
|
982
|
+
const u = lo(), h = s !== void 0 ? " " + uo(s) : "";
|
|
977
983
|
t(
|
|
978
|
-
`%c[${
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
984
|
+
`%c[${u}]%c [${a}]%c ${i}${h}`,
|
|
985
|
+
He.time,
|
|
986
|
+
He.category,
|
|
987
|
+
He[e]
|
|
982
988
|
);
|
|
983
989
|
}
|
|
984
990
|
function d(e, t, n) {
|
|
985
|
-
|
|
991
|
+
ct("debug", console.log, !1, !1, e, t, n);
|
|
986
992
|
}
|
|
987
993
|
function A(e, t, n) {
|
|
988
|
-
|
|
994
|
+
ct("warn", console.warn, !0, !1, e, t, n);
|
|
989
995
|
}
|
|
990
|
-
function
|
|
991
|
-
|
|
996
|
+
function Ee(e, t, n) {
|
|
997
|
+
ct("error", console.error, !0, !0, e, t, n);
|
|
992
998
|
}
|
|
993
|
-
function
|
|
994
|
-
return [...
|
|
999
|
+
function mo() {
|
|
1000
|
+
return [...se];
|
|
995
1001
|
}
|
|
996
|
-
function
|
|
997
|
-
|
|
1002
|
+
function fo() {
|
|
1003
|
+
se.length = 0;
|
|
998
1004
|
}
|
|
999
|
-
function
|
|
1005
|
+
function po(e) {
|
|
1000
1006
|
const t = e && e.length > 0 ? e.join(",") : "true";
|
|
1001
|
-
|
|
1007
|
+
lt(ne.DEBUG_FLAG, t), console.log("[wp] Debug mode enabled");
|
|
1002
1008
|
}
|
|
1003
|
-
function
|
|
1004
|
-
|
|
1009
|
+
function ho() {
|
|
1010
|
+
Re(ne.DEBUG_FLAG), console.log("[wp] Debug mode disabled");
|
|
1005
1011
|
}
|
|
1006
|
-
const
|
|
1007
|
-
function
|
|
1012
|
+
const go = 1024, yo = 5e4;
|
|
1013
|
+
function bo(e) {
|
|
1008
1014
|
if (e == null) return e;
|
|
1009
1015
|
try {
|
|
1010
1016
|
const t = JSON.stringify(e);
|
|
1011
|
-
if (t.length <=
|
|
1017
|
+
if (t.length <= go) return e;
|
|
1012
1018
|
if (typeof e == "object" && !Array.isArray(e)) {
|
|
1013
1019
|
const n = {};
|
|
1014
1020
|
for (const [r, a] of Object.entries(e)) {
|
|
@@ -1022,35 +1028,35 @@ function mo(e) {
|
|
|
1022
1028
|
return "[unserializable]";
|
|
1023
1029
|
}
|
|
1024
1030
|
}
|
|
1025
|
-
async function
|
|
1026
|
-
if (
|
|
1027
|
-
const e =
|
|
1028
|
-
|
|
1031
|
+
async function vo() {
|
|
1032
|
+
if (Ae.length === 0) return;
|
|
1033
|
+
const e = Ae;
|
|
1034
|
+
Ae = [], Xe = null;
|
|
1029
1035
|
try {
|
|
1030
|
-
let n =
|
|
1036
|
+
let n = fe().serverOrigin || "";
|
|
1031
1037
|
if ((n === "/" || !n) && typeof window < "u") {
|
|
1032
1038
|
const l = window.location;
|
|
1033
|
-
(l.hostname === "localhost" || l.hostname === "127.0.0.1") && l.port === String(
|
|
1039
|
+
(l.hostname === "localhost" || l.hostname === "127.0.0.1") && l.port === String(Yt) ? n = `${l.protocol}//${l.hostname}:${nt}` : n = l.origin;
|
|
1034
1040
|
}
|
|
1035
1041
|
const r = `${n.replace(/\/$/, "")}/api/client-log`, a = e.map((l) => ({
|
|
1036
1042
|
level: l.level,
|
|
1037
1043
|
category: l.category,
|
|
1038
1044
|
message: l.message,
|
|
1039
|
-
data:
|
|
1045
|
+
data: bo(l.data),
|
|
1040
1046
|
timestamp: l.timestamp,
|
|
1041
1047
|
url: typeof window < "u" ? window.location.href : void 0,
|
|
1042
1048
|
userAgent: typeof navigator < "u" ? navigator.userAgent : void 0,
|
|
1043
|
-
room_key:
|
|
1044
|
-
client_id:
|
|
1049
|
+
room_key: Je?.room_key,
|
|
1050
|
+
client_id: Je?.client_id
|
|
1045
1051
|
}));
|
|
1046
1052
|
let i = [], s = 0;
|
|
1047
1053
|
for (const l of a) {
|
|
1048
|
-
const
|
|
1049
|
-
s +
|
|
1054
|
+
const u = JSON.stringify(l).length + 1;
|
|
1055
|
+
s + u > yo && i.length > 0 && (await fetch(r, {
|
|
1050
1056
|
method: "POST",
|
|
1051
1057
|
headers: { "Content-Type": "application/json" },
|
|
1052
1058
|
body: JSON.stringify({ logs: i })
|
|
1053
|
-
}), i = [], s = 0), i.push(l), s +=
|
|
1059
|
+
}), i = [], s = 0), i.push(l), s += u;
|
|
1054
1060
|
}
|
|
1055
1061
|
i.length > 0 && await fetch(r, {
|
|
1056
1062
|
method: "POST",
|
|
@@ -1058,70 +1064,70 @@ async function fo() {
|
|
|
1058
1064
|
body: JSON.stringify({ logs: i })
|
|
1059
1065
|
});
|
|
1060
1066
|
} catch (t) {
|
|
1061
|
-
console.warn("[wp] log flush failed (client logs may be lost):",
|
|
1067
|
+
console.warn("[wp] log flush failed (client logs may be lost):", pe(t).error);
|
|
1062
1068
|
}
|
|
1063
1069
|
}
|
|
1064
|
-
function
|
|
1065
|
-
if (
|
|
1066
|
-
const t =
|
|
1067
|
-
|
|
1068
|
-
|
|
1070
|
+
function xt(e) {
|
|
1071
|
+
if (Ae.push(e), !Xe) {
|
|
1072
|
+
const t = bn() ? ao : oo;
|
|
1073
|
+
Xe = setTimeout(() => {
|
|
1074
|
+
vo();
|
|
1069
1075
|
}, t);
|
|
1070
1076
|
}
|
|
1071
1077
|
}
|
|
1072
|
-
function
|
|
1078
|
+
function pe(e) {
|
|
1073
1079
|
return e instanceof Error ? { error: e.message, name: e.name } : { error: String(e), name: typeof e };
|
|
1074
1080
|
}
|
|
1075
|
-
|
|
1076
|
-
enable:
|
|
1077
|
-
disable:
|
|
1078
|
-
history:
|
|
1079
|
-
clear:
|
|
1081
|
+
Fe("__wpDebug", {
|
|
1082
|
+
enable: po,
|
|
1083
|
+
disable: ho,
|
|
1084
|
+
history: mo,
|
|
1085
|
+
clear: fo
|
|
1080
1086
|
});
|
|
1081
1087
|
const Y = {
|
|
1082
1088
|
resolved: !1,
|
|
1083
1089
|
userType: "public",
|
|
1084
1090
|
accountId: null
|
|
1085
1091
|
};
|
|
1086
|
-
function
|
|
1092
|
+
function dt() {
|
|
1087
1093
|
return Y.accountId ? Y.accountId : Y.resolved && Y.userType === "public" ? "anon" : null;
|
|
1088
1094
|
}
|
|
1089
|
-
function
|
|
1095
|
+
function So(e) {
|
|
1090
1096
|
Y.resolved = !0, e.userType && (Y.userType = e.userType), e.userId !== void 0 && (Y.accountId = e.userId && e.userId !== "public" ? e.userId : null);
|
|
1091
1097
|
}
|
|
1092
|
-
function
|
|
1098
|
+
function ut() {
|
|
1093
1099
|
return Y.accountId ?? "public";
|
|
1094
1100
|
}
|
|
1095
|
-
function
|
|
1096
|
-
return
|
|
1101
|
+
function _o() {
|
|
1102
|
+
return dt() ?? "unscoped";
|
|
1097
1103
|
}
|
|
1098
|
-
function
|
|
1099
|
-
return
|
|
1104
|
+
function vn(e) {
|
|
1105
|
+
return at(e) ? gr[e] : "var(--color-neutral-bg)";
|
|
1100
1106
|
}
|
|
1101
|
-
function
|
|
1102
|
-
return
|
|
1107
|
+
function wo(e) {
|
|
1108
|
+
return at(e) ? `${fe().serverOrigin.replace(/\/$/, "")}${br(e)}` : void 0;
|
|
1103
1109
|
}
|
|
1104
|
-
let
|
|
1105
|
-
function
|
|
1106
|
-
return
|
|
1110
|
+
let de = null, Se = null;
|
|
1111
|
+
function xo() {
|
|
1112
|
+
return de ? Promise.resolve() : Se || (Se = (async () => {
|
|
1107
1113
|
try {
|
|
1108
|
-
const e =
|
|
1114
|
+
const e = fe().serverOrigin.replace(/\/$/, ""), t = await fetch(`${e}/media/sprites/names.json`, { cache: "no-cache" });
|
|
1109
1115
|
if (!t.ok) return;
|
|
1110
1116
|
const n = await t.json();
|
|
1111
|
-
|
|
1117
|
+
de = n, Fe("__DISPLAY_NAMES__", n), d("characters", "Loaded display names", n);
|
|
1112
1118
|
} catch (e) {
|
|
1113
|
-
d("characters", "display names fetch failed (degrading to sprite IDs)",
|
|
1119
|
+
d("characters", "display names fetch failed (degrading to sprite IDs)", pe(e));
|
|
1114
1120
|
}
|
|
1115
|
-
})(),
|
|
1121
|
+
})(), Se);
|
|
1116
1122
|
}
|
|
1117
|
-
function
|
|
1118
|
-
return
|
|
1123
|
+
function ue(e) {
|
|
1124
|
+
return de?.[e] || e.charAt(0).toUpperCase() + e.slice(1);
|
|
1119
1125
|
}
|
|
1120
1126
|
function J(e) {
|
|
1121
1127
|
const t = e.toLowerCase();
|
|
1122
|
-
return
|
|
1128
|
+
return Le.some((n) => n === t) ? !0 : de ? Object.values(de).some((n) => n.toLowerCase() === t) : !1;
|
|
1123
1129
|
}
|
|
1124
|
-
const
|
|
1130
|
+
const Io = o.object({
|
|
1125
1131
|
// Identity. There is deliberately NO `name`: a person's name is their
|
|
1126
1132
|
// hadoku key-registry name, resolved by the server from whoami and renamed
|
|
1127
1133
|
// through hadoku_site's POST /session/name (operator decision 2026-10-08).
|
|
@@ -1146,19 +1152,19 @@ const bo = o.object({
|
|
|
1146
1152
|
preferredAudioLang: o.string().optional(),
|
|
1147
1153
|
subtitlesEnabled: o.boolean().optional(),
|
|
1148
1154
|
subtitleStyle: o.string().optional()
|
|
1149
|
-
}),
|
|
1155
|
+
}), le = Kn({
|
|
1150
1156
|
appId: "watchparty",
|
|
1151
|
-
schema:
|
|
1152
|
-
}),
|
|
1153
|
-
function
|
|
1154
|
-
const t =
|
|
1157
|
+
schema: Io
|
|
1158
|
+
}), Co = /* @__PURE__ */ new Set(["theme", "themeMode"]);
|
|
1159
|
+
function De(e) {
|
|
1160
|
+
const t = dt();
|
|
1155
1161
|
return t ? `prefs-cache:${t}:${e}` : null;
|
|
1156
1162
|
}
|
|
1157
|
-
function
|
|
1158
|
-
return
|
|
1163
|
+
function To() {
|
|
1164
|
+
return dt() === null;
|
|
1159
1165
|
}
|
|
1160
|
-
function
|
|
1161
|
-
const t =
|
|
1166
|
+
function It(e) {
|
|
1167
|
+
const t = De(e);
|
|
1162
1168
|
if (!t) return {};
|
|
1163
1169
|
const n = B(t);
|
|
1164
1170
|
if (!n) return {};
|
|
@@ -1168,10 +1174,10 @@ function St(e) {
|
|
|
1168
1174
|
return {};
|
|
1169
1175
|
}
|
|
1170
1176
|
}
|
|
1171
|
-
function
|
|
1177
|
+
function Ao() {
|
|
1172
1178
|
let e = 0;
|
|
1173
|
-
for (const t of
|
|
1174
|
-
const n = t.startsWith("prefs-cache:") && t.endsWith(":watchparty"), r = t ===
|
|
1179
|
+
for (const t of eo()) {
|
|
1180
|
+
const n = t.startsWith("prefs-cache:") && t.endsWith(":watchparty"), r = t === Oe || t.startsWith(`${Oe}:`) && !t.endsWith(":_serverSynced_v1");
|
|
1175
1181
|
if (!n && !r) continue;
|
|
1176
1182
|
const a = B(t);
|
|
1177
1183
|
if (!a) continue;
|
|
@@ -1183,18 +1189,18 @@ function _o() {
|
|
|
1183
1189
|
}
|
|
1184
1190
|
const s = n ? i?.blob : i;
|
|
1185
1191
|
if (!s || typeof s != "object" || !("name" in s)) continue;
|
|
1186
|
-
const { name: l, ...
|
|
1187
|
-
|
|
1192
|
+
const { name: l, ...u } = s, h = n ? { ...i, blob: u } : u;
|
|
1193
|
+
lt(t, JSON.stringify(h)) && e++;
|
|
1188
1194
|
}
|
|
1189
1195
|
return e > 0 && d("preferences", "Stripped retired name from cached prefs rows", { rewritten: e }), e;
|
|
1190
1196
|
}
|
|
1191
|
-
let
|
|
1192
|
-
const
|
|
1193
|
-
function
|
|
1194
|
-
if (
|
|
1197
|
+
let Sn = null, _n = null;
|
|
1198
|
+
const Ct = /* @__PURE__ */ new Set();
|
|
1199
|
+
function mt() {
|
|
1200
|
+
if (To())
|
|
1195
1201
|
return d("preferences", "Boot read deferred — session pending, identity unresolved"), {};
|
|
1196
|
-
const e =
|
|
1197
|
-
if (
|
|
1202
|
+
const e = It("portfolio"), t = It("watchparty"), n = Object.keys(e).length > 0 ? e : Sn ?? {}, r = Object.keys(t).length > 0 ? t : _n ?? {}, a = ut() || "public";
|
|
1203
|
+
if (Ct.has(a))
|
|
1198
1204
|
return d("preferences", "Loaded (sync, SDK-only after first read)", {
|
|
1199
1205
|
uid: a,
|
|
1200
1206
|
sdkThemeKeys: Object.keys(n).length,
|
|
@@ -1204,8 +1210,8 @@ function lt() {
|
|
|
1204
1210
|
themeSource: Object.keys(e).length > 0 ? "cache" : "mem",
|
|
1205
1211
|
appSource: Object.keys(t).length > 0 ? "cache" : "mem"
|
|
1206
1212
|
}), { ...r, ...n };
|
|
1207
|
-
|
|
1208
|
-
const i =
|
|
1213
|
+
Ct.add(a);
|
|
1214
|
+
const i = xn() ?? {}, s = { ...i, ...r, ...n };
|
|
1209
1215
|
return d("preferences", "Loaded (sync, first read — legacy + SDK)", {
|
|
1210
1216
|
uid: a,
|
|
1211
1217
|
sdkThemeKeys: Object.keys(n).length,
|
|
@@ -1215,60 +1221,60 @@ function lt() {
|
|
|
1215
1221
|
appSource: Object.keys(t).length > 0 ? "cache" : "mem"
|
|
1216
1222
|
}), s;
|
|
1217
1223
|
}
|
|
1218
|
-
let
|
|
1219
|
-
function
|
|
1220
|
-
const e =
|
|
1224
|
+
let wn = !1;
|
|
1225
|
+
function Eo() {
|
|
1226
|
+
const e = ut();
|
|
1221
1227
|
return !e || e === "public";
|
|
1222
1228
|
}
|
|
1223
1229
|
function G(e, t) {
|
|
1224
|
-
|
|
1230
|
+
Eo() && (wn = !0), Co.has(e) ? ie.save({ [e]: t }, { scope: "device" }).catch((n) => A("preferences", "themePrefs.save failed", { key: e, err: n?.message })) : le.save({ [e]: t }).catch((n) => A("preferences", "watchpartyPrefs.save failed", { key: e, err: n?.message })), d("preferences", "Saved (via SDK)", { key: e, value: t });
|
|
1225
1231
|
}
|
|
1226
|
-
let
|
|
1227
|
-
function
|
|
1228
|
-
return
|
|
1232
|
+
let _e = null, Tt = !1;
|
|
1233
|
+
function ko() {
|
|
1234
|
+
return _e || (_e = (async () => {
|
|
1229
1235
|
if (typeof window > "u") return !1;
|
|
1230
1236
|
try {
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}),
|
|
1234
|
-
|
|
1237
|
+
Tt || (Tt = !0, ie.subscribe((s) => {
|
|
1238
|
+
Sn = s, kt("portfolio", s), Pt("theme");
|
|
1239
|
+
}), le.subscribe((s) => {
|
|
1240
|
+
_n = s, kt("watchparty", s), Pt("watchparty");
|
|
1235
1241
|
}));
|
|
1236
1242
|
const [e, t] = await Promise.all([
|
|
1237
|
-
|
|
1238
|
-
|
|
1243
|
+
ie.read(),
|
|
1244
|
+
le.read()
|
|
1239
1245
|
]);
|
|
1240
1246
|
try {
|
|
1241
|
-
const { useAppStore: s } = await Promise.resolve().then(() =>
|
|
1247
|
+
const { useAppStore: s } = await Promise.resolve().then(() => Cn);
|
|
1242
1248
|
s.getState().rehydrateFromPrefs();
|
|
1243
1249
|
} catch (s) {
|
|
1244
1250
|
A("preferences", "inline rehydrate after SDK read failed", { err: s?.message });
|
|
1245
1251
|
}
|
|
1246
|
-
const n =
|
|
1252
|
+
const n = De("portfolio"), r = De("watchparty"), a = n ? B(n) : null, i = r ? B(r) : null;
|
|
1247
1253
|
return d("preferences", "sdk.read", {
|
|
1248
1254
|
themeKeys: Object.keys(e ?? {}),
|
|
1249
1255
|
appKeys: Object.keys(t ?? {}),
|
|
1250
1256
|
// Post-fetch cache state: should be non-zero if SDK wrote it.
|
|
1251
1257
|
sdkThemeBytesPost: a?.length ?? 0,
|
|
1252
1258
|
sdkAppBytesPost: i?.length ?? 0
|
|
1253
|
-
}), await
|
|
1254
|
-
|
|
1259
|
+
}), await Po(e, t), wn ? (d("preferences", "Promoting this load's pre-auth picks to the signed-in user"), await Promise.all([
|
|
1260
|
+
ie.promoteAnonPrefsToUser().catch(() => {
|
|
1255
1261
|
}),
|
|
1256
|
-
|
|
1262
|
+
le.promoteAnonPrefsToUser().catch(() => {
|
|
1257
1263
|
})
|
|
1258
1264
|
])) : d("preferences", "Skipping anon promotion — no pre-auth writes this load"), d("preferences", "First-load SDK sync complete"), !0;
|
|
1259
1265
|
} catch (e) {
|
|
1260
1266
|
return A("preferences", "First-load SDK sync failed (non-fatal)", { err: e?.message }), !1;
|
|
1261
1267
|
}
|
|
1262
|
-
})(),
|
|
1268
|
+
})(), _e);
|
|
1263
1269
|
}
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
function
|
|
1267
|
-
const e =
|
|
1268
|
-
return !e || e === "public" ?
|
|
1270
|
+
const Oe = "watchparty_preferences";
|
|
1271
|
+
Ao();
|
|
1272
|
+
function Ze() {
|
|
1273
|
+
const e = ut();
|
|
1274
|
+
return !e || e === "public" ? Oe : `${Oe}:${e}`;
|
|
1269
1275
|
}
|
|
1270
|
-
function
|
|
1271
|
-
const e = B(
|
|
1276
|
+
function xn() {
|
|
1277
|
+
const e = B(Ze());
|
|
1272
1278
|
if (!e) return null;
|
|
1273
1279
|
try {
|
|
1274
1280
|
const t = JSON.parse(e);
|
|
@@ -1277,40 +1283,40 @@ function vn() {
|
|
|
1277
1283
|
return null;
|
|
1278
1284
|
}
|
|
1279
1285
|
}
|
|
1280
|
-
function
|
|
1281
|
-
|
|
1286
|
+
function At() {
|
|
1287
|
+
Re(Ze()), Re(`${Ze()}:_serverSynced_v1`);
|
|
1282
1288
|
}
|
|
1283
|
-
async function
|
|
1284
|
-
const n =
|
|
1289
|
+
async function Po(e, t) {
|
|
1290
|
+
const n = xn();
|
|
1285
1291
|
if (!n || Object.keys(n).length === 0) return;
|
|
1286
1292
|
const r = Object.keys(e ?? {}).length > 0, a = Object.keys(t ?? {}).length > 0, i = {}, s = {};
|
|
1287
1293
|
for (const [h, f] of Object.entries(n))
|
|
1288
1294
|
r || (h === "theme" && typeof f == "string" ? i.theme = f : h === "themeMode" && (f === "simple" || f === "advanced") && (i.themeMode = f)), a || (h === "chatCollapsed" && typeof f == "boolean" ? s.chatCollapsed = f : h === "floatingChatEnabled" && typeof f == "boolean" ? s.floatingChatEnabled = f : h === "volume" && typeof f == "number" && f >= 0 && f <= 1 ? s.volume = f : h === "muted" && typeof f == "boolean" ? s.muted = f : h === "preferredAudioLang" && typeof f == "string" ? s.preferredAudioLang = f : h === "subtitlesEnabled" && typeof f == "boolean" ? s.subtitlesEnabled = f : h === "subtitleStyle" && typeof f == "string" && (s.subtitleStyle = f));
|
|
1289
|
-
const l = Object.keys(i),
|
|
1290
|
-
if (l.length === 0 &&
|
|
1291
|
-
|
|
1295
|
+
const l = Object.keys(i), u = Object.keys(s);
|
|
1296
|
+
if (l.length === 0 && u.length === 0) {
|
|
1297
|
+
At();
|
|
1292
1298
|
return;
|
|
1293
1299
|
}
|
|
1294
1300
|
d("preferences", "Migrating legacy localStorage prefs to SDK", {
|
|
1295
1301
|
themeKeys: l,
|
|
1296
|
-
appKeys:
|
|
1302
|
+
appKeys: u,
|
|
1297
1303
|
sdkHasTheme: r,
|
|
1298
1304
|
sdkHasApp: a
|
|
1299
1305
|
});
|
|
1300
1306
|
try {
|
|
1301
1307
|
await Promise.all([
|
|
1302
|
-
l.length > 0 ?
|
|
1303
|
-
|
|
1304
|
-
]),
|
|
1308
|
+
l.length > 0 ? ie.save(i, { scope: "device" }) : Promise.resolve(),
|
|
1309
|
+
u.length > 0 ? le.save(s) : Promise.resolve()
|
|
1310
|
+
]), At(), d("preferences", "Legacy migration complete");
|
|
1305
1311
|
} catch (h) {
|
|
1306
1312
|
A("preferences", "Legacy migration save failed — will retry next load", {
|
|
1307
1313
|
err: h?.message
|
|
1308
1314
|
});
|
|
1309
1315
|
}
|
|
1310
1316
|
}
|
|
1311
|
-
let
|
|
1312
|
-
function
|
|
1313
|
-
const n =
|
|
1317
|
+
let Et = !1;
|
|
1318
|
+
function kt(e, t) {
|
|
1319
|
+
const n = De(e);
|
|
1314
1320
|
if (n)
|
|
1315
1321
|
try {
|
|
1316
1322
|
const r = {
|
|
@@ -1321,15 +1327,15 @@ function Ct(e, t) {
|
|
|
1321
1327
|
};
|
|
1322
1328
|
localStorage.setItem(n, JSON.stringify(r));
|
|
1323
1329
|
} catch (r) {
|
|
1324
|
-
|
|
1330
|
+
Et || (Et = !0, A("preferences", "writeThrough localStorage failed (in-memory backstop only)", {
|
|
1325
1331
|
appId: e,
|
|
1326
1332
|
err: r?.message,
|
|
1327
1333
|
name: r?.name
|
|
1328
1334
|
}));
|
|
1329
1335
|
}
|
|
1330
1336
|
}
|
|
1331
|
-
function
|
|
1332
|
-
Promise.resolve().then(() =>
|
|
1337
|
+
function Pt(e) {
|
|
1338
|
+
Promise.resolve().then(() => Cn).then(({ useAppStore: t }) => {
|
|
1333
1339
|
try {
|
|
1334
1340
|
t.getState().rehydrateFromPrefs();
|
|
1335
1341
|
} catch (n) {
|
|
@@ -1337,33 +1343,33 @@ function Tt(e) {
|
|
|
1337
1343
|
}
|
|
1338
1344
|
}).catch((t) => A("preferences", "store import failed", { reason: e, err: t?.message }));
|
|
1339
1345
|
}
|
|
1340
|
-
const
|
|
1346
|
+
const In = 320, Me = 240, ft = 640, No = 320, Ro = 36, Nt = 16;
|
|
1341
1347
|
function V(e, t) {
|
|
1342
|
-
if (!Number.isFinite(e)) return
|
|
1343
|
-
let n =
|
|
1344
|
-
return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t -
|
|
1348
|
+
if (!Number.isFinite(e)) return In;
|
|
1349
|
+
let n = ft;
|
|
1350
|
+
return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t - No)), n = Math.max(n, Me), Math.round(Math.min(n, Math.max(Me, e)));
|
|
1345
1351
|
}
|
|
1346
|
-
function
|
|
1352
|
+
function Rt(e, t, n, r) {
|
|
1347
1353
|
return V(e + (t - n), r);
|
|
1348
1354
|
}
|
|
1349
|
-
function
|
|
1355
|
+
function Do(e, t, n) {
|
|
1350
1356
|
switch (t) {
|
|
1351
1357
|
case "ArrowLeft":
|
|
1352
|
-
return V(e +
|
|
1358
|
+
return V(e + Nt, n);
|
|
1353
1359
|
case "ArrowRight":
|
|
1354
|
-
return V(e -
|
|
1360
|
+
return V(e - Nt, n);
|
|
1355
1361
|
case "Home":
|
|
1356
|
-
return V(
|
|
1362
|
+
return V(Me, n);
|
|
1357
1363
|
case "End":
|
|
1358
|
-
return V(
|
|
1364
|
+
return V(ft, n);
|
|
1359
1365
|
default:
|
|
1360
1366
|
return null;
|
|
1361
1367
|
}
|
|
1362
1368
|
}
|
|
1363
|
-
function
|
|
1364
|
-
return { collapsed: e, width: e ?
|
|
1369
|
+
function Oo(e, t) {
|
|
1370
|
+
return { collapsed: e, width: e ? Ro : t };
|
|
1365
1371
|
}
|
|
1366
|
-
const q =
|
|
1372
|
+
const q = mt(), m = Vn((e, t) => ({
|
|
1367
1373
|
ready: !1,
|
|
1368
1374
|
name: "",
|
|
1369
1375
|
sprite: null,
|
|
@@ -1373,7 +1379,7 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1373
1379
|
chat: [],
|
|
1374
1380
|
chatCollapsed: q.chatCollapsed ?? !1,
|
|
1375
1381
|
chromeChatCollapsed: q.chromeChatCollapsed ?? !1,
|
|
1376
|
-
chromeChatWidth: V(q.chromeChatWidth ??
|
|
1382
|
+
chromeChatWidth: V(q.chromeChatWidth ?? In),
|
|
1377
1383
|
// Hardcoded on for everyone — the per-user toggle was removed from the
|
|
1378
1384
|
// control bar; FloatingChat + toggleFloatingChat code is kept for future
|
|
1379
1385
|
// re-enablement but the value is no longer user-controllable.
|
|
@@ -1417,7 +1423,7 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1417
1423
|
ensureAutoIdentity: () => e((n) => {
|
|
1418
1424
|
if (n.name) return {};
|
|
1419
1425
|
if (n.sprite) {
|
|
1420
|
-
const a =
|
|
1426
|
+
const a = ue(n.sprite);
|
|
1421
1427
|
return d("store", "Auto-identity: deriving name from the requested sprite", { name: a, sprite: n.sprite }), { name: a };
|
|
1422
1428
|
}
|
|
1423
1429
|
const r = new Set(Object.values(n.roster).map((a) => a.sprite).filter(Boolean));
|
|
@@ -1425,9 +1431,9 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1425
1431
|
rosterSize: Object.keys(n.roster).length,
|
|
1426
1432
|
usedSprites: Array.from(r)
|
|
1427
1433
|
});
|
|
1428
|
-
for (const a of
|
|
1434
|
+
for (const a of Le)
|
|
1429
1435
|
if (!r.has(a)) {
|
|
1430
|
-
const i =
|
|
1436
|
+
const i = ue(a);
|
|
1431
1437
|
return d("store", "Auto-identity assigned", { name: i, sprite: a }), { name: i, sprite: a };
|
|
1432
1438
|
}
|
|
1433
1439
|
return A("store", "All characters taken, leaving identity unset"), {};
|
|
@@ -1438,7 +1444,7 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1438
1444
|
applySnapshot: (n) => e((r) => {
|
|
1439
1445
|
const a = { ...r.roster };
|
|
1440
1446
|
if (n.users)
|
|
1441
|
-
for (const
|
|
1447
|
+
for (const u of n.users) a[u.clientId] = u;
|
|
1442
1448
|
const i = n.mediaId !== void 0 ? n.mediaId : r.snapshot.mediaId, s = n.leaderId !== void 0 ? n.leaderId : r.snapshot.leaderId;
|
|
1443
1449
|
d("store", "Snapshot applied", {
|
|
1444
1450
|
mediaId: i,
|
|
@@ -1513,8 +1519,8 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1513
1519
|
const s = [...i.drift.rtts, n].slice(-5);
|
|
1514
1520
|
let l = i.drift.offsetMs;
|
|
1515
1521
|
if (r && a) {
|
|
1516
|
-
const
|
|
1517
|
-
l = r -
|
|
1522
|
+
const u = a + n / 2;
|
|
1523
|
+
l = r - u;
|
|
1518
1524
|
}
|
|
1519
1525
|
return { drift: { rtts: s, offsetMs: l } };
|
|
1520
1526
|
}),
|
|
@@ -1568,13 +1574,13 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1568
1574
|
*/
|
|
1569
1575
|
moveTierlistItem: (n, r, a) => e((i) => {
|
|
1570
1576
|
const s = {};
|
|
1571
|
-
for (const [l,
|
|
1572
|
-
const h = (
|
|
1577
|
+
for (const [l, u] of Object.entries(i.tierlistDraft)) {
|
|
1578
|
+
const h = (u ?? []).filter((f) => f !== n);
|
|
1573
1579
|
h.length > 0 && (s[l] = h);
|
|
1574
1580
|
}
|
|
1575
1581
|
if (r !== null) {
|
|
1576
|
-
const l = s[r] ?? [],
|
|
1577
|
-
l.splice(
|
|
1582
|
+
const l = s[r] ?? [], u = Math.max(0, Math.min(a ?? l.length, l.length));
|
|
1583
|
+
l.splice(u, 0, n), s[r] = l;
|
|
1578
1584
|
}
|
|
1579
1585
|
return { tierlistDraft: s };
|
|
1580
1586
|
}),
|
|
@@ -1583,7 +1589,7 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1583
1589
|
setGameSettings: (n) => e({ gameSettings: n }),
|
|
1584
1590
|
setRoomKeyType: (n) => e({ roomKeyType: n }),
|
|
1585
1591
|
rehydrateFromPrefs: () => e((n) => {
|
|
1586
|
-
const r =
|
|
1592
|
+
const r = mt(), a = {};
|
|
1587
1593
|
if (r.chatCollapsed !== void 0 && (a.chatCollapsed = r.chatCollapsed), r.chromeChatCollapsed !== void 0 && (a.chromeChatCollapsed = r.chromeChatCollapsed), r.chromeChatWidth !== void 0 && (a.chromeChatWidth = V(r.chromeChatWidth)), ["volume", "muted", "preferredAudioLang", "subtitlesEnabled", "subtitleStyle"].some((l) => r[l] !== void 0)) {
|
|
1588
1594
|
const l = { ...n.mediaPrefs };
|
|
1589
1595
|
r.volume !== void 0 && (l.volume = r.volume), r.muted !== void 0 && (l.muted = r.muted), r.preferredAudioLang !== void 0 && (l.preferredAudioLang = r.preferredAudioLang), r.subtitlesEnabled !== void 0 && (l.subtitlesEnabled = r.subtitlesEnabled), r.subtitleStyle !== void 0 && ["classic", "cinema", "minimal", "contrast"].includes(r.subtitleStyle) && (l.subtitleStyle = r.subtitleStyle), a.mediaPrefs = l;
|
|
@@ -1592,107 +1598,107 @@ const q = lt(), u = Fn((e, t) => ({
|
|
|
1592
1598
|
}),
|
|
1593
1599
|
setSidebarTab: (n) => e((r) => r.sidebarTab === n && n !== "chat" ? { sidebarTab: "chat" } : { sidebarTab: n, chatCollapsed: !1 })
|
|
1594
1600
|
}));
|
|
1595
|
-
|
|
1596
|
-
const
|
|
1601
|
+
Fe("__ZUSTAND_STORE__", m);
|
|
1602
|
+
const Cn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1597
1603
|
__proto__: null,
|
|
1598
|
-
useAppStore:
|
|
1604
|
+
useAppStore: m
|
|
1599
1605
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1600
|
-
function
|
|
1601
|
-
return `${
|
|
1606
|
+
function Mo(e) {
|
|
1607
|
+
return `${mn()}/media/${e}`.replace(/\\/g, "/");
|
|
1602
1608
|
}
|
|
1603
|
-
function
|
|
1604
|
-
return
|
|
1609
|
+
function Lo(e, t) {
|
|
1610
|
+
return Mo(t ?? `${e}/poster.jpg`);
|
|
1605
1611
|
}
|
|
1606
|
-
function
|
|
1607
|
-
return `${
|
|
1612
|
+
function jo(e) {
|
|
1613
|
+
return `${mn()}${e}`.replace(/\\/g, "/");
|
|
1608
1614
|
}
|
|
1609
|
-
async function
|
|
1615
|
+
async function Uo(e) {
|
|
1610
1616
|
try {
|
|
1611
|
-
const t = await fetch(
|
|
1617
|
+
const t = await fetch(jo("/api/tierlist"));
|
|
1612
1618
|
if (!t.ok)
|
|
1613
1619
|
return A("tierlist", "Board fetch failed", { status: t.status }), null;
|
|
1614
1620
|
const n = await t.json();
|
|
1615
|
-
return
|
|
1621
|
+
return m.getState().setTierlistSnapshot(n, e), d("tierlist", "Board loaded", {
|
|
1616
1622
|
items: n.items.length,
|
|
1617
1623
|
voters: n.voterCount,
|
|
1618
1624
|
placed: n.placed.length
|
|
1619
1625
|
}), n;
|
|
1620
1626
|
} catch (t) {
|
|
1621
|
-
return A("tierlist", "Board fetch threw",
|
|
1627
|
+
return A("tierlist", "Board fetch threw", pe(t)), null;
|
|
1622
1628
|
}
|
|
1623
1629
|
}
|
|
1624
|
-
let
|
|
1625
|
-
function
|
|
1626
|
-
if (
|
|
1627
|
-
const e =
|
|
1630
|
+
let Dt = !1;
|
|
1631
|
+
function Fo() {
|
|
1632
|
+
if (Dt || typeof Image > "u") return;
|
|
1633
|
+
const e = m.getState().tierlist;
|
|
1628
1634
|
if (!(!e || e.items.length === 0)) {
|
|
1629
|
-
|
|
1635
|
+
Dt = !0;
|
|
1630
1636
|
for (const t of e.items) {
|
|
1631
1637
|
const n = new Image();
|
|
1632
|
-
n.decoding = "async", n.src =
|
|
1638
|
+
n.decoding = "async", n.src = Lo(t.id, t.thumbnail);
|
|
1633
1639
|
}
|
|
1634
1640
|
d("tierlist", "Warming posters", { count: e.items.length });
|
|
1635
1641
|
}
|
|
1636
1642
|
}
|
|
1637
|
-
function
|
|
1638
|
-
const e =
|
|
1643
|
+
function Ho() {
|
|
1644
|
+
const e = m.getState(), t = new Set(Object.values(e.roster).map((i) => i.sprite).filter(Boolean)), n = Le.find((i) => !t.has(i));
|
|
1639
1645
|
if (!n)
|
|
1640
1646
|
return A("socket", "sprite_taken: no available sprites to retry with"), null;
|
|
1641
|
-
const r = !!e.name && !J(e.name), a = r ? e.name :
|
|
1647
|
+
const r = !!e.name && !J(e.name), a = r ? e.name : ue(n);
|
|
1642
1648
|
return d("socket", "sprite_taken: retrying with next available", { from: e.sprite, to: n, name: a, keptCustomName: r }), e.setSessionIdentity(a, n), { name: a, sprite: n };
|
|
1643
1649
|
}
|
|
1644
|
-
function
|
|
1645
|
-
const t =
|
|
1650
|
+
function $o(e) {
|
|
1651
|
+
const t = m.getState(), n = e ? t.roster[e] : void 0;
|
|
1646
1652
|
return !n || !!n.sprite && n.sprite === t.sprite;
|
|
1647
1653
|
}
|
|
1648
|
-
const
|
|
1649
|
-
function
|
|
1654
|
+
const Ot = "hadoku:avatar";
|
|
1655
|
+
function Tn(e) {
|
|
1650
1656
|
const t = e?.sprite ?? e?.avatar?.sprite ?? null;
|
|
1651
|
-
return
|
|
1657
|
+
return at(t) ? t : null;
|
|
1652
1658
|
}
|
|
1653
|
-
async function
|
|
1659
|
+
async function Bo(e = {}) {
|
|
1654
1660
|
const t = e.fetch ?? (typeof fetch > "u" ? void 0 : fetch), n = typeof window > "u" ? void 0 : window.location?.origin, r = e.baseUrl ?? (n ? `${n}/prefs` : void 0);
|
|
1655
1661
|
if (!t || !r) return null;
|
|
1656
1662
|
try {
|
|
1657
|
-
const a = await
|
|
1663
|
+
const a = await Xn({ baseUrl: r, fetch: t }).get(), i = Tn(a);
|
|
1658
1664
|
return d("avatar", "Requested character from prefs-api", { sprite: i }), i;
|
|
1659
1665
|
} catch (a) {
|
|
1660
|
-
return a instanceof
|
|
1661
|
-
status: a instanceof
|
|
1662
|
-
...
|
|
1666
|
+
return a instanceof vt && (a.status === 401 || a.status === 403 || a.status === 404) ? d("avatar", "No avatar settings here (signed out, or no prefs-api on this origin)", { status: a.status }) : A("avatar", "Avatar settings read failed — keeping the auto-assigned character", {
|
|
1667
|
+
status: a instanceof vt ? a.status : void 0,
|
|
1668
|
+
...pe(a)
|
|
1663
1669
|
}), null;
|
|
1664
1670
|
}
|
|
1665
1671
|
}
|
|
1666
|
-
function
|
|
1672
|
+
function Mt(e) {
|
|
1667
1673
|
if (!e) return !1;
|
|
1668
|
-
const t =
|
|
1674
|
+
const t = m.getState();
|
|
1669
1675
|
if (t.sprite === e) return !1;
|
|
1670
|
-
const r = !!(t.me.clientId && t.roster[t.me.clientId]?.registryName) || !t.name || !J(t.name) ? t.name :
|
|
1676
|
+
const r = !!(t.me.clientId && t.roster[t.me.clientId]?.registryName) || !t.name || !J(t.name) ? t.name : ue(e);
|
|
1671
1677
|
return t.setSessionIdentity(r, e), !0;
|
|
1672
1678
|
}
|
|
1673
|
-
function
|
|
1679
|
+
function Go(e, t = typeof window > "u" ? void 0 : window) {
|
|
1674
1680
|
if (!t) return () => {
|
|
1675
1681
|
};
|
|
1676
1682
|
const n = (r) => {
|
|
1677
1683
|
const a = r.detail;
|
|
1678
1684
|
!a || typeof a != "object" || e(a);
|
|
1679
1685
|
};
|
|
1680
|
-
return t.addEventListener(
|
|
1686
|
+
return t.addEventListener(Ot, n), () => t.removeEventListener(Ot, n);
|
|
1681
1687
|
}
|
|
1682
|
-
const
|
|
1683
|
-
function
|
|
1688
|
+
const qo = 10;
|
|
1689
|
+
function Vo(e = typeof window < "u" ? window : void 0) {
|
|
1684
1690
|
if (!e) return { framed: !1, depth: 0 };
|
|
1685
1691
|
try {
|
|
1686
1692
|
let t = 0, n = e;
|
|
1687
|
-
for (; n !== n.parent && t <
|
|
1693
|
+
for (; n !== n.parent && t < qo; )
|
|
1688
1694
|
t++, n = n.parent;
|
|
1689
1695
|
return { framed: e.top ? e.top !== e.self : t > 0, depth: t };
|
|
1690
1696
|
} catch {
|
|
1691
1697
|
return { framed: !1, depth: 0 };
|
|
1692
1698
|
}
|
|
1693
1699
|
}
|
|
1694
|
-
const
|
|
1695
|
-
function
|
|
1700
|
+
const Ko = "watchparty_fragment_delivery";
|
|
1701
|
+
function Wo() {
|
|
1696
1702
|
if (typeof window > "u") return null;
|
|
1697
1703
|
try {
|
|
1698
1704
|
const e = new URLSearchParams(window.location.search).get("fragmentDelivery");
|
|
@@ -1700,93 +1706,93 @@ function $o() {
|
|
|
1700
1706
|
if (e === "0" || e === "false") return !1;
|
|
1701
1707
|
} catch {
|
|
1702
1708
|
}
|
|
1703
|
-
return
|
|
1709
|
+
return to(Ko);
|
|
1704
1710
|
}
|
|
1705
|
-
let
|
|
1706
|
-
const
|
|
1707
|
-
function
|
|
1708
|
-
const e = B(
|
|
1711
|
+
let Yo = { ...nn }, $e = null;
|
|
1712
|
+
const Lt = "watchparty_delivery_client_id";
|
|
1713
|
+
function zo() {
|
|
1714
|
+
const e = B(Lt);
|
|
1709
1715
|
if (e) return e;
|
|
1710
1716
|
const t = globalThis.crypto?.randomUUID?.() ?? `d${Math.random().toString(36).slice(2)}`;
|
|
1711
|
-
return
|
|
1717
|
+
return lt(Lt, t) ? t : "";
|
|
1712
1718
|
}
|
|
1713
|
-
function
|
|
1714
|
-
return
|
|
1719
|
+
function Xo() {
|
|
1720
|
+
return $e === null && ($e = Ir(Yo, zo(), Wo())), $e;
|
|
1715
1721
|
}
|
|
1716
|
-
function
|
|
1717
|
-
return
|
|
1722
|
+
function Jo() {
|
|
1723
|
+
return Xo();
|
|
1718
1724
|
}
|
|
1719
1725
|
let ke;
|
|
1720
|
-
function
|
|
1721
|
-
return B(
|
|
1726
|
+
function An() {
|
|
1727
|
+
return B(Yn) || void 0;
|
|
1722
1728
|
}
|
|
1723
|
-
function
|
|
1729
|
+
function Zo() {
|
|
1724
1730
|
if (ke) return;
|
|
1725
|
-
const e =
|
|
1731
|
+
const e = An();
|
|
1726
1732
|
if (e) {
|
|
1727
1733
|
ke = e;
|
|
1728
1734
|
return;
|
|
1729
1735
|
}
|
|
1730
|
-
|
|
1736
|
+
Wn().then((t) => {
|
|
1731
1737
|
t && (ke = t);
|
|
1732
1738
|
}).catch(() => {
|
|
1733
1739
|
d("identity", "device id unavailable — joining without one");
|
|
1734
1740
|
});
|
|
1735
1741
|
}
|
|
1736
|
-
function
|
|
1737
|
-
return ke ??=
|
|
1742
|
+
function Qo() {
|
|
1743
|
+
return ke ??= An();
|
|
1738
1744
|
}
|
|
1739
|
-
function
|
|
1745
|
+
function ea(e, t) {
|
|
1740
1746
|
let n = 0;
|
|
1741
1747
|
for (const r of e.videos) {
|
|
1742
|
-
const a =
|
|
1743
|
-
globalThis.localStorage?.getItem(a) != null && n++,
|
|
1748
|
+
const a = ne.voteKey(t, e.id, r.mediaId);
|
|
1749
|
+
globalThis.localStorage?.getItem(a) != null && n++, Re(a);
|
|
1744
1750
|
}
|
|
1745
1751
|
return n;
|
|
1746
1752
|
}
|
|
1747
|
-
const
|
|
1748
|
-
function
|
|
1753
|
+
const ta = 2e4, na = 1e4;
|
|
1754
|
+
function ra() {
|
|
1749
1755
|
return { unansweredSince: null, lastPongAt: null, lastTickAt: null };
|
|
1750
1756
|
}
|
|
1751
|
-
function
|
|
1757
|
+
function oa(e, t) {
|
|
1752
1758
|
e.lastPongAt = t, e.unansweredSince = null;
|
|
1753
1759
|
}
|
|
1754
|
-
function
|
|
1755
|
-
const r = e.lastTickAt !== null && t - e.lastTickAt >
|
|
1756
|
-
return e.lastTickAt = t, n ? r || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince >
|
|
1760
|
+
function aa(e, t, n) {
|
|
1761
|
+
const r = e.lastTickAt !== null && t - e.lastTickAt > na;
|
|
1762
|
+
return e.lastTickAt = t, n ? r || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince > ta : (e.unansweredSince = null, !1);
|
|
1757
1763
|
}
|
|
1758
|
-
function
|
|
1764
|
+
function ia(e, t) {
|
|
1759
1765
|
return e.lastPongAt === null ? void 0 : Math.max(0, t - e.lastPongAt);
|
|
1760
1766
|
}
|
|
1761
|
-
let S = null, H = null,
|
|
1762
|
-
const
|
|
1763
|
-
let
|
|
1764
|
-
function
|
|
1765
|
-
const t =
|
|
1767
|
+
let S = null, H = null, Pe = null, $ = null, K = null;
|
|
1768
|
+
const sa = da(), ee = ra();
|
|
1769
|
+
let we = null, Be = null, jt = 0, pt = null, me = !1, ht = !1, ae = !1, En = null;
|
|
1770
|
+
function la(e) {
|
|
1771
|
+
const t = re(), n = m.getState();
|
|
1766
1772
|
if (n.me.clientId && n.roster[n.me.clientId])
|
|
1767
1773
|
return (e.name || e.sprite) && (d("socket", "Identity update (already joined)", { name: e.name, sprite: e.sprite }), t.emit(w.IDENTITY_UPDATE, { name: e.name, sprite: e.sprite })), t;
|
|
1768
|
-
const r =
|
|
1769
|
-
return K = r,
|
|
1774
|
+
const r = ca(e);
|
|
1775
|
+
return K = r, pt = { name: r.name, sprite: r.sprite }, t.connected ? (d("socket", "Emitting join", r), t.emit(w.JOIN, r)) : t.once("connect", () => {
|
|
1770
1776
|
d("socket", "Emitting join", r), t.emit(w.JOIN, r);
|
|
1771
1777
|
}), t;
|
|
1772
1778
|
}
|
|
1773
|
-
function
|
|
1779
|
+
function ca(e) {
|
|
1774
1780
|
return {
|
|
1775
1781
|
room_key: e.room_key,
|
|
1776
1782
|
name: e.name,
|
|
1777
1783
|
sprite: e.sprite,
|
|
1778
1784
|
// Entry-path telemetry — see lib/embedContext.ts. Sent on every join AND
|
|
1779
1785
|
// rejoin (lastJoinPayload carries it), so a reconnect keeps the attribution.
|
|
1780
|
-
embed:
|
|
1781
|
-
delivery_arm:
|
|
1786
|
+
embed: Vo(),
|
|
1787
|
+
delivery_arm: Jo(),
|
|
1782
1788
|
// Identity tier input — see lib/deviceId.ts. Sent on every join AND rejoin
|
|
1783
1789
|
// (lastJoinPayload carries it) so a reconnect lands on the same
|
|
1784
1790
|
// ParticipantId rather than minting a new person.
|
|
1785
|
-
device_id:
|
|
1786
|
-
tab_id:
|
|
1791
|
+
device_id: Qo(),
|
|
1792
|
+
tab_id: sa
|
|
1787
1793
|
};
|
|
1788
1794
|
}
|
|
1789
|
-
function
|
|
1795
|
+
function da() {
|
|
1790
1796
|
const e = globalThis.crypto;
|
|
1791
1797
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
1792
1798
|
const t = new Uint8Array(16);
|
|
@@ -1794,67 +1800,67 @@ function oa() {
|
|
|
1794
1800
|
else for (let n = 0; n < t.length; n++) t[n] = Math.floor(Math.random() * 256);
|
|
1795
1801
|
return Array.from(t, (n) => n.toString(16).padStart(2, "0")).join("");
|
|
1796
1802
|
}
|
|
1797
|
-
function
|
|
1803
|
+
function re() {
|
|
1798
1804
|
if (!S) {
|
|
1799
|
-
let t =
|
|
1805
|
+
let t = fe().serverOrigin || "/";
|
|
1800
1806
|
if (t === "/" && typeof window < "u") {
|
|
1801
1807
|
const r = window.location;
|
|
1802
|
-
(r.hostname === "localhost" || r.hostname === "127.0.0.1") && r.port === String(
|
|
1808
|
+
(r.hostname === "localhost" || r.hostname === "127.0.0.1") && r.port === String(Yt) && (t = `${r.protocol}//${r.hostname}:${nt}`, d("socket", "Using dev fallback origin", { origin: t }));
|
|
1803
1809
|
}
|
|
1804
1810
|
const n = new URL(t.startsWith("http") ? t : `${window.location.origin}${t}`).origin;
|
|
1805
|
-
S =
|
|
1806
|
-
if (
|
|
1811
|
+
S = zn(n, { path: er, transports: ["websocket", "polling"] }), d("socket", "Socket initialized", { origin: t }), Fe("__SOCKET__", S), $ && (clearTimeout($), $ = null), H = null, Pe = setInterval(() => {
|
|
1812
|
+
if (aa(ee, Date.now(), !!S?.connected)) {
|
|
1807
1813
|
A("socket", "PONG-WATCHDOG no time_pong for 20s — replacing the connection", {
|
|
1808
1814
|
sid: S?.id,
|
|
1809
|
-
lastPongAgeMs:
|
|
1810
|
-
}),
|
|
1815
|
+
lastPongAgeMs: ia(ee, Date.now()) ?? null
|
|
1816
|
+
}), Be = "pong-watchdog", ee.unansweredSince = null, S?.io.engine?.close();
|
|
1811
1817
|
return;
|
|
1812
1818
|
}
|
|
1813
|
-
|
|
1814
|
-
},
|
|
1815
|
-
|
|
1819
|
+
_a();
|
|
1820
|
+
}, vr), S.on("connect", () => {
|
|
1821
|
+
ht = !1;
|
|
1816
1822
|
const r = S?.id;
|
|
1817
|
-
if (d("socket", "Connected", { id: r, isReconnect:
|
|
1823
|
+
if (d("socket", "Connected", { id: r, isReconnect: ae }), r)
|
|
1818
1824
|
try {
|
|
1819
|
-
|
|
1825
|
+
m.getState().ensureMe(r), m.setState((a) => ({ me: { ...a.me, nextClientSeq: 1 } })), d("socket", "Reset client sequence for new connection");
|
|
1820
1826
|
} catch (a) {
|
|
1821
|
-
|
|
1827
|
+
Ee("socket", "Failed to initialize store on connect", { error: a.message, sid: r });
|
|
1822
1828
|
}
|
|
1823
|
-
if (
|
|
1824
|
-
const a =
|
|
1825
|
-
|
|
1829
|
+
if (ae && K) {
|
|
1830
|
+
const a = m.getState();
|
|
1831
|
+
jt += 1;
|
|
1826
1832
|
const i = {
|
|
1827
1833
|
...K,
|
|
1828
1834
|
name: a.name,
|
|
1829
1835
|
sprite: a.sprite,
|
|
1830
1836
|
reconnect: {
|
|
1831
|
-
count:
|
|
1832
|
-
reason: (
|
|
1833
|
-
offline_ms:
|
|
1837
|
+
count: jt,
|
|
1838
|
+
reason: (we?.reason ?? "unknown").slice(0, 64),
|
|
1839
|
+
offline_ms: we ? Math.max(0, Date.now() - we.at) : 0
|
|
1834
1840
|
}
|
|
1835
|
-
}, s =
|
|
1841
|
+
}, s = En;
|
|
1836
1842
|
if (d("socket", "Re-emitting join after reconnect", { room_key: i.room_key, name: i.name, sprite: i.sprite }), s) {
|
|
1837
1843
|
let l = !1;
|
|
1838
|
-
const
|
|
1839
|
-
l || (l = !0, S.off(w.SNAPSHOT,
|
|
1844
|
+
const u = () => {
|
|
1845
|
+
l || (l = !0, S.off(w.SNAPSHOT, u), S.emit(w.CLIENT_READY, { media_id: s }), d("socket", "Re-emitted client_ready after reconnect snapshot", { mediaId: s }));
|
|
1840
1846
|
};
|
|
1841
|
-
S.on(w.SNAPSHOT,
|
|
1842
|
-
l || (l = !0, S.off(w.SNAPSHOT,
|
|
1847
|
+
S.on(w.SNAPSHOT, u), setTimeout(() => {
|
|
1848
|
+
l || (l = !0, S.off(w.SNAPSHOT, u), A("socket", "client_ready re-emit timed out waiting for snapshot", { mediaId: s }));
|
|
1843
1849
|
}, 1e4);
|
|
1844
1850
|
}
|
|
1845
|
-
|
|
1846
|
-
} else
|
|
1847
|
-
|
|
1851
|
+
pt = { name: i.name, sprite: i.sprite }, S.emit(w.JOIN, i), window.dispatchEvent(new CustomEvent("watchparty:socket-reconnect"));
|
|
1852
|
+
} else ae && A("socket", "Reconnected — no join payload, not re-joining any room");
|
|
1853
|
+
ae = !0;
|
|
1848
1854
|
}), S.on("disconnect", (r) => {
|
|
1849
|
-
|
|
1850
|
-
}), S.on("connect_error", (r) =>
|
|
1855
|
+
yn(null), we = { reason: Be ?? r, at: Date.now() }, Be = null, d("socket", "Disconnected", { reason: r });
|
|
1856
|
+
}), S.on("connect_error", (r) => Ee("socket", "Connection error", { message: r?.message })), S.on("reconnect_attempt", (r) => A("socket", "Reconnect attempt", { attempt: r })), S.on("reconnect_failed", () => Ee("socket", "Reconnect failed")), va(S);
|
|
1851
1857
|
}
|
|
1852
1858
|
return S;
|
|
1853
1859
|
}
|
|
1854
|
-
function
|
|
1860
|
+
function Ge(e) {
|
|
1855
1861
|
return e.play_state === "playing" || e.playing === !0;
|
|
1856
1862
|
}
|
|
1857
|
-
function
|
|
1863
|
+
function Ut(e, t) {
|
|
1858
1864
|
return {
|
|
1859
1865
|
id: String(e.id ?? e.server_seq ?? t ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`),
|
|
1860
1866
|
clientId: e.client_id,
|
|
@@ -1866,22 +1872,22 @@ function Ot(e, t) {
|
|
|
1866
1872
|
// Attachments arrive from other clients, so the key shape is re-checked
|
|
1867
1873
|
// here at the boundary rather than trusted at render time. A malformed
|
|
1868
1874
|
// entry is dropped, not rendered and not allowed near an <img src>.
|
|
1869
|
-
images: Array.isArray(e.images) ? e.images.filter((n) => !!n &&
|
|
1875
|
+
images: Array.isArray(e.images) ? e.images.filter((n) => !!n && tt(n.key)).slice(0, W) : void 0,
|
|
1870
1876
|
isSystem: e.isSystem || !1,
|
|
1871
1877
|
systemType: e.systemType
|
|
1872
1878
|
};
|
|
1873
1879
|
}
|
|
1874
|
-
function
|
|
1880
|
+
function ua(e) {
|
|
1875
1881
|
e.on(w.SNAPSHOT, (t) => {
|
|
1876
|
-
e.emit(
|
|
1882
|
+
e.emit(tn.SYNC), m.getState().applySnapshot({
|
|
1877
1883
|
roomId: t.room_id ?? null,
|
|
1878
1884
|
mediaId: t.media_id ?? null,
|
|
1879
1885
|
playheadMs: t.playhead_ms || 0,
|
|
1880
|
-
playing:
|
|
1886
|
+
playing: Ge(t),
|
|
1881
1887
|
serverSeq: t.server_seq || 0,
|
|
1882
1888
|
leaderId: t.leader_id || null
|
|
1883
|
-
}),
|
|
1884
|
-
const n =
|
|
1889
|
+
}), m.getState().name || d("socket", "Deferring identity to presence event (snapshot carries no roster)");
|
|
1890
|
+
const n = m.getState(), r = S?.id, i = (r ? n.roster[r] : void 0) ?? pt, s = Jn(
|
|
1885
1891
|
{ name: n.name, avatarId: n.sprite },
|
|
1886
1892
|
i ? { name: i.name, avatarId: i.sprite ?? null } : void 0,
|
|
1887
1893
|
// A join that carried no name counts as a default one, so a name that
|
|
@@ -1891,27 +1897,27 @@ function aa(e) {
|
|
|
1891
1897
|
if (s) {
|
|
1892
1898
|
const l = {
|
|
1893
1899
|
...s.name !== void 0 ? { name: s.name } : {},
|
|
1894
|
-
...s.avatarId !== void 0 && !
|
|
1900
|
+
...s.avatarId !== void 0 && !ht ? { sprite: s.avatarId } : {}
|
|
1895
1901
|
};
|
|
1896
1902
|
Object.keys(l).length > 0 && (d("socket", "Identity update on snapshot", l), e.emit(w.IDENTITY_UPDATE, l));
|
|
1897
1903
|
}
|
|
1898
1904
|
d("socket", "Received snapshot", {
|
|
1899
1905
|
mediaId: t.media_id ?? null,
|
|
1900
1906
|
playheadMs: t.playhead_ms || 0,
|
|
1901
|
-
playing:
|
|
1907
|
+
playing: Ge(t),
|
|
1902
1908
|
leaderId: t.leader_id || null,
|
|
1903
1909
|
serverSeq: t.server_seq || 0,
|
|
1904
1910
|
rosterSize: Object.keys(n.roster).length
|
|
1905
|
-
}), K?.room_key && S?.id &&
|
|
1911
|
+
}), K?.room_key && S?.id && yn({ room_key: K.room_key, client_id: S.id });
|
|
1906
1912
|
}), e.on(w.CONTROL_BROADCAST, (t) => {
|
|
1907
|
-
const n =
|
|
1913
|
+
const n = m.getState();
|
|
1908
1914
|
if (Object.prototype.hasOwnProperty.call(t, "media_id")) {
|
|
1909
1915
|
const r = t.media_id ?? null;
|
|
1910
1916
|
n.snapshot.mediaId !== r && (n.applySnapshot({ mediaId: r }), r && n.setReadiness({ mediaId: r, ready: !1, readyCount: 0, total: 0 }), n.bumpLoadGeneration());
|
|
1911
1917
|
}
|
|
1912
1918
|
n.updateControlState({
|
|
1913
1919
|
playheadMs: t.playhead_ms,
|
|
1914
|
-
playing:
|
|
1920
|
+
playing: Ge(t),
|
|
1915
1921
|
serverSeq: t.server_seq,
|
|
1916
1922
|
leaderId: t.leader_id ?? n.snapshot.leaderId
|
|
1917
1923
|
}), d("socket", "Control broadcast received", {
|
|
@@ -1924,17 +1930,17 @@ function aa(e) {
|
|
|
1924
1930
|
}), e.on(w.CONTROL_ACK, (t) => {
|
|
1925
1931
|
typeof t?.client_seq == "number" && typeof t?.server_seq == "number" && d("socket", "Control ack received", t);
|
|
1926
1932
|
}), e.on(w.TIME_PONG, (t) => {
|
|
1927
|
-
if (
|
|
1933
|
+
if (oa(ee, Date.now()), H && H.ts) {
|
|
1928
1934
|
const n = Date.now() - H.ts;
|
|
1929
|
-
|
|
1935
|
+
m.getState().addRttSample(n, t?.server_ts, H.ts), H = null, $ && (clearTimeout($), $ = null), d("socket", "Time sync RTT", { rtt: n, offset: m.getState().drift.offsetMs });
|
|
1930
1936
|
}
|
|
1931
1937
|
}), e.on(w.READY_STATE, (t) => {
|
|
1932
1938
|
if (!t) return;
|
|
1933
1939
|
const n = t.media_id ?? null, r = typeof t.ready_count == "number" ? t.ready_count : 0, a = typeof t.total == "number" ? t.total : 0, i = t.ready === !0;
|
|
1934
|
-
|
|
1940
|
+
m.getState().setReadiness({ mediaId: n, ready: i, readyCount: r, total: a }), d("socket", "Ready state received", { mediaId: n, readyCount: r, total: a, ready: i });
|
|
1935
1941
|
});
|
|
1936
1942
|
}
|
|
1937
|
-
function
|
|
1943
|
+
function ma(e) {
|
|
1938
1944
|
e.on(w.PRESENCE, (t) => {
|
|
1939
1945
|
if (!t) return;
|
|
1940
1946
|
if (Array.isArray(t.users)) {
|
|
@@ -1949,99 +1955,99 @@ function ia(e) {
|
|
|
1949
1955
|
...l.registry_name ? { registryName: !0 } : {},
|
|
1950
1956
|
...l.avatar_url ? { avatarUrl: l.avatar_url } : {}
|
|
1951
1957
|
};
|
|
1952
|
-
const a =
|
|
1958
|
+
const a = m.getState(), i = S?.id, s = i ? r[i] : void 0;
|
|
1953
1959
|
if (s?.registryName)
|
|
1954
|
-
|
|
1960
|
+
m.setState({ roster: r }), (s.name !== a.name || s.sprite && s.sprite !== a.sprite) && (d("socket", "Adopting registry name", { from: a.name, to: s.name }), m.getState().setSessionIdentity(s.name, s.sprite ?? a.sprite));
|
|
1955
1961
|
else if (i && r[i]) {
|
|
1956
|
-
const l = r[i].name,
|
|
1957
|
-
if (a.name && !J(a.name) && (r[i].name = a.name),
|
|
1958
|
-
const h = a.name && !J(a.name), f = h ? a.name :
|
|
1959
|
-
d("socket", "Server reassigned sprite", { from: a.sprite, to:
|
|
1962
|
+
const l = r[i].name, u = r[i].sprite;
|
|
1963
|
+
if (a.name && !J(a.name) && (r[i].name = a.name), m.setState({ roster: r }), u && u !== a.sprite) {
|
|
1964
|
+
const h = a.name && !J(a.name), f = h ? a.name : ue(u);
|
|
1965
|
+
d("socket", "Server reassigned sprite", { from: a.sprite, to: u, newName: f, preservingCustomName: h }), m.getState().setSessionIdentity(f, u), f !== l && e.emit(w.IDENTITY_UPDATE, { name: f });
|
|
1960
1966
|
}
|
|
1961
1967
|
}
|
|
1962
1968
|
}
|
|
1963
1969
|
d("socket", "Received presence update", t);
|
|
1964
|
-
const n =
|
|
1970
|
+
const n = m.getState();
|
|
1965
1971
|
if (!n.name) {
|
|
1966
1972
|
n.ensureAutoIdentity?.();
|
|
1967
|
-
const r =
|
|
1973
|
+
const r = m.getState();
|
|
1968
1974
|
r.name && (d("socket", "Auto-assigned identity on presence", { name: r.name, sprite: r.sprite }), e.emit(w.IDENTITY_UPDATE, { name: r.name, sprite: r.sprite || void 0 }));
|
|
1969
1975
|
}
|
|
1970
1976
|
});
|
|
1971
1977
|
}
|
|
1972
|
-
function
|
|
1978
|
+
function fa(e) {
|
|
1973
1979
|
e.on(w.CHAT_BROADCAST, (t) => {
|
|
1974
|
-
const n =
|
|
1975
|
-
|
|
1980
|
+
const n = Ut(t, t.server_seq);
|
|
1981
|
+
m.getState().appendChat(n), d("chat", "Message received", n);
|
|
1976
1982
|
}), e.on(w.CHAT_HISTORY, (t) => {
|
|
1977
1983
|
if (!t?.messages || !Array.isArray(t.messages)) return;
|
|
1978
|
-
const n = t.messages.map((r) =>
|
|
1979
|
-
|
|
1984
|
+
const n = t.messages.map((r) => Ut(r));
|
|
1985
|
+
m.getState().setChat(n), d("chat", "History loaded", { count: n.length });
|
|
1980
1986
|
});
|
|
1981
1987
|
}
|
|
1982
|
-
function
|
|
1983
|
-
e.on(
|
|
1984
|
-
|
|
1988
|
+
function pa(e) {
|
|
1989
|
+
e.on(be.STATE, (t) => {
|
|
1990
|
+
m.getState().applyPlaylistState({
|
|
1985
1991
|
playlist: t?.playlist ?? null,
|
|
1986
1992
|
activeIndex: t?.activeIndex ?? null,
|
|
1987
1993
|
myVotes: t?.myVotes ?? {}
|
|
1988
1994
|
}), d("playlist", "Playlist state received", { playlistId: t?.playlist?.id ?? null, activeIndex: t?.activeIndex, myVoteCount: Object.keys(t?.myVotes || {}).length });
|
|
1989
|
-
}), e.on(
|
|
1990
|
-
|
|
1991
|
-
}), e.on(
|
|
1992
|
-
|
|
1993
|
-
}), e.on(
|
|
1995
|
+
}), e.on(be.VOTE_PROGRESS, (t) => {
|
|
1996
|
+
m.getState().setVoteProgress(t?.progress ?? []), d("playlist", "Vote progress", { progressCount: t?.progress?.length });
|
|
1997
|
+
}), e.on(be.RESULTS, (t) => {
|
|
1998
|
+
m.getState().setPlaylistResults(t ?? null), d("playlist", "Results received", { playlistId: t?.playlist?.id, update: t?.update === !0 });
|
|
1999
|
+
}), e.on(be.VOTES_CLEARED, (t) => {
|
|
1994
2000
|
if (!t?.playlistId || !Array.isArray(t.mediaIds)) return;
|
|
1995
|
-
const n =
|
|
2001
|
+
const n = ea(
|
|
1996
2002
|
{ id: t.playlistId, videos: t.mediaIds.map((a) => ({ mediaId: a })) },
|
|
1997
|
-
|
|
1998
|
-
), r =
|
|
2003
|
+
_o()
|
|
2004
|
+
), r = m.getState();
|
|
1999
2005
|
r.playlist?.id === t.playlistId && r.applyPlaylistState({ playlist: r.playlist, activeIndex: r.activePlaylistIndex, myVotes: {} }), d("playlist", "Votes cleared by leader", { playlistId: t.playlistId, removed: n });
|
|
2000
2006
|
});
|
|
2001
2007
|
}
|
|
2002
|
-
function
|
|
2003
|
-
e.on(
|
|
2004
|
-
d("tierlist", "Someone saved — refreshing the board"),
|
|
2008
|
+
function ha(e) {
|
|
2009
|
+
e.on(fr.UPDATED, () => {
|
|
2010
|
+
d("tierlist", "Someone saved — refreshing the board"), Uo(!1);
|
|
2005
2011
|
});
|
|
2006
2012
|
}
|
|
2007
|
-
function
|
|
2008
|
-
e.on(
|
|
2013
|
+
function ga(e) {
|
|
2014
|
+
e.on(pr.STATE, (t) => {
|
|
2009
2015
|
if (!t || typeof t.active != "boolean") return;
|
|
2010
2016
|
const n = Array.isArray(t.ready) ? t.ready.filter((r) => typeof r == "string") : [];
|
|
2011
|
-
|
|
2017
|
+
m.getState().setReadyCheckState({ active: t.active, ready: n }), d("ready-check", "State received", { active: t.active, readyCount: n.length });
|
|
2012
2018
|
});
|
|
2013
2019
|
}
|
|
2014
|
-
function
|
|
2015
|
-
e.on(
|
|
2020
|
+
function ya(e) {
|
|
2021
|
+
e.on(tn.ACTIVE, (t) => {
|
|
2016
2022
|
const n = typeof t?.gameId == "string" ? t.gameId : null;
|
|
2017
|
-
|
|
2023
|
+
m.getState().setActiveGameId(n), d("game", "game_active", { gameId: n });
|
|
2018
2024
|
});
|
|
2019
2025
|
}
|
|
2020
|
-
function
|
|
2026
|
+
function ba(e) {
|
|
2021
2027
|
e.on(w.HEALTH_SNAPSHOT, (t) => {
|
|
2022
|
-
|
|
2028
|
+
m.getState().setHealthSnapshot(t);
|
|
2023
2029
|
}), e.on(w.BUFFER_STATUS, (t) => {
|
|
2024
|
-
|
|
2030
|
+
m.getState().setBufferStatus(t);
|
|
2025
2031
|
});
|
|
2026
2032
|
}
|
|
2027
|
-
function
|
|
2028
|
-
|
|
2033
|
+
function va(e) {
|
|
2034
|
+
ua(e), ma(e), fa(e), ba(e), pa(e), ha(e), ga(e), ya(e), e.on(w.ERROR, (t) => {
|
|
2029
2035
|
const n = t?.code || "error/unknown";
|
|
2030
2036
|
if (n === "conflict" && t?.message === "sprite_held_by_you") {
|
|
2031
|
-
|
|
2037
|
+
ht = !0, d("socket", "sprite held by this account's other connection: keeping the server-assigned sprite");
|
|
2032
2038
|
return;
|
|
2033
2039
|
}
|
|
2034
2040
|
if (n === "conflict" && t?.message === "sprite_taken") {
|
|
2035
|
-
if (
|
|
2041
|
+
if ($o(S?.id)) {
|
|
2036
2042
|
d("socket", "sprite_taken: stale, the server already has our sprite");
|
|
2037
2043
|
return;
|
|
2038
2044
|
}
|
|
2039
|
-
|
|
2045
|
+
me = !0;
|
|
2040
2046
|
let s;
|
|
2041
2047
|
try {
|
|
2042
|
-
s =
|
|
2048
|
+
s = Ho();
|
|
2043
2049
|
} finally {
|
|
2044
|
-
|
|
2050
|
+
me = !1;
|
|
2045
2051
|
}
|
|
2046
2052
|
s && e.emit(w.IDENTITY_UPDATE, s);
|
|
2047
2053
|
return;
|
|
@@ -2064,55 +2070,55 @@ function fa(e) {
|
|
|
2064
2070
|
"recap/not_found": "No recap available for the previous episode."
|
|
2065
2071
|
}[n] || n;
|
|
2066
2072
|
if (n.startsWith("recap/")) {
|
|
2067
|
-
d("socket", `recap unavailable: ${a}`, { code: n }),
|
|
2073
|
+
d("socket", `recap unavailable: ${a}`, { code: n }), m.getState().pushToast("info", a);
|
|
2068
2074
|
return;
|
|
2069
2075
|
}
|
|
2070
|
-
(n.startsWith("auth/") ? A :
|
|
2076
|
+
(n.startsWith("auth/") ? A : Ee)("socket", `Server error: ${a}`, { code: n, raw: t }), m.getState().pushToast("error", a);
|
|
2071
2077
|
});
|
|
2072
2078
|
}
|
|
2073
|
-
function
|
|
2074
|
-
|
|
2079
|
+
function Sa(e, t) {
|
|
2080
|
+
re().emit(w.CHAT_SEND, t?.length ? { text: e, images: t } : { text: e });
|
|
2075
2081
|
}
|
|
2076
|
-
function
|
|
2077
|
-
H || (H = { ts: Date.now() },
|
|
2082
|
+
function _a() {
|
|
2083
|
+
H || (H = { ts: Date.now() }, re().emit(w.TIME_PING, {}), $ = setTimeout(() => {
|
|
2078
2084
|
H && (d("socket", "Time ping timed out after 10s, clearing inflight"), H = null), $ = null;
|
|
2079
2085
|
}, 1e4));
|
|
2080
2086
|
}
|
|
2081
|
-
function
|
|
2082
|
-
const t =
|
|
2087
|
+
function kn(e) {
|
|
2088
|
+
const t = m.getState(), n = t.me.clientId;
|
|
2083
2089
|
if (!n || !t.roster[n]) {
|
|
2084
|
-
|
|
2090
|
+
Mt(e), d("socket", "Avatar change before join: the join will carry it", { sprite: e });
|
|
2085
2091
|
return;
|
|
2086
2092
|
}
|
|
2087
|
-
|
|
2093
|
+
me = !0;
|
|
2088
2094
|
try {
|
|
2089
|
-
|
|
2095
|
+
Mt(e);
|
|
2090
2096
|
} finally {
|
|
2091
|
-
|
|
2097
|
+
me = !1;
|
|
2092
2098
|
}
|
|
2093
|
-
const r =
|
|
2094
|
-
r.sprite && r.sprite !== t.sprite && (a.sprite = r.sprite), r.name && r.name !== t.name && (a.name = r.name), d("socket", "Sending avatar change", a),
|
|
2099
|
+
const r = m.getState(), a = { avatar: !0 };
|
|
2100
|
+
r.sprite && r.sprite !== t.sprite && (a.sprite = r.sprite), r.name && r.name !== t.name && (a.name = r.name), d("socket", "Sending avatar change", a), re().emit(w.IDENTITY_UPDATE, a);
|
|
2095
2101
|
}
|
|
2096
|
-
let
|
|
2097
|
-
|
|
2098
|
-
if (e.name === t.name && e.sprite === t.sprite ||
|
|
2102
|
+
let xe = { name: "", sprite: "" };
|
|
2103
|
+
m.subscribe((e, t) => {
|
|
2104
|
+
if (e.name === t.name && e.sprite === t.sprite || me) return;
|
|
2099
2105
|
const n = e.me.clientId;
|
|
2100
2106
|
if (!n) return;
|
|
2101
2107
|
const r = e.roster[n];
|
|
2102
2108
|
if (!r) return;
|
|
2103
|
-
const a = !!e.name && !J(e.name) && e.name !==
|
|
2109
|
+
const a = !!e.name && !J(e.name) && e.name !== xe.name && (J(r.name || "") || r.name !== e.name), i = !!e.sprite && e.sprite !== xe.sprite && r.sprite !== e.sprite;
|
|
2104
2110
|
if (!a && !i) return;
|
|
2105
2111
|
const s = {};
|
|
2106
|
-
a && (s.name = e.name,
|
|
2112
|
+
a && (s.name = e.name, xe.name = e.name), i && (s.sprite = e.sprite, xe.sprite = e.sprite), d("socket", "Identity reassert (store change)", s), S?.connected ? S.emit(w.IDENTITY_UPDATE, s) : re().emit(w.IDENTITY_UPDATE, s);
|
|
2107
2113
|
});
|
|
2108
|
-
function
|
|
2109
|
-
|
|
2114
|
+
function wa() {
|
|
2115
|
+
Pe && (clearInterval(Pe), Pe = null), $ && (clearTimeout($), $ = null), H = null, ee.unansweredSince = null, ee.lastTickAt = null;
|
|
2110
2116
|
}
|
|
2111
|
-
function
|
|
2112
|
-
d("socket", "clearJoinState called", { hadPayload: K !== null, room_key: K?.room_key }), K = null,
|
|
2117
|
+
function xa() {
|
|
2118
|
+
d("socket", "clearJoinState called", { hadPayload: K !== null, room_key: K?.room_key }), K = null, ae = !1, En = null;
|
|
2113
2119
|
}
|
|
2114
|
-
function
|
|
2115
|
-
d("socket", "leaveRoom called", { room_key: K?.room_key }),
|
|
2120
|
+
function Ft() {
|
|
2121
|
+
d("socket", "leaveRoom called", { room_key: K?.room_key }), xa(), wa(), S && (S.disconnect(), S = null), m.setState({
|
|
2116
2122
|
me: { clientId: null, nextClientSeq: 1 },
|
|
2117
2123
|
roster: {},
|
|
2118
2124
|
snapshot: { roomId: null, mediaId: null, playheadMs: 0, playing: !1, serverSeq: 0, leaderId: null },
|
|
@@ -2127,24 +2133,91 @@ function Mt() {
|
|
|
2127
2133
|
activeGameId: null
|
|
2128
2134
|
});
|
|
2129
2135
|
}
|
|
2130
|
-
function
|
|
2131
|
-
d("chat", "Emitting recap_request"),
|
|
2136
|
+
function Ia() {
|
|
2137
|
+
d("chat", "Emitting recap_request"), re().emit("recap_request");
|
|
2132
2138
|
}
|
|
2133
|
-
function
|
|
2134
|
-
D(() =>
|
|
2135
|
-
const t =
|
|
2136
|
-
d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }),
|
|
2139
|
+
function Ca() {
|
|
2140
|
+
D(() => Go((e) => {
|
|
2141
|
+
const t = Tn(e);
|
|
2142
|
+
d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }), kn(t);
|
|
2137
2143
|
}), []);
|
|
2138
2144
|
}
|
|
2139
|
-
|
|
2145
|
+
const Ta = 0.3, Aa = 0.82, Z = 24, Ea = 32;
|
|
2146
|
+
function ka(e) {
|
|
2147
|
+
let t = 0, n = 0, r = 0, a = 0;
|
|
2148
|
+
for (let i = 0; i + 3 < e.length; i += 4) {
|
|
2149
|
+
const s = e[i + 3];
|
|
2150
|
+
s < Ea || (t += e[i] * s, n += e[i + 1] * s, r += e[i + 2] * s, a += s);
|
|
2151
|
+
}
|
|
2152
|
+
return a === 0 ? null : Pa(t / a, n / a, r / a);
|
|
2153
|
+
}
|
|
2154
|
+
function Pa(e, t, n) {
|
|
2155
|
+
const [r, a, i] = Na(e / 255, t / 255, n / 255), s = Math.min(Aa, Math.max(Ta, i)), [l, u, h] = Ra(r, a, s), f = (O) => Math.round(O * 255).toString(16).padStart(2, "0");
|
|
2156
|
+
return `#${f(l)}${f(u)}${f(h)}`;
|
|
2157
|
+
}
|
|
2158
|
+
function Na(e, t, n) {
|
|
2159
|
+
const r = Math.max(e, t, n), a = Math.min(e, t, n), i = (r + a) / 2;
|
|
2160
|
+
if (r === a) return [0, 0, i];
|
|
2161
|
+
const s = r - a, l = i > 0.5 ? s / (2 - r - a) : s / (r + a);
|
|
2162
|
+
let u;
|
|
2163
|
+
return r === e ? u = (t - n) / s + (t < n ? 6 : 0) : r === t ? u = (n - e) / s + 2 : u = (e - t) / s + 4, [u / 6, l, i];
|
|
2164
|
+
}
|
|
2165
|
+
function Ra(e, t, n) {
|
|
2166
|
+
if (t === 0) return [n, n, n];
|
|
2167
|
+
const r = n < 0.5 ? n * (1 + t) : n + t - n * t, a = 2 * n - r, i = (s) => (s < 0 && (s += 1), s > 1 && (s -= 1), s < 1 / 6 ? a + (r - a) * 6 * s : s < 1 / 2 ? r : s < 2 / 3 ? a + (r - a) * (2 / 3 - s) * 6 : a);
|
|
2168
|
+
return [i(e + 1 / 3), i(e), i(e - 1 / 3)];
|
|
2169
|
+
}
|
|
2170
|
+
const Qe = /* @__PURE__ */ new Map(), qe = /* @__PURE__ */ new Set(), et = /* @__PURE__ */ new Set();
|
|
2171
|
+
function Da() {
|
|
2172
|
+
for (const e of et) e();
|
|
2173
|
+
}
|
|
2174
|
+
function Oa(e) {
|
|
2175
|
+
if (Qe.has(e) || qe.has(e) || typeof Image > "u" || typeof document > "u") return;
|
|
2176
|
+
qe.add(e);
|
|
2177
|
+
const t = new Image();
|
|
2178
|
+
t.crossOrigin = "anonymous", t.referrerPolicy = "no-referrer";
|
|
2179
|
+
const n = (r) => {
|
|
2180
|
+
qe.delete(e), Qe.set(e, r), Da();
|
|
2181
|
+
};
|
|
2182
|
+
t.onload = () => {
|
|
2183
|
+
try {
|
|
2184
|
+
const r = document.createElement("canvas");
|
|
2185
|
+
r.width = Z, r.height = Z;
|
|
2186
|
+
const a = r.getContext("2d", { willReadFrequently: !0 });
|
|
2187
|
+
if (!a) {
|
|
2188
|
+
n(null);
|
|
2189
|
+
return;
|
|
2190
|
+
}
|
|
2191
|
+
a.drawImage(t, 0, 0, Z, Z), n(ka(a.getImageData(0, 0, Z, Z).data));
|
|
2192
|
+
} catch (r) {
|
|
2193
|
+
d("avatar", "picture colour unreadable", { url: e, error: r instanceof Error ? r.message : String(r) }), n(null);
|
|
2194
|
+
}
|
|
2195
|
+
}, t.onerror = () => n(null), t.src = e;
|
|
2196
|
+
}
|
|
2197
|
+
function Ma(e) {
|
|
2198
|
+
return et.add(e), () => et.delete(e);
|
|
2199
|
+
}
|
|
2200
|
+
function La(e, t) {
|
|
2201
|
+
if (t) {
|
|
2202
|
+
const n = Qe.get(t);
|
|
2203
|
+
if (n) return n;
|
|
2204
|
+
}
|
|
2205
|
+
return vn(e);
|
|
2206
|
+
}
|
|
2207
|
+
function Pn(e, t) {
|
|
2208
|
+
return D(() => {
|
|
2209
|
+
t && Oa(t);
|
|
2210
|
+
}, [t]), On(Ma, () => La(e, t), () => vn(e));
|
|
2211
|
+
}
|
|
2212
|
+
function ja(e, t) {
|
|
2140
2213
|
if (t) {
|
|
2141
2214
|
for (const n of Object.values(e))
|
|
2142
2215
|
if (n.author === t && n.avatarUrl) return n.avatarUrl;
|
|
2143
2216
|
}
|
|
2144
2217
|
}
|
|
2145
|
-
function
|
|
2146
|
-
const [
|
|
2147
|
-
if (t && t !==
|
|
2218
|
+
function Nn({ sprite: e, url: t, alt: n = "", className: r, style: a, fallback: i }) {
|
|
2219
|
+
const [s, l] = R(null);
|
|
2220
|
+
if (t && t !== s)
|
|
2148
2221
|
return /* @__PURE__ */ c(
|
|
2149
2222
|
"img",
|
|
2150
2223
|
{
|
|
@@ -2152,25 +2225,26 @@ function Tn({ sprite: e, url: t, alt: n = "", className: r, fallback: a }) {
|
|
|
2152
2225
|
alt: n,
|
|
2153
2226
|
referrerPolicy: "no-referrer",
|
|
2154
2227
|
className: r,
|
|
2228
|
+
style: a,
|
|
2155
2229
|
draggable: !1,
|
|
2156
|
-
onError: () =>
|
|
2230
|
+
onError: () => l(t)
|
|
2157
2231
|
}
|
|
2158
2232
|
);
|
|
2159
|
-
const
|
|
2160
|
-
return
|
|
2233
|
+
const u = wo(e);
|
|
2234
|
+
return u ? /* @__PURE__ */ c("img", { src: u, alt: n, crossOrigin: "anonymous", className: r, style: a, draggable: !1 }) : /* @__PURE__ */ c(ce, { children: i });
|
|
2161
2235
|
}
|
|
2162
|
-
function
|
|
2236
|
+
function Ua(e) {
|
|
2163
2237
|
return !(e.button !== 0 || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey);
|
|
2164
2238
|
}
|
|
2165
|
-
function
|
|
2239
|
+
function Fa({ src: e, title: t, onClose: n }) {
|
|
2166
2240
|
D(() => {
|
|
2167
2241
|
const i = (s) => {
|
|
2168
2242
|
s.key === "Escape" && (s.stopPropagation(), n());
|
|
2169
2243
|
};
|
|
2170
2244
|
return document.addEventListener("keydown", i, !0), () => document.removeEventListener("keydown", i, !0);
|
|
2171
2245
|
}, [n]);
|
|
2172
|
-
const r =
|
|
2173
|
-
return a ?
|
|
2246
|
+
const r = Qr(), a = typeof document > "u" ? null : document.fullscreenElement ?? r ?? document.body;
|
|
2247
|
+
return a ? Zn(
|
|
2174
2248
|
/* @__PURE__ */ _(
|
|
2175
2249
|
"div",
|
|
2176
2250
|
{
|
|
@@ -2208,12 +2282,12 @@ function wa({ src: e, title: t, onClose: n }) {
|
|
|
2208
2282
|
a
|
|
2209
2283
|
) : null;
|
|
2210
2284
|
}
|
|
2211
|
-
const
|
|
2212
|
-
function
|
|
2213
|
-
const [t, n] = R(!1), r =
|
|
2285
|
+
const Ve = 240, Ha = 320;
|
|
2286
|
+
function $a({ image: e }) {
|
|
2287
|
+
const [t, n] = R(!1), r = Ne(e.key);
|
|
2214
2288
|
if (!r) return null;
|
|
2215
|
-
const a = e.w > 0 && e.h > 0, i = a ? Math.min(1,
|
|
2216
|
-
return /* @__PURE__ */ _(
|
|
2289
|
+
const a = e.w > 0 && e.h > 0, i = a ? Math.min(1, Ha / e.w, Ve / e.h) : 1;
|
|
2290
|
+
return /* @__PURE__ */ _(ce, { children: [
|
|
2217
2291
|
/* @__PURE__ */ c(
|
|
2218
2292
|
"a",
|
|
2219
2293
|
{
|
|
@@ -2223,7 +2297,7 @@ function Ia({ image: e }) {
|
|
|
2223
2297
|
className: "block max-w-full cursor-zoom-in",
|
|
2224
2298
|
"data-testid": "chat-image",
|
|
2225
2299
|
onClick: (s) => {
|
|
2226
|
-
|
|
2300
|
+
Ua(s) && (s.preventDefault(), n(!0));
|
|
2227
2301
|
},
|
|
2228
2302
|
children: /* @__PURE__ */ c(
|
|
2229
2303
|
"img",
|
|
@@ -2235,13 +2309,13 @@ function Ia({ image: e }) {
|
|
|
2235
2309
|
width: a ? Math.round(e.w * i) : void 0,
|
|
2236
2310
|
height: a ? Math.round(e.h * i) : void 0,
|
|
2237
2311
|
className: "rounded border border-border-light object-contain bg-bg-alt/30",
|
|
2238
|
-
style: a ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight:
|
|
2312
|
+
style: a ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight: Ve } : { maxWidth: "100%", maxHeight: Ve }
|
|
2239
2313
|
}
|
|
2240
2314
|
)
|
|
2241
2315
|
}
|
|
2242
2316
|
),
|
|
2243
2317
|
t && /* @__PURE__ */ c(
|
|
2244
|
-
|
|
2318
|
+
Fa,
|
|
2245
2319
|
{
|
|
2246
2320
|
src: r,
|
|
2247
2321
|
title: e.title,
|
|
@@ -2250,34 +2324,29 @@ function Ia({ image: e }) {
|
|
|
2250
2324
|
)
|
|
2251
2325
|
] });
|
|
2252
2326
|
}
|
|
2253
|
-
function
|
|
2254
|
-
return e?.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: e.map((t, n) => /* @__PURE__ */ c(
|
|
2327
|
+
function Ba({ images: e }) {
|
|
2328
|
+
return e?.length ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1 mt-1", "data-testid": "chat-images", children: e.map((t, n) => /* @__PURE__ */ c($a, { image: t }, `${t.key}-${n}`)) }) : null;
|
|
2255
2329
|
}
|
|
2256
|
-
function
|
|
2330
|
+
function Ga(e, t) {
|
|
2257
2331
|
return e.author && t.author ? e.author === t.author : !!t.clientId && e.clientId === t.clientId;
|
|
2258
2332
|
}
|
|
2259
|
-
function
|
|
2333
|
+
function Ke(e) {
|
|
2260
2334
|
return new Date(e).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
2261
2335
|
}
|
|
2262
|
-
const
|
|
2263
|
-
const n =
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
t.text,
|
|
2275
|
-
/* @__PURE__ */ c("span", { className: "ml-1 text-[10px] opacity-50", children: qe(t.ts) })
|
|
2276
|
-
] });
|
|
2277
|
-
const s = hn(t.sprite);
|
|
2278
|
-
return /* @__PURE__ */ _("div", { className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${a ? "bg-bg-card/30" : ""}`, children: [
|
|
2336
|
+
const qa = Gt.memo(function({ message: t }) {
|
|
2337
|
+
const n = m((l) => l.me.clientId), r = m((l) => l.me.clientId ? l.roster[l.me.clientId]?.author : void 0), a = Ga(t, { clientId: n, author: r }), i = m((l) => ja(l.roster, t.author)), s = Pn(t.sprite, i);
|
|
2338
|
+
return t.isSystem && t.systemType === "recap" ? /* @__PURE__ */ c("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ _("div", { className: "border-l-2 border-border-light pl-2.5 py-0.5", children: [
|
|
2339
|
+
/* @__PURE__ */ _("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-0.5", children: [
|
|
2340
|
+
"Recap",
|
|
2341
|
+
/* @__PURE__ */ c("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: Ke(t.ts) })
|
|
2342
|
+
] }),
|
|
2343
|
+
/* @__PURE__ */ c("p", { className: "text-[13px] text-text-secondary leading-relaxed whitespace-pre-wrap break-words", children: t.text })
|
|
2344
|
+
] }) }) : t.isSystem ? /* @__PURE__ */ _("div", { className: "px-2 py-0.5 text-[11px] text-text-muted italic text-center leading-tight", children: [
|
|
2345
|
+
t.text,
|
|
2346
|
+
/* @__PURE__ */ c("span", { className: "ml-1 text-[10px] opacity-50", children: Ke(t.ts) })
|
|
2347
|
+
] }) : /* @__PURE__ */ _("div", { className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${a ? "bg-bg-card/30" : ""}`, children: [
|
|
2279
2348
|
/* @__PURE__ */ c(
|
|
2280
|
-
|
|
2349
|
+
Nn,
|
|
2281
2350
|
{
|
|
2282
2351
|
sprite: t.sprite,
|
|
2283
2352
|
url: i,
|
|
@@ -2288,18 +2357,18 @@ const Aa = Ft.memo(function({ message: t }) {
|
|
|
2288
2357
|
),
|
|
2289
2358
|
/* @__PURE__ */ _("div", { className: "flex-1 min-w-0 -mt-0.5", children: [
|
|
2290
2359
|
/* @__PURE__ */ c("span", { className: "font-medium text-[13px]", style: { color: s }, children: t.name }),
|
|
2291
|
-
/* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children:
|
|
2360
|
+
/* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: Ke(t.ts) }),
|
|
2292
2361
|
t.text && /* @__PURE__ */ c("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: t.text }),
|
|
2293
|
-
/* @__PURE__ */ c(
|
|
2362
|
+
/* @__PURE__ */ c(Ba, { images: t.images })
|
|
2294
2363
|
] })
|
|
2295
2364
|
] });
|
|
2296
2365
|
});
|
|
2297
|
-
function
|
|
2298
|
-
const e =
|
|
2366
|
+
function Va() {
|
|
2367
|
+
const e = m((a) => a.chat), t = z(null), n = z(!1), r = k(() => {
|
|
2299
2368
|
const a = t.current;
|
|
2300
2369
|
if (!a) return;
|
|
2301
|
-
const { scrollHeight: i, scrollTop: s, clientHeight: l } = a,
|
|
2302
|
-
n.current =
|
|
2370
|
+
const { scrollHeight: i, scrollTop: s, clientHeight: l } = a, u = i - s - l;
|
|
2371
|
+
n.current = u > 40;
|
|
2303
2372
|
}, []);
|
|
2304
2373
|
return D(() => {
|
|
2305
2374
|
const a = t.current;
|
|
@@ -2310,21 +2379,21 @@ function ka() {
|
|
|
2310
2379
|
ref: t,
|
|
2311
2380
|
onScroll: r,
|
|
2312
2381
|
className: "flex-1 overflow-y-auto overflow-x-hidden chat-messages",
|
|
2313
|
-
children: e.length === 0 ? /* @__PURE__ */ c("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ c(
|
|
2382
|
+
children: e.length === 0 ? /* @__PURE__ */ c("div", { className: "p-4 text-xs text-text-muted text-center", children: "No messages yet. Be the first to say something!" }) : /* @__PURE__ */ c(ce, { children: e.map((a, i) => {
|
|
2314
2383
|
const s = i > 0 ? e[i - 1] : null, l = s && a.ts - s.ts > 1440 * 60 * 1e3;
|
|
2315
|
-
return /* @__PURE__ */ _(
|
|
2384
|
+
return /* @__PURE__ */ _(Gt.Fragment, { children: [
|
|
2316
2385
|
l && /* @__PURE__ */ _("div", { className: "flex items-center gap-2 px-4 py-2 my-1", children: [
|
|
2317
2386
|
/* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" }),
|
|
2318
2387
|
/* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted whitespace-nowrap", children: new Date(a.ts).toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" }) }),
|
|
2319
2388
|
/* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" })
|
|
2320
2389
|
] }),
|
|
2321
|
-
/* @__PURE__ */ c(
|
|
2390
|
+
/* @__PURE__ */ c(qa, { message: a })
|
|
2322
2391
|
] }, a.id);
|
|
2323
2392
|
}) })
|
|
2324
2393
|
}
|
|
2325
2394
|
);
|
|
2326
2395
|
}
|
|
2327
|
-
const
|
|
2396
|
+
const gt = [
|
|
2328
2397
|
{
|
|
2329
2398
|
name: "recap",
|
|
2330
2399
|
description: "Summarise the previous episode of what is loaded",
|
|
@@ -2344,13 +2413,13 @@ const mt = [
|
|
|
2344
2413
|
usage: "/help",
|
|
2345
2414
|
scope: "local"
|
|
2346
2415
|
}
|
|
2347
|
-
],
|
|
2348
|
-
function
|
|
2349
|
-
if (!e.startsWith(
|
|
2350
|
-
const t = e.slice(
|
|
2416
|
+
], te = "/";
|
|
2417
|
+
function Ka(e) {
|
|
2418
|
+
if (!e.startsWith(te)) return null;
|
|
2419
|
+
const t = e.slice(te.length);
|
|
2351
2420
|
return /\s/.test(t) ? null : t.toLowerCase();
|
|
2352
2421
|
}
|
|
2353
|
-
function
|
|
2422
|
+
function Wa(e, t = gt) {
|
|
2354
2423
|
const n = e.toLowerCase();
|
|
2355
2424
|
if (!n) return [...t].sort((a, i) => a.name.localeCompare(i.name));
|
|
2356
2425
|
const r = [];
|
|
@@ -2360,23 +2429,23 @@ function Pa(e, t = mt) {
|
|
|
2360
2429
|
}
|
|
2361
2430
|
return r.sort((a, i) => a.rank - i.rank || a.cmd.name.localeCompare(i.cmd.name)).map((a) => a.cmd);
|
|
2362
2431
|
}
|
|
2363
|
-
function
|
|
2364
|
-
return `${
|
|
2432
|
+
function Ya(e) {
|
|
2433
|
+
return `${te}${e.name} `;
|
|
2365
2434
|
}
|
|
2366
|
-
function
|
|
2435
|
+
function We(e, t) {
|
|
2367
2436
|
return t <= 0 ? 0 : (e % t + t) % t;
|
|
2368
2437
|
}
|
|
2369
|
-
function
|
|
2438
|
+
function za(e, t = gt) {
|
|
2370
2439
|
const n = e.trim();
|
|
2371
2440
|
if (!n) return null;
|
|
2372
|
-
if (!n.startsWith(
|
|
2373
|
-
const r = n.slice(
|
|
2441
|
+
if (!n.startsWith(te)) return { kind: "chat", text: n };
|
|
2442
|
+
const r = n.slice(te.length), a = r.search(/\s/), i = (a === -1 ? r : r.slice(0, a)).toLowerCase(), s = a === -1 ? "" : r.slice(a).trim(), l = t.find((u) => u.name.toLowerCase() === i);
|
|
2374
2443
|
return l ? { kind: "command", command: l, args: s } : { kind: "chat", text: n };
|
|
2375
2444
|
}
|
|
2376
|
-
function
|
|
2377
|
-
return e.requiresMedia && !t.hasMedia ? `${
|
|
2445
|
+
function Xa(e, t) {
|
|
2446
|
+
return e.requiresMedia && !t.hasMedia ? `${te}${e.name} needs an episode loaded.` : null;
|
|
2378
2447
|
}
|
|
2379
|
-
function
|
|
2448
|
+
function Ja({
|
|
2380
2449
|
commands: e,
|
|
2381
2450
|
activeIndex: t,
|
|
2382
2451
|
hasMedia: n,
|
|
@@ -2394,22 +2463,22 @@ function Oa({
|
|
|
2394
2463
|
bg-bg-card border border-border-light rounded shadow-lg
|
|
2395
2464
|
list-none m-0 p-0 py-1 mb-1`,
|
|
2396
2465
|
children: e.map((s, l) => {
|
|
2397
|
-
const
|
|
2466
|
+
const u = !!s.requiresMedia && !n, h = l === t;
|
|
2398
2467
|
return /* @__PURE__ */ _(
|
|
2399
2468
|
"li",
|
|
2400
2469
|
{
|
|
2401
2470
|
id: `${i}-opt-${s.name}`,
|
|
2402
2471
|
role: "option",
|
|
2403
2472
|
"aria-selected": h,
|
|
2404
|
-
"aria-disabled":
|
|
2473
|
+
"aria-disabled": u,
|
|
2405
2474
|
onMouseDown: (f) => {
|
|
2406
2475
|
f.preventDefault(), r(s);
|
|
2407
2476
|
},
|
|
2408
2477
|
onMouseEnter: () => a(l),
|
|
2409
|
-
className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${h ? "bg-bg-alt" : ""} ${
|
|
2478
|
+
className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${h ? "bg-bg-alt" : ""} ${u ? "opacity-50" : ""}`,
|
|
2410
2479
|
children: [
|
|
2411
2480
|
/* @__PURE__ */ c("span", { className: "text-sm font-semibold text-text shrink-0", children: s.usage }),
|
|
2412
|
-
/* @__PURE__ */ c("span", { className: "text-xs text-text-secondary truncate", children:
|
|
2481
|
+
/* @__PURE__ */ c("span", { className: "text-xs text-text-secondary truncate", children: u ? "needs an episode loaded" : s.description })
|
|
2413
2482
|
]
|
|
2414
2483
|
},
|
|
2415
2484
|
s.name
|
|
@@ -2418,7 +2487,7 @@ function Oa({
|
|
|
2418
2487
|
}
|
|
2419
2488
|
);
|
|
2420
2489
|
}
|
|
2421
|
-
function
|
|
2490
|
+
function Za({
|
|
2422
2491
|
pending: e,
|
|
2423
2492
|
uploading: t,
|
|
2424
2493
|
onRemove: n
|
|
@@ -2445,31 +2514,31 @@ function Ma({
|
|
|
2445
2514
|
)
|
|
2446
2515
|
] }, r.id)) }) : null;
|
|
2447
2516
|
}
|
|
2448
|
-
function
|
|
2449
|
-
const [e, t] = R([]), [n, r] = R(!1), a =
|
|
2517
|
+
function Qa() {
|
|
2518
|
+
const [e, t] = R([]), [n, r] = R(!1), a = m((p) => p.pushToast), i = z(/* @__PURE__ */ new Set());
|
|
2450
2519
|
D(() => () => {
|
|
2451
|
-
for (const
|
|
2520
|
+
for (const p of i.current) URL.revokeObjectURL(p);
|
|
2452
2521
|
i.current.clear();
|
|
2453
2522
|
}, []);
|
|
2454
|
-
const s =
|
|
2455
|
-
|
|
2456
|
-
}, []), l =
|
|
2457
|
-
if (!
|
|
2523
|
+
const s = k((p) => {
|
|
2524
|
+
Lr(p) && (URL.revokeObjectURL(p.previewUrl), i.current.delete(p.previewUrl));
|
|
2525
|
+
}, []), l = k(async (p) => {
|
|
2526
|
+
if (!p.length) return;
|
|
2458
2527
|
const v = [];
|
|
2459
|
-
for (const b of
|
|
2460
|
-
const I =
|
|
2528
|
+
for (const b of p) {
|
|
2529
|
+
const I = Ur(b);
|
|
2461
2530
|
if (I) {
|
|
2462
2531
|
a("error", I);
|
|
2463
2532
|
continue;
|
|
2464
2533
|
}
|
|
2465
|
-
const { w: g, h:
|
|
2534
|
+
const { w: g, h: E } = await $r(b), N = URL.createObjectURL(b);
|
|
2466
2535
|
i.current.add(N), v.push({
|
|
2467
2536
|
kind: "file",
|
|
2468
2537
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2469
2538
|
file: b,
|
|
2470
2539
|
previewUrl: N,
|
|
2471
2540
|
w: g,
|
|
2472
|
-
h:
|
|
2541
|
+
h: E
|
|
2473
2542
|
});
|
|
2474
2543
|
}
|
|
2475
2544
|
v.length && t((b) => {
|
|
@@ -2485,44 +2554,44 @@ function La() {
|
|
|
2485
2554
|
}
|
|
2486
2555
|
return [...b, ...v.slice(0, I)];
|
|
2487
2556
|
});
|
|
2488
|
-
}, [a, s]),
|
|
2489
|
-
const v =
|
|
2557
|
+
}, [a, s]), u = k((p) => {
|
|
2558
|
+
const v = Ne(p.key);
|
|
2490
2559
|
v && (t((b) => b.length >= W ? (a("info", `Up to ${W} images per message`), b) : [...b, {
|
|
2491
2560
|
kind: "remote",
|
|
2492
2561
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2493
|
-
key:
|
|
2562
|
+
key: p.key,
|
|
2494
2563
|
previewUrl: v,
|
|
2495
2564
|
// The catalogue spells "unknown" as null; the wire schema spells it
|
|
2496
2565
|
// as 0, and the renderer falls back to natural flow on that.
|
|
2497
|
-
w:
|
|
2498
|
-
h:
|
|
2499
|
-
title:
|
|
2500
|
-
}]),
|
|
2501
|
-
}, [a]), h =
|
|
2566
|
+
w: p.width ?? 0,
|
|
2567
|
+
h: p.height ?? 0,
|
|
2568
|
+
title: p.title || void 0
|
|
2569
|
+
}]), je().catalogue(un).recordUse(p.key));
|
|
2570
|
+
}, [a]), h = k((p) => {
|
|
2502
2571
|
t((v) => {
|
|
2503
|
-
const b = v.find((I) => I.id ===
|
|
2504
|
-
return b && s(b), v.filter((I) => I.id !==
|
|
2572
|
+
const b = v.find((I) => I.id === p);
|
|
2573
|
+
return b && s(b), v.filter((I) => I.id !== p);
|
|
2505
2574
|
});
|
|
2506
|
-
}, [s]), f =
|
|
2507
|
-
t((
|
|
2508
|
-
for (const v of
|
|
2575
|
+
}, [s]), f = k(() => {
|
|
2576
|
+
t((p) => {
|
|
2577
|
+
for (const v of p) s(v);
|
|
2509
2578
|
return [];
|
|
2510
2579
|
});
|
|
2511
|
-
}, [s]),
|
|
2512
|
-
const v =
|
|
2513
|
-
v.length && (
|
|
2514
|
-
}, [l]),
|
|
2515
|
-
const v =
|
|
2516
|
-
v.length && (
|
|
2517
|
-
}, [l]),
|
|
2518
|
-
|
|
2519
|
-
}, []), C =
|
|
2580
|
+
}, [s]), O = k((p) => {
|
|
2581
|
+
const v = Fr(p.clipboardData);
|
|
2582
|
+
v.length && (p.preventDefault(), l(v));
|
|
2583
|
+
}, [l]), M = k((p) => {
|
|
2584
|
+
const v = Hr(p.dataTransfer);
|
|
2585
|
+
v.length && (p.preventDefault(), l(v));
|
|
2586
|
+
}, [l]), L = k((p) => {
|
|
2587
|
+
p.dataTransfer?.types?.includes("Files") && p.preventDefault();
|
|
2588
|
+
}, []), C = k(async () => {
|
|
2520
2589
|
if (!e.length) return [];
|
|
2521
2590
|
r(!0);
|
|
2522
2591
|
try {
|
|
2523
|
-
return await
|
|
2524
|
-
} catch (
|
|
2525
|
-
return A("chat", "Image upload failed",
|
|
2592
|
+
return await Gr(e);
|
|
2593
|
+
} catch (p) {
|
|
2594
|
+
return A("chat", "Image upload failed", qr(p)), a("error", jr(p)), null;
|
|
2526
2595
|
} finally {
|
|
2527
2596
|
r(!1);
|
|
2528
2597
|
}
|
|
@@ -2531,49 +2600,49 @@ function La() {
|
|
|
2531
2600
|
pending: e,
|
|
2532
2601
|
uploading: n,
|
|
2533
2602
|
addFiles: l,
|
|
2534
|
-
addMeme:
|
|
2603
|
+
addMeme: u,
|
|
2535
2604
|
remove: h,
|
|
2536
2605
|
clear: f,
|
|
2537
2606
|
uploadPending: C,
|
|
2538
|
-
onPaste:
|
|
2539
|
-
onDrop:
|
|
2540
|
-
onDragOver:
|
|
2607
|
+
onPaste: O,
|
|
2608
|
+
onDrop: M,
|
|
2609
|
+
onDragOver: L
|
|
2541
2610
|
};
|
|
2542
2611
|
}
|
|
2543
|
-
const
|
|
2544
|
-
function
|
|
2545
|
-
const [t, n] = R(""), [r, a] = R(!1), [i, s] = R({ q: null, i: 0 }), [l,
|
|
2546
|
-
() =>
|
|
2547
|
-
[
|
|
2548
|
-
), U =
|
|
2549
|
-
(y) => s({ q:
|
|
2550
|
-
[
|
|
2551
|
-
), P =
|
|
2552
|
-
const
|
|
2553
|
-
if (
|
|
2554
|
-
b("info",
|
|
2612
|
+
const Ht = zt, ei = tr;
|
|
2613
|
+
function ti({ commands: e = gt }) {
|
|
2614
|
+
const [t, n] = R(""), [r, a] = R(!1), [i, s] = R({ q: null, i: 0 }), [l, u] = R(!1), h = z(null), f = Mn(), [O, M] = R(!1), [L, C] = R(!1), p = Qa(), v = m((y) => y.snapshot.mediaId), b = m((y) => y.pushToast), I = m((y) => y.setTierlistOpen), g = !!v, E = Ka(t), N = Q(
|
|
2615
|
+
() => E === null ? [] : Wa(E, e),
|
|
2616
|
+
[E, e]
|
|
2617
|
+
), U = E !== null && !l && N.length > 0, F = i.q === E ? We(i.i, N.length) : 0, x = k(
|
|
2618
|
+
(y) => s({ q: E, i: y }),
|
|
2619
|
+
[E]
|
|
2620
|
+
), P = k((y, j) => {
|
|
2621
|
+
const oe = Xa(y, { hasMedia: g });
|
|
2622
|
+
if (oe) {
|
|
2623
|
+
b("info", oe);
|
|
2555
2624
|
return;
|
|
2556
2625
|
}
|
|
2557
2626
|
switch (y.name) {
|
|
2558
2627
|
case "help":
|
|
2559
|
-
b("info", e.map((
|
|
2628
|
+
b("info", e.map((Rn) => Rn.usage).join(" "));
|
|
2560
2629
|
break;
|
|
2561
2630
|
case "recap":
|
|
2562
|
-
|
|
2631
|
+
Ia();
|
|
2563
2632
|
break;
|
|
2564
2633
|
case "tierlist":
|
|
2565
|
-
|
|
2634
|
+
Fo(), I(!0);
|
|
2566
2635
|
break;
|
|
2567
2636
|
default:
|
|
2568
2637
|
b("info", `${y.usage} is not implemented yet.`);
|
|
2569
2638
|
}
|
|
2570
|
-
}, [g, b, e, I]), T =
|
|
2571
|
-
n(
|
|
2572
|
-
}, []),
|
|
2573
|
-
if (y.preventDefault(), r ||
|
|
2574
|
-
const j =
|
|
2575
|
-
if (!j && !
|
|
2576
|
-
if (j?.kind === "command" &&
|
|
2639
|
+
}, [g, b, e, I]), T = k((y) => {
|
|
2640
|
+
n(Ya(y)), u(!1), h.current?.focus();
|
|
2641
|
+
}, []), he = k(async (y) => {
|
|
2642
|
+
if (y.preventDefault(), r || p.uploading) return;
|
|
2643
|
+
const j = za(t, e);
|
|
2644
|
+
if (!j && !p.pending.length) return;
|
|
2645
|
+
if (j?.kind === "command" && p.pending.length) {
|
|
2577
2646
|
b("info", "Send images on their own, not with a command.");
|
|
2578
2647
|
return;
|
|
2579
2648
|
}
|
|
@@ -2581,18 +2650,18 @@ function Ua({ commands: e = mt }) {
|
|
|
2581
2650
|
P(j.command, j.args), n(""), !document.hidden && document.hasFocus() && h.current?.focus();
|
|
2582
2651
|
return;
|
|
2583
2652
|
}
|
|
2584
|
-
const
|
|
2585
|
-
|
|
2586
|
-
}, [t, r, P,
|
|
2653
|
+
const oe = await p.uploadPending();
|
|
2654
|
+
oe !== null && (Sa(j?.text ?? "", oe), n(""), p.clear(), a(!0), setTimeout(() => a(!1), ei), !document.hidden && document.hasFocus() && h.current?.focus());
|
|
2655
|
+
}, [t, r, P, p, b, e]), ge = k((y) => {
|
|
2587
2656
|
if (y.key === "Escape" && U) {
|
|
2588
|
-
y.preventDefault(),
|
|
2657
|
+
y.preventDefault(), u(!0);
|
|
2589
2658
|
return;
|
|
2590
2659
|
}
|
|
2591
2660
|
if (U) {
|
|
2592
2661
|
if (y.key === "ArrowDown")
|
|
2593
|
-
y.preventDefault(), x(
|
|
2662
|
+
y.preventDefault(), x(We(F + 1, N.length));
|
|
2594
2663
|
else if (y.key === "ArrowUp")
|
|
2595
|
-
y.preventDefault(), x(
|
|
2664
|
+
y.preventDefault(), x(We(F - 1, N.length));
|
|
2596
2665
|
else if (y.key === "Tab") {
|
|
2597
2666
|
y.preventDefault();
|
|
2598
2667
|
const j = N[F];
|
|
@@ -2610,22 +2679,22 @@ function Ua({ commands: e = mt }) {
|
|
|
2610
2679
|
};
|
|
2611
2680
|
return window.addEventListener("watchparty:focus-chat-input", y), () => window.removeEventListener("watchparty:focus-chat-input", y);
|
|
2612
2681
|
}, []);
|
|
2613
|
-
const
|
|
2682
|
+
const ye = Ht - t.length, yt = ye <= 100, bt = U ? N[F] : void 0;
|
|
2614
2683
|
return /* @__PURE__ */ _(
|
|
2615
2684
|
"form",
|
|
2616
2685
|
{
|
|
2617
2686
|
onSubmit: (y) => {
|
|
2618
|
-
|
|
2687
|
+
he(y);
|
|
2619
2688
|
},
|
|
2620
|
-
onPaste:
|
|
2621
|
-
onDrop:
|
|
2622
|
-
onDragOver:
|
|
2689
|
+
onPaste: p.onPaste,
|
|
2690
|
+
onDrop: p.onDrop,
|
|
2691
|
+
onDragOver: p.onDragOver,
|
|
2623
2692
|
className: "p-2 border-t border-border",
|
|
2624
2693
|
children: [
|
|
2625
|
-
/* @__PURE__ */ c(
|
|
2694
|
+
/* @__PURE__ */ c(Za, { pending: p.pending, uploading: p.uploading, onRemove: p.remove }),
|
|
2626
2695
|
/* @__PURE__ */ _("div", { className: "relative", children: [
|
|
2627
2696
|
U && /* @__PURE__ */ c(
|
|
2628
|
-
|
|
2697
|
+
Ja,
|
|
2629
2698
|
{
|
|
2630
2699
|
commands: N,
|
|
2631
2700
|
activeIndex: F,
|
|
@@ -2636,13 +2705,13 @@ function Ua({ commands: e = mt }) {
|
|
|
2636
2705
|
}
|
|
2637
2706
|
),
|
|
2638
2707
|
/* @__PURE__ */ c(
|
|
2639
|
-
|
|
2708
|
+
zr,
|
|
2640
2709
|
{
|
|
2641
|
-
open:
|
|
2642
|
-
onClose: () =>
|
|
2643
|
-
onPick:
|
|
2710
|
+
open: O,
|
|
2711
|
+
onClose: () => M(!1),
|
|
2712
|
+
onPick: p.addMeme,
|
|
2644
2713
|
onUnavailable: () => {
|
|
2645
|
-
C(!0),
|
|
2714
|
+
C(!0), M(!1);
|
|
2646
2715
|
}
|
|
2647
2716
|
}
|
|
2648
2717
|
),
|
|
@@ -2655,32 +2724,32 @@ function Ua({ commands: e = mt }) {
|
|
|
2655
2724
|
type: "text",
|
|
2656
2725
|
value: t,
|
|
2657
2726
|
onChange: (y) => {
|
|
2658
|
-
n(y.target.value),
|
|
2727
|
+
n(y.target.value), u(!1);
|
|
2659
2728
|
},
|
|
2660
|
-
onKeyDown:
|
|
2661
|
-
maxLength:
|
|
2729
|
+
onKeyDown: ge,
|
|
2730
|
+
maxLength: Ht,
|
|
2662
2731
|
placeholder: "Send a message",
|
|
2663
2732
|
role: "combobox",
|
|
2664
2733
|
"aria-expanded": U,
|
|
2665
2734
|
"aria-controls": U ? f : void 0,
|
|
2666
|
-
"aria-activedescendant":
|
|
2735
|
+
"aria-activedescendant": bt ? `${f}-opt-${bt.name}` : void 0,
|
|
2667
2736
|
"aria-autocomplete": "list",
|
|
2668
|
-
className: `w-full bg-bg-card border border-border-light rounded px-3 py-1.5 text-sm focus:outline-none focus:border-text-muted ${
|
|
2737
|
+
className: `w-full bg-bg-card border border-border-light rounded px-3 py-1.5 text-sm focus:outline-none focus:border-text-muted ${yt ? "pr-12" : ""}`
|
|
2669
2738
|
}
|
|
2670
2739
|
),
|
|
2671
|
-
/* @__PURE__ */ c("span", { className: `absolute right-2 top-1/2 -translate-y-1/2 text-[10px] ${
|
|
2740
|
+
/* @__PURE__ */ c("span", { className: `absolute right-2 top-1/2 -translate-y-1/2 text-[10px] ${ye <= 50 ? ye <= 0 ? "bg-danger-bg text-on-danger-bg px-1 rounded" : "bg-primary-bg text-on-primary-bg px-1 rounded" : "text-text-muted"}`, children: yt && ye })
|
|
2672
2741
|
] }),
|
|
2673
|
-
!
|
|
2742
|
+
!L && /* @__PURE__ */ c(
|
|
2674
2743
|
"button",
|
|
2675
2744
|
{
|
|
2676
2745
|
type: "button",
|
|
2677
|
-
onClick: () =>
|
|
2746
|
+
onClick: () => M((y) => !y),
|
|
2678
2747
|
"aria-label": "Add a meme",
|
|
2679
|
-
"aria-expanded":
|
|
2748
|
+
"aria-expanded": O,
|
|
2680
2749
|
title: "Add a meme",
|
|
2681
2750
|
"data-testid": "meme-button",
|
|
2682
|
-
className: `shrink-0 rounded border border-border-light px-2 py-1.5 text-sm hover:border-primary ${
|
|
2683
|
-
children: /* @__PURE__ */ c(
|
|
2751
|
+
className: `shrink-0 rounded border border-border-light px-2 py-1.5 text-sm hover:border-primary ${O ? "text-text border-primary" : "text-text-secondary"}`,
|
|
2752
|
+
children: /* @__PURE__ */ c(Ln, { name: "image" })
|
|
2684
2753
|
}
|
|
2685
2754
|
)
|
|
2686
2755
|
] })
|
|
@@ -2689,28 +2758,29 @@ function Ua({ commands: e = mt }) {
|
|
|
2689
2758
|
}
|
|
2690
2759
|
);
|
|
2691
2760
|
}
|
|
2692
|
-
function
|
|
2693
|
-
const e =
|
|
2694
|
-
return t.length ? /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: t.map((n) => {
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
}
|
|
2712
|
-
|
|
2713
|
-
|
|
2761
|
+
function ni() {
|
|
2762
|
+
const e = m((n) => n.roster), t = Object.values(e);
|
|
2763
|
+
return t.length ? /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: t.map((n) => /* @__PURE__ */ c(ri, { u: n }, n.clientId)) }) : /* @__PURE__ */ c("div", { className: "text-xs text-text-muted", children: "No users online" });
|
|
2764
|
+
}
|
|
2765
|
+
function ri({ u: e }) {
|
|
2766
|
+
const t = Pn(e.sprite, e.avatarUrl);
|
|
2767
|
+
return /* @__PURE__ */ _("div", { className: "flex items-center gap-2 py-0.5", children: [
|
|
2768
|
+
/* @__PURE__ */ c(
|
|
2769
|
+
Nn,
|
|
2770
|
+
{
|
|
2771
|
+
sprite: e.sprite,
|
|
2772
|
+
url: e.avatarUrl,
|
|
2773
|
+
alt: e.name || "Anon",
|
|
2774
|
+
className: "w-6 h-6 rounded-full object-cover flex-shrink-0",
|
|
2775
|
+
fallback: /* @__PURE__ */ c("span", { className: "w-6 h-6 bg-bg-alt rounded-full flex-shrink-0" })
|
|
2776
|
+
}
|
|
2777
|
+
),
|
|
2778
|
+
/* @__PURE__ */ c("span", { className: "text-xs font-medium truncate", style: { color: t }, children: e.name || "Anon" }),
|
|
2779
|
+
e.isLeader && /* @__PURE__ */ c("span", { className: "ml-auto px-1.5 py-0.5 rounded text-[9px] font-medium bg-success/20 text-success", children: "Leader" })
|
|
2780
|
+
] });
|
|
2781
|
+
}
|
|
2782
|
+
function oi() {
|
|
2783
|
+
const e = m((a) => Object.keys(a.roster).length), [t, n] = R(!1), r = z(null);
|
|
2714
2784
|
return D(() => {
|
|
2715
2785
|
if (!t) return;
|
|
2716
2786
|
function a(i) {
|
|
@@ -2737,12 +2807,12 @@ function Ha() {
|
|
|
2737
2807
|
e,
|
|
2738
2808
|
" online"
|
|
2739
2809
|
] }),
|
|
2740
|
-
/* @__PURE__ */ c(
|
|
2810
|
+
/* @__PURE__ */ c(ni, {})
|
|
2741
2811
|
] })
|
|
2742
2812
|
] });
|
|
2743
2813
|
}
|
|
2744
|
-
function
|
|
2745
|
-
const t =
|
|
2814
|
+
function $t({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
|
|
2815
|
+
const t = m((r) => r.toasts), n = m((r) => r.popToast);
|
|
2746
2816
|
return D(() => {
|
|
2747
2817
|
const r = t.map((a) => setTimeout(() => n(a.id), 4e3));
|
|
2748
2818
|
return () => {
|
|
@@ -2750,39 +2820,39 @@ function jt({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
|
|
|
2750
2820
|
};
|
|
2751
2821
|
}, [t, n]), /* @__PURE__ */ c("div", { className: `${e} flex flex-col gap-2 z-50`, children: t.map((r) => /* @__PURE__ */ c("div", { className: `px-3 py-2 rounded text-sm shadow font-medium border ${r.kind === "error" ? "bg-danger-bg text-on-danger-bg border-danger" : "bg-bg-card border-border-light text-text"}`, children: r.msg }, r.id)) });
|
|
2752
2822
|
}
|
|
2753
|
-
const
|
|
2754
|
-
function
|
|
2755
|
-
return e || (
|
|
2823
|
+
const Bt = (e) => typeof e == "string" && jn.includes(e);
|
|
2824
|
+
function ai(e, t, n) {
|
|
2825
|
+
return e || (Bt(t) ? t : Bt(n) ? n : "dark");
|
|
2756
2826
|
}
|
|
2757
|
-
function
|
|
2827
|
+
function ii(e, t) {
|
|
2758
2828
|
if (t(e.clientWidth), typeof ResizeObserver > "u") return () => {
|
|
2759
2829
|
};
|
|
2760
2830
|
const n = new ResizeObserver(() => t(e.clientWidth));
|
|
2761
2831
|
return n.observe(e), () => n.disconnect();
|
|
2762
2832
|
}
|
|
2763
|
-
function
|
|
2833
|
+
function si(e) {
|
|
2764
2834
|
const t = e?.trim() ?? "";
|
|
2765
2835
|
return t ? { source: "host", name: t } : { source: "auto" };
|
|
2766
2836
|
}
|
|
2767
|
-
function
|
|
2837
|
+
function li(e) {
|
|
2768
2838
|
if (e.source !== "host") return;
|
|
2769
|
-
const { setSessionIdentity: t, sprite: n } =
|
|
2839
|
+
const { setSessionIdentity: t, sprite: n } = m.getState();
|
|
2770
2840
|
t(e.name, n);
|
|
2771
2841
|
}
|
|
2772
|
-
function
|
|
2842
|
+
function ci({ className: e = "w-4 h-4" }) {
|
|
2773
2843
|
return /* @__PURE__ */ _("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
|
|
2774
2844
|
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 4v16" }),
|
|
2775
2845
|
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 12l-5 4v-8l5 4z" })
|
|
2776
2846
|
] });
|
|
2777
2847
|
}
|
|
2778
|
-
function
|
|
2848
|
+
function di({ className: e = "w-4 h-4" }) {
|
|
2779
2849
|
return /* @__PURE__ */ _("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
|
|
2780
2850
|
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 4v16" }),
|
|
2781
2851
|
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l5 4v-8l-5 4z" })
|
|
2782
2852
|
] });
|
|
2783
2853
|
}
|
|
2784
|
-
const
|
|
2785
|
-
function
|
|
2854
|
+
const ui = 1500;
|
|
2855
|
+
function Ci({
|
|
2786
2856
|
roomKey: e,
|
|
2787
2857
|
serverOrigin: t,
|
|
2788
2858
|
userType: n,
|
|
@@ -2791,61 +2861,61 @@ function si({
|
|
|
2791
2861
|
name: i,
|
|
2792
2862
|
onLeave: s,
|
|
2793
2863
|
onLayoutChange: l,
|
|
2794
|
-
collapsible:
|
|
2864
|
+
collapsible: u = !0,
|
|
2795
2865
|
debug: h,
|
|
2796
2866
|
children: f
|
|
2797
2867
|
}) {
|
|
2798
|
-
const [
|
|
2799
|
-
() =>
|
|
2868
|
+
const [O, M] = R(null), { setFrame: L, ...C } = mi(l, u), p = Vt(() => i), v = Q(() => (So({ userType: n, userId: r ?? null }), mt().theme), [n, r]), b = Un(), I = b?.theme, g = Q(
|
|
2869
|
+
() => ai(a, I, v),
|
|
2800
2870
|
[a, I, v]
|
|
2801
2871
|
);
|
|
2802
2872
|
D(() => {
|
|
2803
2873
|
}, [a, b !== null]);
|
|
2804
2874
|
const N = Q(
|
|
2805
|
-
() => ({ ...
|
|
2875
|
+
() => ({ ...st, serverOrigin: t, defaultRoomKey: e }),
|
|
2806
2876
|
[t, e]
|
|
2807
2877
|
);
|
|
2808
2878
|
return D(() => {
|
|
2809
|
-
h &&
|
|
2810
|
-
}, [h]),
|
|
2811
|
-
|
|
2879
|
+
h && no();
|
|
2880
|
+
}, [h]), Ca(), D(() => {
|
|
2881
|
+
Xr({ serverOrigin: t, defaultRoomKey: e }), m.getState().rehydrateFromPrefs(), Zo();
|
|
2812
2882
|
let U = !1;
|
|
2813
|
-
const F =
|
|
2883
|
+
const F = xo();
|
|
2814
2884
|
return (async () => {
|
|
2815
2885
|
try {
|
|
2816
2886
|
await Promise.race([
|
|
2817
2887
|
Promise.all([
|
|
2818
2888
|
F,
|
|
2819
|
-
|
|
2820
|
-
T &&
|
|
2889
|
+
ko().then((T) => {
|
|
2890
|
+
T && m.getState().rehydrateFromPrefs();
|
|
2821
2891
|
}),
|
|
2822
2892
|
// The character chosen in the settings popout (lib/avatar.ts).
|
|
2823
|
-
|
|
2893
|
+
Bo().then(kn)
|
|
2824
2894
|
]),
|
|
2825
|
-
new Promise((T) => setTimeout(T,
|
|
2895
|
+
new Promise((T) => setTimeout(T, ui))
|
|
2826
2896
|
]);
|
|
2827
2897
|
} catch (T) {
|
|
2828
|
-
A("room-chrome", "pre-join wait threw, proceeding anyway",
|
|
2898
|
+
A("room-chrome", "pre-join wait threw, proceeding anyway", pe(T));
|
|
2829
2899
|
}
|
|
2830
2900
|
if (U) return;
|
|
2831
|
-
const x =
|
|
2832
|
-
|
|
2833
|
-
const P =
|
|
2834
|
-
d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }),
|
|
2901
|
+
const x = si(p());
|
|
2902
|
+
m.getState().ensureAutoIdentity(), li(x);
|
|
2903
|
+
const P = m.getState();
|
|
2904
|
+
d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }), la({ room_key: e, name: P.name || void 0, sprite: P.sprite || void 0 });
|
|
2835
2905
|
})(), () => {
|
|
2836
|
-
U = !0,
|
|
2906
|
+
U = !0, Ft();
|
|
2837
2907
|
};
|
|
2838
|
-
}, [e, t, n, r]), /* @__PURE__ */ c(
|
|
2908
|
+
}, [e, t, n, r]), /* @__PURE__ */ c(Jr.Provider, { value: N, children: /* @__PURE__ */ c(fn.Provider, { value: O, children: /* @__PURE__ */ _("div", { ref: L, className: "wp-room-chrome-frame", children: [
|
|
2839
2909
|
/* @__PURE__ */ c("div", { className: "wp-room-chrome-frame__content", children: f }),
|
|
2840
2910
|
/* @__PURE__ */ c(
|
|
2841
2911
|
"aside",
|
|
2842
2912
|
{
|
|
2843
|
-
ref:
|
|
2913
|
+
ref: M,
|
|
2844
2914
|
className: "wp-room-chrome",
|
|
2845
2915
|
"data-theme": g,
|
|
2846
2916
|
"data-collapsed": C.collapsed ? "1" : "0",
|
|
2847
2917
|
style: { "--wp-room-chrome-width": `${C.state.width}px` },
|
|
2848
|
-
children: C.collapsed ? /* @__PURE__ */ _(
|
|
2918
|
+
children: C.collapsed ? /* @__PURE__ */ _(ce, { children: [
|
|
2849
2919
|
/* @__PURE__ */ c(
|
|
2850
2920
|
"button",
|
|
2851
2921
|
{
|
|
@@ -2854,19 +2924,19 @@ function si({
|
|
|
2854
2924
|
title: "Show chat",
|
|
2855
2925
|
"aria-label": "Show chat",
|
|
2856
2926
|
"aria-expanded": !1,
|
|
2857
|
-
children: /* @__PURE__ */ c(
|
|
2927
|
+
children: /* @__PURE__ */ c(di, {})
|
|
2858
2928
|
}
|
|
2859
2929
|
),
|
|
2860
|
-
/* @__PURE__ */ c(
|
|
2861
|
-
] }) : /* @__PURE__ */ _(
|
|
2930
|
+
/* @__PURE__ */ c($t, { className: "absolute bottom-2 right-full mr-2 w-72" })
|
|
2931
|
+
] }) : /* @__PURE__ */ _(ce, { children: [
|
|
2862
2932
|
/* @__PURE__ */ c(
|
|
2863
2933
|
"div",
|
|
2864
2934
|
{
|
|
2865
2935
|
role: "separator",
|
|
2866
2936
|
"aria-orientation": "vertical",
|
|
2867
2937
|
"aria-label": "Resize chat",
|
|
2868
|
-
"aria-valuemin":
|
|
2869
|
-
"aria-valuemax":
|
|
2938
|
+
"aria-valuemin": Me,
|
|
2939
|
+
"aria-valuemax": ft,
|
|
2870
2940
|
"aria-valuenow": C.state.width,
|
|
2871
2941
|
tabIndex: 0,
|
|
2872
2942
|
className: "wp-room-chrome__resize",
|
|
@@ -2879,13 +2949,13 @@ function si({
|
|
|
2879
2949
|
}
|
|
2880
2950
|
),
|
|
2881
2951
|
/* @__PURE__ */ _("div", { className: "flex items-center gap-1 px-2 py-1.5 border-b border-border", children: [
|
|
2882
|
-
/* @__PURE__ */ c(
|
|
2952
|
+
/* @__PURE__ */ c(oi, {}),
|
|
2883
2953
|
/* @__PURE__ */ c("div", { className: "flex-1" }),
|
|
2884
2954
|
s && /* @__PURE__ */ c(
|
|
2885
2955
|
"button",
|
|
2886
2956
|
{
|
|
2887
2957
|
onClick: () => {
|
|
2888
|
-
|
|
2958
|
+
Ft(), s();
|
|
2889
2959
|
},
|
|
2890
2960
|
className: "wp-room-chrome__leave",
|
|
2891
2961
|
title: "Leave room",
|
|
@@ -2893,7 +2963,7 @@ function si({
|
|
|
2893
2963
|
children: "Leave"
|
|
2894
2964
|
}
|
|
2895
2965
|
),
|
|
2896
|
-
|
|
2966
|
+
u && /* @__PURE__ */ c(
|
|
2897
2967
|
"button",
|
|
2898
2968
|
{
|
|
2899
2969
|
onClick: C.toggleCollapsed,
|
|
@@ -2901,51 +2971,51 @@ function si({
|
|
|
2901
2971
|
title: "Hide chat",
|
|
2902
2972
|
"aria-label": "Hide chat",
|
|
2903
2973
|
"aria-expanded": !0,
|
|
2904
|
-
children: /* @__PURE__ */ c(
|
|
2974
|
+
children: /* @__PURE__ */ c(ci, {})
|
|
2905
2975
|
}
|
|
2906
2976
|
)
|
|
2907
2977
|
] }),
|
|
2908
|
-
/* @__PURE__ */ c(
|
|
2909
|
-
/* @__PURE__ */ c(
|
|
2910
|
-
/* @__PURE__ */ c(
|
|
2978
|
+
/* @__PURE__ */ c(Va, {}),
|
|
2979
|
+
/* @__PURE__ */ c(ti, { commands: [] }),
|
|
2980
|
+
/* @__PURE__ */ c($t, { className: "absolute bottom-14 left-2 right-2" })
|
|
2911
2981
|
] })
|
|
2912
2982
|
}
|
|
2913
2983
|
)
|
|
2914
2984
|
] }) }) });
|
|
2915
2985
|
}
|
|
2916
|
-
function
|
|
2917
|
-
const n =
|
|
2986
|
+
function mi(e, t) {
|
|
2987
|
+
const n = m((g) => g.chromeChatCollapsed) && t, r = m((g) => g.chromeChatWidth), a = m((g) => g.toggleChromeChatCollapsed), i = m((g) => g.setChromeChatWidth), [s, l] = R(null), [u, h] = R(void 0), [f, O] = R(null);
|
|
2918
2988
|
D(() => {
|
|
2919
2989
|
if (s)
|
|
2920
|
-
return
|
|
2990
|
+
return ii(s, h);
|
|
2921
2991
|
}, [s]);
|
|
2922
|
-
const
|
|
2992
|
+
const M = V(f?.current ?? r, u), L = Q(() => Oo(n, M), [n, M]), C = Vt((g) => e?.(g));
|
|
2923
2993
|
return D(() => {
|
|
2924
|
-
C(
|
|
2925
|
-
}, [
|
|
2994
|
+
C(L);
|
|
2995
|
+
}, [L]), {
|
|
2926
2996
|
setFrame: l,
|
|
2927
2997
|
collapsed: n,
|
|
2928
|
-
state:
|
|
2998
|
+
state: L,
|
|
2929
2999
|
dragging: f !== null,
|
|
2930
3000
|
toggleCollapsed: a,
|
|
2931
3001
|
onPointerDown: (g) => {
|
|
2932
|
-
g.button === 0 && (g.preventDefault(), g.currentTarget.setPointerCapture(g.pointerId),
|
|
3002
|
+
g.button === 0 && (g.preventDefault(), g.currentTarget.setPointerCapture(g.pointerId), O({ pointerId: g.pointerId, startX: g.clientX, startWidth: M, current: M }));
|
|
2933
3003
|
},
|
|
2934
3004
|
onPointerMove: (g) => {
|
|
2935
|
-
!f || f.pointerId !== g.pointerId ||
|
|
3005
|
+
!f || f.pointerId !== g.pointerId || O({ ...f, current: Rt(f.startWidth, f.startX, g.clientX, u) });
|
|
2936
3006
|
},
|
|
2937
3007
|
onPointerEnd: (g) => {
|
|
2938
3008
|
if (!f || f.pointerId !== g.pointerId) return;
|
|
2939
|
-
const
|
|
2940
|
-
|
|
3009
|
+
const E = Rt(f.startWidth, f.startX, g.clientX, u);
|
|
3010
|
+
O(null), E !== r && i(E);
|
|
2941
3011
|
},
|
|
2942
3012
|
onKeyDown: (g) => {
|
|
2943
|
-
const
|
|
2944
|
-
|
|
3013
|
+
const E = Do(M, g.key, u);
|
|
3014
|
+
E !== null && (g.preventDefault(), E !== r && i(E));
|
|
2945
3015
|
}
|
|
2946
3016
|
};
|
|
2947
3017
|
}
|
|
2948
3018
|
export {
|
|
2949
|
-
|
|
3019
|
+
Ci as RoomChrome
|
|
2950
3020
|
};
|
|
2951
3021
|
//# sourceMappingURL=room-chrome.js.map
|