@hadoku/watchparty-ui 0.44.13 → 0.44.18
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-DfRZgmQ8.js} +14 -14
- package/dist/chunks/{AdminPanel-BmZPZ-JU.js.map → AdminPanel-DfRZgmQ8.js.map} +1 -1
- package/dist/chunks/{GameModule-k9Cccia2.js → GameModule-DLAQtwXo.js} +155 -155
- package/dist/chunks/{GameModule-k9Cccia2.js.map → GameModule-DLAQtwXo.js.map} +1 -1
- package/dist/chunks/{MapEditor-ChMOAaVW.js → MapEditor-BGlAunbV.js} +2 -2
- package/dist/chunks/{MapEditor-ChMOAaVW.js.map → MapEditor-BGlAunbV.js.map} +1 -1
- package/dist/chunks/{MediaDrawer-C7esBn07.js → MediaDrawer-CRMWTqGy.js} +19 -19
- package/dist/chunks/{MediaDrawer-C7esBn07.js.map → MediaDrawer-CRMWTqGy.js.map} +1 -1
- package/dist/chunks/{PlaylistPanel-C17X31ES.js → PlaylistPanel-CxweX09p.js} +15 -15
- package/dist/chunks/{PlaylistPanel-C17X31ES.js.map → PlaylistPanel-CxweX09p.js.map} +1 -1
- package/dist/chunks/{Room-gmERzNR6.js → Room-CHqS_SkX.js} +1843 -1868
- package/dist/chunks/Room-CHqS_SkX.js.map +1 -0
- package/dist/chunks/{index-CR-0msod.js → index-BcGwR0hg.js} +2538 -2394
- package/dist/chunks/index-BcGwR0hg.js.map +1 -0
- package/dist/chunks/{submissionsApi-DsHETYSv.js → submissionsApi-DI0nNhQi.js} +8 -8
- package/dist/chunks/{submissionsApi-DsHETYSv.js.map → submissionsApi-DI0nNhQi.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 +1229 -1347
- 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 _, Fragment as le } from "react/jsx-runtime";
|
|
2
|
+
import Ht, { useState as R, useRef as z, useMemo as Q, useCallback as E, useEffect as D, createContext as $t, useContext as En, useId as Pn, useEffectEvent as Bt } from "react";
|
|
3
|
+
import { themePrefs as ie, Icon as Nn, THEMES as Rn, useHadokuThemeOptional as Dn } 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 {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
import { createCdnClient as On, kindOfType as Mn, MAX_BYTES as Ln, measureImage as jn, filesFromClipboard as Un, filesFromDrop as Fn, CdnError as qe } from "@wolffm/cdn-client";
|
|
6
|
+
import { create as Hn } from "zustand";
|
|
7
|
+
import { createPrefsClient as $n, getDeviceId as Bn, DEVICE_ID_KEY as Gn } from "@wolffm/prefs-client";
|
|
8
|
+
import { io as Kn } from "socket.io-client";
|
|
9
|
+
import { createAvatarClient as Wn, AvatarError as ht } from "@wolffm/prefs-client/avatar";
|
|
10
|
+
import { resolveIdentityReassert as qn } from "@wolffm/rooms-protocol";
|
|
11
|
+
import { createPortal as Vn } from "react-dom";
|
|
12
|
+
import { useCatalogueSearch as Yn } from "@wolffm/cdn-client/react";
|
|
13
|
+
const Gt = "https://cdn.hadoku.me", Kt = /^[0-9a-f]{64}\.(?:png|jpe?g|gif|webp|avif)$/;
|
|
14
|
+
function Je(e) {
|
|
15
|
+
return typeof e == "string" && Kt.test(e);
|
|
16
|
+
}
|
|
17
|
+
const Qe = 8080, Wt = 5173, zn = "/watchparty/ws", qt = 500, Xn = 1e3, V = 4, Vt = typeof process < "u" && process.env ? process.env : {};
|
|
18
|
+
Vt.PRODUCTION_UI_URL;
|
|
19
|
+
Vt.PRODUCTION_SERVER_URL;
|
|
20
|
+
const xe = r.enum(["S", "A", "B", "C", "D", "F"]), gt = 2e4, Jn = 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
|
+
}, Qn = r.enum(["play", "pause", "seek", "load", "home"]), Zn = 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: Zn.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: Qn,
|
|
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 Yt = r.object({
|
|
109
|
+
key: r.string().regex(Kt, "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
|
*
|
|
@@ -129,14 +134,14 @@ const Jt = r.object({
|
|
|
129
134
|
* value only, never as markup. Bounded so one message cannot carry a
|
|
130
135
|
* paragraph; the library's own titles run well under this.
|
|
131
136
|
*/
|
|
132
|
-
title: r.string().max(
|
|
137
|
+
title: r.string().max(Jn).optional()
|
|
133
138
|
});
|
|
134
139
|
r.object({
|
|
135
|
-
text: r.string().max(
|
|
140
|
+
text: r.string().max(qt),
|
|
136
141
|
style: r.string().max(64).optional(),
|
|
137
|
-
images: r.array(
|
|
142
|
+
images: r.array(Yt).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 er = 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(Yt).max(V).optional(),
|
|
153
158
|
isSystem: r.boolean().optional(),
|
|
154
|
-
systemType:
|
|
159
|
+
systemType: er.optional()
|
|
155
160
|
});
|
|
156
|
-
const
|
|
161
|
+
const tr = 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
|
+
}), nr = tr.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(nr),
|
|
210
215
|
server_ts: r.number().int().nonnegative()
|
|
211
216
|
});
|
|
212
|
-
const
|
|
217
|
+
const rr = 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(rr),
|
|
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"]), or = 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,11 +249,11 @@ 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"]), zt = r.object({
|
|
248
253
|
id: r.string(),
|
|
249
254
|
name: r.string(),
|
|
250
|
-
type:
|
|
251
|
-
videos: r.array(
|
|
255
|
+
type: ir.default("vote"),
|
|
256
|
+
videos: r.array(or),
|
|
252
257
|
cover: r.string().optional()
|
|
253
258
|
// media-relative path to the playlist cover image
|
|
254
259
|
});
|
|
@@ -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: zt.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 ar = 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(ar)
|
|
278
283
|
});
|
|
279
284
|
r.object({
|
|
280
|
-
playlist:
|
|
281
|
-
votes: r.record(r.string(), r.record(r.string(),
|
|
285
|
+
playlist: zt,
|
|
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
|
+
}, Xt = 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(Xt)
|
|
306
311
|
});
|
|
307
|
-
const
|
|
308
|
-
r.object({ board:
|
|
309
|
-
const
|
|
312
|
+
const Jt = r.partialRecord(xe, r.array(r.string()));
|
|
313
|
+
r.object({ board: Jt });
|
|
314
|
+
const sr = 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(Xt),
|
|
328
|
+
placed: r.array(sr),
|
|
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: Jt
|
|
331
336
|
});
|
|
332
|
-
const
|
|
337
|
+
const lr = {
|
|
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 cr = {
|
|
346
351
|
STATE: "ready_check_state"
|
|
347
352
|
// distinct from buffer-readiness 'ready_state'
|
|
348
|
-
},
|
|
353
|
+
}, Qt = {
|
|
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 dr = 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(dr)
|
|
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 ur = 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(ur),
|
|
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 mr = [
|
|
443
448
|
{
|
|
444
449
|
id: "fantasy",
|
|
445
450
|
characters: [
|
|
@@ -483,23 +488,23 @@ const nn = [
|
|
|
483
488
|
{ id: "mentor", color: "#e1e0dc" }
|
|
484
489
|
]
|
|
485
490
|
}
|
|
486
|
-
],
|
|
487
|
-
function
|
|
488
|
-
const t =
|
|
491
|
+
], et = mr.flatMap((e) => e.characters), Me = et.map((e) => e.id), fr = Object.fromEntries(et.map((e) => [e.id, e.color])), pr = Object.fromEntries(et.map((e) => [e.id, "rev" in e ? e.rev : 1]));
|
|
492
|
+
function hr(e) {
|
|
493
|
+
const t = pr[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
|
|
495
|
-
function
|
|
496
|
-
return typeof e == "string" &&
|
|
499
|
+
const gr = 5e3, Zt = { mode: "off", percent: 0 }, br = ["off", "on", "ab"];
|
|
500
|
+
function yr(e) {
|
|
501
|
+
return typeof e == "string" && br.includes(e);
|
|
497
502
|
}
|
|
498
|
-
function
|
|
499
|
-
const t = e && typeof e == "object" ? e : {}, n =
|
|
503
|
+
function vr(e) {
|
|
504
|
+
const t = e && typeof e == "object" ? e : {}, n = yr(t.mode) ? t.mode : Zt.mode, o = Number(t.percent), i = Number.isFinite(o) ? Math.min(100, Math.max(0, Math.round(o))) : 0;
|
|
500
505
|
return { mode: n, percent: i };
|
|
501
506
|
}
|
|
502
|
-
function
|
|
507
|
+
function Sr(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;
|
|
@@ -510,10 +515,10 @@ function _r(e, t, n) {
|
|
|
510
515
|
return "fragment";
|
|
511
516
|
if (n === !1)
|
|
512
517
|
return "range";
|
|
513
|
-
const o =
|
|
514
|
-
return o.mode === "on" ? "fragment" : o.mode === "off" || o.percent <= 0 ? "range" : o.percent >= 100 || t &&
|
|
518
|
+
const o = vr(e);
|
|
519
|
+
return o.mode === "on" ? "fragment" : o.mode === "off" || o.percent <= 0 ? "range" : o.percent >= 100 || t && Sr(t) % 100 < o.percent ? "fragment" : "range";
|
|
515
520
|
}
|
|
516
|
-
const
|
|
521
|
+
const en = r.enum(["url", "magnet", "upload"]), wr = 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 xr = 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: en,
|
|
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(),
|
|
@@ -550,7 +555,7 @@ const Cr = r.object({
|
|
|
550
555
|
* misroute the copy.
|
|
551
556
|
*/
|
|
552
557
|
series: r.string().optional(),
|
|
553
|
-
state:
|
|
558
|
+
state: wr,
|
|
554
559
|
createdAt: r.number().int().nonnegative(),
|
|
555
560
|
updatedAt: r.number().int().nonnegative(),
|
|
556
561
|
/** Why it failed, or why an operator rejected it. */
|
|
@@ -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
|
+
}), Ir = 4096, tn = 300, Cr = 100;
|
|
562
567
|
r.object({
|
|
563
|
-
kind:
|
|
564
|
-
source: r.string().min(1).max(
|
|
565
|
-
title: r.string().min(1).max(
|
|
568
|
+
kind: en,
|
|
569
|
+
source: r.string().min(1).max(Ir),
|
|
570
|
+
title: r.string().min(1).max(tn).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(Cr).optional()
|
|
568
573
|
});
|
|
569
574
|
r.object({
|
|
570
|
-
reason: r.string().min(1).max(
|
|
575
|
+
reason: r.string().min(1).max(tn).optional()
|
|
571
576
|
});
|
|
572
577
|
r.object({
|
|
573
|
-
submissions: r.array(
|
|
578
|
+
submissions: r.array(xr)
|
|
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 Tr = /^[a-z0-9][a-z0-9-]{0,31}$/,
|
|
583
|
-
function
|
|
587
|
+
const Tr = /^[a-z0-9][a-z0-9-]{0,31}$/, yt = "https://game-catalog.invalid";
|
|
588
|
+
function kr(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 nn = r.string().min(2).max(512).refine(kr, {
|
|
593
598
|
message: "must be a root-relative path on the page origin (e.g. /cardtable/embed/x.js)"
|
|
594
|
-
}),
|
|
599
|
+
}), vt = {
|
|
595
600
|
id: r.string().regex(Tr),
|
|
596
601
|
name: r.string().min(1).max(64),
|
|
597
|
-
cover:
|
|
602
|
+
cover: nn.optional()
|
|
598
603
|
}, Ar = r.discriminatedUnion("kind", [
|
|
599
|
-
r.object({ ...
|
|
600
|
-
r.object({ ...
|
|
604
|
+
r.object({ ...vt, kind: r.literal("iframe") }).strict(),
|
|
605
|
+
r.object({ ...vt, kind: r.literal("module"), url: nn }).strict()
|
|
601
606
|
]);
|
|
602
607
|
r.array(Ar).max(32).refine((e) => new Set(e.map((t) => t.id)).size === e.length, { message: "game ids must be unique" });
|
|
603
|
-
const
|
|
604
|
-
source:
|
|
608
|
+
const nt = r.enum(["anilist", "tmdb"]), Er = 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,9 +627,9 @@ 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(Er),
|
|
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
634
|
const Pr = r.object({
|
|
630
635
|
id: r.string(),
|
|
@@ -636,33 +641,33 @@ const Pr = r.object({
|
|
|
636
641
|
});
|
|
637
642
|
r.object({ results: r.array(Pr) });
|
|
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, rn = Gt;
|
|
649
|
+
function Nr(e) {
|
|
650
|
+
e.cdnBase && (rn = e.cdnBase);
|
|
646
651
|
}
|
|
647
|
-
function
|
|
648
|
-
return
|
|
652
|
+
function on() {
|
|
653
|
+
return rn.replace(/\/+$/, "");
|
|
649
654
|
}
|
|
650
|
-
function
|
|
651
|
-
const e =
|
|
652
|
-
return (!
|
|
655
|
+
function Le() {
|
|
656
|
+
const e = on();
|
|
657
|
+
return (!ye || ye.base !== e) && (ye = { base: e, client: On({ cdnBase: e }) }), ye.client;
|
|
653
658
|
}
|
|
654
659
|
function Pe(e) {
|
|
655
|
-
return !
|
|
660
|
+
return !Je(e) || !on() ? null : Le().urlFor(e);
|
|
656
661
|
}
|
|
657
|
-
function
|
|
662
|
+
function Rr(e) {
|
|
658
663
|
return e.kind === "file";
|
|
659
664
|
}
|
|
660
|
-
class
|
|
665
|
+
class an 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,177 +687,177 @@ function ke(e) {
|
|
|
682
687
|
return "Image upload failed";
|
|
683
688
|
}
|
|
684
689
|
}
|
|
685
|
-
function Rr(e) {
|
|
686
|
-
return e instanceof ze ? ke(e.reason) : e instanceof dn ? e.message : "Image upload failed";
|
|
687
|
-
}
|
|
688
690
|
function Dr(e) {
|
|
691
|
+
return e instanceof qe ? Ie(e.reason) : e instanceof an ? e.message : "Image upload failed";
|
|
692
|
+
}
|
|
693
|
+
function Or(e) {
|
|
689
694
|
const t = e.type.toLowerCase().split(";")[0].trim();
|
|
690
|
-
return t &&
|
|
695
|
+
return t && Mn(t) !== "image" ? Ie("unsupported-type") : e.size > Ln.image ? Ie("too-large") : e.size === 0 ? Ie("invalid") : null;
|
|
691
696
|
}
|
|
692
|
-
function
|
|
693
|
-
return
|
|
697
|
+
function Mr(e) {
|
|
698
|
+
return Un(e);
|
|
694
699
|
}
|
|
695
|
-
function
|
|
696
|
-
return
|
|
700
|
+
function Lr(e) {
|
|
701
|
+
return Fn(e);
|
|
697
702
|
}
|
|
698
|
-
async function
|
|
699
|
-
const t = await
|
|
703
|
+
async function jr(e) {
|
|
704
|
+
const t = await jn(e);
|
|
700
705
|
return { w: t?.width ?? 0, h: t?.height ?? 0 };
|
|
701
706
|
}
|
|
702
|
-
async function
|
|
703
|
-
const n = await
|
|
704
|
-
if (!
|
|
705
|
-
throw new
|
|
707
|
+
async function Ur(e, t = {}) {
|
|
708
|
+
const n = await Le().upload(e, { signal: t.signal });
|
|
709
|
+
if (!Je(n.key))
|
|
710
|
+
throw new an("Image upload returned an unusable key");
|
|
706
711
|
return { key: n.key, deduplicated: n.deduplicated === !0 };
|
|
707
712
|
}
|
|
708
|
-
async function
|
|
713
|
+
async function Fr(e, t = {}) {
|
|
709
714
|
const n = [];
|
|
710
715
|
for (const o of e) {
|
|
711
716
|
if (o.kind === "remote") {
|
|
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: i } = await
|
|
720
|
+
const { key: i } = await Ur(o.file, t);
|
|
716
721
|
n.push({ key: i, w: o.w, h: o.h });
|
|
717
722
|
}
|
|
718
723
|
return n;
|
|
719
724
|
}
|
|
720
|
-
function
|
|
725
|
+
function Hr(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
|
|
729
|
-
function
|
|
730
|
-
let o = t.left -
|
|
731
|
-
o <
|
|
732
|
-
const i =
|
|
733
|
-
let
|
|
734
|
-
return
|
|
733
|
+
const Ve = 240, X = 8, $r = 28, sn = 240;
|
|
734
|
+
function Br(e, t, n) {
|
|
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 i = sn + $r;
|
|
738
|
+
let a = e.top + e.height / 2 - i / 2;
|
|
739
|
+
return a = Math.min(a, n.height - i - X), a = Math.max(X, a), { left: o, top: a };
|
|
735
740
|
}
|
|
736
|
-
const
|
|
741
|
+
const ln = "/dataplatform/api/memes", Gr = 120;
|
|
737
742
|
function Kr({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
738
|
-
const [o, i] =
|
|
739
|
-
|
|
740
|
-
|
|
743
|
+
const [o, i] = R(""), a = z(null), s = z(null), l = Le(), { items: p, loading: h, error: f, hasMore: L, loadMore: O } = Yn(
|
|
744
|
+
l,
|
|
745
|
+
ln,
|
|
741
746
|
o.trim()
|
|
742
|
-
),
|
|
743
|
-
const
|
|
744
|
-
return
|
|
745
|
-
}, [
|
|
746
|
-
|
|
747
|
-
}, []),
|
|
748
|
-
|
|
749
|
-
}, [
|
|
750
|
-
(
|
|
751
|
-
const
|
|
752
|
-
if (!
|
|
753
|
-
const
|
|
754
|
-
item:
|
|
755
|
-
...
|
|
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, v] = R(null), y = z(null), I = E(() => {
|
|
751
|
+
y.current !== null && (window.clearTimeout(y.current), y.current = null);
|
|
752
|
+
}, []), g = E(() => {
|
|
753
|
+
I(), v(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 = a.current;
|
|
757
|
+
if (!pe) return;
|
|
758
|
+
const he = () => v({
|
|
759
|
+
item: x,
|
|
760
|
+
...Br(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, Gr);
|
|
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
|
+
a.current && !a.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__ */ _(
|
|
782
787
|
"div",
|
|
783
788
|
{
|
|
784
|
-
ref:
|
|
789
|
+
ref: a,
|
|
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) => i(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__ */ _(
|
|
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__ */ _(
|
|
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: sn }
|
|
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
|
)
|
|
@@ -899,61 +904,58 @@ function Kr({ onClose: e, onPick: t, onUnavailable: n }) {
|
|
|
899
904
|
}
|
|
900
905
|
);
|
|
901
906
|
}
|
|
902
|
-
function
|
|
903
|
-
return e ? /* @__PURE__ */
|
|
907
|
+
function Wr({ open: e, ...t }) {
|
|
908
|
+
return e ? /* @__PURE__ */ c(Kr, { ...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: Gt
|
|
909
914
|
};
|
|
910
|
-
let
|
|
911
|
-
function
|
|
915
|
+
let Ce = { ...rt };
|
|
916
|
+
function qr(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 }, Nr({ cdnBase: Ce.cdnBase });
|
|
919
921
|
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
return Wt(pn);
|
|
922
|
+
function me() {
|
|
923
|
+
return Ce;
|
|
923
924
|
}
|
|
924
|
-
|
|
925
|
+
const Vr = $t(rt);
|
|
926
|
+
function Yr(e) {
|
|
925
927
|
return e.serverOrigin?.replace(/\/$/, "") || "";
|
|
926
928
|
}
|
|
927
|
-
function
|
|
928
|
-
return
|
|
929
|
+
function cn() {
|
|
930
|
+
return Yr(me());
|
|
929
931
|
}
|
|
930
|
-
const
|
|
931
|
-
function
|
|
932
|
-
return
|
|
932
|
+
const dn = $t(null);
|
|
933
|
+
function zr() {
|
|
934
|
+
return En(dn);
|
|
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;
|
|
@@ -961,7 +963,7 @@ function at(e, t) {
|
|
|
961
963
|
}
|
|
962
964
|
function Xr() {
|
|
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,46 +975,46 @@ 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
984
|
function Jr(e) {
|
|
983
|
-
const t =
|
|
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 un = /* @__PURE__ */ new Map();
|
|
989
|
+
let mn = !1;
|
|
990
|
+
function Ue(e, t) {
|
|
991
|
+
un.set(e, t), mn && fn(e, t);
|
|
990
992
|
}
|
|
991
|
-
function
|
|
992
|
-
|
|
993
|
-
for (const [e, t] of
|
|
993
|
+
function Qr() {
|
|
994
|
+
mn = !0;
|
|
995
|
+
for (const [e, t] of un) fn(e, t);
|
|
994
996
|
}
|
|
995
|
-
function
|
|
997
|
+
function fn(e, t) {
|
|
996
998
|
typeof window > "u" || (window[e] = t);
|
|
997
999
|
}
|
|
998
|
-
const
|
|
999
|
-
let Te = [],
|
|
1000
|
+
const ae = [], Zr = 500;
|
|
1001
|
+
let Te = [], Ye = null;
|
|
1000
1002
|
const eo = 1e3, to = 200;
|
|
1001
|
-
let
|
|
1002
|
-
function
|
|
1003
|
-
|
|
1003
|
+
let ze = null;
|
|
1004
|
+
function pn(e) {
|
|
1005
|
+
ze = e;
|
|
1004
1006
|
}
|
|
1005
|
-
function
|
|
1006
|
-
return
|
|
1007
|
+
function hn() {
|
|
1008
|
+
return B(te.REPORT_LOGS_FLAG) === "true";
|
|
1007
1009
|
}
|
|
1008
1010
|
function no() {
|
|
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
1016
|
function ro() {
|
|
1015
|
-
const e =
|
|
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;
|
|
@@ -1027,9 +1029,9 @@ function oo() {
|
|
|
1027
1029
|
});
|
|
1028
1030
|
}
|
|
1029
1031
|
function io(e) {
|
|
1030
|
-
|
|
1032
|
+
ae.push(e), ae.length > Zr && ae.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;",
|
|
@@ -1043,51 +1045,51 @@ function ao(e) {
|
|
|
1043
1045
|
return "[unserializable]";
|
|
1044
1046
|
}
|
|
1045
1047
|
}
|
|
1046
|
-
function
|
|
1047
|
-
const
|
|
1048
|
+
function it(e, t, n, o, i, a, s) {
|
|
1049
|
+
const l = {
|
|
1048
1050
|
level: e,
|
|
1049
1051
|
category: i,
|
|
1050
|
-
message:
|
|
1051
|
-
data:
|
|
1052
|
+
message: a,
|
|
1053
|
+
data: s,
|
|
1052
1054
|
timestamp: Date.now()
|
|
1053
1055
|
};
|
|
1054
|
-
if (io(
|
|
1056
|
+
if (io(l), (n || hn()) && St(l), !o) {
|
|
1055
1057
|
if (!no()) return;
|
|
1056
|
-
const
|
|
1057
|
-
if (
|
|
1058
|
+
const f = ro();
|
|
1059
|
+
if (f && !f.has(i.toLowerCase())) return;
|
|
1058
1060
|
}
|
|
1059
|
-
const
|
|
1061
|
+
const p = oo(), h = s !== void 0 ? " " + ao(s) : "";
|
|
1060
1062
|
t(
|
|
1061
|
-
`%c[${
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1063
|
+
`%c[${p}]%c [${i}]%c ${a}${h}`,
|
|
1064
|
+
Fe.time,
|
|
1065
|
+
Fe.category,
|
|
1066
|
+
Fe[e]
|
|
1065
1067
|
);
|
|
1066
1068
|
}
|
|
1067
1069
|
function d(e, t, n) {
|
|
1068
|
-
|
|
1070
|
+
it("debug", console.log, !1, !1, e, t, n);
|
|
1069
1071
|
}
|
|
1070
|
-
function
|
|
1071
|
-
|
|
1072
|
+
function k(e, t, n) {
|
|
1073
|
+
it("warn", console.warn, !0, !1, e, t, n);
|
|
1072
1074
|
}
|
|
1073
|
-
function
|
|
1074
|
-
|
|
1075
|
+
function ke(e, t, n) {
|
|
1076
|
+
it("error", console.error, !0, !0, e, t, n);
|
|
1075
1077
|
}
|
|
1076
1078
|
function so() {
|
|
1077
|
-
return [...
|
|
1079
|
+
return [...ae];
|
|
1078
1080
|
}
|
|
1079
1081
|
function lo() {
|
|
1080
|
-
|
|
1082
|
+
ae.length = 0;
|
|
1081
1083
|
}
|
|
1082
1084
|
function co(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
1088
|
function uo() {
|
|
1087
|
-
|
|
1089
|
+
Ne(te.DEBUG_FLAG), console.log("[wp] Debug mode disabled");
|
|
1088
1090
|
}
|
|
1089
|
-
const mo = 1024,
|
|
1090
|
-
function
|
|
1091
|
+
const mo = 1024, fo = 5e4;
|
|
1092
|
+
function po(e) {
|
|
1091
1093
|
if (e == null) return e;
|
|
1092
1094
|
try {
|
|
1093
1095
|
const t = JSON.stringify(e);
|
|
@@ -1095,8 +1097,8 @@ function fo(e) {
|
|
|
1095
1097
|
if (typeof e == "object" && !Array.isArray(e)) {
|
|
1096
1098
|
const n = {};
|
|
1097
1099
|
for (const [o, i] of Object.entries(e)) {
|
|
1098
|
-
const
|
|
1099
|
-
n[o] =
|
|
1100
|
+
const a = JSON.stringify(i);
|
|
1101
|
+
n[o] = a && a.length > 200 ? `[truncated ${a.length} chars]` : i;
|
|
1100
1102
|
}
|
|
1101
1103
|
return n;
|
|
1102
1104
|
}
|
|
@@ -1108,117 +1110,111 @@ function fo(e) {
|
|
|
1108
1110
|
async function ho() {
|
|
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(Wt) ? n = `${l.protocol}//${l.hostname}:${Qe}` : n = l.origin;
|
|
1117
1119
|
}
|
|
1118
|
-
const o = `${n.replace(/\/$/, "")}/api/client-log`, i = e.map((
|
|
1119
|
-
level:
|
|
1120
|
-
category:
|
|
1121
|
-
message:
|
|
1122
|
-
data:
|
|
1123
|
-
timestamp:
|
|
1120
|
+
const o = `${n.replace(/\/$/, "")}/api/client-log`, i = e.map((l) => ({
|
|
1121
|
+
level: l.level,
|
|
1122
|
+
category: l.category,
|
|
1123
|
+
message: l.message,
|
|
1124
|
+
data: po(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 a = [], s = 0;
|
|
1132
|
+
for (const l of i) {
|
|
1133
|
+
const p = JSON.stringify(l).length + 1;
|
|
1134
|
+
s + p > fo && a.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: a })
|
|
1138
|
+
}), a = [], s = 0), a.push(l), s += p;
|
|
1137
1139
|
}
|
|
1138
|
-
|
|
1140
|
+
a.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: a })
|
|
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 = hn() ? to : eo;
|
|
1152
|
+
Ye = setTimeout(ho, 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
|
-
|
|
1158
|
+
Ue("__wpDebug", {
|
|
1157
1159
|
enable: co,
|
|
1158
1160
|
disable: uo,
|
|
1159
1161
|
history: so,
|
|
1160
1162
|
clear: lo
|
|
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
|
+
function at() {
|
|
1170
|
+
return Y.accountId ? Y.accountId : Y.resolved && Y.userType === "public" ? "anon" : null;
|
|
1169
1171
|
}
|
|
1170
1172
|
function go(e) {
|
|
1171
|
-
|
|
1173
|
+
Y.resolved = !0, e.userType && (Y.userType = e.userType), e.userId !== void 0 && (Y.accountId = e.userId && e.userId !== "public" ? e.userId : null);
|
|
1172
1174
|
}
|
|
1173
|
-
function
|
|
1174
|
-
return
|
|
1175
|
+
function st() {
|
|
1176
|
+
return Y.accountId ?? "public";
|
|
1175
1177
|
}
|
|
1176
1178
|
function bo() {
|
|
1177
|
-
return
|
|
1178
|
-
}
|
|
1179
|
-
function yo() {
|
|
1180
|
-
return nn.flatMap((e) => {
|
|
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 at() ?? "unscoped";
|
|
1190
1180
|
}
|
|
1191
|
-
function
|
|
1192
|
-
return
|
|
1181
|
+
function gn(e) {
|
|
1182
|
+
return tt(e) ? fr[e] : "var(--color-neutral-bg)";
|
|
1193
1183
|
}
|
|
1194
|
-
function
|
|
1195
|
-
return
|
|
1184
|
+
function yo(e) {
|
|
1185
|
+
return tt(e) ? `${me().serverOrigin.replace(/\/$/, "")}${hr(e)}` : void 0;
|
|
1196
1186
|
}
|
|
1197
|
-
let
|
|
1187
|
+
let ce = null, ve = null;
|
|
1198
1188
|
function vo() {
|
|
1199
|
-
return
|
|
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
1207
|
const So = 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 = $n({
|
|
1237
1233
|
appId: "watchparty",
|
|
1238
1234
|
schema: So
|
|
1239
|
-
}),
|
|
1240
|
-
function
|
|
1241
|
-
const t =
|
|
1235
|
+
}), _o = /* @__PURE__ */ new Set(["theme", "themeMode"]);
|
|
1236
|
+
function Re(e) {
|
|
1237
|
+
const t = at();
|
|
1242
1238
|
return t ? `prefs-cache:${t}:${e}` : null;
|
|
1243
1239
|
}
|
|
1244
|
-
function
|
|
1245
|
-
return
|
|
1240
|
+
function wo() {
|
|
1241
|
+
return at() === 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 ?? {};
|
|
@@ -1258,30 +1254,30 @@ function Ct(e) {
|
|
|
1258
1254
|
function xo() {
|
|
1259
1255
|
let e = 0;
|
|
1260
1256
|
for (const t of Xr()) {
|
|
1261
|
-
const n = t.startsWith("prefs-cache:") && t.endsWith(":watchparty"), o = t ===
|
|
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 i =
|
|
1259
|
+
const i = B(t);
|
|
1264
1260
|
if (!i) continue;
|
|
1265
|
-
let
|
|
1261
|
+
let a;
|
|
1266
1262
|
try {
|
|
1267
|
-
|
|
1263
|
+
a = JSON.parse(i);
|
|
1268
1264
|
} catch {
|
|
1269
1265
|
continue;
|
|
1270
1266
|
}
|
|
1271
|
-
const
|
|
1272
|
-
if (!
|
|
1273
|
-
const { name:
|
|
1274
|
-
|
|
1267
|
+
const s = n ? a?.blob : a;
|
|
1268
|
+
if (!s || typeof s != "object" || !("name" in s)) continue;
|
|
1269
|
+
const { name: l, ...p } = s, h = n ? { ...a, 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 bn = null, yn = null;
|
|
1275
|
+
const wt = /* @__PURE__ */ new Set();
|
|
1276
|
+
function lt() {
|
|
1277
|
+
if (wo())
|
|
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 : bn ?? {}, o = Object.keys(t).length > 0 ? t : yn ?? {}, i = st() || "public";
|
|
1280
|
+
if (wt.has(i))
|
|
1285
1281
|
return d("preferences", "Loaded (sync, SDK-only after first read)", {
|
|
1286
1282
|
uid: i,
|
|
1287
1283
|
sdkThemeKeys: Object.keys(n).length,
|
|
@@ -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(i);
|
|
1291
|
+
const a = Sn() ?? {}, s = { ...a, ...o, ...n };
|
|
1296
1292
|
return d("preferences", "Loaded (sync, first read — legacy + SDK)", {
|
|
1297
1293
|
uid: i,
|
|
1298
1294
|
sdkThemeKeys: Object.keys(n).length,
|
|
1299
1295
|
sdkAppKeys: Object.keys(o).length,
|
|
1300
|
-
legacyKeys: Object.keys(
|
|
1296
|
+
legacyKeys: Object.keys(a).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
|
|
1306
|
-
function
|
|
1307
|
-
const e =
|
|
1301
|
+
let vn = !1;
|
|
1302
|
+
function Io() {
|
|
1303
|
+
const e = st();
|
|
1308
1304
|
return !e || e === "public";
|
|
1309
1305
|
}
|
|
1310
|
-
function
|
|
1311
|
-
|
|
1306
|
+
function G(e, t) {
|
|
1307
|
+
Io() && (vn = !0), _o.has(e) ? ie.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 Co() {
|
|
1311
|
+
return Se || (Se = (async () => {
|
|
1316
1312
|
if (typeof window > "u") return !1;
|
|
1317
1313
|
try {
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
}),
|
|
1321
|
-
|
|
1314
|
+
xt || (xt = !0, ie.subscribe((s) => {
|
|
1315
|
+
bn = s, Tt("portfolio", s), kt("theme");
|
|
1316
|
+
}), se.subscribe((s) => {
|
|
1317
|
+
yn = s, Tt("watchparty", s), kt("watchparty");
|
|
1322
1318
|
}));
|
|
1323
1319
|
const [e, t] = await Promise.all([
|
|
1324
|
-
|
|
1325
|
-
|
|
1320
|
+
ie.read(),
|
|
1321
|
+
se.read()
|
|
1326
1322
|
]);
|
|
1327
1323
|
try {
|
|
1328
|
-
const { useAppStore:
|
|
1329
|
-
|
|
1330
|
-
} catch (
|
|
1331
|
-
|
|
1324
|
+
const { useAppStore: s } = await Promise.resolve().then(() => wn);
|
|
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"), i = n ? B(n) : null, a = 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
1335
|
sdkThemeBytesPost: i?.length ?? 0,
|
|
1341
|
-
sdkAppBytesPost:
|
|
1342
|
-
}), await
|
|
1343
|
-
|
|
1336
|
+
sdkAppBytesPost: a?.length ?? 0
|
|
1337
|
+
}), await To(e, t), vn ? (d("preferences", "Promoting this load's pre-auth picks to the signed-in user"), await Promise.all([
|
|
1338
|
+
ie.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
|
|
1348
|
+
const De = "watchparty_preferences";
|
|
1354
1349
|
xo();
|
|
1355
|
-
function
|
|
1356
|
-
const e =
|
|
1357
|
-
return !e || e === "public" ?
|
|
1350
|
+
function Xe() {
|
|
1351
|
+
const e = st();
|
|
1352
|
+
return !e || e === "public" ? De : `${De}:${e}`;
|
|
1358
1353
|
}
|
|
1359
|
-
function
|
|
1360
|
-
const e =
|
|
1354
|
+
function Sn() {
|
|
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 To(e, t) {
|
|
1368
|
+
const n = Sn();
|
|
1374
1369
|
if (!n || Object.keys(n).length === 0) return;
|
|
1375
|
-
const o = Object.keys(e ?? {}).length > 0, i = Object.keys(t ?? {}).length > 0,
|
|
1376
|
-
for (const [
|
|
1377
|
-
o || (
|
|
1378
|
-
const
|
|
1379
|
-
if (
|
|
1380
|
-
|
|
1370
|
+
const o = Object.keys(e ?? {}).length > 0, i = Object.keys(t ?? {}).length > 0, a = {}, s = {};
|
|
1371
|
+
for (const [h, f] of Object.entries(n))
|
|
1372
|
+
o || (h === "theme" && typeof f == "string" ? a.theme = f : h === "themeMode" && (f === "simple" || f === "advanced") && (a.themeMode = f)), i || (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(a), 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
1382
|
sdkHasApp: i
|
|
1388
1383
|
});
|
|
1389
1384
|
try {
|
|
1390
1385
|
await Promise.all([
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
]),
|
|
1394
|
-
} catch (
|
|
1395
|
-
|
|
1396
|
-
err:
|
|
1386
|
+
l.length > 0 ? ie.save(a, { 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,64 +1405,63 @@ 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(() => wn).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 _n = 320, Oe = 240, ct = 640, ko = 320, Ao = 36, At = 16;
|
|
1425
|
+
function W(e, t) {
|
|
1426
|
+
if (!Number.isFinite(e)) return _n;
|
|
1427
|
+
let n = ct;
|
|
1428
|
+
return t !== void 0 && Number.isFinite(t) && t > 0 && (n = Math.min(n, t - ko)), 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 Eo(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
|
}
|
|
1451
1446
|
}
|
|
1452
|
-
function
|
|
1453
|
-
return { collapsed: e, width: e ?
|
|
1447
|
+
function Po(e, t) {
|
|
1448
|
+
return { collapsed: e, width: e ? Ao : t };
|
|
1454
1449
|
}
|
|
1455
|
-
const
|
|
1450
|
+
const K = lt(), u = Hn((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 ?? _n),
|
|
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,29 +1497,26 @@ 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 i =
|
|
1516
|
-
return d("store", "Auto-identity: deriving name from
|
|
1506
|
+
const i = de(n.sprite);
|
|
1507
|
+
return d("store", "Auto-identity: deriving name from the requested sprite", { name: i, sprite: n.sprite }), { name: i };
|
|
1517
1508
|
}
|
|
1518
1509
|
const o = new Set(Object.values(n.roster).map((i) => i.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 i of
|
|
1514
|
+
for (const i of Me)
|
|
1524
1515
|
if (!o.has(i)) {
|
|
1525
|
-
const
|
|
1526
|
-
return d("store", "Auto-identity assigned", { name:
|
|
1516
|
+
const a = de(i);
|
|
1517
|
+
return d("store", "Auto-identity assigned", { name: a, sprite: i }), { name: a, sprite: i };
|
|
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 } }));
|
|
@@ -1533,23 +1524,23 @@ const q = dt(), m = Gn((e, t) => ({
|
|
|
1533
1524
|
applySnapshot: (n) => e((o) => {
|
|
1534
1525
|
const i = { ...o.roster };
|
|
1535
1526
|
if (n.users)
|
|
1536
|
-
for (const
|
|
1537
|
-
const
|
|
1527
|
+
for (const p of n.users) i[p.clientId] = p;
|
|
1528
|
+
const a = 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: a,
|
|
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: a,
|
|
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
1545
|
roster: i,
|
|
1555
1546
|
// Always update — initial snapshot on join often has playheadMs=0
|
|
@@ -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,14 +1595,14 @@ const q = dt(), m = Gn((e, t) => ({
|
|
|
1605
1595
|
snapshotReceivedAt: Date.now()
|
|
1606
1596
|
}));
|
|
1607
1597
|
},
|
|
1608
|
-
addRttSample: (n, o, i) => e((
|
|
1609
|
-
const
|
|
1610
|
-
let
|
|
1598
|
+
addRttSample: (n, o, i) => e((a) => {
|
|
1599
|
+
const s = [...a.drift.rtts, n].slice(-5);
|
|
1600
|
+
let l = a.drift.offsetMs;
|
|
1611
1601
|
if (o && i) {
|
|
1612
|
-
const
|
|
1613
|
-
|
|
1602
|
+
const p = i + 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
1608
|
d("store", "Toast pushed", { kind: n, msg: o }), e((i) => ({ toasts: [...i.toasts, { id: Math.random().toString(36).slice(2), kind: n, msg: o, ts: Date.now() }].slice(-5) }));
|
|
@@ -1622,11 +1612,11 @@ const q = dt(), m = Gn((e, t) => ({
|
|
|
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({
|
|
@@ -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, i) => e((
|
|
1666
|
-
const
|
|
1667
|
-
for (const [
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1655
|
+
moveTierlistItem: (n, o, i) => e((a) => {
|
|
1656
|
+
const s = {};
|
|
1657
|
+
for (const [l, p] of Object.entries(a.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(i ?? 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,116 @@ 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(), i = {};
|
|
1675
|
+
if (o.chatCollapsed !== void 0 && (i.chatCollapsed = o.chatCollapsed), o.chromeChatCollapsed !== void 0 && (i.chromeChatCollapsed = o.chromeChatCollapsed), o.chromeChatWidth !== void 0 && (i.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), i.mediaPrefs = l;
|
|
1688
1678
|
}
|
|
1689
1679
|
return i;
|
|
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 wn = /* @__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 No(e) {
|
|
1689
|
+
return `${cn()}/media/${e}`.replace(/\\/g, "/");
|
|
1700
1690
|
}
|
|
1701
|
-
function
|
|
1702
|
-
return
|
|
1691
|
+
function Ro(e, t) {
|
|
1692
|
+
return No(t ?? `${e}/poster.jpg`);
|
|
1703
1693
|
}
|
|
1704
|
-
function
|
|
1705
|
-
return `${
|
|
1694
|
+
function Do(e) {
|
|
1695
|
+
return `${cn()}${e}`.replace(/\\/g, "/");
|
|
1706
1696
|
}
|
|
1707
|
-
async function
|
|
1697
|
+
async function Oo(e) {
|
|
1708
1698
|
try {
|
|
1709
|
-
const t = await fetch(
|
|
1699
|
+
const t = await fetch(Do("/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 Mo() {
|
|
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 = Ro(t.id, t.thumbnail);
|
|
1731
1721
|
}
|
|
1732
1722
|
d("tierlist", "Warming posters", { count: e.items.length });
|
|
1733
1723
|
}
|
|
1734
1724
|
}
|
|
1735
1725
|
function Lo() {
|
|
1736
|
-
const e =
|
|
1726
|
+
const e = u.getState(), t = new Set(Object.values(e.roster).map((a) => a.sprite).filter(Boolean)), n = Me.find((a) => !t.has(a));
|
|
1737
1727
|
if (!n)
|
|
1738
|
-
return
|
|
1739
|
-
const o = !!e.name && !
|
|
1728
|
+
return k("socket", "sprite_taken: no available sprites to retry with"), null;
|
|
1729
|
+
const o = !!e.name && !J(e.name), i = o ? e.name : de(n);
|
|
1740
1730
|
return d("socket", "sprite_taken: retrying with next available", { from: e.sprite, to: n, name: i, keptCustomName: o }), e.setSessionIdentity(i, n), { name: i, sprite: n };
|
|
1741
1731
|
}
|
|
1742
1732
|
function jo(e) {
|
|
1743
|
-
const t =
|
|
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
|
|
1736
|
+
const Nt = "hadoku:avatar";
|
|
1737
|
+
function xn(e) {
|
|
1738
|
+
const t = e?.sprite ?? e?.avatar?.sprite ?? null;
|
|
1739
|
+
return tt(t) ? t : null;
|
|
1740
|
+
}
|
|
1741
|
+
async function Uo(e = {}) {
|
|
1742
|
+
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);
|
|
1743
|
+
if (!t || !o) return null;
|
|
1744
|
+
try {
|
|
1745
|
+
const i = await Wn({ baseUrl: o, fetch: t }).get(), a = xn(i);
|
|
1746
|
+
return d("avatar", "Requested character from prefs-api", { sprite: a }), a;
|
|
1747
|
+
} catch (i) {
|
|
1748
|
+
return i instanceof ht && (i.status === 401 || i.status === 403 || i.status === 404) ? d("avatar", "No avatar settings here (signed out, or no prefs-api on this origin)", { status: i.status }) : k("avatar", "Avatar settings read failed — keeping the auto-assigned character", {
|
|
1749
|
+
status: i instanceof ht ? i.status : void 0,
|
|
1750
|
+
...fe(i)
|
|
1751
|
+
}), null;
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
function Rt(e) {
|
|
1755
|
+
if (!e) return !1;
|
|
1756
|
+
const t = u.getState();
|
|
1757
|
+
if (t.sprite === e) return !1;
|
|
1758
|
+
const o = !!(t.me.clientId && t.roster[t.me.clientId]?.registryName) || !t.name || !J(t.name) ? t.name : de(e);
|
|
1759
|
+
return t.setSessionIdentity(o, e), !0;
|
|
1760
|
+
}
|
|
1761
|
+
function Fo(e, t = typeof window > "u" ? void 0 : window) {
|
|
1762
|
+
if (!t) return () => {
|
|
1763
|
+
};
|
|
1764
|
+
const n = (o) => {
|
|
1765
|
+
const i = o.detail;
|
|
1766
|
+
!i || typeof i != "object" || e(i);
|
|
1767
|
+
};
|
|
1768
|
+
return t.addEventListener(Nt, n), () => t.removeEventListener(Nt, n);
|
|
1769
|
+
}
|
|
1770
|
+
const Ho = 10;
|
|
1771
|
+
function $o(e = typeof window < "u" ? window : void 0) {
|
|
1748
1772
|
if (!e) return { framed: !1, depth: 0 };
|
|
1749
1773
|
try {
|
|
1750
1774
|
let t = 0, n = e;
|
|
1751
|
-
for (; n !== n.parent && t <
|
|
1775
|
+
for (; n !== n.parent && t < Ho; )
|
|
1752
1776
|
t++, n = n.parent;
|
|
1753
1777
|
return { framed: e.top ? e.top !== e.self : t > 0, depth: t };
|
|
1754
1778
|
} catch {
|
|
1755
1779
|
return { framed: !1, depth: 0 };
|
|
1756
1780
|
}
|
|
1757
1781
|
}
|
|
1758
|
-
const
|
|
1759
|
-
function
|
|
1782
|
+
const Bo = "watchparty_fragment_delivery";
|
|
1783
|
+
function Go() {
|
|
1760
1784
|
if (typeof window > "u") return null;
|
|
1761
1785
|
try {
|
|
1762
1786
|
const e = new URLSearchParams(window.location.search).get("fragmentDelivery");
|
|
@@ -1764,93 +1788,93 @@ function $o() {
|
|
|
1764
1788
|
if (e === "0" || e === "false") return !1;
|
|
1765
1789
|
} catch {
|
|
1766
1790
|
}
|
|
1767
|
-
return Jr(
|
|
1791
|
+
return Jr(Bo);
|
|
1768
1792
|
}
|
|
1769
|
-
let
|
|
1770
|
-
const
|
|
1771
|
-
function
|
|
1772
|
-
const e =
|
|
1793
|
+
let Ko = { ...Zt }, He = null;
|
|
1794
|
+
const Dt = "watchparty_delivery_client_id";
|
|
1795
|
+
function Wo() {
|
|
1796
|
+
const e = B(Dt);
|
|
1773
1797
|
if (e) return e;
|
|
1774
1798
|
const t = globalThis.crypto?.randomUUID?.() ?? `d${Math.random().toString(36).slice(2)}`;
|
|
1775
|
-
return
|
|
1799
|
+
return ot(Dt, t) ? t : "";
|
|
1776
1800
|
}
|
|
1777
|
-
function
|
|
1778
|
-
return
|
|
1801
|
+
function qo() {
|
|
1802
|
+
return He === null && (He = _r(Ko, Wo(), Go())), He;
|
|
1779
1803
|
}
|
|
1780
|
-
function
|
|
1781
|
-
return
|
|
1804
|
+
function Vo() {
|
|
1805
|
+
return qo();
|
|
1782
1806
|
}
|
|
1783
|
-
let
|
|
1784
|
-
function
|
|
1785
|
-
return
|
|
1807
|
+
let Ae;
|
|
1808
|
+
function In() {
|
|
1809
|
+
return B(Gn) || void 0;
|
|
1786
1810
|
}
|
|
1787
|
-
function
|
|
1788
|
-
if (
|
|
1789
|
-
const e =
|
|
1811
|
+
function Yo() {
|
|
1812
|
+
if (Ae) return;
|
|
1813
|
+
const e = In();
|
|
1790
1814
|
if (e) {
|
|
1791
|
-
|
|
1815
|
+
Ae = e;
|
|
1792
1816
|
return;
|
|
1793
1817
|
}
|
|
1794
|
-
|
|
1795
|
-
t && (
|
|
1818
|
+
Bn().then((t) => {
|
|
1819
|
+
t && (Ae = t);
|
|
1796
1820
|
}).catch(() => {
|
|
1797
1821
|
d("identity", "device id unavailable — joining without one");
|
|
1798
1822
|
});
|
|
1799
1823
|
}
|
|
1800
|
-
function
|
|
1801
|
-
return
|
|
1824
|
+
function zo() {
|
|
1825
|
+
return Ae ??= In();
|
|
1802
1826
|
}
|
|
1803
|
-
function
|
|
1827
|
+
function Xo(e, t) {
|
|
1804
1828
|
let n = 0;
|
|
1805
1829
|
for (const o of e.videos) {
|
|
1806
|
-
const i =
|
|
1807
|
-
globalThis.localStorage?.getItem(i) != null && n++,
|
|
1830
|
+
const i = te.voteKey(t, e.id, o.mediaId);
|
|
1831
|
+
globalThis.localStorage?.getItem(i) != null && n++, Ne(i);
|
|
1808
1832
|
}
|
|
1809
1833
|
return n;
|
|
1810
1834
|
}
|
|
1811
|
-
const
|
|
1812
|
-
function
|
|
1835
|
+
const Jo = 2e4, Qo = 1e4;
|
|
1836
|
+
function Zo() {
|
|
1813
1837
|
return { unansweredSince: null, lastPongAt: null, lastTickAt: null };
|
|
1814
1838
|
}
|
|
1815
|
-
function
|
|
1839
|
+
function ei(e, t) {
|
|
1816
1840
|
e.lastPongAt = t, e.unansweredSince = null;
|
|
1817
1841
|
}
|
|
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 >
|
|
1842
|
+
function ti(e, t, n) {
|
|
1843
|
+
const o = e.lastTickAt !== null && t - e.lastTickAt > Qo;
|
|
1844
|
+
return e.lastTickAt = t, n ? o || e.unansweredSince === null ? (e.unansweredSince = t, !1) : t - e.unansweredSince > Jo : (e.unansweredSince = null, !1);
|
|
1821
1845
|
}
|
|
1822
|
-
function
|
|
1846
|
+
function ni(e, t) {
|
|
1823
1847
|
return e.lastPongAt === null ? void 0 : Math.max(0, t - e.lastPongAt);
|
|
1824
1848
|
}
|
|
1825
|
-
let
|
|
1826
|
-
const
|
|
1827
|
-
let _e = null,
|
|
1828
|
-
function
|
|
1829
|
-
const t =
|
|
1849
|
+
let S = null, H = null, Ee = null, $ = null, q = null;
|
|
1850
|
+
const ri = ai(), Z = Zo();
|
|
1851
|
+
let _e = null, $e = null, Ot = 0, dt = null, ue = !1, ut = !1, oe = !1, Cn = null;
|
|
1852
|
+
function oi(e) {
|
|
1853
|
+
const t = ne(), n = u.getState();
|
|
1830
1854
|
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(
|
|
1855
|
+
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;
|
|
1856
|
+
const o = ii(e);
|
|
1857
|
+
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", () => {
|
|
1858
|
+
d("socket", "Emitting join", o), t.emit(w.JOIN, o);
|
|
1835
1859
|
}), t;
|
|
1836
1860
|
}
|
|
1837
|
-
function
|
|
1861
|
+
function ii(e) {
|
|
1838
1862
|
return {
|
|
1839
1863
|
room_key: e.room_key,
|
|
1840
1864
|
name: e.name,
|
|
1841
1865
|
sprite: e.sprite,
|
|
1842
1866
|
// Entry-path telemetry — see lib/embedContext.ts. Sent on every join AND
|
|
1843
1867
|
// rejoin (lastJoinPayload carries it), so a reconnect keeps the attribution.
|
|
1844
|
-
embed:
|
|
1845
|
-
delivery_arm:
|
|
1868
|
+
embed: $o(),
|
|
1869
|
+
delivery_arm: Vo(),
|
|
1846
1870
|
// Identity tier input — see lib/deviceId.ts. Sent on every join AND rejoin
|
|
1847
1871
|
// (lastJoinPayload carries it) so a reconnect lands on the same
|
|
1848
1872
|
// ParticipantId rather than minting a new person.
|
|
1849
|
-
device_id:
|
|
1850
|
-
tab_id:
|
|
1873
|
+
device_id: zo(),
|
|
1874
|
+
tab_id: ri
|
|
1851
1875
|
};
|
|
1852
1876
|
}
|
|
1853
|
-
function
|
|
1877
|
+
function ai() {
|
|
1854
1878
|
const e = globalThis.crypto;
|
|
1855
1879
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
1856
1880
|
const t = new Uint8Array(16);
|
|
@@ -1858,67 +1882,67 @@ function oi() {
|
|
|
1858
1882
|
else for (let n = 0; n < t.length; n++) t[n] = Math.floor(Math.random() * 256);
|
|
1859
1883
|
return Array.from(t, (n) => n.toString(16).padStart(2, "0")).join("");
|
|
1860
1884
|
}
|
|
1861
|
-
function
|
|
1862
|
-
if (!
|
|
1863
|
-
let t =
|
|
1885
|
+
function ne() {
|
|
1886
|
+
if (!S) {
|
|
1887
|
+
let t = me().serverOrigin || "/";
|
|
1864
1888
|
if (t === "/" && typeof window < "u") {
|
|
1865
1889
|
const o = window.location;
|
|
1866
|
-
(o.hostname === "localhost" || o.hostname === "127.0.0.1") && o.port === String(
|
|
1890
|
+
(o.hostname === "localhost" || o.hostname === "127.0.0.1") && o.port === String(Wt) && (t = `${o.protocol}//${o.hostname}:${Qe}`, d("socket", "Using dev fallback origin", { origin: t }));
|
|
1867
1891
|
}
|
|
1868
1892
|
const n = new URL(t.startsWith("http") ? t : `${window.location.origin}${t}`).origin;
|
|
1869
|
-
|
|
1870
|
-
if (
|
|
1871
|
-
|
|
1872
|
-
sid:
|
|
1873
|
-
lastPongAgeMs:
|
|
1874
|
-
}),
|
|
1893
|
+
S = Kn(n, { path: zn, transports: ["websocket", "polling"] }), d("socket", "Socket initialized", { origin: t }), Ue("__SOCKET__", S), $ && (clearTimeout($), $ = null), H = null, Ee = setInterval(() => {
|
|
1894
|
+
if (ti(Z, Date.now(), !!S?.connected)) {
|
|
1895
|
+
k("socket", "PONG-WATCHDOG no time_pong for 20s — replacing the connection", {
|
|
1896
|
+
sid: S?.id,
|
|
1897
|
+
lastPongAgeMs: ni(Z, Date.now()) ?? null
|
|
1898
|
+
}), $e = "pong-watchdog", Z.unansweredSince = null, S?.io.engine?.close();
|
|
1875
1899
|
return;
|
|
1876
1900
|
}
|
|
1877
|
-
|
|
1878
|
-
},
|
|
1879
|
-
|
|
1880
|
-
const o =
|
|
1881
|
-
if (d("socket", "Connected", { id: o, isReconnect:
|
|
1901
|
+
bi();
|
|
1902
|
+
}, gr), S.on("connect", () => {
|
|
1903
|
+
ut = !1;
|
|
1904
|
+
const o = S?.id;
|
|
1905
|
+
if (d("socket", "Connected", { id: o, isReconnect: oe }), o)
|
|
1882
1906
|
try {
|
|
1883
|
-
|
|
1907
|
+
u.getState().ensureMe(o), u.setState((i) => ({ me: { ...i.me, nextClientSeq: 1 } })), d("socket", "Reset client sequence for new connection");
|
|
1884
1908
|
} catch (i) {
|
|
1885
|
-
|
|
1909
|
+
ke("socket", "Failed to initialize store on connect", { error: i.message, sid: o });
|
|
1886
1910
|
}
|
|
1887
|
-
if (
|
|
1888
|
-
const i =
|
|
1889
|
-
|
|
1890
|
-
const
|
|
1891
|
-
...
|
|
1911
|
+
if (oe && q) {
|
|
1912
|
+
const i = u.getState();
|
|
1913
|
+
Ot += 1;
|
|
1914
|
+
const a = {
|
|
1915
|
+
...q,
|
|
1892
1916
|
name: i.name,
|
|
1893
1917
|
sprite: i.sprite,
|
|
1894
1918
|
reconnect: {
|
|
1895
|
-
count:
|
|
1919
|
+
count: Ot,
|
|
1896
1920
|
reason: (_e?.reason ?? "unknown").slice(0, 64),
|
|
1897
1921
|
offline_ms: _e ? Math.max(0, Date.now() - _e.at) : 0
|
|
1898
1922
|
}
|
|
1899
|
-
},
|
|
1900
|
-
if (d("socket", "Re-emitting join after reconnect", { room_key:
|
|
1901
|
-
let
|
|
1902
|
-
const
|
|
1903
|
-
|
|
1923
|
+
}, s = Cn;
|
|
1924
|
+
if (d("socket", "Re-emitting join after reconnect", { room_key: a.room_key, name: a.name, sprite: a.sprite }), s) {
|
|
1925
|
+
let l = !1;
|
|
1926
|
+
const p = () => {
|
|
1927
|
+
l || (l = !0, S.off(w.SNAPSHOT, p), S.emit(w.CLIENT_READY, { media_id: s }), d("socket", "Re-emitted client_ready after reconnect snapshot", { mediaId: s }));
|
|
1904
1928
|
};
|
|
1905
|
-
|
|
1906
|
-
|
|
1929
|
+
S.on(w.SNAPSHOT, p), setTimeout(() => {
|
|
1930
|
+
l || (l = !0, S.off(w.SNAPSHOT, p), k("socket", "client_ready re-emit timed out waiting for snapshot", { mediaId: s }));
|
|
1907
1931
|
}, 1e4);
|
|
1908
1932
|
}
|
|
1909
|
-
|
|
1910
|
-
} else
|
|
1911
|
-
|
|
1912
|
-
}),
|
|
1913
|
-
|
|
1914
|
-
}),
|
|
1933
|
+
dt = { name: a.name, sprite: a.sprite }, S.emit(w.JOIN, a), window.dispatchEvent(new CustomEvent("watchparty:socket-reconnect"));
|
|
1934
|
+
} else oe && k("socket", "Reconnected — no join payload, not re-joining any room");
|
|
1935
|
+
oe = !0;
|
|
1936
|
+
}), S.on("disconnect", (o) => {
|
|
1937
|
+
pn(null), _e = { reason: $e ?? o, at: Date.now() }, $e = null, d("socket", "Disconnected", { reason: o });
|
|
1938
|
+
}), S.on("connect_error", (o) => ke("socket", "Connection error", { message: o?.message })), S.on("reconnect_attempt", (o) => k("socket", "Reconnect attempt", { attempt: o })), S.on("reconnect_failed", () => ke("socket", "Reconnect failed")), hi(S);
|
|
1915
1939
|
}
|
|
1916
|
-
return
|
|
1940
|
+
return S;
|
|
1917
1941
|
}
|
|
1918
|
-
function
|
|
1942
|
+
function Be(e) {
|
|
1919
1943
|
return e.play_state === "playing" || e.playing === !0;
|
|
1920
1944
|
}
|
|
1921
|
-
function
|
|
1945
|
+
function Mt(e, t) {
|
|
1922
1946
|
return {
|
|
1923
1947
|
id: String(e.id ?? e.server_seq ?? t ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`),
|
|
1924
1948
|
clientId: e.client_id,
|
|
@@ -1930,52 +1954,52 @@ function Lt(e, t) {
|
|
|
1930
1954
|
// Attachments arrive from other clients, so the key shape is re-checked
|
|
1931
1955
|
// here at the boundary rather than trusted at render time. A malformed
|
|
1932
1956
|
// entry is dropped, not rendered and not allowed near an <img src>.
|
|
1933
|
-
images: Array.isArray(e.images) ? e.images.filter((n) => !!n &&
|
|
1957
|
+
images: Array.isArray(e.images) ? e.images.filter((n) => !!n && Je(n.key)).slice(0, V) : void 0,
|
|
1934
1958
|
isSystem: e.isSystem || !1,
|
|
1935
1959
|
systemType: e.systemType
|
|
1936
1960
|
};
|
|
1937
1961
|
}
|
|
1938
|
-
function
|
|
1939
|
-
e.on(
|
|
1940
|
-
e.emit(
|
|
1962
|
+
function si(e) {
|
|
1963
|
+
e.on(w.SNAPSHOT, (t) => {
|
|
1964
|
+
e.emit(Qt.SYNC), u.getState().applySnapshot({
|
|
1941
1965
|
roomId: t.room_id ?? null,
|
|
1942
1966
|
mediaId: t.media_id ?? null,
|
|
1943
1967
|
playheadMs: t.playhead_ms || 0,
|
|
1944
|
-
playing:
|
|
1968
|
+
playing: Be(t),
|
|
1945
1969
|
serverSeq: t.server_seq || 0,
|
|
1946
1970
|
leaderId: t.leader_id || null
|
|
1947
|
-
}),
|
|
1948
|
-
const n =
|
|
1971
|
+
}), u.getState().name || d("socket", "Deferring identity to presence event (snapshot carries no roster)");
|
|
1972
|
+
const n = u.getState(), o = S?.id, a = (o ? n.roster[o] : void 0) ?? dt, s = qn(
|
|
1949
1973
|
{ name: n.name, avatarId: n.sprite },
|
|
1950
|
-
|
|
1974
|
+
a ? { name: a.name, avatarId: a.sprite ?? null } : void 0,
|
|
1951
1975
|
// A join that carried no name counts as a default one, so a name that
|
|
1952
1976
|
// landed after the join (prefs) is still asserted.
|
|
1953
|
-
(
|
|
1977
|
+
(l) => l === "" || J(l)
|
|
1954
1978
|
);
|
|
1955
|
-
if (
|
|
1956
|
-
const
|
|
1957
|
-
...
|
|
1958
|
-
...
|
|
1979
|
+
if (s) {
|
|
1980
|
+
const l = {
|
|
1981
|
+
...s.name !== void 0 ? { name: s.name } : {},
|
|
1982
|
+
...s.avatarId !== void 0 && !ut ? { sprite: s.avatarId } : {}
|
|
1959
1983
|
};
|
|
1960
|
-
Object.keys(
|
|
1984
|
+
Object.keys(l).length > 0 && (d("socket", "Identity update on snapshot", l), e.emit(w.IDENTITY_UPDATE, l));
|
|
1961
1985
|
}
|
|
1962
1986
|
d("socket", "Received snapshot", {
|
|
1963
1987
|
mediaId: t.media_id ?? null,
|
|
1964
1988
|
playheadMs: t.playhead_ms || 0,
|
|
1965
|
-
playing:
|
|
1989
|
+
playing: Be(t),
|
|
1966
1990
|
leaderId: t.leader_id || null,
|
|
1967
1991
|
serverSeq: t.server_seq || 0,
|
|
1968
1992
|
rosterSize: Object.keys(n.roster).length
|
|
1969
|
-
}),
|
|
1970
|
-
}), e.on(
|
|
1971
|
-
const n =
|
|
1993
|
+
}), q?.room_key && S?.id && pn({ room_key: q.room_key, client_id: S.id });
|
|
1994
|
+
}), e.on(w.CONTROL_BROADCAST, (t) => {
|
|
1995
|
+
const n = u.getState();
|
|
1972
1996
|
if (Object.prototype.hasOwnProperty.call(t, "media_id")) {
|
|
1973
1997
|
const o = t.media_id ?? null;
|
|
1974
1998
|
n.snapshot.mediaId !== o && (n.applySnapshot({ mediaId: o }), o && n.setReadiness({ mediaId: o, ready: !1, readyCount: 0, total: 0 }), n.bumpLoadGeneration());
|
|
1975
1999
|
}
|
|
1976
2000
|
n.updateControlState({
|
|
1977
2001
|
playheadMs: t.playhead_ms,
|
|
1978
|
-
playing:
|
|
2002
|
+
playing: Be(t),
|
|
1979
2003
|
serverSeq: t.server_seq,
|
|
1980
2004
|
leaderId: t.leader_id ?? n.snapshot.leaderId
|
|
1981
2005
|
}), d("socket", "Control broadcast received", {
|
|
@@ -1985,128 +2009,129 @@ function ii(e) {
|
|
|
1985
2009
|
playState: t.play_state,
|
|
1986
2010
|
mediaId: t.media_id
|
|
1987
2011
|
});
|
|
1988
|
-
}), e.on(
|
|
2012
|
+
}), e.on(w.CONTROL_ACK, (t) => {
|
|
1989
2013
|
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
|
-
|
|
2014
|
+
}), e.on(w.TIME_PONG, (t) => {
|
|
2015
|
+
if (ei(Z, Date.now()), H && H.ts) {
|
|
2016
|
+
const n = Date.now() - H.ts;
|
|
2017
|
+
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
2018
|
}
|
|
1995
|
-
}), e.on(
|
|
2019
|
+
}), e.on(w.READY_STATE, (t) => {
|
|
1996
2020
|
if (!t) return;
|
|
1997
|
-
const n = t.media_id ?? null, o = typeof t.ready_count == "number" ? t.ready_count : 0, i = typeof t.total == "number" ? t.total : 0,
|
|
1998
|
-
|
|
2021
|
+
const n = t.media_id ?? null, o = typeof t.ready_count == "number" ? t.ready_count : 0, i = typeof t.total == "number" ? t.total : 0, a = t.ready === !0;
|
|
2022
|
+
u.getState().setReadiness({ mediaId: n, ready: a, readyCount: o, total: i }), d("socket", "Ready state received", { mediaId: n, readyCount: o, total: i, ready: a });
|
|
1999
2023
|
});
|
|
2000
2024
|
}
|
|
2001
|
-
function
|
|
2002
|
-
e.on(
|
|
2025
|
+
function li(e) {
|
|
2026
|
+
e.on(w.PRESENCE, (t) => {
|
|
2003
2027
|
if (!t) return;
|
|
2004
2028
|
if (Array.isArray(t.users)) {
|
|
2005
2029
|
const o = {};
|
|
2006
|
-
for (const
|
|
2007
|
-
o[
|
|
2008
|
-
clientId:
|
|
2009
|
-
...
|
|
2010
|
-
name:
|
|
2011
|
-
sprite:
|
|
2012
|
-
isLeader:
|
|
2013
|
-
...
|
|
2030
|
+
for (const l of t.users)
|
|
2031
|
+
o[l.client_id] = {
|
|
2032
|
+
clientId: l.client_id,
|
|
2033
|
+
...l.author ? { author: l.author } : {},
|
|
2034
|
+
name: l.name || "Anon",
|
|
2035
|
+
sprite: l.sprite_id ?? l.sprite ?? null,
|
|
2036
|
+
isLeader: l.is_leader,
|
|
2037
|
+
...l.registry_name ? { registryName: !0 } : {},
|
|
2038
|
+
...l.avatar_url ? { avatarUrl: l.avatar_url } : {}
|
|
2014
2039
|
};
|
|
2015
|
-
const i =
|
|
2016
|
-
if (
|
|
2017
|
-
|
|
2018
|
-
else if (
|
|
2019
|
-
const
|
|
2020
|
-
if (i.name && !
|
|
2021
|
-
const
|
|
2022
|
-
d("socket", "Server reassigned sprite", { from: i.sprite, to:
|
|
2040
|
+
const i = u.getState(), a = S?.id, s = a ? o[a] : void 0;
|
|
2041
|
+
if (s?.registryName)
|
|
2042
|
+
u.setState({ roster: o }), (s.name !== i.name || s.sprite && s.sprite !== i.sprite) && (d("socket", "Adopting registry name", { from: i.name, to: s.name }), u.getState().setSessionIdentity(s.name, s.sprite ?? i.sprite));
|
|
2043
|
+
else if (a && o[a]) {
|
|
2044
|
+
const l = o[a].name, p = o[a].sprite;
|
|
2045
|
+
if (i.name && !J(i.name) && (o[a].name = i.name), u.setState({ roster: o }), p && p !== i.sprite) {
|
|
2046
|
+
const h = i.name && !J(i.name), f = h ? i.name : de(p);
|
|
2047
|
+
d("socket", "Server reassigned sprite", { from: i.sprite, to: p, newName: f, preservingCustomName: h }), u.getState().setSessionIdentity(f, p), f !== l && e.emit(w.IDENTITY_UPDATE, { name: f });
|
|
2023
2048
|
}
|
|
2024
2049
|
}
|
|
2025
2050
|
}
|
|
2026
2051
|
d("socket", "Received presence update", t);
|
|
2027
|
-
const n =
|
|
2052
|
+
const n = u.getState();
|
|
2028
2053
|
if (!n.name) {
|
|
2029
2054
|
n.ensureAutoIdentity?.();
|
|
2030
|
-
const o =
|
|
2031
|
-
o.name && (d("socket", "Auto-assigned identity on presence", { name: o.name, sprite: o.sprite }), e.emit(
|
|
2055
|
+
const o = u.getState();
|
|
2056
|
+
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
2057
|
}
|
|
2033
2058
|
});
|
|
2034
2059
|
}
|
|
2035
|
-
function
|
|
2036
|
-
e.on(
|
|
2037
|
-
const n =
|
|
2038
|
-
|
|
2039
|
-
}), e.on(
|
|
2060
|
+
function ci(e) {
|
|
2061
|
+
e.on(w.CHAT_BROADCAST, (t) => {
|
|
2062
|
+
const n = Mt(t, t.server_seq);
|
|
2063
|
+
u.getState().appendChat(n), d("chat", "Message received", n);
|
|
2064
|
+
}), e.on(w.CHAT_HISTORY, (t) => {
|
|
2040
2065
|
if (!t?.messages || !Array.isArray(t.messages)) return;
|
|
2041
|
-
const n = t.messages.map((o) =>
|
|
2042
|
-
|
|
2066
|
+
const n = t.messages.map((o) => Mt(o));
|
|
2067
|
+
u.getState().setChat(n), d("chat", "History loaded", { count: n.length });
|
|
2043
2068
|
});
|
|
2044
2069
|
}
|
|
2045
|
-
function
|
|
2046
|
-
e.on(
|
|
2047
|
-
|
|
2070
|
+
function di(e) {
|
|
2071
|
+
e.on(be.STATE, (t) => {
|
|
2072
|
+
u.getState().applyPlaylistState({
|
|
2048
2073
|
playlist: t?.playlist ?? null,
|
|
2049
2074
|
activeIndex: t?.activeIndex ?? null,
|
|
2050
2075
|
myVotes: t?.myVotes ?? {}
|
|
2051
2076
|
}), 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(
|
|
2077
|
+
}), e.on(be.VOTE_PROGRESS, (t) => {
|
|
2078
|
+
u.getState().setVoteProgress(t?.progress ?? []), d("playlist", "Vote progress", { progressCount: t?.progress?.length });
|
|
2079
|
+
}), e.on(be.RESULTS, (t) => {
|
|
2080
|
+
u.getState().setPlaylistResults(t ?? null), d("playlist", "Results received", { playlistId: t?.playlist?.id, update: t?.update === !0 });
|
|
2081
|
+
}), e.on(be.VOTES_CLEARED, (t) => {
|
|
2057
2082
|
if (!t?.playlistId || !Array.isArray(t.mediaIds)) return;
|
|
2058
|
-
const n =
|
|
2083
|
+
const n = Xo(
|
|
2059
2084
|
{ id: t.playlistId, videos: t.mediaIds.map((i) => ({ mediaId: i })) },
|
|
2060
2085
|
bo()
|
|
2061
|
-
), o =
|
|
2086
|
+
), o = u.getState();
|
|
2062
2087
|
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
2088
|
});
|
|
2064
2089
|
}
|
|
2065
|
-
function
|
|
2066
|
-
e.on(
|
|
2067
|
-
d("tierlist", "Someone saved — refreshing the board"),
|
|
2090
|
+
function ui(e) {
|
|
2091
|
+
e.on(lr.UPDATED, () => {
|
|
2092
|
+
d("tierlist", "Someone saved — refreshing the board"), Oo(!1);
|
|
2068
2093
|
});
|
|
2069
2094
|
}
|
|
2070
|
-
function
|
|
2071
|
-
e.on(
|
|
2095
|
+
function mi(e) {
|
|
2096
|
+
e.on(cr.STATE, (t) => {
|
|
2072
2097
|
if (!t || typeof t.active != "boolean") return;
|
|
2073
2098
|
const n = Array.isArray(t.ready) ? t.ready.filter((o) => typeof o == "string") : [];
|
|
2074
|
-
|
|
2099
|
+
u.getState().setReadyCheckState({ active: t.active, ready: n }), d("ready-check", "State received", { active: t.active, readyCount: n.length });
|
|
2075
2100
|
});
|
|
2076
2101
|
}
|
|
2077
|
-
function
|
|
2078
|
-
e.on(
|
|
2102
|
+
function fi(e) {
|
|
2103
|
+
e.on(Qt.ACTIVE, (t) => {
|
|
2079
2104
|
const n = typeof t?.gameId == "string" ? t.gameId : null;
|
|
2080
|
-
|
|
2105
|
+
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
2106
|
});
|
|
2082
2107
|
}
|
|
2083
|
-
function
|
|
2084
|
-
e.on(
|
|
2085
|
-
|
|
2086
|
-
}), e.on(
|
|
2087
|
-
|
|
2108
|
+
function pi(e) {
|
|
2109
|
+
e.on(w.HEALTH_SNAPSHOT, (t) => {
|
|
2110
|
+
u.getState().setHealthSnapshot(t);
|
|
2111
|
+
}), e.on(w.BUFFER_STATUS, (t) => {
|
|
2112
|
+
u.getState().setBufferStatus(t);
|
|
2088
2113
|
});
|
|
2089
2114
|
}
|
|
2090
|
-
function
|
|
2091
|
-
|
|
2115
|
+
function hi(e) {
|
|
2116
|
+
si(e), li(e), ci(e), pi(e), di(e), ui(e), mi(e), fi(e), e.on(w.ERROR, (t) => {
|
|
2092
2117
|
const n = t?.code || "error/unknown";
|
|
2093
2118
|
if (n === "conflict" && t?.message === "sprite_held_by_you") {
|
|
2094
|
-
|
|
2119
|
+
ut = !0, d("socket", "sprite held by this account's other connection: keeping the server-assigned sprite");
|
|
2095
2120
|
return;
|
|
2096
2121
|
}
|
|
2097
2122
|
if (n === "conflict" && t?.message === "sprite_taken") {
|
|
2098
|
-
if (jo(
|
|
2123
|
+
if (jo(S?.id)) {
|
|
2099
2124
|
d("socket", "sprite_taken: stale, the server already has our sprite");
|
|
2100
2125
|
return;
|
|
2101
2126
|
}
|
|
2102
|
-
|
|
2103
|
-
let
|
|
2127
|
+
ue = !0;
|
|
2128
|
+
let s;
|
|
2104
2129
|
try {
|
|
2105
|
-
|
|
2130
|
+
s = Lo();
|
|
2106
2131
|
} finally {
|
|
2107
|
-
|
|
2132
|
+
ue = !1;
|
|
2108
2133
|
}
|
|
2109
|
-
|
|
2134
|
+
s && e.emit(w.IDENTITY_UPDATE, s);
|
|
2110
2135
|
return;
|
|
2111
2136
|
}
|
|
2112
2137
|
const i = {
|
|
@@ -2127,44 +2152,55 @@ function pi(e) {
|
|
|
2127
2152
|
"recap/not_found": "No recap available for the previous episode."
|
|
2128
2153
|
}[n] || n;
|
|
2129
2154
|
if (n.startsWith("recap/")) {
|
|
2130
|
-
d("socket", `recap unavailable: ${i}`, { code: n }),
|
|
2155
|
+
d("socket", `recap unavailable: ${i}`, { code: n }), u.getState().pushToast("info", i);
|
|
2131
2156
|
return;
|
|
2132
2157
|
}
|
|
2133
|
-
(n.startsWith("auth/") ?
|
|
2158
|
+
(n.startsWith("auth/") ? k : ke)("socket", `Server error: ${i}`, { code: n, raw: t }), u.getState().pushToast("error", i);
|
|
2134
2159
|
});
|
|
2135
2160
|
}
|
|
2136
|
-
function
|
|
2137
|
-
|
|
2161
|
+
function gi(e, t) {
|
|
2162
|
+
ne().emit(w.CHAT_SEND, t?.length ? { text: e, images: t } : { text: e });
|
|
2138
2163
|
}
|
|
2139
|
-
function
|
|
2140
|
-
|
|
2141
|
-
|
|
2164
|
+
function bi() {
|
|
2165
|
+
H || (H = { ts: Date.now() }, ne().emit(w.TIME_PING, {}), $ = setTimeout(() => {
|
|
2166
|
+
H && (d("socket", "Time ping timed out after 10s, clearing inflight"), H = null), $ = null;
|
|
2142
2167
|
}, 1e4));
|
|
2143
2168
|
}
|
|
2144
|
-
function
|
|
2145
|
-
const n =
|
|
2146
|
-
|
|
2169
|
+
function Tn(e) {
|
|
2170
|
+
const t = u.getState(), n = t.me.clientId;
|
|
2171
|
+
if (!n || !t.roster[n]) {
|
|
2172
|
+
Rt(e), d("socket", "Avatar change before join: the join will carry it", { sprite: e });
|
|
2173
|
+
return;
|
|
2174
|
+
}
|
|
2175
|
+
ue = !0;
|
|
2176
|
+
try {
|
|
2177
|
+
Rt(e);
|
|
2178
|
+
} finally {
|
|
2179
|
+
ue = !1;
|
|
2180
|
+
}
|
|
2181
|
+
const o = u.getState(), i = { avatar: !0 };
|
|
2182
|
+
o.sprite && o.sprite !== t.sprite && (i.sprite = o.sprite), o.name && o.name !== t.name && (i.name = o.name), d("socket", "Sending avatar change", i), ne().emit(w.IDENTITY_UPDATE, i);
|
|
2147
2183
|
}
|
|
2148
|
-
let
|
|
2149
|
-
|
|
2150
|
-
if (e.name === t.name && e.sprite === t.sprite ||
|
|
2184
|
+
let we = { name: "", sprite: "" };
|
|
2185
|
+
u.subscribe((e, t) => {
|
|
2186
|
+
if (e.name === t.name && e.sprite === t.sprite || ue) return;
|
|
2151
2187
|
const n = e.me.clientId;
|
|
2152
2188
|
if (!n) return;
|
|
2153
2189
|
const o = e.roster[n];
|
|
2154
2190
|
if (!o) return;
|
|
2155
|
-
const i = !!e.name && !
|
|
2156
|
-
if (!i && !
|
|
2157
|
-
const
|
|
2158
|
-
i && (
|
|
2191
|
+
const i = !!e.name && !J(e.name) && e.name !== we.name && (J(o.name || "") || o.name !== e.name), a = !!e.sprite && e.sprite !== we.sprite && o.sprite !== e.sprite;
|
|
2192
|
+
if (!i && !a) return;
|
|
2193
|
+
const s = {};
|
|
2194
|
+
i && (s.name = e.name, we.name = e.name), a && (s.sprite = e.sprite, we.sprite = e.sprite), d("socket", "Identity reassert (store change)", s), S?.connected ? S.emit(w.IDENTITY_UPDATE, s) : ne().emit(w.IDENTITY_UPDATE, s);
|
|
2159
2195
|
});
|
|
2160
|
-
function bi() {
|
|
2161
|
-
Ae && (clearInterval(Ae), Ae = null), B && (clearTimeout(B), B = null), $ = null, ee.unansweredSince = null, ee.lastTickAt = null;
|
|
2162
|
-
}
|
|
2163
2196
|
function yi() {
|
|
2164
|
-
|
|
2197
|
+
Ee && (clearInterval(Ee), Ee = null), $ && (clearTimeout($), $ = null), H = null, Z.unansweredSince = null, Z.lastTickAt = null;
|
|
2165
2198
|
}
|
|
2166
|
-
function
|
|
2167
|
-
d("socket", "
|
|
2199
|
+
function vi() {
|
|
2200
|
+
d("socket", "clearJoinState called", { hadPayload: q !== null, room_key: q?.room_key }), q = null, oe = !1, Cn = null;
|
|
2201
|
+
}
|
|
2202
|
+
function Lt() {
|
|
2203
|
+
d("socket", "leaveRoom called", { room_key: q?.room_key }), vi(), yi(), S && (S.disconnect(), S = null), u.setState({
|
|
2168
2204
|
me: { clientId: null, nextClientSeq: 1 },
|
|
2169
2205
|
roster: {},
|
|
2170
2206
|
snapshot: { roomId: null, mediaId: null, playheadMs: 0, playing: !1, serverSeq: 0, leaderId: null },
|
|
@@ -2180,22 +2216,51 @@ function jt() {
|
|
|
2180
2216
|
gameSessionWins: {}
|
|
2181
2217
|
});
|
|
2182
2218
|
}
|
|
2183
|
-
function
|
|
2184
|
-
d("chat", "Emitting recap_request"),
|
|
2219
|
+
function Si() {
|
|
2220
|
+
d("chat", "Emitting recap_request"), ne().emit("recap_request");
|
|
2221
|
+
}
|
|
2222
|
+
function _i() {
|
|
2223
|
+
D(() => Fo((e) => {
|
|
2224
|
+
const t = xn(e);
|
|
2225
|
+
d("avatar", "Avatar changed in the settings popout", { sprite: t, source: e.avatar?.source }), Tn(t);
|
|
2226
|
+
}), []);
|
|
2227
|
+
}
|
|
2228
|
+
function wi(e, t) {
|
|
2229
|
+
if (t) {
|
|
2230
|
+
for (const n of Object.values(e))
|
|
2231
|
+
if (n.author === t && n.avatarUrl) return n.avatarUrl;
|
|
2232
|
+
}
|
|
2185
2233
|
}
|
|
2186
|
-
function
|
|
2234
|
+
function kn({ sprite: e, url: t, alt: n = "", className: o, fallback: i }) {
|
|
2235
|
+
const [a, s] = R(null);
|
|
2236
|
+
if (t && t !== a)
|
|
2237
|
+
return /* @__PURE__ */ c(
|
|
2238
|
+
"img",
|
|
2239
|
+
{
|
|
2240
|
+
src: t,
|
|
2241
|
+
alt: n,
|
|
2242
|
+
referrerPolicy: "no-referrer",
|
|
2243
|
+
className: o,
|
|
2244
|
+
draggable: !1,
|
|
2245
|
+
onError: () => s(t)
|
|
2246
|
+
}
|
|
2247
|
+
);
|
|
2248
|
+
const l = yo(e);
|
|
2249
|
+
return l ? /* @__PURE__ */ c("img", { src: l, alt: n, crossOrigin: "anonymous", className: o, draggable: !1 }) : /* @__PURE__ */ c(le, { children: i });
|
|
2250
|
+
}
|
|
2251
|
+
function xi(e) {
|
|
2187
2252
|
return !(e.button !== 0 || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey);
|
|
2188
2253
|
}
|
|
2189
|
-
function
|
|
2190
|
-
|
|
2191
|
-
const
|
|
2192
|
-
|
|
2254
|
+
function Ii({ src: e, title: t, onClose: n }) {
|
|
2255
|
+
D(() => {
|
|
2256
|
+
const a = (s) => {
|
|
2257
|
+
s.key === "Escape" && (s.stopPropagation(), n());
|
|
2193
2258
|
};
|
|
2194
|
-
return document.addEventListener("keydown",
|
|
2259
|
+
return document.addEventListener("keydown", a, !0), () => document.removeEventListener("keydown", a, !0);
|
|
2195
2260
|
}, [n]);
|
|
2196
|
-
const o =
|
|
2197
|
-
return i ?
|
|
2198
|
-
/* @__PURE__ */
|
|
2261
|
+
const o = zr(), i = typeof document > "u" ? null : document.fullscreenElement ?? o ?? document.body;
|
|
2262
|
+
return i ? Vn(
|
|
2263
|
+
/* @__PURE__ */ _(
|
|
2199
2264
|
"div",
|
|
2200
2265
|
{
|
|
2201
2266
|
className: "fixed inset-0 z-[10000] flex flex-col items-center justify-center bg-black/85 p-6",
|
|
@@ -2205,18 +2270,18 @@ function wi({ src: e, title: t, onClose: n }) {
|
|
|
2205
2270
|
"aria-modal": "true",
|
|
2206
2271
|
"aria-label": t || "Image",
|
|
2207
2272
|
children: [
|
|
2208
|
-
/* @__PURE__ */
|
|
2273
|
+
/* @__PURE__ */ c(
|
|
2209
2274
|
"img",
|
|
2210
2275
|
{
|
|
2211
2276
|
src: e,
|
|
2212
2277
|
alt: t ?? "",
|
|
2213
|
-
onClick: (
|
|
2278
|
+
onClick: (a) => a.stopPropagation(),
|
|
2214
2279
|
className: "max-h-full max-w-full rounded object-contain shadow-2xl",
|
|
2215
2280
|
"data-testid": "chat-image-lightbox-img"
|
|
2216
2281
|
}
|
|
2217
2282
|
),
|
|
2218
|
-
t && /* @__PURE__ */
|
|
2219
|
-
/* @__PURE__ */
|
|
2283
|
+
t && /* @__PURE__ */ c("p", { className: "mt-3 max-w-full truncate text-center text-sm text-white/80", children: t }),
|
|
2284
|
+
/* @__PURE__ */ c(
|
|
2220
2285
|
"button",
|
|
2221
2286
|
{
|
|
2222
2287
|
type: "button",
|
|
@@ -2232,13 +2297,13 @@ function wi({ src: e, title: t, onClose: n }) {
|
|
|
2232
2297
|
i
|
|
2233
2298
|
) : null;
|
|
2234
2299
|
}
|
|
2235
|
-
const
|
|
2236
|
-
function
|
|
2237
|
-
const [t, n] =
|
|
2300
|
+
const Ge = 240, Ci = 320;
|
|
2301
|
+
function Ti({ image: e }) {
|
|
2302
|
+
const [t, n] = R(!1), o = Pe(e.key);
|
|
2238
2303
|
if (!o) return null;
|
|
2239
|
-
const i = e.w > 0 && e.h > 0,
|
|
2240
|
-
return /* @__PURE__ */
|
|
2241
|
-
/* @__PURE__ */
|
|
2304
|
+
const i = e.w > 0 && e.h > 0, a = i ? Math.min(1, Ci / e.w, Ge / e.h) : 1;
|
|
2305
|
+
return /* @__PURE__ */ _(le, { children: [
|
|
2306
|
+
/* @__PURE__ */ c(
|
|
2242
2307
|
"a",
|
|
2243
2308
|
{
|
|
2244
2309
|
href: o,
|
|
@@ -2246,26 +2311,26 @@ function xi({ image: e }) {
|
|
|
2246
2311
|
rel: "noreferrer noopener",
|
|
2247
2312
|
className: "block max-w-full cursor-zoom-in",
|
|
2248
2313
|
"data-testid": "chat-image",
|
|
2249
|
-
onClick: (
|
|
2250
|
-
|
|
2314
|
+
onClick: (s) => {
|
|
2315
|
+
xi(s) && (s.preventDefault(), n(!0));
|
|
2251
2316
|
},
|
|
2252
|
-
children: /* @__PURE__ */
|
|
2317
|
+
children: /* @__PURE__ */ c(
|
|
2253
2318
|
"img",
|
|
2254
2319
|
{
|
|
2255
2320
|
src: o,
|
|
2256
2321
|
alt: e.title ?? "",
|
|
2257
2322
|
loading: "lazy",
|
|
2258
2323
|
decoding: "async",
|
|
2259
|
-
width: i ? Math.round(e.w *
|
|
2260
|
-
height: i ? Math.round(e.h *
|
|
2324
|
+
width: i ? Math.round(e.w * a) : void 0,
|
|
2325
|
+
height: i ? Math.round(e.h * a) : void 0,
|
|
2261
2326
|
className: "rounded border border-border-light object-contain bg-bg-alt/30",
|
|
2262
|
-
style: i ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight:
|
|
2327
|
+
style: i ? { aspectRatio: `${e.w} / ${e.h}`, maxWidth: "100%", maxHeight: Ge } : { maxWidth: "100%", maxHeight: Ge }
|
|
2263
2328
|
}
|
|
2264
2329
|
)
|
|
2265
2330
|
}
|
|
2266
2331
|
),
|
|
2267
|
-
t && /* @__PURE__ */
|
|
2268
|
-
|
|
2332
|
+
t && /* @__PURE__ */ c(
|
|
2333
|
+
Ii,
|
|
2269
2334
|
{
|
|
2270
2335
|
src: o,
|
|
2271
2336
|
title: e.title,
|
|
@@ -2274,80 +2339,81 @@ function xi({ image: e }) {
|
|
|
2274
2339
|
)
|
|
2275
2340
|
] });
|
|
2276
2341
|
}
|
|
2277
|
-
function
|
|
2278
|
-
return e?.length ? /* @__PURE__ */
|
|
2342
|
+
function ki({ images: e }) {
|
|
2343
|
+
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(Ti, { image: t }, `${t.key}-${n}`)) }) : null;
|
|
2279
2344
|
}
|
|
2280
|
-
function
|
|
2345
|
+
function Ai(e, t) {
|
|
2281
2346
|
return e.author && t.author ? e.author === t.author : !!t.clientId && e.clientId === t.clientId;
|
|
2282
2347
|
}
|
|
2283
|
-
function
|
|
2348
|
+
function Ke(e) {
|
|
2284
2349
|
return new Date(e).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
2285
2350
|
}
|
|
2286
|
-
const
|
|
2287
|
-
const n =
|
|
2351
|
+
const Ei = Ht.memo(function({ message: t }) {
|
|
2352
|
+
const n = u((l) => l.me.clientId), o = u((l) => l.me.clientId ? l.roster[l.me.clientId]?.author : void 0), i = Ai(t, { clientId: n, author: o }), a = u((l) => wi(l.roster, t.author));
|
|
2288
2353
|
if (t.isSystem && t.systemType === "recap")
|
|
2289
|
-
return /* @__PURE__ */
|
|
2290
|
-
/* @__PURE__ */
|
|
2354
|
+
return /* @__PURE__ */ c("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ _("div", { className: "border-l-2 border-border-light pl-2.5 py-0.5", children: [
|
|
2355
|
+
/* @__PURE__ */ _("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-0.5", children: [
|
|
2291
2356
|
"Recap",
|
|
2292
|
-
/* @__PURE__ */
|
|
2357
|
+
/* @__PURE__ */ c("span", { className: "ml-1.5 normal-case tracking-normal opacity-60", children: Ke(t.ts) })
|
|
2293
2358
|
] }),
|
|
2294
|
-
/* @__PURE__ */
|
|
2359
|
+
/* @__PURE__ */ c("p", { className: "text-[13px] text-text-secondary leading-relaxed whitespace-pre-wrap break-words", children: t.text })
|
|
2295
2360
|
] }) });
|
|
2296
2361
|
if (t.isSystem)
|
|
2297
|
-
return /* @__PURE__ */
|
|
2362
|
+
return /* @__PURE__ */ _("div", { className: "px-2 py-0.5 text-[11px] text-text-muted italic text-center leading-tight", children: [
|
|
2298
2363
|
t.text,
|
|
2299
|
-
/* @__PURE__ */
|
|
2364
|
+
/* @__PURE__ */ c("span", { className: "ml-1 text-[10px] opacity-50", children: Ke(t.ts) })
|
|
2300
2365
|
] });
|
|
2301
|
-
const s =
|
|
2302
|
-
return /* @__PURE__ */
|
|
2303
|
-
|
|
2304
|
-
|
|
2366
|
+
const s = gn(t.sprite);
|
|
2367
|
+
return /* @__PURE__ */ _("div", { className: `flex items-start gap-2 px-2 py-1 hover:bg-bg-card/20 ${i ? "bg-bg-card/30" : ""}`, children: [
|
|
2368
|
+
/* @__PURE__ */ c(
|
|
2369
|
+
kn,
|
|
2305
2370
|
{
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
className: "w-8 h-8 rounded-full object-cover flex-shrink-0"
|
|
2371
|
+
sprite: t.sprite,
|
|
2372
|
+
url: a,
|
|
2373
|
+
alt: t.name,
|
|
2374
|
+
className: "w-8 h-8 rounded-full object-cover flex-shrink-0",
|
|
2375
|
+
fallback: /* @__PURE__ */ c("span", { className: "w-8 h-8 bg-bg-alt/50 rounded-full flex-shrink-0" })
|
|
2310
2376
|
}
|
|
2311
|
-
)
|
|
2312
|
-
/* @__PURE__ */
|
|
2313
|
-
/* @__PURE__ */
|
|
2314
|
-
/* @__PURE__ */
|
|
2315
|
-
t.text && /* @__PURE__ */
|
|
2316
|
-
/* @__PURE__ */
|
|
2377
|
+
),
|
|
2378
|
+
/* @__PURE__ */ _("div", { className: "flex-1 min-w-0 -mt-0.5", children: [
|
|
2379
|
+
/* @__PURE__ */ c("span", { className: "font-medium text-[13px]", style: { color: s }, children: t.name }),
|
|
2380
|
+
/* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted opacity-60 ml-1.5", children: Ke(t.ts) }),
|
|
2381
|
+
t.text && /* @__PURE__ */ c("p", { className: "text-[13px] text-text break-words leading-snug m-0", children: t.text }),
|
|
2382
|
+
/* @__PURE__ */ c(ki, { images: t.images })
|
|
2317
2383
|
] })
|
|
2318
2384
|
] });
|
|
2319
2385
|
});
|
|
2320
|
-
function
|
|
2321
|
-
const e =
|
|
2386
|
+
function Pi() {
|
|
2387
|
+
const e = u((i) => i.chat), t = z(null), n = z(!1), o = E(() => {
|
|
2322
2388
|
const i = t.current;
|
|
2323
2389
|
if (!i) return;
|
|
2324
|
-
const { scrollHeight:
|
|
2325
|
-
n.current =
|
|
2390
|
+
const { scrollHeight: a, scrollTop: s, clientHeight: l } = i, p = a - s - l;
|
|
2391
|
+
n.current = p > 40;
|
|
2326
2392
|
}, []);
|
|
2327
|
-
return
|
|
2393
|
+
return D(() => {
|
|
2328
2394
|
const i = t.current;
|
|
2329
2395
|
i && !n.current && i.scrollTo({ top: i.scrollHeight, behavior: "smooth" });
|
|
2330
|
-
}, [e.length]), /* @__PURE__ */
|
|
2396
|
+
}, [e.length]), /* @__PURE__ */ c(
|
|
2331
2397
|
"div",
|
|
2332
2398
|
{
|
|
2333
2399
|
ref: t,
|
|
2334
2400
|
onScroll: o,
|
|
2335
2401
|
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__ */
|
|
2402
|
+
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((i, a) => {
|
|
2403
|
+
const s = a > 0 ? e[a - 1] : null, l = s && i.ts - s.ts > 1440 * 60 * 1e3;
|
|
2404
|
+
return /* @__PURE__ */ _(Ht.Fragment, { children: [
|
|
2405
|
+
l && /* @__PURE__ */ _("div", { className: "flex items-center gap-2 px-4 py-2 my-1", children: [
|
|
2406
|
+
/* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" }),
|
|
2407
|
+
/* @__PURE__ */ c("span", { className: "text-[10px] text-text-muted whitespace-nowrap", children: new Date(i.ts).toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" }) }),
|
|
2408
|
+
/* @__PURE__ */ c("div", { className: "flex-1 h-px bg-border" })
|
|
2343
2409
|
] }),
|
|
2344
|
-
/* @__PURE__ */
|
|
2410
|
+
/* @__PURE__ */ c(Ei, { message: i })
|
|
2345
2411
|
] }, i.id);
|
|
2346
2412
|
}) })
|
|
2347
2413
|
}
|
|
2348
2414
|
);
|
|
2349
2415
|
}
|
|
2350
|
-
const
|
|
2416
|
+
const mt = [
|
|
2351
2417
|
{
|
|
2352
2418
|
name: "recap",
|
|
2353
2419
|
description: "Summarise the previous episode of what is loaded",
|
|
@@ -2361,99 +2427,93 @@ const ft = [
|
|
|
2361
2427
|
usage: "/tierlist",
|
|
2362
2428
|
scope: "local"
|
|
2363
2429
|
},
|
|
2364
|
-
{
|
|
2365
|
-
name: "character",
|
|
2366
|
-
description: "Change your character",
|
|
2367
|
-
usage: "/character",
|
|
2368
|
-
scope: "local"
|
|
2369
|
-
},
|
|
2370
2430
|
{
|
|
2371
2431
|
name: "help",
|
|
2372
2432
|
description: "List the available commands",
|
|
2373
2433
|
usage: "/help",
|
|
2374
2434
|
scope: "local"
|
|
2375
2435
|
}
|
|
2376
|
-
],
|
|
2377
|
-
function
|
|
2378
|
-
if (!e.startsWith(
|
|
2379
|
-
const t = e.slice(
|
|
2436
|
+
], ee = "/";
|
|
2437
|
+
function Ni(e) {
|
|
2438
|
+
if (!e.startsWith(ee)) return null;
|
|
2439
|
+
const t = e.slice(ee.length);
|
|
2380
2440
|
return /\s/.test(t) ? null : t.toLowerCase();
|
|
2381
2441
|
}
|
|
2382
|
-
function
|
|
2442
|
+
function Ri(e, t = mt) {
|
|
2383
2443
|
const n = e.toLowerCase();
|
|
2384
|
-
if (!n) return [...t].sort((i,
|
|
2444
|
+
if (!n) return [...t].sort((i, a) => i.name.localeCompare(a.name));
|
|
2385
2445
|
const o = [];
|
|
2386
2446
|
for (const i of t) {
|
|
2387
|
-
const
|
|
2388
|
-
|
|
2447
|
+
const a = i.name.toLowerCase();
|
|
2448
|
+
a.startsWith(n) ? o.push({ cmd: i, rank: 0 }) : a.includes(n) && o.push({ cmd: i, rank: 1 });
|
|
2389
2449
|
}
|
|
2390
|
-
return o.sort((i,
|
|
2450
|
+
return o.sort((i, a) => i.rank - a.rank || i.cmd.name.localeCompare(a.cmd.name)).map((i) => i.cmd);
|
|
2391
2451
|
}
|
|
2392
|
-
function
|
|
2393
|
-
return `${
|
|
2452
|
+
function Di(e) {
|
|
2453
|
+
return `${ee}${e.name} `;
|
|
2394
2454
|
}
|
|
2395
|
-
function
|
|
2455
|
+
function We(e, t) {
|
|
2396
2456
|
return t <= 0 ? 0 : (e % t + t) % t;
|
|
2397
2457
|
}
|
|
2398
|
-
function
|
|
2458
|
+
function Oi(e, t = mt) {
|
|
2399
2459
|
const n = e.trim();
|
|
2400
2460
|
if (!n) return null;
|
|
2401
|
-
if (!n.startsWith(
|
|
2402
|
-
const o = n.slice(
|
|
2403
|
-
return
|
|
2461
|
+
if (!n.startsWith(ee)) return { kind: "chat", text: n };
|
|
2462
|
+
const o = n.slice(ee.length), i = o.search(/\s/), a = (i === -1 ? o : o.slice(0, i)).toLowerCase(), s = i === -1 ? "" : o.slice(i).trim(), l = t.find((p) => p.name.toLowerCase() === a);
|
|
2463
|
+
return l ? { kind: "command", command: l, args: s } : { kind: "chat", text: n };
|
|
2404
2464
|
}
|
|
2405
2465
|
function Mi(e, t) {
|
|
2406
|
-
return e.requiresMedia && !t.hasMedia ? `${
|
|
2466
|
+
return e.requiresMedia && !t.hasMedia ? `${ee}${e.name} needs an episode loaded.` : null;
|
|
2407
2467
|
}
|
|
2408
|
-
function
|
|
2468
|
+
function Li({
|
|
2409
2469
|
commands: e,
|
|
2410
2470
|
activeIndex: t,
|
|
2411
2471
|
hasMedia: n,
|
|
2412
2472
|
onPick: o,
|
|
2413
2473
|
onHover: i,
|
|
2414
|
-
listboxId:
|
|
2474
|
+
listboxId: a
|
|
2415
2475
|
}) {
|
|
2416
|
-
return e.length === 0 ? null : /* @__PURE__ */
|
|
2476
|
+
return e.length === 0 ? null : /* @__PURE__ */ c(
|
|
2417
2477
|
"ul",
|
|
2418
2478
|
{
|
|
2419
|
-
id:
|
|
2479
|
+
id: a,
|
|
2420
2480
|
role: "listbox",
|
|
2421
2481
|
"aria-label": "Slash commands",
|
|
2422
2482
|
className: `absolute bottom-full left-0 right-0 z-30 max-h-56 overflow-y-auto
|
|
2423
2483
|
bg-bg-card border border-border-light rounded shadow-lg
|
|
2424
2484
|
list-none m-0 p-0 py-1 mb-1`,
|
|
2425
|
-
children: e.map((
|
|
2426
|
-
const
|
|
2427
|
-
return /* @__PURE__ */
|
|
2485
|
+
children: e.map((s, l) => {
|
|
2486
|
+
const p = !!s.requiresMedia && !n, h = l === t;
|
|
2487
|
+
return /* @__PURE__ */ _(
|
|
2428
2488
|
"li",
|
|
2429
2489
|
{
|
|
2430
|
-
id: `${
|
|
2490
|
+
id: `${a}-opt-${s.name}`,
|
|
2431
2491
|
role: "option",
|
|
2432
|
-
"aria-selected":
|
|
2433
|
-
"aria-disabled":
|
|
2434
|
-
onMouseDown: (
|
|
2435
|
-
|
|
2492
|
+
"aria-selected": h,
|
|
2493
|
+
"aria-disabled": p,
|
|
2494
|
+
onMouseDown: (f) => {
|
|
2495
|
+
f.preventDefault(), o(s);
|
|
2436
2496
|
},
|
|
2437
|
-
onMouseEnter: () => i(
|
|
2438
|
-
className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${
|
|
2497
|
+
onMouseEnter: () => i(l),
|
|
2498
|
+
className: `px-3 py-1.5 cursor-pointer flex items-baseline gap-2 ${h ? "bg-bg-alt" : ""} ${p ? "opacity-50" : ""}`,
|
|
2439
2499
|
children: [
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
/* @__PURE__ */
|
|
2500
|
+
/* @__PURE__ */ c("span", { className: "text-sm font-semibold text-text shrink-0", children: s.usage }),
|
|
2501
|
+
/* @__PURE__ */ c("span", { className: "text-xs text-text-secondary truncate", children: p ? "needs an episode loaded" : s.description })
|
|
2442
2502
|
]
|
|
2443
2503
|
},
|
|
2444
|
-
|
|
2504
|
+
s.name
|
|
2445
2505
|
);
|
|
2446
2506
|
})
|
|
2447
2507
|
}
|
|
2448
2508
|
);
|
|
2449
2509
|
}
|
|
2450
|
-
function
|
|
2510
|
+
function ji({
|
|
2451
2511
|
pending: e,
|
|
2452
2512
|
uploading: t,
|
|
2453
2513
|
onRemove: n
|
|
2454
2514
|
}) {
|
|
2455
|
-
return e.length ? /* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2515
|
+
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__ */ _("div", { className: "relative", children: [
|
|
2516
|
+
/* @__PURE__ */ c(
|
|
2457
2517
|
"img",
|
|
2458
2518
|
{
|
|
2459
2519
|
src: o.previewUrl,
|
|
@@ -2461,7 +2521,7 @@ function Ri({
|
|
|
2461
2521
|
className: `h-14 w-14 rounded border border-border-light object-cover ${t ? "opacity-50" : ""}`
|
|
2462
2522
|
}
|
|
2463
2523
|
),
|
|
2464
|
-
/* @__PURE__ */
|
|
2524
|
+
/* @__PURE__ */ c(
|
|
2465
2525
|
"button",
|
|
2466
2526
|
{
|
|
2467
2527
|
type: "button",
|
|
@@ -2474,84 +2534,84 @@ function Ri({
|
|
|
2474
2534
|
)
|
|
2475
2535
|
] }, o.id)) }) : null;
|
|
2476
2536
|
}
|
|
2477
|
-
function
|
|
2478
|
-
const [e, t] =
|
|
2479
|
-
|
|
2480
|
-
for (const
|
|
2481
|
-
|
|
2537
|
+
function Ui() {
|
|
2538
|
+
const [e, t] = R([]), [n, o] = R(!1), i = u((m) => m.pushToast), a = z(/* @__PURE__ */ new Set());
|
|
2539
|
+
D(() => () => {
|
|
2540
|
+
for (const m of a.current) URL.revokeObjectURL(m);
|
|
2541
|
+
a.current.clear();
|
|
2482
2542
|
}, []);
|
|
2483
|
-
const
|
|
2484
|
-
|
|
2485
|
-
}, []),
|
|
2486
|
-
if (!
|
|
2487
|
-
const
|
|
2488
|
-
for (const
|
|
2489
|
-
const
|
|
2490
|
-
if (
|
|
2491
|
-
i("error",
|
|
2543
|
+
const s = E((m) => {
|
|
2544
|
+
Rr(m) && (URL.revokeObjectURL(m.previewUrl), a.current.delete(m.previewUrl));
|
|
2545
|
+
}, []), l = E(async (m) => {
|
|
2546
|
+
if (!m.length) return;
|
|
2547
|
+
const v = [];
|
|
2548
|
+
for (const y of m) {
|
|
2549
|
+
const I = Or(y);
|
|
2550
|
+
if (I) {
|
|
2551
|
+
i("error", I);
|
|
2492
2552
|
continue;
|
|
2493
2553
|
}
|
|
2494
|
-
const { w:
|
|
2495
|
-
|
|
2554
|
+
const { w: g, h: A } = await jr(y), N = URL.createObjectURL(y);
|
|
2555
|
+
a.current.add(N), v.push({
|
|
2496
2556
|
kind: "file",
|
|
2497
2557
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2498
|
-
file:
|
|
2499
|
-
previewUrl:
|
|
2500
|
-
w:
|
|
2501
|
-
h:
|
|
2558
|
+
file: y,
|
|
2559
|
+
previewUrl: N,
|
|
2560
|
+
w: g,
|
|
2561
|
+
h: A
|
|
2502
2562
|
});
|
|
2503
2563
|
}
|
|
2504
|
-
|
|
2505
|
-
const
|
|
2506
|
-
if (
|
|
2507
|
-
i("info", `Up to ${
|
|
2508
|
-
for (const
|
|
2509
|
-
return
|
|
2564
|
+
v.length && t((y) => {
|
|
2565
|
+
const I = V - y.length;
|
|
2566
|
+
if (I <= 0) {
|
|
2567
|
+
i("info", `Up to ${V} images per message`);
|
|
2568
|
+
for (const g of v) s(g);
|
|
2569
|
+
return y;
|
|
2510
2570
|
}
|
|
2511
|
-
if (
|
|
2512
|
-
i("info", `Up to ${
|
|
2513
|
-
for (const
|
|
2571
|
+
if (v.length > I) {
|
|
2572
|
+
i("info", `Up to ${V} images per message`);
|
|
2573
|
+
for (const g of v.slice(I)) s(g);
|
|
2514
2574
|
}
|
|
2515
|
-
return [...
|
|
2575
|
+
return [...y, ...v.slice(0, I)];
|
|
2516
2576
|
});
|
|
2517
|
-
}, [i,
|
|
2518
|
-
const
|
|
2519
|
-
|
|
2577
|
+
}, [i, s]), p = E((m) => {
|
|
2578
|
+
const v = Pe(m.key);
|
|
2579
|
+
v && (t((y) => y.length >= V ? (i("info", `Up to ${V} images per message`), y) : [...y, {
|
|
2520
2580
|
kind: "remote",
|
|
2521
2581
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2522
|
-
key:
|
|
2523
|
-
previewUrl:
|
|
2582
|
+
key: m.key,
|
|
2583
|
+
previewUrl: v,
|
|
2524
2584
|
// The catalogue spells "unknown" as null; the wire schema spells it
|
|
2525
2585
|
// as 0, and the renderer falls back to natural flow on that.
|
|
2526
|
-
w:
|
|
2527
|
-
h:
|
|
2528
|
-
title:
|
|
2529
|
-
}]),
|
|
2530
|
-
}, [i]),
|
|
2531
|
-
t((
|
|
2532
|
-
const
|
|
2533
|
-
return
|
|
2586
|
+
w: m.width ?? 0,
|
|
2587
|
+
h: m.height ?? 0,
|
|
2588
|
+
title: m.title || void 0
|
|
2589
|
+
}]), Le().catalogue(ln).recordUse(m.key));
|
|
2590
|
+
}, [i]), h = E((m) => {
|
|
2591
|
+
t((v) => {
|
|
2592
|
+
const y = v.find((I) => I.id === m);
|
|
2593
|
+
return y && s(y), v.filter((I) => I.id !== m);
|
|
2534
2594
|
});
|
|
2535
|
-
}, [
|
|
2536
|
-
t((
|
|
2537
|
-
for (const
|
|
2595
|
+
}, [s]), f = E(() => {
|
|
2596
|
+
t((m) => {
|
|
2597
|
+
for (const v of m) s(v);
|
|
2538
2598
|
return [];
|
|
2539
2599
|
});
|
|
2540
|
-
}, [
|
|
2541
|
-
const
|
|
2542
|
-
|
|
2543
|
-
}, [
|
|
2544
|
-
const
|
|
2545
|
-
|
|
2546
|
-
}, [
|
|
2547
|
-
|
|
2548
|
-
}, []), C =
|
|
2600
|
+
}, [s]), L = E((m) => {
|
|
2601
|
+
const v = Mr(m.clipboardData);
|
|
2602
|
+
v.length && (m.preventDefault(), l(v));
|
|
2603
|
+
}, [l]), O = E((m) => {
|
|
2604
|
+
const v = Lr(m.dataTransfer);
|
|
2605
|
+
v.length && (m.preventDefault(), l(v));
|
|
2606
|
+
}, [l]), M = E((m) => {
|
|
2607
|
+
m.dataTransfer?.types?.includes("Files") && m.preventDefault();
|
|
2608
|
+
}, []), C = E(async () => {
|
|
2549
2609
|
if (!e.length) return [];
|
|
2550
2610
|
o(!0);
|
|
2551
2611
|
try {
|
|
2552
|
-
return await
|
|
2553
|
-
} catch (
|
|
2554
|
-
return
|
|
2612
|
+
return await Fr(e);
|
|
2613
|
+
} catch (m) {
|
|
2614
|
+
return k("chat", "Image upload failed", Hr(m)), i("error", Dr(m)), null;
|
|
2555
2615
|
} finally {
|
|
2556
2616
|
o(!1);
|
|
2557
2617
|
}
|
|
@@ -2559,160 +2619,157 @@ function Di() {
|
|
|
2559
2619
|
return {
|
|
2560
2620
|
pending: e,
|
|
2561
2621
|
uploading: n,
|
|
2562
|
-
addFiles:
|
|
2563
|
-
addMeme:
|
|
2564
|
-
remove:
|
|
2565
|
-
clear:
|
|
2622
|
+
addFiles: l,
|
|
2623
|
+
addMeme: p,
|
|
2624
|
+
remove: h,
|
|
2625
|
+
clear: f,
|
|
2566
2626
|
uploadPending: C,
|
|
2567
|
-
onPaste:
|
|
2568
|
-
onDrop:
|
|
2569
|
-
onDragOver:
|
|
2627
|
+
onPaste: L,
|
|
2628
|
+
onDrop: O,
|
|
2629
|
+
onDragOver: M
|
|
2570
2630
|
};
|
|
2571
2631
|
}
|
|
2572
|
-
const
|
|
2573
|
-
function
|
|
2574
|
-
const [t, n] =
|
|
2575
|
-
() =>
|
|
2576
|
-
[
|
|
2577
|
-
),
|
|
2578
|
-
(
|
|
2579
|
-
[
|
|
2580
|
-
),
|
|
2581
|
-
const
|
|
2582
|
-
if (
|
|
2583
|
-
|
|
2632
|
+
const jt = qt, Fi = Xn;
|
|
2633
|
+
function Hi({ commands: e = mt }) {
|
|
2634
|
+
const [t, n] = R(""), [o, i] = R(!1), [a, s] = R({ q: null, i: 0 }), [l, p] = R(!1), h = z(null), f = Pn(), [L, O] = R(!1), [M, C] = R(!1), m = Ui(), v = u((b) => b.snapshot.mediaId), y = u((b) => b.pushToast), I = u((b) => b.setTierlistOpen), g = !!v, A = Ni(t), N = Q(
|
|
2635
|
+
() => A === null ? [] : Ri(A, e),
|
|
2636
|
+
[A, e]
|
|
2637
|
+
), U = A !== null && !l && N.length > 0, F = a.q === A ? We(a.i, N.length) : 0, x = E(
|
|
2638
|
+
(b) => s({ q: A, i: b }),
|
|
2639
|
+
[A]
|
|
2640
|
+
), P = E((b, j) => {
|
|
2641
|
+
const re = Mi(b, { hasMedia: g });
|
|
2642
|
+
if (re) {
|
|
2643
|
+
y("info", re);
|
|
2584
2644
|
return;
|
|
2585
2645
|
}
|
|
2586
|
-
switch (
|
|
2646
|
+
switch (b.name) {
|
|
2587
2647
|
case "help":
|
|
2588
|
-
|
|
2648
|
+
y("info", e.map((An) => An.usage).join(" "));
|
|
2589
2649
|
break;
|
|
2590
2650
|
case "recap":
|
|
2591
|
-
|
|
2651
|
+
Si();
|
|
2592
2652
|
break;
|
|
2593
2653
|
case "tierlist":
|
|
2594
|
-
|
|
2595
|
-
break;
|
|
2596
|
-
case "character":
|
|
2597
|
-
u(!0);
|
|
2654
|
+
Mo(), I(!0);
|
|
2598
2655
|
break;
|
|
2599
2656
|
default:
|
|
2600
|
-
|
|
2657
|
+
y("info", `${b.usage} is not implemented yet.`);
|
|
2601
2658
|
}
|
|
2602
|
-
}, [
|
|
2603
|
-
n(
|
|
2604
|
-
}, []),
|
|
2605
|
-
if (
|
|
2606
|
-
const j =
|
|
2607
|
-
if (!j && !
|
|
2608
|
-
if (j?.kind === "command" &&
|
|
2609
|
-
|
|
2659
|
+
}, [g, y, e, I]), T = E((b) => {
|
|
2660
|
+
n(Di(b)), p(!1), h.current?.focus();
|
|
2661
|
+
}, []), pe = E(async (b) => {
|
|
2662
|
+
if (b.preventDefault(), o || m.uploading) return;
|
|
2663
|
+
const j = Oi(t, e);
|
|
2664
|
+
if (!j && !m.pending.length) return;
|
|
2665
|
+
if (j?.kind === "command" && m.pending.length) {
|
|
2666
|
+
y("info", "Send images on their own, not with a command.");
|
|
2610
2667
|
return;
|
|
2611
2668
|
}
|
|
2612
2669
|
if (j?.kind === "command") {
|
|
2613
|
-
|
|
2670
|
+
P(j.command, j.args), n(""), !document.hidden && document.hasFocus() && h.current?.focus();
|
|
2614
2671
|
return;
|
|
2615
2672
|
}
|
|
2616
|
-
const
|
|
2617
|
-
|
|
2618
|
-
}, [t, o,
|
|
2619
|
-
if (
|
|
2620
|
-
|
|
2673
|
+
const re = await m.uploadPending();
|
|
2674
|
+
re !== null && (gi(j?.text ?? "", re), n(""), m.clear(), i(!0), setTimeout(() => i(!1), Fi), !document.hidden && document.hasFocus() && h.current?.focus());
|
|
2675
|
+
}, [t, o, P, m, y, e]), he = E((b) => {
|
|
2676
|
+
if (b.key === "Escape" && U) {
|
|
2677
|
+
b.preventDefault(), p(!0);
|
|
2621
2678
|
return;
|
|
2622
2679
|
}
|
|
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 &&
|
|
2680
|
+
if (U) {
|
|
2681
|
+
if (b.key === "ArrowDown")
|
|
2682
|
+
b.preventDefault(), x(We(F + 1, N.length));
|
|
2683
|
+
else if (b.key === "ArrowUp")
|
|
2684
|
+
b.preventDefault(), x(We(F - 1, N.length));
|
|
2685
|
+
else if (b.key === "Tab") {
|
|
2686
|
+
b.preventDefault();
|
|
2687
|
+
const j = N[F];
|
|
2688
|
+
j && T(j);
|
|
2689
|
+
} else if (b.key === "Enter") {
|
|
2690
|
+
b.preventDefault();
|
|
2691
|
+
const j = N[F];
|
|
2692
|
+
j && T(j);
|
|
2636
2693
|
}
|
|
2637
2694
|
}
|
|
2638
|
-
}, [
|
|
2639
|
-
|
|
2640
|
-
const
|
|
2641
|
-
document.hidden || !document.hasFocus() || (
|
|
2695
|
+
}, [U, N, F, T, x]);
|
|
2696
|
+
D(() => {
|
|
2697
|
+
const b = () => {
|
|
2698
|
+
document.hidden || !document.hasFocus() || (h.current?.focus(), h.current?.scrollIntoView({ block: "nearest" }));
|
|
2642
2699
|
};
|
|
2643
|
-
return window.addEventListener("watchparty:focus-chat-input",
|
|
2700
|
+
return window.addEventListener("watchparty:focus-chat-input", b), () => window.removeEventListener("watchparty:focus-chat-input", b);
|
|
2644
2701
|
}, []);
|
|
2645
|
-
const
|
|
2646
|
-
return /* @__PURE__ */
|
|
2702
|
+
const ge = jt - t.length, ft = ge <= 100, pt = U ? N[F] : void 0;
|
|
2703
|
+
return /* @__PURE__ */ _(
|
|
2647
2704
|
"form",
|
|
2648
2705
|
{
|
|
2649
|
-
onSubmit: (
|
|
2650
|
-
|
|
2706
|
+
onSubmit: (b) => {
|
|
2707
|
+
pe(b);
|
|
2651
2708
|
},
|
|
2652
|
-
onPaste:
|
|
2653
|
-
onDrop:
|
|
2654
|
-
onDragOver:
|
|
2709
|
+
onPaste: m.onPaste,
|
|
2710
|
+
onDrop: m.onDrop,
|
|
2711
|
+
onDragOver: m.onDragOver,
|
|
2655
2712
|
className: "p-2 border-t border-border",
|
|
2656
2713
|
children: [
|
|
2657
|
-
/* @__PURE__ */
|
|
2658
|
-
/* @__PURE__ */
|
|
2659
|
-
|
|
2660
|
-
|
|
2714
|
+
/* @__PURE__ */ c(ji, { pending: m.pending, uploading: m.uploading, onRemove: m.remove }),
|
|
2715
|
+
/* @__PURE__ */ _("div", { className: "relative", children: [
|
|
2716
|
+
U && /* @__PURE__ */ c(
|
|
2717
|
+
Li,
|
|
2661
2718
|
{
|
|
2662
|
-
commands:
|
|
2663
|
-
activeIndex:
|
|
2664
|
-
hasMedia:
|
|
2665
|
-
onPick:
|
|
2666
|
-
onHover:
|
|
2667
|
-
listboxId:
|
|
2719
|
+
commands: N,
|
|
2720
|
+
activeIndex: F,
|
|
2721
|
+
hasMedia: g,
|
|
2722
|
+
onPick: T,
|
|
2723
|
+
onHover: x,
|
|
2724
|
+
listboxId: f
|
|
2668
2725
|
}
|
|
2669
2726
|
),
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
|
|
2727
|
+
/* @__PURE__ */ c(
|
|
2728
|
+
Wr,
|
|
2672
2729
|
{
|
|
2673
|
-
open:
|
|
2674
|
-
onClose: () =>
|
|
2675
|
-
onPick:
|
|
2730
|
+
open: L,
|
|
2731
|
+
onClose: () => O(!1),
|
|
2732
|
+
onPick: m.addMeme,
|
|
2676
2733
|
onUnavailable: () => {
|
|
2677
|
-
C(!0),
|
|
2734
|
+
C(!0), O(!1);
|
|
2678
2735
|
}
|
|
2679
2736
|
}
|
|
2680
2737
|
),
|
|
2681
|
-
/* @__PURE__ */
|
|
2682
|
-
/* @__PURE__ */
|
|
2683
|
-
/* @__PURE__ */
|
|
2738
|
+
/* @__PURE__ */ _("div", { className: "flex items-center gap-1.5", children: [
|
|
2739
|
+
/* @__PURE__ */ _("div", { className: "relative flex-1", children: [
|
|
2740
|
+
/* @__PURE__ */ c(
|
|
2684
2741
|
"input",
|
|
2685
2742
|
{
|
|
2686
|
-
ref:
|
|
2743
|
+
ref: h,
|
|
2687
2744
|
type: "text",
|
|
2688
2745
|
value: t,
|
|
2689
|
-
onChange: (
|
|
2690
|
-
n(
|
|
2746
|
+
onChange: (b) => {
|
|
2747
|
+
n(b.target.value), p(!1);
|
|
2691
2748
|
},
|
|
2692
|
-
onKeyDown:
|
|
2693
|
-
maxLength:
|
|
2749
|
+
onKeyDown: he,
|
|
2750
|
+
maxLength: jt,
|
|
2694
2751
|
placeholder: "Send a message",
|
|
2695
2752
|
role: "combobox",
|
|
2696
|
-
"aria-expanded":
|
|
2697
|
-
"aria-controls":
|
|
2698
|
-
"aria-activedescendant":
|
|
2753
|
+
"aria-expanded": U,
|
|
2754
|
+
"aria-controls": U ? f : void 0,
|
|
2755
|
+
"aria-activedescendant": pt ? `${f}-opt-${pt.name}` : void 0,
|
|
2699
2756
|
"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 ${
|
|
2757
|
+
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
2758
|
}
|
|
2702
2759
|
),
|
|
2703
|
-
/* @__PURE__ */
|
|
2760
|
+
/* @__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
2761
|
] }),
|
|
2705
|
-
!
|
|
2762
|
+
!M && /* @__PURE__ */ c(
|
|
2706
2763
|
"button",
|
|
2707
2764
|
{
|
|
2708
2765
|
type: "button",
|
|
2709
|
-
onClick: () =>
|
|
2766
|
+
onClick: () => O((b) => !b),
|
|
2710
2767
|
"aria-label": "Add a meme",
|
|
2711
|
-
"aria-expanded":
|
|
2768
|
+
"aria-expanded": L,
|
|
2712
2769
|
title: "Add a meme",
|
|
2713
2770
|
"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__ */
|
|
2771
|
+
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"}`,
|
|
2772
|
+
children: /* @__PURE__ */ c(Nn, { name: "image" })
|
|
2716
2773
|
}
|
|
2717
2774
|
)
|
|
2718
2775
|
] })
|
|
@@ -2721,35 +2778,36 @@ function ji({ commands: e = ft }) {
|
|
|
2721
2778
|
}
|
|
2722
2779
|
);
|
|
2723
2780
|
}
|
|
2724
|
-
function
|
|
2725
|
-
const e =
|
|
2726
|
-
return t.length ? /* @__PURE__ */
|
|
2727
|
-
const o =
|
|
2728
|
-
return /* @__PURE__ */
|
|
2729
|
-
|
|
2730
|
-
|
|
2781
|
+
function $i() {
|
|
2782
|
+
const e = u((n) => n.roster), t = Object.values(e);
|
|
2783
|
+
return t.length ? /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: t.map((n) => {
|
|
2784
|
+
const o = gn(n.sprite);
|
|
2785
|
+
return /* @__PURE__ */ _("div", { className: "flex items-center gap-2 py-0.5", children: [
|
|
2786
|
+
/* @__PURE__ */ c(
|
|
2787
|
+
kn,
|
|
2731
2788
|
{
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
className: "w-6 h-6 rounded-full object-cover flex-shrink-0"
|
|
2789
|
+
sprite: n.sprite,
|
|
2790
|
+
url: n.avatarUrl,
|
|
2791
|
+
alt: n.name || "Anon",
|
|
2792
|
+
className: "w-6 h-6 rounded-full object-cover flex-shrink-0",
|
|
2793
|
+
fallback: /* @__PURE__ */ c("span", { className: "w-6 h-6 bg-bg-alt rounded-full flex-shrink-0" })
|
|
2736
2794
|
}
|
|
2737
|
-
)
|
|
2738
|
-
/* @__PURE__ */
|
|
2739
|
-
n.isLeader && /* @__PURE__ */
|
|
2795
|
+
),
|
|
2796
|
+
/* @__PURE__ */ c("span", { className: "text-xs font-medium truncate", style: { color: o }, children: n.name || "Anon" }),
|
|
2797
|
+
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
2798
|
] }, n.clientId);
|
|
2741
|
-
}) }) : /* @__PURE__ */
|
|
2799
|
+
}) }) : /* @__PURE__ */ c("div", { className: "text-xs text-text-muted", children: "No users online" });
|
|
2742
2800
|
}
|
|
2743
|
-
function
|
|
2744
|
-
const e =
|
|
2745
|
-
return
|
|
2801
|
+
function Bi() {
|
|
2802
|
+
const e = u((i) => Object.keys(i.roster).length), [t, n] = R(!1), o = z(null);
|
|
2803
|
+
return D(() => {
|
|
2746
2804
|
if (!t) return;
|
|
2747
|
-
function i(
|
|
2748
|
-
o.current && !o.current.contains(
|
|
2805
|
+
function i(a) {
|
|
2806
|
+
o.current && !o.current.contains(a.target) && n(!1);
|
|
2749
2807
|
}
|
|
2750
2808
|
return document.addEventListener("mousedown", i), () => document.removeEventListener("mousedown", i);
|
|
2751
|
-
}, [t]), /* @__PURE__ */
|
|
2752
|
-
/* @__PURE__ */
|
|
2809
|
+
}, [t]), /* @__PURE__ */ _("div", { className: "relative", ref: o, children: [
|
|
2810
|
+
/* @__PURE__ */ _(
|
|
2753
2811
|
"button",
|
|
2754
2812
|
{
|
|
2755
2813
|
onClick: () => {
|
|
@@ -2758,208 +2816,34 @@ function Fi() {
|
|
|
2758
2816
|
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
2817
|
title: "Users",
|
|
2760
2818
|
children: [
|
|
2761
|
-
/* @__PURE__ */
|
|
2762
|
-
/* @__PURE__ */
|
|
2819
|
+
/* @__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" }) }),
|
|
2820
|
+
/* @__PURE__ */ c("span", { className: "text-xs", children: e })
|
|
2763
2821
|
]
|
|
2764
2822
|
}
|
|
2765
2823
|
),
|
|
2766
|
-
t && /* @__PURE__ */
|
|
2767
|
-
/* @__PURE__ */
|
|
2824
|
+
t && /* @__PURE__ */ _("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: [
|
|
2825
|
+
/* @__PURE__ */ _("div", { className: "text-[10px] uppercase tracking-wide text-text-muted mb-2", children: [
|
|
2768
2826
|
e,
|
|
2769
2827
|
" online"
|
|
2770
2828
|
] }),
|
|
2771
|
-
/* @__PURE__ */
|
|
2829
|
+
/* @__PURE__ */ c($i, {})
|
|
2772
2830
|
] })
|
|
2773
2831
|
] });
|
|
2774
2832
|
}
|
|
2775
|
-
function
|
|
2776
|
-
const
|
|
2777
|
-
return
|
|
2778
|
-
"button",
|
|
2779
|
-
{
|
|
2780
|
-
onClick: () => {
|
|
2781
|
-
d("chat", "Opening character modal", { currentSprite: e }), t(!0);
|
|
2782
|
-
},
|
|
2783
|
-
className: "p-1 rounded hover:bg-bg-alt transition-colors cursor-pointer",
|
|
2784
|
-
title: "Change character",
|
|
2785
|
-
children: fe(e) ? /* @__PURE__ */ l(
|
|
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(() => {
|
|
2833
|
+
function Ut({ className: e = "fixed bottom-4 left-1/2 -translate-x-1/2" }) {
|
|
2834
|
+
const t = u((o) => o.toasts), n = u((o) => o.popToast);
|
|
2835
|
+
return D(() => {
|
|
2952
2836
|
const o = t.map((i) => setTimeout(() => n(i.id), 4e3));
|
|
2953
2837
|
return () => {
|
|
2954
2838
|
o.forEach(clearTimeout);
|
|
2955
2839
|
};
|
|
2956
|
-
}, [t, n]), /* @__PURE__ */
|
|
2840
|
+
}, [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
2841
|
}
|
|
2958
|
-
const
|
|
2959
|
-
function
|
|
2960
|
-
return e || (
|
|
2842
|
+
const Ft = (e) => typeof e == "string" && Rn.includes(e);
|
|
2843
|
+
function Gi(e, t, n) {
|
|
2844
|
+
return e || (Ft(t) ? t : Ft(n) ? n : "dark");
|
|
2961
2845
|
}
|
|
2962
|
-
function
|
|
2846
|
+
function Ki(e, t) {
|
|
2963
2847
|
if (t(e.clientWidth), typeof ResizeObserver > "u") return () => {
|
|
2964
2848
|
};
|
|
2965
2849
|
const n = new ResizeObserver(() => t(e.clientWidth));
|
|
@@ -2969,190 +2853,188 @@ function Wi(e) {
|
|
|
2969
2853
|
const t = e?.trim() ?? "";
|
|
2970
2854
|
return t ? { source: "host", name: t } : { source: "auto" };
|
|
2971
2855
|
}
|
|
2972
|
-
function
|
|
2856
|
+
function qi(e) {
|
|
2973
2857
|
if (e.source !== "host") return;
|
|
2974
|
-
const { setSessionIdentity: t, sprite: n } =
|
|
2858
|
+
const { setSessionIdentity: t, sprite: n } = u.getState();
|
|
2975
2859
|
t(e.name, n);
|
|
2976
2860
|
}
|
|
2977
|
-
function
|
|
2978
|
-
return /* @__PURE__ */
|
|
2979
|
-
/* @__PURE__ */
|
|
2980
|
-
/* @__PURE__ */
|
|
2861
|
+
function Vi({ className: e = "w-4 h-4" }) {
|
|
2862
|
+
return /* @__PURE__ */ _("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
|
|
2863
|
+
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 4v16" }),
|
|
2864
|
+
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 12l-5 4v-8l5 4z" })
|
|
2981
2865
|
] });
|
|
2982
2866
|
}
|
|
2983
|
-
function
|
|
2984
|
-
return /* @__PURE__ */
|
|
2985
|
-
/* @__PURE__ */
|
|
2986
|
-
/* @__PURE__ */
|
|
2867
|
+
function Yi({ className: e = "w-4 h-4" }) {
|
|
2868
|
+
return /* @__PURE__ */ _("svg", { className: e, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
|
|
2869
|
+
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 4v16" }),
|
|
2870
|
+
/* @__PURE__ */ c("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l5 4v-8l-5 4z" })
|
|
2987
2871
|
] });
|
|
2988
2872
|
}
|
|
2989
2873
|
const zi = 1500;
|
|
2990
|
-
function
|
|
2874
|
+
function ca({
|
|
2991
2875
|
roomKey: e,
|
|
2992
2876
|
serverOrigin: t,
|
|
2993
2877
|
userType: n,
|
|
2994
2878
|
userId: o,
|
|
2995
2879
|
theme: i,
|
|
2996
|
-
name:
|
|
2997
|
-
onLeave:
|
|
2998
|
-
onLayoutChange:
|
|
2999
|
-
collapsible:
|
|
3000
|
-
debug:
|
|
3001
|
-
children:
|
|
2880
|
+
name: a,
|
|
2881
|
+
onLeave: s,
|
|
2882
|
+
onLayoutChange: l,
|
|
2883
|
+
collapsible: p = !0,
|
|
2884
|
+
debug: h,
|
|
2885
|
+
children: f
|
|
3002
2886
|
}) {
|
|
3003
|
-
const [
|
|
3004
|
-
() =>
|
|
3005
|
-
[i,
|
|
2887
|
+
const [L, O] = R(null), { setFrame: M, ...C } = Xi(l, p), m = Bt(() => a), v = Q(() => (go({ userType: n, userId: o ?? null }), lt().theme), [n, o]), y = Dn(), I = y?.theme, g = Q(
|
|
2888
|
+
() => Gi(i, I, v),
|
|
2889
|
+
[i, I, v]
|
|
3006
2890
|
);
|
|
3007
|
-
|
|
3008
|
-
}, [i,
|
|
3009
|
-
const
|
|
3010
|
-
() => ({ ...
|
|
2891
|
+
D(() => {
|
|
2892
|
+
}, [i, y !== null]);
|
|
2893
|
+
const N = Q(
|
|
2894
|
+
() => ({ ...rt, serverOrigin: t, defaultRoomKey: e }),
|
|
3011
2895
|
[t, e]
|
|
3012
2896
|
);
|
|
3013
|
-
return
|
|
3014
|
-
|
|
3015
|
-
}, [
|
|
3016
|
-
|
|
3017
|
-
let
|
|
3018
|
-
const
|
|
2897
|
+
return D(() => {
|
|
2898
|
+
h && Qr();
|
|
2899
|
+
}, [h]), _i(), D(() => {
|
|
2900
|
+
qr({ serverOrigin: t, defaultRoomKey: e }), u.getState().rehydrateFromPrefs(), Yo();
|
|
2901
|
+
let U = !1;
|
|
2902
|
+
const F = vo();
|
|
3019
2903
|
return (async () => {
|
|
3020
2904
|
try {
|
|
3021
2905
|
await Promise.race([
|
|
3022
2906
|
Promise.all([
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
})
|
|
2907
|
+
F,
|
|
2908
|
+
Co().then((T) => {
|
|
2909
|
+
T && u.getState().rehydrateFromPrefs();
|
|
2910
|
+
}),
|
|
2911
|
+
// The character chosen in the settings popout (lib/avatar.ts).
|
|
2912
|
+
Uo().then(Tn)
|
|
3027
2913
|
]),
|
|
3028
|
-
new Promise((
|
|
2914
|
+
new Promise((T) => setTimeout(T, zi))
|
|
3029
2915
|
]);
|
|
3030
|
-
} catch (
|
|
3031
|
-
|
|
2916
|
+
} catch (T) {
|
|
2917
|
+
k("room-chrome", "pre-join wait threw, proceeding anyway", fe(T));
|
|
3032
2918
|
}
|
|
3033
|
-
if (
|
|
3034
|
-
const
|
|
3035
|
-
|
|
3036
|
-
const
|
|
3037
|
-
d("room-chrome", "Joining room", { roomKey: e, name:
|
|
2919
|
+
if (U) return;
|
|
2920
|
+
const x = Wi(m());
|
|
2921
|
+
u.getState().ensureAutoIdentity(), qi(x);
|
|
2922
|
+
const P = u.getState();
|
|
2923
|
+
d("room-chrome", "Joining room", { roomKey: e, name: P.name, sprite: P.sprite }), oi({ room_key: e, name: P.name || void 0, sprite: P.sprite || void 0 });
|
|
3038
2924
|
})(), () => {
|
|
3039
|
-
|
|
2925
|
+
U = !0, Lt();
|
|
3040
2926
|
};
|
|
3041
|
-
}, [e, t, n, o]), /* @__PURE__ */
|
|
3042
|
-
/* @__PURE__ */
|
|
3043
|
-
/* @__PURE__ */
|
|
2927
|
+
}, [e, t, n, o]), /* @__PURE__ */ c(Vr.Provider, { value: N, children: /* @__PURE__ */ c(dn.Provider, { value: L, children: /* @__PURE__ */ _("div", { ref: M, className: "wp-room-chrome-frame", children: [
|
|
2928
|
+
/* @__PURE__ */ c("div", { className: "wp-room-chrome-frame__content", children: f }),
|
|
2929
|
+
/* @__PURE__ */ c(
|
|
3044
2930
|
"aside",
|
|
3045
2931
|
{
|
|
3046
|
-
ref:
|
|
2932
|
+
ref: O,
|
|
3047
2933
|
className: "wp-room-chrome",
|
|
3048
|
-
"data-theme":
|
|
2934
|
+
"data-theme": g,
|
|
3049
2935
|
"data-collapsed": C.collapsed ? "1" : "0",
|
|
3050
2936
|
style: { "--wp-room-chrome-width": `${C.state.width}px` },
|
|
3051
|
-
children: [
|
|
3052
|
-
|
|
3053
|
-
|
|
2937
|
+
children: C.collapsed ? /* @__PURE__ */ _(le, { children: [
|
|
2938
|
+
/* @__PURE__ */ c(
|
|
2939
|
+
"button",
|
|
2940
|
+
{
|
|
2941
|
+
onClick: C.toggleCollapsed,
|
|
2942
|
+
className: "wp-room-chrome__icon-btn",
|
|
2943
|
+
title: "Show chat",
|
|
2944
|
+
"aria-label": "Show chat",
|
|
2945
|
+
"aria-expanded": !1,
|
|
2946
|
+
children: /* @__PURE__ */ c(Yi, {})
|
|
2947
|
+
}
|
|
2948
|
+
),
|
|
2949
|
+
/* @__PURE__ */ c(Ut, { className: "absolute bottom-2 right-full mr-2 w-72" })
|
|
2950
|
+
] }) : /* @__PURE__ */ _(le, { children: [
|
|
2951
|
+
/* @__PURE__ */ c(
|
|
2952
|
+
"div",
|
|
2953
|
+
{
|
|
2954
|
+
role: "separator",
|
|
2955
|
+
"aria-orientation": "vertical",
|
|
2956
|
+
"aria-label": "Resize chat",
|
|
2957
|
+
"aria-valuemin": Oe,
|
|
2958
|
+
"aria-valuemax": ct,
|
|
2959
|
+
"aria-valuenow": C.state.width,
|
|
2960
|
+
tabIndex: 0,
|
|
2961
|
+
className: "wp-room-chrome__resize",
|
|
2962
|
+
"data-dragging": C.dragging ? "1" : "0",
|
|
2963
|
+
onPointerDown: C.onPointerDown,
|
|
2964
|
+
onPointerMove: C.onPointerMove,
|
|
2965
|
+
onPointerUp: C.onPointerEnd,
|
|
2966
|
+
onPointerCancel: C.onPointerEnd,
|
|
2967
|
+
onKeyDown: C.onKeyDown
|
|
2968
|
+
}
|
|
2969
|
+
),
|
|
2970
|
+
/* @__PURE__ */ _("div", { className: "flex items-center gap-1 px-2 py-1.5 border-b border-border", children: [
|
|
2971
|
+
/* @__PURE__ */ c(Bi, {}),
|
|
2972
|
+
/* @__PURE__ */ c("div", { className: "flex-1" }),
|
|
2973
|
+
s && /* @__PURE__ */ c(
|
|
3054
2974
|
"button",
|
|
3055
2975
|
{
|
|
3056
|
-
onClick:
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
"
|
|
3061
|
-
|
|
2976
|
+
onClick: () => {
|
|
2977
|
+
Lt(), s();
|
|
2978
|
+
},
|
|
2979
|
+
className: "wp-room-chrome__leave",
|
|
2980
|
+
title: "Leave room",
|
|
2981
|
+
"aria-label": "Leave room",
|
|
2982
|
+
children: "Leave"
|
|
3062
2983
|
}
|
|
3063
2984
|
),
|
|
3064
|
-
/* @__PURE__ */
|
|
3065
|
-
|
|
3066
|
-
/* @__PURE__ */ l(
|
|
3067
|
-
"div",
|
|
2985
|
+
p && /* @__PURE__ */ c(
|
|
2986
|
+
"button",
|
|
3068
2987
|
{
|
|
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
|
|
2988
|
+
onClick: C.toggleCollapsed,
|
|
2989
|
+
className: "wp-room-chrome__icon-btn",
|
|
2990
|
+
title: "Hide chat",
|
|
2991
|
+
"aria-label": "Hide chat",
|
|
2992
|
+
"aria-expanded": !0,
|
|
2993
|
+
children: /* @__PURE__ */ c(Vi, {})
|
|
3083
2994
|
}
|
|
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" })
|
|
2995
|
+
)
|
|
3116
2996
|
] }),
|
|
3117
|
-
|
|
3118
|
-
|
|
2997
|
+
/* @__PURE__ */ c(Pi, {}),
|
|
2998
|
+
/* @__PURE__ */ c(Hi, { commands: [] }),
|
|
2999
|
+
/* @__PURE__ */ c(Ut, { className: "absolute bottom-14 left-2 right-2" })
|
|
3000
|
+
] })
|
|
3119
3001
|
}
|
|
3120
3002
|
)
|
|
3121
3003
|
] }) }) });
|
|
3122
3004
|
}
|
|
3123
|
-
function
|
|
3124
|
-
const n =
|
|
3125
|
-
|
|
3126
|
-
if (
|
|
3127
|
-
return
|
|
3128
|
-
}, [
|
|
3129
|
-
const
|
|
3130
|
-
return
|
|
3131
|
-
C(
|
|
3132
|
-
}, [
|
|
3133
|
-
setFrame:
|
|
3005
|
+
function Xi(e, t) {
|
|
3006
|
+
const n = u((g) => g.chromeChatCollapsed) && t, o = u((g) => g.chromeChatWidth), i = u((g) => g.toggleChromeChatCollapsed), a = u((g) => g.setChromeChatWidth), [s, l] = R(null), [p, h] = R(void 0), [f, L] = R(null);
|
|
3007
|
+
D(() => {
|
|
3008
|
+
if (s)
|
|
3009
|
+
return Ki(s, h);
|
|
3010
|
+
}, [s]);
|
|
3011
|
+
const O = W(f?.current ?? o, p), M = Q(() => Po(n, O), [n, O]), C = Bt((g) => e?.(g));
|
|
3012
|
+
return D(() => {
|
|
3013
|
+
C(M);
|
|
3014
|
+
}, [M]), {
|
|
3015
|
+
setFrame: l,
|
|
3134
3016
|
collapsed: n,
|
|
3135
|
-
state:
|
|
3136
|
-
dragging:
|
|
3017
|
+
state: M,
|
|
3018
|
+
dragging: f !== null,
|
|
3137
3019
|
toggleCollapsed: i,
|
|
3138
|
-
onPointerDown: (
|
|
3139
|
-
|
|
3020
|
+
onPointerDown: (g) => {
|
|
3021
|
+
g.button === 0 && (g.preventDefault(), g.currentTarget.setPointerCapture(g.pointerId), L({ pointerId: g.pointerId, startX: g.clientX, startWidth: O, current: O }));
|
|
3140
3022
|
},
|
|
3141
|
-
onPointerMove: (
|
|
3142
|
-
!
|
|
3023
|
+
onPointerMove: (g) => {
|
|
3024
|
+
!f || f.pointerId !== g.pointerId || L({ ...f, current: Et(f.startWidth, f.startX, g.clientX, p) });
|
|
3143
3025
|
},
|
|
3144
|
-
onPointerEnd: (
|
|
3145
|
-
if (!
|
|
3146
|
-
const
|
|
3147
|
-
|
|
3026
|
+
onPointerEnd: (g) => {
|
|
3027
|
+
if (!f || f.pointerId !== g.pointerId) return;
|
|
3028
|
+
const A = Et(f.startWidth, f.startX, g.clientX, p);
|
|
3029
|
+
L(null), A !== o && a(A);
|
|
3148
3030
|
},
|
|
3149
|
-
onKeyDown: (
|
|
3150
|
-
const
|
|
3151
|
-
|
|
3031
|
+
onKeyDown: (g) => {
|
|
3032
|
+
const A = Eo(O, g.key, p);
|
|
3033
|
+
A !== null && (g.preventDefault(), A !== o && a(A));
|
|
3152
3034
|
}
|
|
3153
3035
|
};
|
|
3154
3036
|
}
|
|
3155
3037
|
export {
|
|
3156
|
-
|
|
3038
|
+
ca as RoomChrome
|
|
3157
3039
|
};
|
|
3158
3040
|
//# sourceMappingURL=room-chrome.js.map
|