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