@thestatic-tv/dcl-sdk 2.5.10 → 2.5.13
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/index.d.mts +49 -2
- package/dist/index.d.ts +49 -2
- package/dist/index.js +423 -252
- package/dist/index.mjs +392 -223
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38,11 +38,13 @@ __export(index_exports, {
|
|
|
38
38
|
InteractionsModule: () => InteractionsModule,
|
|
39
39
|
KEY_TYPE_CHANNEL: () => KEY_TYPE_CHANNEL,
|
|
40
40
|
KEY_TYPE_SCENE: () => KEY_TYPE_SCENE,
|
|
41
|
+
NotificationBanner: () => NotificationBanner,
|
|
41
42
|
SessionModule: () => SessionModule,
|
|
42
43
|
StaticTVClient: () => StaticTVClient,
|
|
43
44
|
fetchUserData: () => fetchUserData,
|
|
44
45
|
getPlayerDisplayName: () => getPlayerDisplayName,
|
|
45
46
|
getPlayerWallet: () => getPlayerWallet,
|
|
47
|
+
hideNotification: () => hideNotification,
|
|
46
48
|
setupStaticUI: () => setupStaticUI,
|
|
47
49
|
showNotification: () => showNotification
|
|
48
50
|
});
|
|
@@ -668,6 +670,17 @@ var UI_DIMENSIONS = {
|
|
|
668
670
|
buttonHeightSmall: 30,
|
|
669
671
|
inputHeight: 36
|
|
670
672
|
},
|
|
673
|
+
// Notification banner - centered, aligned with toggle buttons
|
|
674
|
+
notification: {
|
|
675
|
+
width: 340,
|
|
676
|
+
height: 36,
|
|
677
|
+
// Same as toggle buttons
|
|
678
|
+
bottom: 10,
|
|
679
|
+
// Same as toggle buttons
|
|
680
|
+
borderWidth: 2,
|
|
681
|
+
fontSize: 14
|
|
682
|
+
// Same as toggle buttons (14)
|
|
683
|
+
},
|
|
671
684
|
// Shared
|
|
672
685
|
closeButton: {
|
|
673
686
|
size: 40,
|
|
@@ -2295,12 +2308,144 @@ var ChatUIModule = class {
|
|
|
2295
2308
|
};
|
|
2296
2309
|
|
|
2297
2310
|
// src/ui/admin-panel-ui.tsx
|
|
2298
|
-
var
|
|
2311
|
+
var import_react_ecs5 = __toESM(require("@dcl/sdk/react-ecs"));
|
|
2299
2312
|
var import_math5 = require("@dcl/sdk/math");
|
|
2300
2313
|
var import_players2 = require("@dcl/sdk/players");
|
|
2301
2314
|
var import_RestrictedActions3 = require("~system/RestrictedActions");
|
|
2315
|
+
|
|
2316
|
+
// src/ui/ui-renderer.tsx
|
|
2317
|
+
var import_react_ecs4 = __toESM(require("@dcl/sdk/react-ecs"));
|
|
2318
|
+
var import_ecs2 = require("@dcl/sdk/ecs");
|
|
2319
|
+
var notificationText = "";
|
|
2320
|
+
var notificationVisible = false;
|
|
2321
|
+
var notificationEndTime = 0;
|
|
2322
|
+
var notificationInitialized = false;
|
|
2323
|
+
var C = THEME.colors;
|
|
2324
|
+
var N = UI_DIMENSIONS.notification;
|
|
2325
|
+
function showNotification(message, durationMs = 5e3) {
|
|
2326
|
+
notificationText = message;
|
|
2327
|
+
notificationVisible = true;
|
|
2328
|
+
notificationEndTime = Date.now() + durationMs;
|
|
2329
|
+
}
|
|
2330
|
+
function hideNotification() {
|
|
2331
|
+
notificationVisible = false;
|
|
2332
|
+
}
|
|
2333
|
+
function initNotificationSystem() {
|
|
2334
|
+
if (notificationInitialized) return;
|
|
2335
|
+
notificationInitialized = true;
|
|
2336
|
+
import_ecs2.engine.addSystem(() => {
|
|
2337
|
+
if (notificationVisible && Date.now() > notificationEndTime) {
|
|
2338
|
+
notificationVisible = false;
|
|
2339
|
+
}
|
|
2340
|
+
});
|
|
2341
|
+
}
|
|
2342
|
+
function NotificationBanner() {
|
|
2343
|
+
initNotificationSystem();
|
|
2344
|
+
if (!notificationVisible) return null;
|
|
2345
|
+
return (
|
|
2346
|
+
// Full-width container to center the notification
|
|
2347
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2348
|
+
import_react_ecs4.UiEntity,
|
|
2349
|
+
{
|
|
2350
|
+
uiTransform: {
|
|
2351
|
+
positionType: "absolute",
|
|
2352
|
+
position: { bottom: N.bottom, left: 0, right: 0 },
|
|
2353
|
+
height: N.height,
|
|
2354
|
+
justifyContent: "center",
|
|
2355
|
+
alignItems: "center"
|
|
2356
|
+
}
|
|
2357
|
+
},
|
|
2358
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2359
|
+
import_react_ecs4.UiEntity,
|
|
2360
|
+
{
|
|
2361
|
+
uiTransform: {
|
|
2362
|
+
width: N.width,
|
|
2363
|
+
height: N.height,
|
|
2364
|
+
flexDirection: "row",
|
|
2365
|
+
alignItems: "center"
|
|
2366
|
+
},
|
|
2367
|
+
uiBackground: { color: C.panel }
|
|
2368
|
+
},
|
|
2369
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2370
|
+
import_react_ecs4.UiEntity,
|
|
2371
|
+
{
|
|
2372
|
+
uiTransform: {
|
|
2373
|
+
width: N.borderWidth,
|
|
2374
|
+
height: "100%"
|
|
2375
|
+
},
|
|
2376
|
+
uiBackground: { color: C.cyan }
|
|
2377
|
+
}
|
|
2378
|
+
),
|
|
2379
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2380
|
+
import_react_ecs4.UiEntity,
|
|
2381
|
+
{
|
|
2382
|
+
uiTransform: {
|
|
2383
|
+
flexGrow: 1,
|
|
2384
|
+
height: "100%",
|
|
2385
|
+
padding: { left: 10, right: 10 },
|
|
2386
|
+
justifyContent: "center",
|
|
2387
|
+
alignItems: "flex-start"
|
|
2388
|
+
}
|
|
2389
|
+
},
|
|
2390
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2391
|
+
import_react_ecs4.Label,
|
|
2392
|
+
{
|
|
2393
|
+
value: notificationText,
|
|
2394
|
+
fontSize: N.fontSize,
|
|
2395
|
+
color: C.white,
|
|
2396
|
+
textAlign: "middle-left"
|
|
2397
|
+
}
|
|
2398
|
+
)
|
|
2399
|
+
),
|
|
2400
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2401
|
+
import_react_ecs4.UiEntity,
|
|
2402
|
+
{
|
|
2403
|
+
uiTransform: {
|
|
2404
|
+
width: 5,
|
|
2405
|
+
height: 5,
|
|
2406
|
+
margin: { right: 10 }
|
|
2407
|
+
},
|
|
2408
|
+
uiBackground: { color: C.cyan }
|
|
2409
|
+
}
|
|
2410
|
+
)
|
|
2411
|
+
)
|
|
2412
|
+
)
|
|
2413
|
+
);
|
|
2414
|
+
}
|
|
2415
|
+
function createStaticUI(client) {
|
|
2416
|
+
initNotificationSystem();
|
|
2417
|
+
return function StaticUI() {
|
|
2418
|
+
const currentScale = client.uiScale;
|
|
2419
|
+
const guideComponent = client.guideUI?.getComponent() ?? null;
|
|
2420
|
+
const chatComponent = client.chatUI?.getComponent() ?? null;
|
|
2421
|
+
const adminComponent = client.adminPanel?.getComponent() ?? null;
|
|
2422
|
+
return /* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2423
|
+
import_react_ecs4.UiEntity,
|
|
2424
|
+
{
|
|
2425
|
+
key: `static-ui-root-${currentScale}`,
|
|
2426
|
+
uiTransform: {
|
|
2427
|
+
width: "100%",
|
|
2428
|
+
height: "100%",
|
|
2429
|
+
positionType: "absolute",
|
|
2430
|
+
flexDirection: "column",
|
|
2431
|
+
alignItems: "center"
|
|
2432
|
+
}
|
|
2433
|
+
},
|
|
2434
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(NotificationBanner, null),
|
|
2435
|
+
guideComponent,
|
|
2436
|
+
chatComponent,
|
|
2437
|
+
adminComponent
|
|
2438
|
+
);
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
function setupStaticUI(client) {
|
|
2442
|
+
const StaticUI = createStaticUI(client);
|
|
2443
|
+
import_react_ecs4.ReactEcsRenderer.setUiRenderer(StaticUI);
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
// src/ui/admin-panel-ui.tsx
|
|
2302
2447
|
var BAN_KICK_POSITION = import_math5.Vector3.create(16, -50, 16);
|
|
2303
|
-
var
|
|
2448
|
+
var C2 = {
|
|
2304
2449
|
bg: import_math5.Color4.create(0.08, 0.08, 0.12, 0.98),
|
|
2305
2450
|
header: import_math5.Color4.create(0.9, 0.15, 0.15, 1),
|
|
2306
2451
|
tabActive: import_math5.Color4.create(0, 0.7, 0.7, 1),
|
|
@@ -2341,6 +2486,8 @@ var AdminPanelUIModule = class {
|
|
|
2341
2486
|
this.streamControlling = false;
|
|
2342
2487
|
this.streamControlStatus = "";
|
|
2343
2488
|
this.pollIntervalId = null;
|
|
2489
|
+
this.commandPollIntervalId = null;
|
|
2490
|
+
this.lastCommandTimestamp = 0;
|
|
2344
2491
|
this.trialClaiming = false;
|
|
2345
2492
|
this.trialClaimError = "";
|
|
2346
2493
|
// Mod tab state
|
|
@@ -2352,22 +2499,22 @@ var AdminPanelUIModule = class {
|
|
|
2352
2499
|
this.modStatus = "";
|
|
2353
2500
|
this.modsFetched = false;
|
|
2354
2501
|
// --- UI Components ---
|
|
2355
|
-
this.SectionHead = ({ label, color }) => /* @__PURE__ */
|
|
2356
|
-
|
|
2502
|
+
this.SectionHead = ({ label, color }) => /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2503
|
+
import_react_ecs5.UiEntity,
|
|
2357
2504
|
{
|
|
2358
2505
|
uiTransform: { width: "100%", height: this.s(UI_DIMENSIONS.admin.sectionHeadHeight), margin: { bottom: 8 }, padding: { left: 10 }, alignItems: "center" },
|
|
2359
2506
|
uiBackground: { color: import_math5.Color4.create(color.r * 0.3, color.g * 0.3, color.b * 0.3, 0.5) }
|
|
2360
2507
|
},
|
|
2361
|
-
/* @__PURE__ */
|
|
2508
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: label, fontSize: this.theme.sectionHead, color })
|
|
2362
2509
|
);
|
|
2363
|
-
this.TabBtn = ({ label, tab }) => /* @__PURE__ */
|
|
2364
|
-
|
|
2510
|
+
this.TabBtn = ({ label, tab }) => /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2511
|
+
import_react_ecs5.Button,
|
|
2365
2512
|
{
|
|
2366
2513
|
uiTransform: { flexGrow: 1, height: this.s(UI_DIMENSIONS.admin.tabHeight), justifyContent: "center", alignItems: "center" },
|
|
2367
|
-
uiBackground: { color: this.activeTab === tab ?
|
|
2514
|
+
uiBackground: { color: this.activeTab === tab ? C2.tabActive : C2.tabInactive },
|
|
2368
2515
|
value: label,
|
|
2369
2516
|
fontSize: this.theme.tabButton,
|
|
2370
|
-
color: this.activeTab === tab ? import_math5.Color4.Black() :
|
|
2517
|
+
color: this.activeTab === tab ? import_math5.Color4.Black() : C2.text,
|
|
2371
2518
|
textAlign: "middle-center",
|
|
2372
2519
|
onMouseDown: () => this.setActiveTab(tab)
|
|
2373
2520
|
}
|
|
@@ -2377,365 +2524,368 @@ var AdminPanelUIModule = class {
|
|
|
2377
2524
|
this.fetchStreamData();
|
|
2378
2525
|
}
|
|
2379
2526
|
const t = this.theme;
|
|
2380
|
-
return /* @__PURE__ */
|
|
2381
|
-
|
|
2527
|
+
return /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", width: "100%", padding: 10 } }, !this.streamData?.hasChannel && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "LIVE STREAM", color: C2.btn }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "No streaming channel linked", fontSize: t.labelSmall, color: C2.textDim, uiTransform: { margin: { bottom: 8 } } }), this.isOwner && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column" } }, this.streamData?.trialAvailable && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 10 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2528
|
+
import_react_ecs5.Button,
|
|
2382
2529
|
{
|
|
2383
2530
|
uiTransform: { width: this.s(200), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: { bottom: 6 } },
|
|
2384
|
-
uiBackground: { color: this.trialClaiming ?
|
|
2531
|
+
uiBackground: { color: this.trialClaiming ? C2.btn : C2.green },
|
|
2385
2532
|
value: this.trialClaiming ? "Claiming..." : "Start Free 4-Hour Trial",
|
|
2386
2533
|
fontSize: t.button,
|
|
2387
|
-
color:
|
|
2534
|
+
color: C2.text,
|
|
2388
2535
|
onMouseDown: () => this.claimTrial()
|
|
2389
2536
|
}
|
|
2390
|
-
), this.trialClaimError && /* @__PURE__ */
|
|
2391
|
-
|
|
2537
|
+
), this.trialClaimError && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: this.trialClaimError, fontSize: t.status, color: C2.red }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "One-time trial \u2022 4 hours of streaming", fontSize: t.labelSmall, color: C2.textDim, uiTransform: { margin: { top: 4 } } })), !this.streamData?.trialAvailable && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column" } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2538
|
+
import_react_ecs5.Button,
|
|
2392
2539
|
{
|
|
2393
2540
|
uiTransform: { width: this.s(170), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: { bottom: 6 } },
|
|
2394
|
-
uiBackground: { color: this.channelCreating ?
|
|
2541
|
+
uiBackground: { color: this.channelCreating ? C2.btn : C2.cyan },
|
|
2395
2542
|
value: this.channelCreating ? "Creating..." : "+ Create Channel",
|
|
2396
2543
|
fontSize: t.button,
|
|
2397
|
-
color:
|
|
2544
|
+
color: C2.text,
|
|
2398
2545
|
onMouseDown: () => this.createChannel()
|
|
2399
2546
|
}
|
|
2400
|
-
), this.channelCreateError && /* @__PURE__ */
|
|
2401
|
-
|
|
2547
|
+
), this.channelCreateError && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: this.channelCreateError, fontSize: t.status, color: C2.red }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Relay tier \u2022 $25/mo \u2022 8 hours streaming", fontSize: t.labelSmall, color: C2.textDim, uiTransform: { margin: { top: 4 } } })))), this.streamData?.hasChannel && this.isOwner && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: this.streamData.isLive ? "LIVE STREAM" : "STREAM SETTINGS", color: this.streamData.isLive ? C2.red : C2.yellow }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 8 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2548
|
+
import_react_ecs5.Label,
|
|
2402
2549
|
{
|
|
2403
2550
|
value: this.streamData.isLive ? `LIVE \u2022 ${this.streamData.currentViewers || 0} viewers` : "OFFLINE",
|
|
2404
2551
|
fontSize: t.label,
|
|
2405
|
-
color: this.streamData.isLive ?
|
|
2552
|
+
color: this.streamData.isLive ? C2.red : C2.textDim
|
|
2406
2553
|
}
|
|
2407
|
-
), /* @__PURE__ */
|
|
2408
|
-
|
|
2554
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: ` \u2022 ${this.streamData.tier?.toUpperCase() || "RELAY"}`, fontSize: t.labelSmall, color: C2.cyan }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: ` \u2022 ${this.streamData.sparksBalance || 0} Sparks`, fontSize: t.labelSmall, color: C2.textDim })), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2555
|
+
import_react_ecs5.Label,
|
|
2409
2556
|
{
|
|
2410
2557
|
value: `Channel: ${this.streamData.channelName || this.streamData.channelId}`,
|
|
2411
2558
|
fontSize: t.labelSmall,
|
|
2412
|
-
color:
|
|
2559
|
+
color: C2.textDim,
|
|
2413
2560
|
uiTransform: { margin: { bottom: 10 } }
|
|
2414
2561
|
}
|
|
2415
|
-
), /* @__PURE__ */
|
|
2416
|
-
|
|
2562
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "RTMP Server:", fontSize: t.labelSmall, color: C2.textDim }), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2563
|
+
import_react_ecs5.Label,
|
|
2417
2564
|
{
|
|
2418
2565
|
value: this.streamData.rtmpUrl || "Loading...",
|
|
2419
2566
|
fontSize: t.label,
|
|
2420
|
-
color: this.streamData.rtmpUrl ?
|
|
2567
|
+
color: this.streamData.rtmpUrl ? C2.text : C2.textDim,
|
|
2421
2568
|
uiTransform: { margin: { left: 6 } }
|
|
2422
2569
|
}
|
|
2423
|
-
)), /* @__PURE__ */
|
|
2424
|
-
|
|
2570
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Stream Key:", fontSize: t.labelSmall, color: C2.textDim }), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2571
|
+
import_react_ecs5.Label,
|
|
2425
2572
|
{
|
|
2426
2573
|
value: this.streamData.streamKey || "Loading...",
|
|
2427
2574
|
fontSize: t.label,
|
|
2428
|
-
color: this.streamData.streamKey ?
|
|
2575
|
+
color: this.streamData.streamKey ? C2.cyan : C2.textDim,
|
|
2429
2576
|
uiTransform: { margin: { left: 6 } }
|
|
2430
2577
|
}
|
|
2431
|
-
)), /* @__PURE__ */
|
|
2432
|
-
|
|
2578
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 10 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "HLS Playback:", fontSize: t.labelSmall, color: C2.textDim }), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2579
|
+
import_react_ecs5.Label,
|
|
2433
2580
|
{
|
|
2434
2581
|
value: this.streamData.hlsUrl || "Not available",
|
|
2435
2582
|
fontSize: t.label,
|
|
2436
|
-
color: this.streamData.hlsUrl ?
|
|
2583
|
+
color: this.streamData.hlsUrl ? C2.green : C2.textDim,
|
|
2437
2584
|
uiTransform: { margin: { left: 6 } }
|
|
2438
2585
|
}
|
|
2439
|
-
)), /* @__PURE__ */
|
|
2440
|
-
|
|
2586
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 6 } } }, !this.streamData.isLive && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2587
|
+
import_react_ecs5.Button,
|
|
2441
2588
|
{
|
|
2442
2589
|
uiTransform: { width: this.s(110), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2443
|
-
uiBackground: { color: this.streamControlling ?
|
|
2590
|
+
uiBackground: { color: this.streamControlling ? C2.btn : C2.green },
|
|
2444
2591
|
value: this.streamControlling ? "Starting..." : "Start Stream",
|
|
2445
2592
|
fontSize: t.buttonSmall,
|
|
2446
|
-
color:
|
|
2593
|
+
color: C2.text,
|
|
2447
2594
|
onMouseDown: () => this.startStream()
|
|
2448
2595
|
}
|
|
2449
|
-
), this.streamData.isLive && /* @__PURE__ */
|
|
2450
|
-
|
|
2596
|
+
), this.streamData.isLive && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2597
|
+
import_react_ecs5.Button,
|
|
2451
2598
|
{
|
|
2452
2599
|
uiTransform: { width: this.s(110), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2453
|
-
uiBackground: { color: this.streamControlling ?
|
|
2600
|
+
uiBackground: { color: this.streamControlling ? C2.btn : C2.red },
|
|
2454
2601
|
value: this.streamControlling ? "Stopping..." : "Stop Stream",
|
|
2455
2602
|
fontSize: t.buttonSmall,
|
|
2456
|
-
color:
|
|
2603
|
+
color: C2.text,
|
|
2457
2604
|
onMouseDown: () => this.stopStream()
|
|
2458
2605
|
}
|
|
2459
|
-
), this.streamData.isLive && this.streamData.hlsUrl && /* @__PURE__ */
|
|
2460
|
-
|
|
2606
|
+
), this.streamData.isLive && this.streamData.hlsUrl && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2607
|
+
import_react_ecs5.Button,
|
|
2461
2608
|
{
|
|
2462
2609
|
uiTransform: { width: this.s(100), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2463
|
-
uiBackground: { color:
|
|
2610
|
+
uiBackground: { color: C2.cyan },
|
|
2464
2611
|
value: "Play on Screen",
|
|
2465
2612
|
fontSize: t.buttonSmall,
|
|
2466
|
-
color:
|
|
2613
|
+
color: C2.text,
|
|
2467
2614
|
onMouseDown: () => this.config.onVideoPlay?.(this.streamData.hlsUrl)
|
|
2468
2615
|
}
|
|
2469
|
-
)), /* @__PURE__ */
|
|
2470
|
-
|
|
2616
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 6 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2617
|
+
import_react_ecs5.Button,
|
|
2471
2618
|
{
|
|
2472
2619
|
uiTransform: { width: this.s(80), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2473
|
-
uiBackground: { color:
|
|
2620
|
+
uiBackground: { color: C2.btn },
|
|
2474
2621
|
value: "Refresh",
|
|
2475
2622
|
fontSize: t.buttonSmall,
|
|
2476
|
-
color:
|
|
2623
|
+
color: C2.text,
|
|
2477
2624
|
onMouseDown: () => this.refreshStreamStatus()
|
|
2478
2625
|
}
|
|
2479
|
-
), /* @__PURE__ */
|
|
2480
|
-
|
|
2626
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2627
|
+
import_react_ecs5.Button,
|
|
2481
2628
|
{
|
|
2482
2629
|
uiTransform: { width: this.s(95), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2483
|
-
uiBackground: { color: this.keyRotating ?
|
|
2630
|
+
uiBackground: { color: this.keyRotating ? C2.btn : C2.yellow },
|
|
2484
2631
|
value: this.keyRotating ? "..." : "Rotate Key",
|
|
2485
2632
|
fontSize: t.buttonSmall,
|
|
2486
|
-
color:
|
|
2633
|
+
color: C2.text,
|
|
2487
2634
|
onMouseDown: () => this.rotateStreamKey()
|
|
2488
2635
|
}
|
|
2489
|
-
), !this.streamData.isLive && /* @__PURE__ */
|
|
2490
|
-
|
|
2636
|
+
), !this.streamData.isLive && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2637
|
+
import_react_ecs5.Button,
|
|
2491
2638
|
{
|
|
2492
2639
|
uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2493
|
-
uiBackground: { color: this.channelDeleting ?
|
|
2640
|
+
uiBackground: { color: this.channelDeleting ? C2.btn : C2.red },
|
|
2494
2641
|
value: this.channelDeleting ? "..." : "Delete",
|
|
2495
2642
|
fontSize: t.buttonSmall,
|
|
2496
|
-
color:
|
|
2643
|
+
color: C2.text,
|
|
2497
2644
|
onMouseDown: () => this.deleteChannel()
|
|
2498
2645
|
}
|
|
2499
|
-
)), this.streamControlStatus === "started" && /* @__PURE__ */
|
|
2500
|
-
|
|
2646
|
+
)), this.streamControlStatus === "started" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Stream started - begin broadcasting in OBS", fontSize: t.status, color: C2.green }), this.streamControlStatus === "stopped" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Stream stopped", fontSize: t.status, color: C2.textDim }), this.keyRotateStatus === "success" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Key rotated! Update OBS", fontSize: t.status, color: C2.green }), this.keyRotateStatus === "error" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Failed to rotate key", fontSize: t.status, color: C2.red }), this.channelDeleteError && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: this.channelDeleteError, fontSize: t.status, color: C2.red }), this.streamControlStatus === "error" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Stream control failed", fontSize: t.status, color: C2.red })), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "PLAY NOW", color: C2.orange }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2647
|
+
import_react_ecs5.Input,
|
|
2501
2648
|
{
|
|
2502
2649
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2503
2650
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2504
2651
|
placeholder: "Video URL...",
|
|
2505
|
-
placeholderColor:
|
|
2506
|
-
color:
|
|
2652
|
+
placeholderColor: C2.textDim,
|
|
2653
|
+
color: C2.text,
|
|
2507
2654
|
fontSize: t.input,
|
|
2508
2655
|
value: this.customVideoUrl,
|
|
2509
2656
|
onChange: (val) => {
|
|
2510
2657
|
this.customVideoUrl = val;
|
|
2511
2658
|
}
|
|
2512
2659
|
}
|
|
2513
|
-
), /* @__PURE__ */
|
|
2514
|
-
|
|
2660
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2661
|
+
import_react_ecs5.Button,
|
|
2515
2662
|
{
|
|
2516
2663
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2517
|
-
uiBackground: { color:
|
|
2664
|
+
uiBackground: { color: C2.green },
|
|
2518
2665
|
value: "Play",
|
|
2519
2666
|
fontSize: t.button,
|
|
2520
|
-
color:
|
|
2667
|
+
color: C2.text,
|
|
2521
2668
|
onMouseDown: () => {
|
|
2522
2669
|
if (this.customVideoUrl) this.config.onVideoPlay?.(this.customVideoUrl);
|
|
2523
2670
|
}
|
|
2524
2671
|
}
|
|
2525
|
-
), /* @__PURE__ */
|
|
2526
|
-
|
|
2672
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2673
|
+
import_react_ecs5.Button,
|
|
2527
2674
|
{
|
|
2528
2675
|
uiTransform: { width: this.s(65), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 6 } },
|
|
2529
|
-
uiBackground: { color:
|
|
2676
|
+
uiBackground: { color: C2.btn },
|
|
2530
2677
|
value: "Clear",
|
|
2531
2678
|
fontSize: t.button,
|
|
2532
|
-
color:
|
|
2679
|
+
color: C2.text,
|
|
2533
2680
|
onMouseDown: () => {
|
|
2534
2681
|
this.customVideoUrl = "";
|
|
2535
2682
|
}
|
|
2536
2683
|
}
|
|
2537
|
-
)), /* @__PURE__ */
|
|
2538
|
-
|
|
2684
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "PLAYBACK", color: C2.green }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2685
|
+
import_react_ecs5.Button,
|
|
2539
2686
|
{
|
|
2540
2687
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2541
|
-
uiBackground: { color:
|
|
2688
|
+
uiBackground: { color: C2.green },
|
|
2542
2689
|
value: "Play",
|
|
2543
2690
|
fontSize: t.button,
|
|
2544
|
-
color:
|
|
2691
|
+
color: C2.text,
|
|
2545
2692
|
onMouseDown: () => this.config.onCommand?.("videoPlay", { playing: true })
|
|
2546
2693
|
}
|
|
2547
|
-
), /* @__PURE__ */
|
|
2548
|
-
|
|
2694
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2695
|
+
import_react_ecs5.Button,
|
|
2549
2696
|
{
|
|
2550
2697
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2551
|
-
uiBackground: { color:
|
|
2698
|
+
uiBackground: { color: C2.red },
|
|
2552
2699
|
value: "Stop",
|
|
2553
2700
|
fontSize: t.button,
|
|
2554
|
-
color:
|
|
2701
|
+
color: C2.text,
|
|
2555
2702
|
onMouseDown: () => this.config.onVideoStop?.()
|
|
2556
2703
|
}
|
|
2557
|
-
), /* @__PURE__ */
|
|
2558
|
-
|
|
2704
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2705
|
+
import_react_ecs5.Button,
|
|
2559
2706
|
{
|
|
2560
2707
|
uiTransform: { width: this.s(100), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2561
|
-
uiBackground: { color:
|
|
2708
|
+
uiBackground: { color: C2.btn },
|
|
2562
2709
|
value: "Reset Default",
|
|
2563
2710
|
fontSize: t.buttonSmall,
|
|
2564
|
-
color:
|
|
2711
|
+
color: C2.text,
|
|
2565
2712
|
onMouseDown: () => this.config.onCommand?.("videoClear", {})
|
|
2566
2713
|
}
|
|
2567
|
-
)), /* @__PURE__ */
|
|
2568
|
-
|
|
2714
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "VIDEO SLOTS", color: C2.cyan }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 10 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Button, { uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 }, uiBackground: { color: C2.cyan }, value: "Play 1", fontSize: t.button, color: C2.text, onMouseDown: () => this.playSlot("slot1") }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Button, { uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 }, uiBackground: { color: C2.cyan }, value: "Play 2", fontSize: t.button, color: C2.text, onMouseDown: () => this.playSlot("slot2") }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Button, { uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 }, uiBackground: { color: C2.cyan }, value: "Play 3", fontSize: t.button, color: C2.text, onMouseDown: () => this.playSlot("slot3") }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Button, { uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 }, uiBackground: { color: C2.cyan }, value: "Play 4", fontSize: t.button, color: C2.text, onMouseDown: () => this.playSlot("slot4") }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Button, { uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 }, uiBackground: { color: C2.cyan }, value: "Play 5", fontSize: t.button, color: C2.text, onMouseDown: () => this.playSlot("slot5") })), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2715
|
+
import_react_ecs5.Button,
|
|
2569
2716
|
{
|
|
2570
2717
|
uiTransform: { height: this.s(24) },
|
|
2571
2718
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0) },
|
|
2572
2719
|
value: "Edit slots at thestatic.tv",
|
|
2573
2720
|
fontSize: t.labelSmall,
|
|
2574
|
-
color:
|
|
2721
|
+
color: C2.cyan,
|
|
2575
2722
|
onMouseDown: () => (0, import_RestrictedActions3.openExternalUrl)({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2576
2723
|
}
|
|
2577
2724
|
));
|
|
2578
2725
|
};
|
|
2579
2726
|
this.ModTab = () => {
|
|
2580
2727
|
const t = this.theme;
|
|
2581
|
-
return /* @__PURE__ */
|
|
2582
|
-
|
|
2728
|
+
return /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", width: "100%", padding: 10 } }, this.modStatus === "loading" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Loading...", fontSize: t.status, color: C2.yellow }), this.modStatus === "saved" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Saved!", fontSize: t.status, color: C2.green }), this.modStatus === "error" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "Error - check input", fontSize: t.status, color: C2.red }), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "BROADCAST", color: C2.orange }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2729
|
+
import_react_ecs5.Input,
|
|
2583
2730
|
{
|
|
2584
2731
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2585
2732
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2586
2733
|
placeholder: "Message to all players...",
|
|
2587
|
-
placeholderColor:
|
|
2588
|
-
color:
|
|
2734
|
+
placeholderColor: C2.textDim,
|
|
2735
|
+
color: C2.text,
|
|
2589
2736
|
fontSize: t.input,
|
|
2590
2737
|
value: this.broadcastText,
|
|
2591
2738
|
onChange: (val) => {
|
|
2592
2739
|
this.broadcastText = val;
|
|
2593
2740
|
}
|
|
2594
2741
|
}
|
|
2595
|
-
), /* @__PURE__ */
|
|
2596
|
-
|
|
2742
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2743
|
+
import_react_ecs5.Button,
|
|
2597
2744
|
{
|
|
2598
2745
|
uiTransform: { width: this.s(65), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2599
|
-
uiBackground: { color:
|
|
2746
|
+
uiBackground: { color: C2.orange },
|
|
2600
2747
|
value: "Send",
|
|
2601
2748
|
fontSize: t.button,
|
|
2602
|
-
color:
|
|
2749
|
+
color: C2.text,
|
|
2603
2750
|
onMouseDown: () => this.sendBroadcast()
|
|
2604
2751
|
}
|
|
2605
|
-
)), /* @__PURE__ */
|
|
2606
|
-
|
|
2752
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "CHAOS MODE", color: C2.red }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2753
|
+
import_react_ecs5.Button,
|
|
2607
2754
|
{
|
|
2608
2755
|
uiTransform: { width: this.s(130), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: 4 },
|
|
2609
|
-
uiBackground: { color:
|
|
2756
|
+
uiBackground: { color: C2.red },
|
|
2610
2757
|
value: "KICK ALL",
|
|
2611
2758
|
fontSize: t.button,
|
|
2612
|
-
color:
|
|
2759
|
+
color: C2.text,
|
|
2613
2760
|
onMouseDown: () => {
|
|
2614
2761
|
this.log("KICK ALL clicked");
|
|
2615
2762
|
this.config.onCommand?.("kickAll", {});
|
|
2616
2763
|
}
|
|
2617
2764
|
}
|
|
2618
|
-
)), /* @__PURE__ */
|
|
2619
|
-
|
|
2765
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "SCENE ADMINS", color: C2.purple }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, this.sceneAdmins.length === 0 && this.modStatus !== "loading" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "No scene admins", fontSize: t.labelSmall, color: C2.textDim }), this.sceneAdmins.map((wallet, i) => /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2766
|
+
import_react_ecs5.UiEntity,
|
|
2620
2767
|
{
|
|
2621
2768
|
key: `admin-${i}`,
|
|
2622
2769
|
uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 5 }, width: "100%" }
|
|
2623
2770
|
},
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
|
|
2771
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2772
|
+
import_react_ecs5.Label,
|
|
2626
2773
|
{
|
|
2627
2774
|
value: `${wallet.slice(0, 6)}...${wallet.slice(-4)}`,
|
|
2628
2775
|
fontSize: t.label,
|
|
2629
|
-
color:
|
|
2776
|
+
color: C2.text,
|
|
2630
2777
|
uiTransform: { width: this.s(130) }
|
|
2631
2778
|
}
|
|
2632
2779
|
),
|
|
2633
|
-
/* @__PURE__ */
|
|
2634
|
-
|
|
2780
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2781
|
+
import_react_ecs5.Button,
|
|
2635
2782
|
{
|
|
2636
2783
|
uiTransform: { width: this.s(70), height: this.s(28), margin: { left: 8 } },
|
|
2637
|
-
uiBackground: { color:
|
|
2784
|
+
uiBackground: { color: C2.btn },
|
|
2638
2785
|
value: "Remove",
|
|
2639
2786
|
fontSize: t.buttonSmall,
|
|
2640
|
-
color:
|
|
2787
|
+
color: C2.text,
|
|
2641
2788
|
onMouseDown: () => this.removeSceneAdmin(wallet)
|
|
2642
2789
|
}
|
|
2643
2790
|
)
|
|
2644
|
-
))), /* @__PURE__ */
|
|
2645
|
-
|
|
2791
|
+
))), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2792
|
+
import_react_ecs5.Input,
|
|
2646
2793
|
{
|
|
2647
2794
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2648
2795
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2649
2796
|
placeholder: "0x... add admin",
|
|
2650
|
-
placeholderColor:
|
|
2651
|
-
color:
|
|
2797
|
+
placeholderColor: C2.textDim,
|
|
2798
|
+
color: C2.text,
|
|
2652
2799
|
fontSize: t.input,
|
|
2653
2800
|
value: this.newAdminWallet,
|
|
2654
2801
|
onChange: (val) => {
|
|
2655
2802
|
this.newAdminWallet = val;
|
|
2656
2803
|
}
|
|
2657
2804
|
}
|
|
2658
|
-
), /* @__PURE__ */
|
|
2659
|
-
|
|
2805
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2806
|
+
import_react_ecs5.Button,
|
|
2660
2807
|
{
|
|
2661
2808
|
uiTransform: { width: this.s(60), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2662
|
-
uiBackground: { color:
|
|
2809
|
+
uiBackground: { color: C2.purple },
|
|
2663
2810
|
value: "Add",
|
|
2664
2811
|
fontSize: t.button,
|
|
2665
|
-
color:
|
|
2812
|
+
color: C2.text,
|
|
2666
2813
|
onMouseDown: () => {
|
|
2667
2814
|
if (this.newAdminWallet) this.addSceneAdmin(this.newAdminWallet);
|
|
2668
2815
|
}
|
|
2669
2816
|
}
|
|
2670
|
-
)), /* @__PURE__ */
|
|
2671
|
-
|
|
2817
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(this.SectionHead, { label: "BANNED WALLETS", color: C2.red }), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, this.bannedWallets.length === 0 && this.modStatus !== "loading" && /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: "No banned wallets", fontSize: t.labelSmall, color: C2.textDim }), this.bannedWallets.map((wallet, i) => /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2818
|
+
import_react_ecs5.UiEntity,
|
|
2672
2819
|
{
|
|
2673
2820
|
key: `ban-${i}`,
|
|
2674
2821
|
uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 5 }, width: "100%" }
|
|
2675
2822
|
},
|
|
2676
|
-
/* @__PURE__ */
|
|
2677
|
-
|
|
2823
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2824
|
+
import_react_ecs5.Label,
|
|
2678
2825
|
{
|
|
2679
2826
|
value: `${wallet.slice(0, 6)}...${wallet.slice(-4)}`,
|
|
2680
2827
|
fontSize: t.label,
|
|
2681
|
-
color:
|
|
2828
|
+
color: C2.red,
|
|
2682
2829
|
uiTransform: { width: this.s(130) }
|
|
2683
2830
|
}
|
|
2684
2831
|
),
|
|
2685
|
-
/* @__PURE__ */
|
|
2686
|
-
|
|
2832
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2833
|
+
import_react_ecs5.Button,
|
|
2687
2834
|
{
|
|
2688
2835
|
uiTransform: { width: this.s(70), height: this.s(28), margin: { left: 8 } },
|
|
2689
|
-
uiBackground: { color:
|
|
2836
|
+
uiBackground: { color: C2.green },
|
|
2690
2837
|
value: "Unban",
|
|
2691
2838
|
fontSize: t.buttonSmall,
|
|
2692
|
-
color:
|
|
2839
|
+
color: C2.text,
|
|
2693
2840
|
onMouseDown: () => this.unbanWallet(wallet)
|
|
2694
2841
|
}
|
|
2695
2842
|
)
|
|
2696
|
-
))), /* @__PURE__ */
|
|
2697
|
-
|
|
2843
|
+
))), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 10 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2844
|
+
import_react_ecs5.Input,
|
|
2698
2845
|
{
|
|
2699
2846
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2700
2847
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2701
2848
|
placeholder: "0x... ban wallet",
|
|
2702
|
-
placeholderColor:
|
|
2703
|
-
color:
|
|
2849
|
+
placeholderColor: C2.textDim,
|
|
2850
|
+
color: C2.text,
|
|
2704
2851
|
fontSize: t.input,
|
|
2705
2852
|
value: this.newBanWallet,
|
|
2706
2853
|
onChange: (val) => {
|
|
2707
2854
|
this.newBanWallet = val;
|
|
2708
2855
|
}
|
|
2709
2856
|
}
|
|
2710
|
-
), /* @__PURE__ */
|
|
2711
|
-
|
|
2857
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2858
|
+
import_react_ecs5.Button,
|
|
2712
2859
|
{
|
|
2713
2860
|
uiTransform: { width: this.s(60), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2714
|
-
uiBackground: { color:
|
|
2861
|
+
uiBackground: { color: C2.red },
|
|
2715
2862
|
value: "Ban",
|
|
2716
2863
|
fontSize: t.button,
|
|
2717
|
-
color:
|
|
2864
|
+
color: C2.text,
|
|
2718
2865
|
onMouseDown: () => {
|
|
2719
2866
|
if (this.newBanWallet) this.banWallet(this.newBanWallet);
|
|
2720
2867
|
}
|
|
2721
2868
|
}
|
|
2722
|
-
)), /* @__PURE__ */
|
|
2723
|
-
|
|
2869
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2870
|
+
import_react_ecs5.Button,
|
|
2724
2871
|
{
|
|
2725
2872
|
uiTransform: { height: this.s(24) },
|
|
2726
2873
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0) },
|
|
2727
2874
|
value: "Manage at thestatic.tv",
|
|
2728
2875
|
fontSize: t.labelSmall,
|
|
2729
|
-
color:
|
|
2876
|
+
color: C2.cyan,
|
|
2730
2877
|
onMouseDown: () => (0, import_RestrictedActions3.openExternalUrl)({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2731
2878
|
}
|
|
2732
2879
|
));
|
|
2733
2880
|
};
|
|
2734
2881
|
/**
|
|
2735
2882
|
* Get the React-ECS component for the admin panel
|
|
2883
|
+
* Always renders NotificationBanner (for broadcasts), admin panel only for admins
|
|
2736
2884
|
*/
|
|
2737
2885
|
this.getComponent = () => {
|
|
2738
|
-
if (!this.isAdmin)
|
|
2886
|
+
if (!this.isAdmin) {
|
|
2887
|
+
return /* @__PURE__ */ import_react_ecs5.default.createElement(NotificationBanner, null);
|
|
2888
|
+
}
|
|
2739
2889
|
const t = this.theme;
|
|
2740
2890
|
const tabs = [];
|
|
2741
2891
|
if (this.config.sceneTabs && this.config.sceneTabs.length > 0) {
|
|
@@ -2750,8 +2900,8 @@ var AdminPanelUIModule = class {
|
|
|
2750
2900
|
if (!tabs.find((tab) => tab.id === this.activeTab) && tabs.length > 0) {
|
|
2751
2901
|
this.activeTab = tabs[0].id;
|
|
2752
2902
|
}
|
|
2753
|
-
return /* @__PURE__ */
|
|
2754
|
-
|
|
2903
|
+
return /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2904
|
+
import_react_ecs5.UiEntity,
|
|
2755
2905
|
{
|
|
2756
2906
|
uiTransform: {
|
|
2757
2907
|
width: "100%",
|
|
@@ -2759,28 +2909,29 @@ var AdminPanelUIModule = class {
|
|
|
2759
2909
|
positionType: "absolute"
|
|
2760
2910
|
}
|
|
2761
2911
|
},
|
|
2762
|
-
/* @__PURE__ */
|
|
2763
|
-
|
|
2912
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(NotificationBanner, null),
|
|
2913
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2914
|
+
import_react_ecs5.UiEntity,
|
|
2764
2915
|
{
|
|
2765
2916
|
uiTransform: {
|
|
2766
2917
|
position: { right: 20 + this.s(100) + 10 + this.s(100) + 10, bottom: 10 },
|
|
2767
2918
|
positionType: "absolute"
|
|
2768
2919
|
}
|
|
2769
2920
|
},
|
|
2770
|
-
/* @__PURE__ */
|
|
2771
|
-
|
|
2921
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2922
|
+
import_react_ecs5.Button,
|
|
2772
2923
|
{
|
|
2773
2924
|
uiTransform: { width: this.s(100), height: this.s(45) },
|
|
2774
|
-
uiBackground: { color: this.panelOpen ?
|
|
2925
|
+
uiBackground: { color: this.panelOpen ? C2.btn : C2.header },
|
|
2775
2926
|
value: this.panelOpen ? "CLOSE" : "ADMIN",
|
|
2776
2927
|
fontSize: this.s(14),
|
|
2777
|
-
color:
|
|
2928
|
+
color: C2.text,
|
|
2778
2929
|
onMouseDown: () => this.toggle()
|
|
2779
2930
|
}
|
|
2780
2931
|
)
|
|
2781
2932
|
),
|
|
2782
|
-
this.panelOpen && /* @__PURE__ */
|
|
2783
|
-
|
|
2933
|
+
this.panelOpen && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2934
|
+
import_react_ecs5.UiEntity,
|
|
2784
2935
|
{
|
|
2785
2936
|
key: `admin-panel-${this.client.uiScale}`,
|
|
2786
2937
|
uiTransform: {
|
|
@@ -2791,10 +2942,10 @@ var AdminPanelUIModule = class {
|
|
|
2791
2942
|
positionType: "absolute",
|
|
2792
2943
|
flexDirection: "column"
|
|
2793
2944
|
},
|
|
2794
|
-
uiBackground: { color:
|
|
2945
|
+
uiBackground: { color: C2.bg }
|
|
2795
2946
|
},
|
|
2796
|
-
/* @__PURE__ */
|
|
2797
|
-
|
|
2947
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2948
|
+
import_react_ecs5.UiEntity,
|
|
2798
2949
|
{
|
|
2799
2950
|
uiTransform: {
|
|
2800
2951
|
width: "100%",
|
|
@@ -2804,11 +2955,11 @@ var AdminPanelUIModule = class {
|
|
|
2804
2955
|
flexDirection: "row",
|
|
2805
2956
|
padding: { left: 12, right: 8 }
|
|
2806
2957
|
},
|
|
2807
|
-
uiBackground: { color:
|
|
2958
|
+
uiBackground: { color: C2.header }
|
|
2808
2959
|
},
|
|
2809
|
-
/* @__PURE__ */
|
|
2810
|
-
/* @__PURE__ */
|
|
2811
|
-
|
|
2960
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: this.config.title || "ADMIN PANEL", fontSize: t.header, color: C2.text }),
|
|
2961
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2962
|
+
import_react_ecs5.Button,
|
|
2812
2963
|
{
|
|
2813
2964
|
uiTransform: { width: this.s(28), height: this.s(28) },
|
|
2814
2965
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0.3) },
|
|
@@ -2819,9 +2970,9 @@ var AdminPanelUIModule = class {
|
|
|
2819
2970
|
}
|
|
2820
2971
|
)
|
|
2821
2972
|
),
|
|
2822
|
-
/* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
2824
|
-
|
|
2973
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { width: "100%", height: this.s(UI_DIMENSIONS.admin.tabHeight), flexDirection: "row" } }, tabs.map((tab) => /* @__PURE__ */ import_react_ecs5.default.createElement(this.TabBtn, { label: tab.label, tab: tab.id }))),
|
|
2974
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2975
|
+
import_react_ecs5.UiEntity,
|
|
2825
2976
|
{
|
|
2826
2977
|
uiTransform: {
|
|
2827
2978
|
width: "100%",
|
|
@@ -2830,12 +2981,12 @@ var AdminPanelUIModule = class {
|
|
|
2830
2981
|
flexDirection: "column"
|
|
2831
2982
|
}
|
|
2832
2983
|
},
|
|
2833
|
-
this.activeTab === "video" && /* @__PURE__ */
|
|
2834
|
-
this.activeTab === "mod" && this.isOwner && /* @__PURE__ */
|
|
2984
|
+
this.activeTab === "video" && /* @__PURE__ */ import_react_ecs5.default.createElement(this.VideoTab, null),
|
|
2985
|
+
this.activeTab === "mod" && this.isOwner && /* @__PURE__ */ import_react_ecs5.default.createElement(this.ModTab, null),
|
|
2835
2986
|
this.config.sceneTabs?.map((tab) => this.activeTab === tab.id && tab.render())
|
|
2836
2987
|
),
|
|
2837
|
-
/* @__PURE__ */
|
|
2838
|
-
|
|
2988
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2989
|
+
import_react_ecs5.UiEntity,
|
|
2839
2990
|
{
|
|
2840
2991
|
uiTransform: {
|
|
2841
2992
|
width: "100%",
|
|
@@ -2843,16 +2994,16 @@ var AdminPanelUIModule = class {
|
|
|
2843
2994
|
justifyContent: "center",
|
|
2844
2995
|
alignItems: "center"
|
|
2845
2996
|
},
|
|
2846
|
-
uiBackground: { color:
|
|
2997
|
+
uiBackground: { color: C2.section }
|
|
2847
2998
|
},
|
|
2848
|
-
/* @__PURE__ */
|
|
2849
|
-
|
|
2999
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
3000
|
+
import_react_ecs5.Button,
|
|
2850
3001
|
{
|
|
2851
3002
|
uiTransform: { height: this.s(24) },
|
|
2852
3003
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0) },
|
|
2853
3004
|
value: `thestatic.tv/scene/${this.config.sceneId}`,
|
|
2854
3005
|
fontSize: t.labelSmall,
|
|
2855
|
-
color:
|
|
3006
|
+
color: C2.cyan,
|
|
2856
3007
|
onMouseDown: () => (0, import_RestrictedActions3.openExternalUrl)({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2857
3008
|
}
|
|
2858
3009
|
)
|
|
@@ -2875,7 +3026,7 @@ var AdminPanelUIModule = class {
|
|
|
2875
3026
|
};
|
|
2876
3027
|
this.baseUrl = client.getBaseUrl();
|
|
2877
3028
|
if (config.headerColor) {
|
|
2878
|
-
|
|
3029
|
+
C2.header = import_math5.Color4.create(
|
|
2879
3030
|
config.headerColor.r,
|
|
2880
3031
|
config.headerColor.g,
|
|
2881
3032
|
config.headerColor.b,
|
|
@@ -2903,6 +3054,7 @@ var AdminPanelUIModule = class {
|
|
|
2903
3054
|
await this.checkAdminStatus();
|
|
2904
3055
|
await this.fetchVideoState();
|
|
2905
3056
|
this.autoPlayDefault();
|
|
3057
|
+
this.startCommandPolling();
|
|
2906
3058
|
this.log("Initialized");
|
|
2907
3059
|
}
|
|
2908
3060
|
/**
|
|
@@ -3008,6 +3160,61 @@ var AdminPanelUIModule = class {
|
|
|
3008
3160
|
this.log("Stream polling stopped");
|
|
3009
3161
|
}
|
|
3010
3162
|
}
|
|
3163
|
+
// --- Command Polling (receives broadcasts from website) ---
|
|
3164
|
+
startCommandPolling() {
|
|
3165
|
+
if (this.commandPollIntervalId !== null) return;
|
|
3166
|
+
this.commandPollIntervalId = dclSetInterval(() => {
|
|
3167
|
+
this.pollCommands();
|
|
3168
|
+
}, 5e3);
|
|
3169
|
+
this.pollCommands();
|
|
3170
|
+
this.log("Command polling started");
|
|
3171
|
+
}
|
|
3172
|
+
stopCommandPolling() {
|
|
3173
|
+
if (this.commandPollIntervalId !== null) {
|
|
3174
|
+
dclClearInterval(this.commandPollIntervalId);
|
|
3175
|
+
this.commandPollIntervalId = null;
|
|
3176
|
+
this.log("Command polling stopped");
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
async pollCommands() {
|
|
3180
|
+
try {
|
|
3181
|
+
const res = await fetch(`${this.baseUrl}/scene/${this.config.sceneId}/commands`);
|
|
3182
|
+
if (!res.ok) return;
|
|
3183
|
+
const data = await res.json();
|
|
3184
|
+
const commands = data.commands || [];
|
|
3185
|
+
for (const cmd of commands) {
|
|
3186
|
+
if (cmd.timestamp <= this.lastCommandTimestamp) continue;
|
|
3187
|
+
this.lastCommandTimestamp = cmd.timestamp;
|
|
3188
|
+
if (cmd.type === "broadcast" && cmd.payload?.text) {
|
|
3189
|
+
const msg = cmd.payload.from ? `${cmd.payload.from}: ${cmd.payload.text}` : cmd.payload.text;
|
|
3190
|
+
this.log("Received broadcast:", msg);
|
|
3191
|
+
this.config.onBroadcast?.(msg);
|
|
3192
|
+
} else if (cmd.type === "clearBroadcast") {
|
|
3193
|
+
this.log("Received clearBroadcast");
|
|
3194
|
+
hideNotification();
|
|
3195
|
+
} else if ((cmd.type === "videoPlay" || cmd.type === "videoSetUrl") && cmd.payload?.url) {
|
|
3196
|
+
this.log("Received video play:", cmd.type, cmd.payload.url);
|
|
3197
|
+
this.config.onVideoPlay?.(cmd.payload.url);
|
|
3198
|
+
} else if (cmd.type === "videoStop" || cmd.type === "videoClear") {
|
|
3199
|
+
this.log("Received video stop/clear:", cmd.type);
|
|
3200
|
+
this.config.onVideoStop?.();
|
|
3201
|
+
} else if (cmd.type === "videoPlaySlot" && cmd.payload?.slot) {
|
|
3202
|
+
const slotId = cmd.payload.slot;
|
|
3203
|
+
if (cmd.payload.url) {
|
|
3204
|
+
this.log("Received videoPlaySlot with URL:", slotId, cmd.payload.url);
|
|
3205
|
+
this.config.onVideoPlay?.(cmd.payload.url);
|
|
3206
|
+
} else {
|
|
3207
|
+
this.log("Received videoPlaySlot:", slotId);
|
|
3208
|
+
this.playSlot(slotId);
|
|
3209
|
+
}
|
|
3210
|
+
} else if (this.config.onCommand) {
|
|
3211
|
+
this.log("Received command:", cmd.type, cmd.payload);
|
|
3212
|
+
this.config.onCommand(cmd.type, cmd.payload);
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
} catch (err) {
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3011
3218
|
// --- Stream API Calls ---
|
|
3012
3219
|
async fetchStreamData() {
|
|
3013
3220
|
if (this.streamFetched || !this.playerWallet) return;
|
|
@@ -3439,87 +3646,6 @@ var AdminPanelUIModule = class {
|
|
|
3439
3646
|
}
|
|
3440
3647
|
};
|
|
3441
3648
|
|
|
3442
|
-
// src/ui/ui-renderer.tsx
|
|
3443
|
-
var import_react_ecs5 = __toESM(require("@dcl/sdk/react-ecs"));
|
|
3444
|
-
var import_math6 = require("@dcl/sdk/math");
|
|
3445
|
-
var import_ecs2 = require("@dcl/sdk/ecs");
|
|
3446
|
-
var notificationText = "";
|
|
3447
|
-
var notificationVisible = false;
|
|
3448
|
-
var notificationEndTime = 0;
|
|
3449
|
-
var notificationInitialized = false;
|
|
3450
|
-
function showNotification(message, durationMs = 5e3) {
|
|
3451
|
-
notificationText = message;
|
|
3452
|
-
notificationVisible = true;
|
|
3453
|
-
notificationEndTime = Date.now() + durationMs;
|
|
3454
|
-
}
|
|
3455
|
-
function initNotificationSystem() {
|
|
3456
|
-
if (notificationInitialized) return;
|
|
3457
|
-
notificationInitialized = true;
|
|
3458
|
-
import_ecs2.engine.addSystem(() => {
|
|
3459
|
-
if (notificationVisible && Date.now() > notificationEndTime) {
|
|
3460
|
-
notificationVisible = false;
|
|
3461
|
-
}
|
|
3462
|
-
});
|
|
3463
|
-
}
|
|
3464
|
-
function NotificationBanner() {
|
|
3465
|
-
if (!notificationVisible) return null;
|
|
3466
|
-
return /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
3467
|
-
import_react_ecs5.UiEntity,
|
|
3468
|
-
{
|
|
3469
|
-
uiTransform: {
|
|
3470
|
-
positionType: "absolute",
|
|
3471
|
-
position: { top: 80 },
|
|
3472
|
-
width: 500,
|
|
3473
|
-
height: 60,
|
|
3474
|
-
padding: 16,
|
|
3475
|
-
alignSelf: "center",
|
|
3476
|
-
justifyContent: "center",
|
|
3477
|
-
alignItems: "center"
|
|
3478
|
-
},
|
|
3479
|
-
uiBackground: { color: import_math6.Color4.create(0.1, 0.1, 0.15, 0.95) }
|
|
3480
|
-
},
|
|
3481
|
-
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
3482
|
-
import_react_ecs5.Label,
|
|
3483
|
-
{
|
|
3484
|
-
value: notificationText,
|
|
3485
|
-
fontSize: 18,
|
|
3486
|
-
color: import_math6.Color4.create(0, 1, 1, 1),
|
|
3487
|
-
textAlign: "middle-center"
|
|
3488
|
-
}
|
|
3489
|
-
)
|
|
3490
|
-
);
|
|
3491
|
-
}
|
|
3492
|
-
function createStaticUI(client) {
|
|
3493
|
-
initNotificationSystem();
|
|
3494
|
-
return function StaticUI() {
|
|
3495
|
-
const currentScale = client.uiScale;
|
|
3496
|
-
const guideComponent = client.guideUI?.getComponent() ?? null;
|
|
3497
|
-
const chatComponent = client.chatUI?.getComponent() ?? null;
|
|
3498
|
-
const adminComponent = client.adminPanel?.getComponent() ?? null;
|
|
3499
|
-
return /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
3500
|
-
import_react_ecs5.UiEntity,
|
|
3501
|
-
{
|
|
3502
|
-
key: `static-ui-root-${currentScale}`,
|
|
3503
|
-
uiTransform: {
|
|
3504
|
-
width: "100%",
|
|
3505
|
-
height: "100%",
|
|
3506
|
-
positionType: "absolute",
|
|
3507
|
-
flexDirection: "column",
|
|
3508
|
-
alignItems: "center"
|
|
3509
|
-
}
|
|
3510
|
-
},
|
|
3511
|
-
/* @__PURE__ */ import_react_ecs5.default.createElement(NotificationBanner, null),
|
|
3512
|
-
guideComponent,
|
|
3513
|
-
chatComponent,
|
|
3514
|
-
adminComponent
|
|
3515
|
-
);
|
|
3516
|
-
};
|
|
3517
|
-
}
|
|
3518
|
-
function setupStaticUI(client) {
|
|
3519
|
-
const StaticUI = createStaticUI(client);
|
|
3520
|
-
import_react_ecs5.ReactEcsRenderer.setUiRenderer(StaticUI);
|
|
3521
|
-
}
|
|
3522
|
-
|
|
3523
3649
|
// src/StaticTVClient.ts
|
|
3524
3650
|
var import_ecs3 = require("@dcl/sdk/ecs");
|
|
3525
3651
|
var utils = __toESM(require("@dcl-sdk/utils"));
|
|
@@ -3800,10 +3926,13 @@ var StaticTVClient = class {
|
|
|
3800
3926
|
*/
|
|
3801
3927
|
stopVideo() {
|
|
3802
3928
|
const screen = this.config.videoScreen;
|
|
3929
|
+
this._pendingVideoData = null;
|
|
3930
|
+
this._streamVerified = false;
|
|
3931
|
+
this._clearVerificationTimeout();
|
|
3932
|
+
if (this.guideUI) {
|
|
3933
|
+
this.guideUI.currentVideoId = null;
|
|
3934
|
+
}
|
|
3803
3935
|
if (screen !== void 0) {
|
|
3804
|
-
if (this.guideUI) {
|
|
3805
|
-
this.guideUI.currentVideoId = null;
|
|
3806
|
-
}
|
|
3807
3936
|
const fallbackUrl = this.config.fallbackVideoUrl;
|
|
3808
3937
|
const fallbackDisabled = fallbackUrl === "";
|
|
3809
3938
|
if (fallbackDisabled) {
|
|
@@ -3959,20 +4088,60 @@ var StaticTVClient = class {
|
|
|
3959
4088
|
}
|
|
3960
4089
|
/**
|
|
3961
4090
|
* Play video with stream verification for live content
|
|
4091
|
+
* Works with both videoScreen (SDK-managed) and onVideoPlay (user-managed) modes.
|
|
3962
4092
|
* @internal
|
|
3963
4093
|
*/
|
|
3964
4094
|
_playVideoWithVerification(video, isLiveStream) {
|
|
3965
4095
|
const screen = this.config.videoScreen;
|
|
4096
|
+
const hasCallback = this.config.onVideoPlay !== void 0;
|
|
4097
|
+
this.log(`Playing video: ${video.src} (live: ${isLiveStream}, screen: ${screen !== void 0}, callback: ${hasCallback})`);
|
|
4098
|
+
this._currentVideoUrl = video.src;
|
|
4099
|
+
this._clearVerificationTimeout();
|
|
4100
|
+
this._streamVerified = false;
|
|
3966
4101
|
if (screen !== void 0) {
|
|
3967
|
-
this.log(`Playing video: ${video.src} (live: ${isLiveStream})`);
|
|
3968
|
-
this._currentVideoUrl = video.src;
|
|
3969
4102
|
this._playVideoInternal(video.src, false, isLiveStream);
|
|
3970
|
-
if (this.guideUI) {
|
|
3971
|
-
this.guideUI.currentVideoId = video.id;
|
|
3972
|
-
}
|
|
3973
4103
|
}
|
|
3974
|
-
if (
|
|
4104
|
+
if (hasCallback) {
|
|
3975
4105
|
this.config.onVideoPlay(video.src);
|
|
4106
|
+
if (isLiveStream) {
|
|
4107
|
+
this._startCallbackVerification(video);
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
if (this.guideUI) {
|
|
4111
|
+
this.guideUI.currentVideoId = video.id;
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
/**
|
|
4115
|
+
* Start stream verification for callback-based video playback
|
|
4116
|
+
* Shows CONNECTING state and triggers fallback if verification times out
|
|
4117
|
+
* @internal
|
|
4118
|
+
*/
|
|
4119
|
+
_startCallbackVerification(video) {
|
|
4120
|
+
this.showNotification(`Connecting to ${video.name}...`, 6e3);
|
|
4121
|
+
this._verificationTimeoutId = utils.timers.setTimeout(() => {
|
|
4122
|
+
if (!this._streamVerified && this._pendingVideoData) {
|
|
4123
|
+
this.log(`Stream verification timeout (callback mode): ${video.name}`);
|
|
4124
|
+
this._handleStreamOffline();
|
|
4125
|
+
}
|
|
4126
|
+
}, 5e3);
|
|
4127
|
+
}
|
|
4128
|
+
/**
|
|
4129
|
+
* Call this to confirm that a video stream is playing successfully.
|
|
4130
|
+
* Use this when you're managing video playback yourself (onVideoPlay callback).
|
|
4131
|
+
*
|
|
4132
|
+
* @example
|
|
4133
|
+
* ```typescript
|
|
4134
|
+
* // In your video player's onReady or similar event:
|
|
4135
|
+
* videoPlayer.events.on('playing', () => {
|
|
4136
|
+
* staticTV.confirmVideoPlaying()
|
|
4137
|
+
* })
|
|
4138
|
+
* ```
|
|
4139
|
+
*/
|
|
4140
|
+
confirmVideoPlaying() {
|
|
4141
|
+
if (this._pendingVideoData && !this._streamVerified) {
|
|
4142
|
+
this._streamVerified = true;
|
|
4143
|
+
this._clearVerificationTimeout();
|
|
4144
|
+
this.log(`Stream confirmed playing: ${this._pendingVideoData.name}`);
|
|
3976
4145
|
}
|
|
3977
4146
|
}
|
|
3978
4147
|
/**
|
|
@@ -4247,11 +4416,13 @@ var StaticTVClient = class {
|
|
|
4247
4416
|
InteractionsModule,
|
|
4248
4417
|
KEY_TYPE_CHANNEL,
|
|
4249
4418
|
KEY_TYPE_SCENE,
|
|
4419
|
+
NotificationBanner,
|
|
4250
4420
|
SessionModule,
|
|
4251
4421
|
StaticTVClient,
|
|
4252
4422
|
fetchUserData,
|
|
4253
4423
|
getPlayerDisplayName,
|
|
4254
4424
|
getPlayerWallet,
|
|
4425
|
+
hideNotification,
|
|
4255
4426
|
setupStaticUI,
|
|
4256
4427
|
showNotification
|
|
4257
4428
|
});
|