@thestatic-tv/dcl-sdk 2.5.9 → 2.5.11
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 +411 -253
- package/dist/index.mjs +380 -224
- 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 - next to DCL native chat panel
|
|
674
|
+
notification: {
|
|
675
|
+
width: 340,
|
|
676
|
+
height: 44,
|
|
677
|
+
bottom: 55,
|
|
678
|
+
// Above the chat input area
|
|
679
|
+
left: 400,
|
|
680
|
+
// Right of DCL native chat (chat is ~380px wide)
|
|
681
|
+
borderWidth: 2,
|
|
682
|
+
fontSize: 14
|
|
683
|
+
},
|
|
671
684
|
// Shared
|
|
672
685
|
closeButton: {
|
|
673
686
|
size: 40,
|
|
@@ -2295,12 +2308,131 @@ 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 /* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2346
|
+
import_react_ecs4.UiEntity,
|
|
2347
|
+
{
|
|
2348
|
+
uiTransform: {
|
|
2349
|
+
positionType: "absolute",
|
|
2350
|
+
position: { bottom: N.bottom, left: N.left },
|
|
2351
|
+
width: N.width,
|
|
2352
|
+
height: N.height,
|
|
2353
|
+
flexDirection: "row",
|
|
2354
|
+
alignItems: "center"
|
|
2355
|
+
},
|
|
2356
|
+
uiBackground: { color: C.panel }
|
|
2357
|
+
},
|
|
2358
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2359
|
+
import_react_ecs4.UiEntity,
|
|
2360
|
+
{
|
|
2361
|
+
uiTransform: {
|
|
2362
|
+
width: N.borderWidth,
|
|
2363
|
+
height: "100%"
|
|
2364
|
+
},
|
|
2365
|
+
uiBackground: { color: C.cyan }
|
|
2366
|
+
}
|
|
2367
|
+
),
|
|
2368
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2369
|
+
import_react_ecs4.UiEntity,
|
|
2370
|
+
{
|
|
2371
|
+
uiTransform: {
|
|
2372
|
+
flexGrow: 1,
|
|
2373
|
+
height: "100%",
|
|
2374
|
+
padding: { left: 12, right: 12 },
|
|
2375
|
+
justifyContent: "center",
|
|
2376
|
+
alignItems: "flex-start"
|
|
2377
|
+
}
|
|
2378
|
+
},
|
|
2379
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2380
|
+
import_react_ecs4.Label,
|
|
2381
|
+
{
|
|
2382
|
+
value: notificationText,
|
|
2383
|
+
fontSize: N.fontSize,
|
|
2384
|
+
color: C.white,
|
|
2385
|
+
textAlign: "middle-left"
|
|
2386
|
+
}
|
|
2387
|
+
)
|
|
2388
|
+
),
|
|
2389
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2390
|
+
import_react_ecs4.UiEntity,
|
|
2391
|
+
{
|
|
2392
|
+
uiTransform: {
|
|
2393
|
+
width: 6,
|
|
2394
|
+
height: 6,
|
|
2395
|
+
margin: { right: 12 }
|
|
2396
|
+
},
|
|
2397
|
+
uiBackground: { color: C.cyan }
|
|
2398
|
+
}
|
|
2399
|
+
)
|
|
2400
|
+
);
|
|
2401
|
+
}
|
|
2402
|
+
function createStaticUI(client) {
|
|
2403
|
+
initNotificationSystem();
|
|
2404
|
+
return function StaticUI() {
|
|
2405
|
+
const currentScale = client.uiScale;
|
|
2406
|
+
const guideComponent = client.guideUI?.getComponent() ?? null;
|
|
2407
|
+
const chatComponent = client.chatUI?.getComponent() ?? null;
|
|
2408
|
+
const adminComponent = client.adminPanel?.getComponent() ?? null;
|
|
2409
|
+
return /* @__PURE__ */ import_react_ecs4.default.createElement(
|
|
2410
|
+
import_react_ecs4.UiEntity,
|
|
2411
|
+
{
|
|
2412
|
+
key: `static-ui-root-${currentScale}`,
|
|
2413
|
+
uiTransform: {
|
|
2414
|
+
width: "100%",
|
|
2415
|
+
height: "100%",
|
|
2416
|
+
positionType: "absolute",
|
|
2417
|
+
flexDirection: "column",
|
|
2418
|
+
alignItems: "center"
|
|
2419
|
+
}
|
|
2420
|
+
},
|
|
2421
|
+
/* @__PURE__ */ import_react_ecs4.default.createElement(NotificationBanner, null),
|
|
2422
|
+
guideComponent,
|
|
2423
|
+
chatComponent,
|
|
2424
|
+
adminComponent
|
|
2425
|
+
);
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
function setupStaticUI(client) {
|
|
2429
|
+
const StaticUI = createStaticUI(client);
|
|
2430
|
+
import_react_ecs4.ReactEcsRenderer.setUiRenderer(StaticUI);
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
// src/ui/admin-panel-ui.tsx
|
|
2302
2434
|
var BAN_KICK_POSITION = import_math5.Vector3.create(16, -50, 16);
|
|
2303
|
-
var
|
|
2435
|
+
var C2 = {
|
|
2304
2436
|
bg: import_math5.Color4.create(0.08, 0.08, 0.12, 0.98),
|
|
2305
2437
|
header: import_math5.Color4.create(0.9, 0.15, 0.15, 1),
|
|
2306
2438
|
tabActive: import_math5.Color4.create(0, 0.7, 0.7, 1),
|
|
@@ -2341,6 +2473,8 @@ var AdminPanelUIModule = class {
|
|
|
2341
2473
|
this.streamControlling = false;
|
|
2342
2474
|
this.streamControlStatus = "";
|
|
2343
2475
|
this.pollIntervalId = null;
|
|
2476
|
+
this.commandPollIntervalId = null;
|
|
2477
|
+
this.lastCommandTimestamp = 0;
|
|
2344
2478
|
this.trialClaiming = false;
|
|
2345
2479
|
this.trialClaimError = "";
|
|
2346
2480
|
// Mod tab state
|
|
@@ -2352,22 +2486,22 @@ var AdminPanelUIModule = class {
|
|
|
2352
2486
|
this.modStatus = "";
|
|
2353
2487
|
this.modsFetched = false;
|
|
2354
2488
|
// --- UI Components ---
|
|
2355
|
-
this.SectionHead = ({ label, color }) => /* @__PURE__ */
|
|
2356
|
-
|
|
2489
|
+
this.SectionHead = ({ label, color }) => /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2490
|
+
import_react_ecs5.UiEntity,
|
|
2357
2491
|
{
|
|
2358
2492
|
uiTransform: { width: "100%", height: this.s(UI_DIMENSIONS.admin.sectionHeadHeight), margin: { bottom: 8 }, padding: { left: 10 }, alignItems: "center" },
|
|
2359
2493
|
uiBackground: { color: import_math5.Color4.create(color.r * 0.3, color.g * 0.3, color.b * 0.3, 0.5) }
|
|
2360
2494
|
},
|
|
2361
|
-
/* @__PURE__ */
|
|
2495
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: label, fontSize: this.theme.sectionHead, color })
|
|
2362
2496
|
);
|
|
2363
|
-
this.TabBtn = ({ label, tab }) => /* @__PURE__ */
|
|
2364
|
-
|
|
2497
|
+
this.TabBtn = ({ label, tab }) => /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2498
|
+
import_react_ecs5.Button,
|
|
2365
2499
|
{
|
|
2366
2500
|
uiTransform: { flexGrow: 1, height: this.s(UI_DIMENSIONS.admin.tabHeight), justifyContent: "center", alignItems: "center" },
|
|
2367
|
-
uiBackground: { color: this.activeTab === tab ?
|
|
2501
|
+
uiBackground: { color: this.activeTab === tab ? C2.tabActive : C2.tabInactive },
|
|
2368
2502
|
value: label,
|
|
2369
2503
|
fontSize: this.theme.tabButton,
|
|
2370
|
-
color: this.activeTab === tab ? import_math5.Color4.Black() :
|
|
2504
|
+
color: this.activeTab === tab ? import_math5.Color4.Black() : C2.text,
|
|
2371
2505
|
textAlign: "middle-center",
|
|
2372
2506
|
onMouseDown: () => this.setActiveTab(tab)
|
|
2373
2507
|
}
|
|
@@ -2377,365 +2511,368 @@ var AdminPanelUIModule = class {
|
|
|
2377
2511
|
this.fetchStreamData();
|
|
2378
2512
|
}
|
|
2379
2513
|
const t = this.theme;
|
|
2380
|
-
return /* @__PURE__ */
|
|
2381
|
-
|
|
2514
|
+
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(
|
|
2515
|
+
import_react_ecs5.Button,
|
|
2382
2516
|
{
|
|
2383
2517
|
uiTransform: { width: this.s(200), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: { bottom: 6 } },
|
|
2384
|
-
uiBackground: { color: this.trialClaiming ?
|
|
2518
|
+
uiBackground: { color: this.trialClaiming ? C2.btn : C2.green },
|
|
2385
2519
|
value: this.trialClaiming ? "Claiming..." : "Start Free 4-Hour Trial",
|
|
2386
2520
|
fontSize: t.button,
|
|
2387
|
-
color:
|
|
2521
|
+
color: C2.text,
|
|
2388
2522
|
onMouseDown: () => this.claimTrial()
|
|
2389
2523
|
}
|
|
2390
|
-
), this.trialClaimError && /* @__PURE__ */
|
|
2391
|
-
|
|
2524
|
+
), 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(
|
|
2525
|
+
import_react_ecs5.Button,
|
|
2392
2526
|
{
|
|
2393
2527
|
uiTransform: { width: this.s(170), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: { bottom: 6 } },
|
|
2394
|
-
uiBackground: { color: this.channelCreating ?
|
|
2528
|
+
uiBackground: { color: this.channelCreating ? C2.btn : C2.cyan },
|
|
2395
2529
|
value: this.channelCreating ? "Creating..." : "+ Create Channel",
|
|
2396
2530
|
fontSize: t.button,
|
|
2397
|
-
color:
|
|
2531
|
+
color: C2.text,
|
|
2398
2532
|
onMouseDown: () => this.createChannel()
|
|
2399
2533
|
}
|
|
2400
|
-
), this.channelCreateError && /* @__PURE__ */
|
|
2401
|
-
|
|
2534
|
+
), 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(
|
|
2535
|
+
import_react_ecs5.Label,
|
|
2402
2536
|
{
|
|
2403
2537
|
value: this.streamData.isLive ? `LIVE \u2022 ${this.streamData.currentViewers || 0} viewers` : "OFFLINE",
|
|
2404
2538
|
fontSize: t.label,
|
|
2405
|
-
color: this.streamData.isLive ?
|
|
2539
|
+
color: this.streamData.isLive ? C2.red : C2.textDim
|
|
2406
2540
|
}
|
|
2407
|
-
), /* @__PURE__ */
|
|
2408
|
-
|
|
2541
|
+
), /* @__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(
|
|
2542
|
+
import_react_ecs5.Label,
|
|
2409
2543
|
{
|
|
2410
2544
|
value: `Channel: ${this.streamData.channelName || this.streamData.channelId}`,
|
|
2411
2545
|
fontSize: t.labelSmall,
|
|
2412
|
-
color:
|
|
2546
|
+
color: C2.textDim,
|
|
2413
2547
|
uiTransform: { margin: { bottom: 10 } }
|
|
2414
2548
|
}
|
|
2415
|
-
), /* @__PURE__ */
|
|
2416
|
-
|
|
2549
|
+
), /* @__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(
|
|
2550
|
+
import_react_ecs5.Label,
|
|
2417
2551
|
{
|
|
2418
2552
|
value: this.streamData.rtmpUrl || "Loading...",
|
|
2419
2553
|
fontSize: t.label,
|
|
2420
|
-
color: this.streamData.rtmpUrl ?
|
|
2554
|
+
color: this.streamData.rtmpUrl ? C2.text : C2.textDim,
|
|
2421
2555
|
uiTransform: { margin: { left: 6 } }
|
|
2422
2556
|
}
|
|
2423
|
-
)), /* @__PURE__ */
|
|
2424
|
-
|
|
2557
|
+
)), /* @__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(
|
|
2558
|
+
import_react_ecs5.Label,
|
|
2425
2559
|
{
|
|
2426
2560
|
value: this.streamData.streamKey || "Loading...",
|
|
2427
2561
|
fontSize: t.label,
|
|
2428
|
-
color: this.streamData.streamKey ?
|
|
2562
|
+
color: this.streamData.streamKey ? C2.cyan : C2.textDim,
|
|
2429
2563
|
uiTransform: { margin: { left: 6 } }
|
|
2430
2564
|
}
|
|
2431
|
-
)), /* @__PURE__ */
|
|
2432
|
-
|
|
2565
|
+
)), /* @__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(
|
|
2566
|
+
import_react_ecs5.Label,
|
|
2433
2567
|
{
|
|
2434
2568
|
value: this.streamData.hlsUrl || "Not available",
|
|
2435
2569
|
fontSize: t.label,
|
|
2436
|
-
color: this.streamData.hlsUrl ?
|
|
2570
|
+
color: this.streamData.hlsUrl ? C2.green : C2.textDim,
|
|
2437
2571
|
uiTransform: { margin: { left: 6 } }
|
|
2438
2572
|
}
|
|
2439
|
-
)), /* @__PURE__ */
|
|
2440
|
-
|
|
2573
|
+
)), /* @__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(
|
|
2574
|
+
import_react_ecs5.Button,
|
|
2441
2575
|
{
|
|
2442
2576
|
uiTransform: { width: this.s(110), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2443
|
-
uiBackground: { color: this.streamControlling ?
|
|
2577
|
+
uiBackground: { color: this.streamControlling ? C2.btn : C2.green },
|
|
2444
2578
|
value: this.streamControlling ? "Starting..." : "Start Stream",
|
|
2445
2579
|
fontSize: t.buttonSmall,
|
|
2446
|
-
color:
|
|
2580
|
+
color: C2.text,
|
|
2447
2581
|
onMouseDown: () => this.startStream()
|
|
2448
2582
|
}
|
|
2449
|
-
), this.streamData.isLive && /* @__PURE__ */
|
|
2450
|
-
|
|
2583
|
+
), this.streamData.isLive && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2584
|
+
import_react_ecs5.Button,
|
|
2451
2585
|
{
|
|
2452
2586
|
uiTransform: { width: this.s(110), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2453
|
-
uiBackground: { color: this.streamControlling ?
|
|
2587
|
+
uiBackground: { color: this.streamControlling ? C2.btn : C2.red },
|
|
2454
2588
|
value: this.streamControlling ? "Stopping..." : "Stop Stream",
|
|
2455
2589
|
fontSize: t.buttonSmall,
|
|
2456
|
-
color:
|
|
2590
|
+
color: C2.text,
|
|
2457
2591
|
onMouseDown: () => this.stopStream()
|
|
2458
2592
|
}
|
|
2459
|
-
), this.streamData.isLive && this.streamData.hlsUrl && /* @__PURE__ */
|
|
2460
|
-
|
|
2593
|
+
), this.streamData.isLive && this.streamData.hlsUrl && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2594
|
+
import_react_ecs5.Button,
|
|
2461
2595
|
{
|
|
2462
2596
|
uiTransform: { width: this.s(100), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2463
|
-
uiBackground: { color:
|
|
2597
|
+
uiBackground: { color: C2.cyan },
|
|
2464
2598
|
value: "Play on Screen",
|
|
2465
2599
|
fontSize: t.buttonSmall,
|
|
2466
|
-
color:
|
|
2600
|
+
color: C2.text,
|
|
2467
2601
|
onMouseDown: () => this.config.onVideoPlay?.(this.streamData.hlsUrl)
|
|
2468
2602
|
}
|
|
2469
|
-
)), /* @__PURE__ */
|
|
2470
|
-
|
|
2603
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 6 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2604
|
+
import_react_ecs5.Button,
|
|
2471
2605
|
{
|
|
2472
2606
|
uiTransform: { width: this.s(80), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2473
|
-
uiBackground: { color:
|
|
2607
|
+
uiBackground: { color: C2.btn },
|
|
2474
2608
|
value: "Refresh",
|
|
2475
2609
|
fontSize: t.buttonSmall,
|
|
2476
|
-
color:
|
|
2610
|
+
color: C2.text,
|
|
2477
2611
|
onMouseDown: () => this.refreshStreamStatus()
|
|
2478
2612
|
}
|
|
2479
|
-
), /* @__PURE__ */
|
|
2480
|
-
|
|
2613
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2614
|
+
import_react_ecs5.Button,
|
|
2481
2615
|
{
|
|
2482
2616
|
uiTransform: { width: this.s(95), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2483
|
-
uiBackground: { color: this.keyRotating ?
|
|
2617
|
+
uiBackground: { color: this.keyRotating ? C2.btn : C2.yellow },
|
|
2484
2618
|
value: this.keyRotating ? "..." : "Rotate Key",
|
|
2485
2619
|
fontSize: t.buttonSmall,
|
|
2486
|
-
color:
|
|
2620
|
+
color: C2.text,
|
|
2487
2621
|
onMouseDown: () => this.rotateStreamKey()
|
|
2488
2622
|
}
|
|
2489
|
-
), !this.streamData.isLive && /* @__PURE__ */
|
|
2490
|
-
|
|
2623
|
+
), !this.streamData.isLive && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2624
|
+
import_react_ecs5.Button,
|
|
2491
2625
|
{
|
|
2492
2626
|
uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2493
|
-
uiBackground: { color: this.channelDeleting ?
|
|
2627
|
+
uiBackground: { color: this.channelDeleting ? C2.btn : C2.red },
|
|
2494
2628
|
value: this.channelDeleting ? "..." : "Delete",
|
|
2495
2629
|
fontSize: t.buttonSmall,
|
|
2496
|
-
color:
|
|
2630
|
+
color: C2.text,
|
|
2497
2631
|
onMouseDown: () => this.deleteChannel()
|
|
2498
2632
|
}
|
|
2499
|
-
)), this.streamControlStatus === "started" && /* @__PURE__ */
|
|
2500
|
-
|
|
2633
|
+
)), 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(
|
|
2634
|
+
import_react_ecs5.Input,
|
|
2501
2635
|
{
|
|
2502
2636
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2503
2637
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2504
2638
|
placeholder: "Video URL...",
|
|
2505
|
-
placeholderColor:
|
|
2506
|
-
color:
|
|
2639
|
+
placeholderColor: C2.textDim,
|
|
2640
|
+
color: C2.text,
|
|
2507
2641
|
fontSize: t.input,
|
|
2508
2642
|
value: this.customVideoUrl,
|
|
2509
2643
|
onChange: (val) => {
|
|
2510
2644
|
this.customVideoUrl = val;
|
|
2511
2645
|
}
|
|
2512
2646
|
}
|
|
2513
|
-
), /* @__PURE__ */
|
|
2514
|
-
|
|
2647
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2648
|
+
import_react_ecs5.Button,
|
|
2515
2649
|
{
|
|
2516
2650
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2517
|
-
uiBackground: { color:
|
|
2651
|
+
uiBackground: { color: C2.green },
|
|
2518
2652
|
value: "Play",
|
|
2519
2653
|
fontSize: t.button,
|
|
2520
|
-
color:
|
|
2654
|
+
color: C2.text,
|
|
2521
2655
|
onMouseDown: () => {
|
|
2522
2656
|
if (this.customVideoUrl) this.config.onVideoPlay?.(this.customVideoUrl);
|
|
2523
2657
|
}
|
|
2524
2658
|
}
|
|
2525
|
-
), /* @__PURE__ */
|
|
2526
|
-
|
|
2659
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2660
|
+
import_react_ecs5.Button,
|
|
2527
2661
|
{
|
|
2528
2662
|
uiTransform: { width: this.s(65), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 6 } },
|
|
2529
|
-
uiBackground: { color:
|
|
2663
|
+
uiBackground: { color: C2.btn },
|
|
2530
2664
|
value: "Clear",
|
|
2531
2665
|
fontSize: t.button,
|
|
2532
|
-
color:
|
|
2666
|
+
color: C2.text,
|
|
2533
2667
|
onMouseDown: () => {
|
|
2534
2668
|
this.customVideoUrl = "";
|
|
2535
2669
|
}
|
|
2536
2670
|
}
|
|
2537
|
-
)), /* @__PURE__ */
|
|
2538
|
-
|
|
2671
|
+
)), /* @__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(
|
|
2672
|
+
import_react_ecs5.Button,
|
|
2539
2673
|
{
|
|
2540
2674
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2541
|
-
uiBackground: { color:
|
|
2675
|
+
uiBackground: { color: C2.green },
|
|
2542
2676
|
value: "Play",
|
|
2543
2677
|
fontSize: t.button,
|
|
2544
|
-
color:
|
|
2678
|
+
color: C2.text,
|
|
2545
2679
|
onMouseDown: () => this.config.onCommand?.("videoPlay", { playing: true })
|
|
2546
2680
|
}
|
|
2547
|
-
), /* @__PURE__ */
|
|
2548
|
-
|
|
2681
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2682
|
+
import_react_ecs5.Button,
|
|
2549
2683
|
{
|
|
2550
2684
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2551
|
-
uiBackground: { color:
|
|
2685
|
+
uiBackground: { color: C2.red },
|
|
2552
2686
|
value: "Stop",
|
|
2553
2687
|
fontSize: t.button,
|
|
2554
|
-
color:
|
|
2688
|
+
color: C2.text,
|
|
2555
2689
|
onMouseDown: () => this.config.onVideoStop?.()
|
|
2556
2690
|
}
|
|
2557
|
-
), /* @__PURE__ */
|
|
2558
|
-
|
|
2691
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2692
|
+
import_react_ecs5.Button,
|
|
2559
2693
|
{
|
|
2560
2694
|
uiTransform: { width: this.s(100), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2561
|
-
uiBackground: { color:
|
|
2695
|
+
uiBackground: { color: C2.btn },
|
|
2562
2696
|
value: "Reset Default",
|
|
2563
2697
|
fontSize: t.buttonSmall,
|
|
2564
|
-
color:
|
|
2698
|
+
color: C2.text,
|
|
2565
2699
|
onMouseDown: () => this.config.onCommand?.("videoClear", {})
|
|
2566
2700
|
}
|
|
2567
|
-
)), /* @__PURE__ */
|
|
2568
|
-
|
|
2701
|
+
)), /* @__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(
|
|
2702
|
+
import_react_ecs5.Button,
|
|
2569
2703
|
{
|
|
2570
2704
|
uiTransform: { height: this.s(24) },
|
|
2571
2705
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0) },
|
|
2572
2706
|
value: "Edit slots at thestatic.tv",
|
|
2573
2707
|
fontSize: t.labelSmall,
|
|
2574
|
-
color:
|
|
2708
|
+
color: C2.cyan,
|
|
2575
2709
|
onMouseDown: () => (0, import_RestrictedActions3.openExternalUrl)({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2576
2710
|
}
|
|
2577
2711
|
));
|
|
2578
2712
|
};
|
|
2579
2713
|
this.ModTab = () => {
|
|
2580
2714
|
const t = this.theme;
|
|
2581
|
-
return /* @__PURE__ */
|
|
2582
|
-
|
|
2715
|
+
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(
|
|
2716
|
+
import_react_ecs5.Input,
|
|
2583
2717
|
{
|
|
2584
2718
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2585
2719
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2586
2720
|
placeholder: "Message to all players...",
|
|
2587
|
-
placeholderColor:
|
|
2588
|
-
color:
|
|
2721
|
+
placeholderColor: C2.textDim,
|
|
2722
|
+
color: C2.text,
|
|
2589
2723
|
fontSize: t.input,
|
|
2590
2724
|
value: this.broadcastText,
|
|
2591
2725
|
onChange: (val) => {
|
|
2592
2726
|
this.broadcastText = val;
|
|
2593
2727
|
}
|
|
2594
2728
|
}
|
|
2595
|
-
), /* @__PURE__ */
|
|
2596
|
-
|
|
2729
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2730
|
+
import_react_ecs5.Button,
|
|
2597
2731
|
{
|
|
2598
2732
|
uiTransform: { width: this.s(65), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2599
|
-
uiBackground: { color:
|
|
2733
|
+
uiBackground: { color: C2.orange },
|
|
2600
2734
|
value: "Send",
|
|
2601
2735
|
fontSize: t.button,
|
|
2602
|
-
color:
|
|
2736
|
+
color: C2.text,
|
|
2603
2737
|
onMouseDown: () => this.sendBroadcast()
|
|
2604
2738
|
}
|
|
2605
|
-
)), /* @__PURE__ */
|
|
2606
|
-
|
|
2739
|
+
)), /* @__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(
|
|
2740
|
+
import_react_ecs5.Button,
|
|
2607
2741
|
{
|
|
2608
2742
|
uiTransform: { width: this.s(130), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: 4 },
|
|
2609
|
-
uiBackground: { color:
|
|
2743
|
+
uiBackground: { color: C2.red },
|
|
2610
2744
|
value: "KICK ALL",
|
|
2611
2745
|
fontSize: t.button,
|
|
2612
|
-
color:
|
|
2746
|
+
color: C2.text,
|
|
2613
2747
|
onMouseDown: () => {
|
|
2614
2748
|
this.log("KICK ALL clicked");
|
|
2615
2749
|
this.config.onCommand?.("kickAll", {});
|
|
2616
2750
|
}
|
|
2617
2751
|
}
|
|
2618
|
-
)), /* @__PURE__ */
|
|
2619
|
-
|
|
2752
|
+
)), /* @__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(
|
|
2753
|
+
import_react_ecs5.UiEntity,
|
|
2620
2754
|
{
|
|
2621
2755
|
key: `admin-${i}`,
|
|
2622
2756
|
uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 5 }, width: "100%" }
|
|
2623
2757
|
},
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
|
|
2758
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2759
|
+
import_react_ecs5.Label,
|
|
2626
2760
|
{
|
|
2627
2761
|
value: `${wallet.slice(0, 6)}...${wallet.slice(-4)}`,
|
|
2628
2762
|
fontSize: t.label,
|
|
2629
|
-
color:
|
|
2763
|
+
color: C2.text,
|
|
2630
2764
|
uiTransform: { width: this.s(130) }
|
|
2631
2765
|
}
|
|
2632
2766
|
),
|
|
2633
|
-
/* @__PURE__ */
|
|
2634
|
-
|
|
2767
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2768
|
+
import_react_ecs5.Button,
|
|
2635
2769
|
{
|
|
2636
2770
|
uiTransform: { width: this.s(70), height: this.s(28), margin: { left: 8 } },
|
|
2637
|
-
uiBackground: { color:
|
|
2771
|
+
uiBackground: { color: C2.btn },
|
|
2638
2772
|
value: "Remove",
|
|
2639
2773
|
fontSize: t.buttonSmall,
|
|
2640
|
-
color:
|
|
2774
|
+
color: C2.text,
|
|
2641
2775
|
onMouseDown: () => this.removeSceneAdmin(wallet)
|
|
2642
2776
|
}
|
|
2643
2777
|
)
|
|
2644
|
-
))), /* @__PURE__ */
|
|
2645
|
-
|
|
2778
|
+
))), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2779
|
+
import_react_ecs5.Input,
|
|
2646
2780
|
{
|
|
2647
2781
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2648
2782
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2649
2783
|
placeholder: "0x... add admin",
|
|
2650
|
-
placeholderColor:
|
|
2651
|
-
color:
|
|
2784
|
+
placeholderColor: C2.textDim,
|
|
2785
|
+
color: C2.text,
|
|
2652
2786
|
fontSize: t.input,
|
|
2653
2787
|
value: this.newAdminWallet,
|
|
2654
2788
|
onChange: (val) => {
|
|
2655
2789
|
this.newAdminWallet = val;
|
|
2656
2790
|
}
|
|
2657
2791
|
}
|
|
2658
|
-
), /* @__PURE__ */
|
|
2659
|
-
|
|
2792
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2793
|
+
import_react_ecs5.Button,
|
|
2660
2794
|
{
|
|
2661
2795
|
uiTransform: { width: this.s(60), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2662
|
-
uiBackground: { color:
|
|
2796
|
+
uiBackground: { color: C2.purple },
|
|
2663
2797
|
value: "Add",
|
|
2664
2798
|
fontSize: t.button,
|
|
2665
|
-
color:
|
|
2799
|
+
color: C2.text,
|
|
2666
2800
|
onMouseDown: () => {
|
|
2667
2801
|
if (this.newAdminWallet) this.addSceneAdmin(this.newAdminWallet);
|
|
2668
2802
|
}
|
|
2669
2803
|
}
|
|
2670
|
-
)), /* @__PURE__ */
|
|
2671
|
-
|
|
2804
|
+
)), /* @__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(
|
|
2805
|
+
import_react_ecs5.UiEntity,
|
|
2672
2806
|
{
|
|
2673
2807
|
key: `ban-${i}`,
|
|
2674
2808
|
uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 5 }, width: "100%" }
|
|
2675
2809
|
},
|
|
2676
|
-
/* @__PURE__ */
|
|
2677
|
-
|
|
2810
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2811
|
+
import_react_ecs5.Label,
|
|
2678
2812
|
{
|
|
2679
2813
|
value: `${wallet.slice(0, 6)}...${wallet.slice(-4)}`,
|
|
2680
2814
|
fontSize: t.label,
|
|
2681
|
-
color:
|
|
2815
|
+
color: C2.red,
|
|
2682
2816
|
uiTransform: { width: this.s(130) }
|
|
2683
2817
|
}
|
|
2684
2818
|
),
|
|
2685
|
-
/* @__PURE__ */
|
|
2686
|
-
|
|
2819
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2820
|
+
import_react_ecs5.Button,
|
|
2687
2821
|
{
|
|
2688
2822
|
uiTransform: { width: this.s(70), height: this.s(28), margin: { left: 8 } },
|
|
2689
|
-
uiBackground: { color:
|
|
2823
|
+
uiBackground: { color: C2.green },
|
|
2690
2824
|
value: "Unban",
|
|
2691
2825
|
fontSize: t.buttonSmall,
|
|
2692
|
-
color:
|
|
2826
|
+
color: C2.text,
|
|
2693
2827
|
onMouseDown: () => this.unbanWallet(wallet)
|
|
2694
2828
|
}
|
|
2695
2829
|
)
|
|
2696
|
-
))), /* @__PURE__ */
|
|
2697
|
-
|
|
2830
|
+
))), /* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.UiEntity, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 10 } } }, /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2831
|
+
import_react_ecs5.Input,
|
|
2698
2832
|
{
|
|
2699
2833
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2700
2834
|
uiBackground: { color: import_math5.Color4.create(0.15, 0.15, 0.2, 1) },
|
|
2701
2835
|
placeholder: "0x... ban wallet",
|
|
2702
|
-
placeholderColor:
|
|
2703
|
-
color:
|
|
2836
|
+
placeholderColor: C2.textDim,
|
|
2837
|
+
color: C2.text,
|
|
2704
2838
|
fontSize: t.input,
|
|
2705
2839
|
value: this.newBanWallet,
|
|
2706
2840
|
onChange: (val) => {
|
|
2707
2841
|
this.newBanWallet = val;
|
|
2708
2842
|
}
|
|
2709
2843
|
}
|
|
2710
|
-
), /* @__PURE__ */
|
|
2711
|
-
|
|
2844
|
+
), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2845
|
+
import_react_ecs5.Button,
|
|
2712
2846
|
{
|
|
2713
2847
|
uiTransform: { width: this.s(60), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2714
|
-
uiBackground: { color:
|
|
2848
|
+
uiBackground: { color: C2.red },
|
|
2715
2849
|
value: "Ban",
|
|
2716
2850
|
fontSize: t.button,
|
|
2717
|
-
color:
|
|
2851
|
+
color: C2.text,
|
|
2718
2852
|
onMouseDown: () => {
|
|
2719
2853
|
if (this.newBanWallet) this.banWallet(this.newBanWallet);
|
|
2720
2854
|
}
|
|
2721
2855
|
}
|
|
2722
|
-
)), /* @__PURE__ */
|
|
2723
|
-
|
|
2856
|
+
)), /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2857
|
+
import_react_ecs5.Button,
|
|
2724
2858
|
{
|
|
2725
2859
|
uiTransform: { height: this.s(24) },
|
|
2726
2860
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0) },
|
|
2727
2861
|
value: "Manage at thestatic.tv",
|
|
2728
2862
|
fontSize: t.labelSmall,
|
|
2729
|
-
color:
|
|
2863
|
+
color: C2.cyan,
|
|
2730
2864
|
onMouseDown: () => (0, import_RestrictedActions3.openExternalUrl)({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2731
2865
|
}
|
|
2732
2866
|
));
|
|
2733
2867
|
};
|
|
2734
2868
|
/**
|
|
2735
2869
|
* Get the React-ECS component for the admin panel
|
|
2870
|
+
* Always renders NotificationBanner (for broadcasts), admin panel only for admins
|
|
2736
2871
|
*/
|
|
2737
2872
|
this.getComponent = () => {
|
|
2738
|
-
if (!this.isAdmin)
|
|
2873
|
+
if (!this.isAdmin) {
|
|
2874
|
+
return /* @__PURE__ */ import_react_ecs5.default.createElement(NotificationBanner, null);
|
|
2875
|
+
}
|
|
2739
2876
|
const t = this.theme;
|
|
2740
2877
|
const tabs = [];
|
|
2741
2878
|
if (this.config.sceneTabs && this.config.sceneTabs.length > 0) {
|
|
@@ -2750,8 +2887,8 @@ var AdminPanelUIModule = class {
|
|
|
2750
2887
|
if (!tabs.find((tab) => tab.id === this.activeTab) && tabs.length > 0) {
|
|
2751
2888
|
this.activeTab = tabs[0].id;
|
|
2752
2889
|
}
|
|
2753
|
-
return /* @__PURE__ */
|
|
2754
|
-
|
|
2890
|
+
return /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2891
|
+
import_react_ecs5.UiEntity,
|
|
2755
2892
|
{
|
|
2756
2893
|
uiTransform: {
|
|
2757
2894
|
width: "100%",
|
|
@@ -2759,28 +2896,29 @@ var AdminPanelUIModule = class {
|
|
|
2759
2896
|
positionType: "absolute"
|
|
2760
2897
|
}
|
|
2761
2898
|
},
|
|
2762
|
-
/* @__PURE__ */
|
|
2763
|
-
|
|
2899
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(NotificationBanner, null),
|
|
2900
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2901
|
+
import_react_ecs5.UiEntity,
|
|
2764
2902
|
{
|
|
2765
2903
|
uiTransform: {
|
|
2766
2904
|
position: { right: 20 + this.s(100) + 10 + this.s(100) + 10, bottom: 10 },
|
|
2767
2905
|
positionType: "absolute"
|
|
2768
2906
|
}
|
|
2769
2907
|
},
|
|
2770
|
-
/* @__PURE__ */
|
|
2771
|
-
|
|
2908
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2909
|
+
import_react_ecs5.Button,
|
|
2772
2910
|
{
|
|
2773
2911
|
uiTransform: { width: this.s(100), height: this.s(45) },
|
|
2774
|
-
uiBackground: { color: this.panelOpen ?
|
|
2912
|
+
uiBackground: { color: this.panelOpen ? C2.btn : C2.header },
|
|
2775
2913
|
value: this.panelOpen ? "CLOSE" : "ADMIN",
|
|
2776
2914
|
fontSize: this.s(14),
|
|
2777
|
-
color:
|
|
2915
|
+
color: C2.text,
|
|
2778
2916
|
onMouseDown: () => this.toggle()
|
|
2779
2917
|
}
|
|
2780
2918
|
)
|
|
2781
2919
|
),
|
|
2782
|
-
this.panelOpen && /* @__PURE__ */
|
|
2783
|
-
|
|
2920
|
+
this.panelOpen && /* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2921
|
+
import_react_ecs5.UiEntity,
|
|
2784
2922
|
{
|
|
2785
2923
|
key: `admin-panel-${this.client.uiScale}`,
|
|
2786
2924
|
uiTransform: {
|
|
@@ -2791,10 +2929,10 @@ var AdminPanelUIModule = class {
|
|
|
2791
2929
|
positionType: "absolute",
|
|
2792
2930
|
flexDirection: "column"
|
|
2793
2931
|
},
|
|
2794
|
-
uiBackground: { color:
|
|
2932
|
+
uiBackground: { color: C2.bg }
|
|
2795
2933
|
},
|
|
2796
|
-
/* @__PURE__ */
|
|
2797
|
-
|
|
2934
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2935
|
+
import_react_ecs5.UiEntity,
|
|
2798
2936
|
{
|
|
2799
2937
|
uiTransform: {
|
|
2800
2938
|
width: "100%",
|
|
@@ -2804,11 +2942,11 @@ var AdminPanelUIModule = class {
|
|
|
2804
2942
|
flexDirection: "row",
|
|
2805
2943
|
padding: { left: 12, right: 8 }
|
|
2806
2944
|
},
|
|
2807
|
-
uiBackground: { color:
|
|
2945
|
+
uiBackground: { color: C2.header }
|
|
2808
2946
|
},
|
|
2809
|
-
/* @__PURE__ */
|
|
2810
|
-
/* @__PURE__ */
|
|
2811
|
-
|
|
2947
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(import_react_ecs5.Label, { value: this.config.title || "ADMIN PANEL", fontSize: t.header, color: C2.text }),
|
|
2948
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2949
|
+
import_react_ecs5.Button,
|
|
2812
2950
|
{
|
|
2813
2951
|
uiTransform: { width: this.s(28), height: this.s(28) },
|
|
2814
2952
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0.3) },
|
|
@@ -2819,9 +2957,9 @@ var AdminPanelUIModule = class {
|
|
|
2819
2957
|
}
|
|
2820
2958
|
)
|
|
2821
2959
|
),
|
|
2822
|
-
/* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
2824
|
-
|
|
2960
|
+
/* @__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 }))),
|
|
2961
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2962
|
+
import_react_ecs5.UiEntity,
|
|
2825
2963
|
{
|
|
2826
2964
|
uiTransform: {
|
|
2827
2965
|
width: "100%",
|
|
@@ -2830,12 +2968,12 @@ var AdminPanelUIModule = class {
|
|
|
2830
2968
|
flexDirection: "column"
|
|
2831
2969
|
}
|
|
2832
2970
|
},
|
|
2833
|
-
this.activeTab === "video" && /* @__PURE__ */
|
|
2834
|
-
this.activeTab === "mod" && this.isOwner && /* @__PURE__ */
|
|
2971
|
+
this.activeTab === "video" && /* @__PURE__ */ import_react_ecs5.default.createElement(this.VideoTab, null),
|
|
2972
|
+
this.activeTab === "mod" && this.isOwner && /* @__PURE__ */ import_react_ecs5.default.createElement(this.ModTab, null),
|
|
2835
2973
|
this.config.sceneTabs?.map((tab) => this.activeTab === tab.id && tab.render())
|
|
2836
2974
|
),
|
|
2837
|
-
/* @__PURE__ */
|
|
2838
|
-
|
|
2975
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2976
|
+
import_react_ecs5.UiEntity,
|
|
2839
2977
|
{
|
|
2840
2978
|
uiTransform: {
|
|
2841
2979
|
width: "100%",
|
|
@@ -2843,16 +2981,16 @@ var AdminPanelUIModule = class {
|
|
|
2843
2981
|
justifyContent: "center",
|
|
2844
2982
|
alignItems: "center"
|
|
2845
2983
|
},
|
|
2846
|
-
uiBackground: { color:
|
|
2984
|
+
uiBackground: { color: C2.section }
|
|
2847
2985
|
},
|
|
2848
|
-
/* @__PURE__ */
|
|
2849
|
-
|
|
2986
|
+
/* @__PURE__ */ import_react_ecs5.default.createElement(
|
|
2987
|
+
import_react_ecs5.Button,
|
|
2850
2988
|
{
|
|
2851
2989
|
uiTransform: { height: this.s(24) },
|
|
2852
2990
|
uiBackground: { color: import_math5.Color4.create(0, 0, 0, 0) },
|
|
2853
2991
|
value: `thestatic.tv/scene/${this.config.sceneId}`,
|
|
2854
2992
|
fontSize: t.labelSmall,
|
|
2855
|
-
color:
|
|
2993
|
+
color: C2.cyan,
|
|
2856
2994
|
onMouseDown: () => (0, import_RestrictedActions3.openExternalUrl)({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2857
2995
|
}
|
|
2858
2996
|
)
|
|
@@ -2875,7 +3013,7 @@ var AdminPanelUIModule = class {
|
|
|
2875
3013
|
};
|
|
2876
3014
|
this.baseUrl = client.getBaseUrl();
|
|
2877
3015
|
if (config.headerColor) {
|
|
2878
|
-
|
|
3016
|
+
C2.header = import_math5.Color4.create(
|
|
2879
3017
|
config.headerColor.r,
|
|
2880
3018
|
config.headerColor.g,
|
|
2881
3019
|
config.headerColor.b,
|
|
@@ -2903,6 +3041,7 @@ var AdminPanelUIModule = class {
|
|
|
2903
3041
|
await this.checkAdminStatus();
|
|
2904
3042
|
await this.fetchVideoState();
|
|
2905
3043
|
this.autoPlayDefault();
|
|
3044
|
+
this.startCommandPolling();
|
|
2906
3045
|
this.log("Initialized");
|
|
2907
3046
|
}
|
|
2908
3047
|
/**
|
|
@@ -3008,6 +3147,61 @@ var AdminPanelUIModule = class {
|
|
|
3008
3147
|
this.log("Stream polling stopped");
|
|
3009
3148
|
}
|
|
3010
3149
|
}
|
|
3150
|
+
// --- Command Polling (receives broadcasts from website) ---
|
|
3151
|
+
startCommandPolling() {
|
|
3152
|
+
if (this.commandPollIntervalId !== null) return;
|
|
3153
|
+
this.commandPollIntervalId = dclSetInterval(() => {
|
|
3154
|
+
this.pollCommands();
|
|
3155
|
+
}, 5e3);
|
|
3156
|
+
this.pollCommands();
|
|
3157
|
+
this.log("Command polling started");
|
|
3158
|
+
}
|
|
3159
|
+
stopCommandPolling() {
|
|
3160
|
+
if (this.commandPollIntervalId !== null) {
|
|
3161
|
+
dclClearInterval(this.commandPollIntervalId);
|
|
3162
|
+
this.commandPollIntervalId = null;
|
|
3163
|
+
this.log("Command polling stopped");
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
async pollCommands() {
|
|
3167
|
+
try {
|
|
3168
|
+
const res = await fetch(`${this.baseUrl}/scene/${this.config.sceneId}/commands`);
|
|
3169
|
+
if (!res.ok) return;
|
|
3170
|
+
const data = await res.json();
|
|
3171
|
+
const commands = data.commands || [];
|
|
3172
|
+
for (const cmd of commands) {
|
|
3173
|
+
if (cmd.timestamp <= this.lastCommandTimestamp) continue;
|
|
3174
|
+
this.lastCommandTimestamp = cmd.timestamp;
|
|
3175
|
+
if (cmd.type === "broadcast" && cmd.payload?.text) {
|
|
3176
|
+
const msg = cmd.payload.from ? `${cmd.payload.from}: ${cmd.payload.text}` : cmd.payload.text;
|
|
3177
|
+
this.log("Received broadcast:", msg);
|
|
3178
|
+
this.config.onBroadcast?.(msg);
|
|
3179
|
+
} else if (cmd.type === "clearBroadcast") {
|
|
3180
|
+
this.log("Received clearBroadcast");
|
|
3181
|
+
hideNotification();
|
|
3182
|
+
} else if ((cmd.type === "videoPlay" || cmd.type === "videoSetUrl") && cmd.payload?.url) {
|
|
3183
|
+
this.log("Received video play:", cmd.type, cmd.payload.url);
|
|
3184
|
+
this.config.onVideoPlay?.(cmd.payload.url);
|
|
3185
|
+
} else if (cmd.type === "videoStop" || cmd.type === "videoClear") {
|
|
3186
|
+
this.log("Received video stop/clear:", cmd.type);
|
|
3187
|
+
this.config.onVideoStop?.();
|
|
3188
|
+
} else if (cmd.type === "videoPlaySlot" && cmd.payload?.slot) {
|
|
3189
|
+
const slotId = cmd.payload.slot;
|
|
3190
|
+
if (cmd.payload.url) {
|
|
3191
|
+
this.log("Received videoPlaySlot with URL:", slotId, cmd.payload.url);
|
|
3192
|
+
this.config.onVideoPlay?.(cmd.payload.url);
|
|
3193
|
+
} else {
|
|
3194
|
+
this.log("Received videoPlaySlot:", slotId);
|
|
3195
|
+
this.playSlot(slotId);
|
|
3196
|
+
}
|
|
3197
|
+
} else if (this.config.onCommand) {
|
|
3198
|
+
this.log("Received command:", cmd.type, cmd.payload);
|
|
3199
|
+
this.config.onCommand(cmd.type, cmd.payload);
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
} catch (err) {
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3011
3205
|
// --- Stream API Calls ---
|
|
3012
3206
|
async fetchStreamData() {
|
|
3013
3207
|
if (this.streamFetched || !this.playerWallet) return;
|
|
@@ -3439,87 +3633,6 @@ var AdminPanelUIModule = class {
|
|
|
3439
3633
|
}
|
|
3440
3634
|
};
|
|
3441
3635
|
|
|
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
3636
|
// src/StaticTVClient.ts
|
|
3524
3637
|
var import_ecs3 = require("@dcl/sdk/ecs");
|
|
3525
3638
|
var utils = __toESM(require("@dcl-sdk/utils"));
|
|
@@ -3800,10 +3913,13 @@ var StaticTVClient = class {
|
|
|
3800
3913
|
*/
|
|
3801
3914
|
stopVideo() {
|
|
3802
3915
|
const screen = this.config.videoScreen;
|
|
3916
|
+
this._pendingVideoData = null;
|
|
3917
|
+
this._streamVerified = false;
|
|
3918
|
+
this._clearVerificationTimeout();
|
|
3919
|
+
if (this.guideUI) {
|
|
3920
|
+
this.guideUI.currentVideoId = null;
|
|
3921
|
+
}
|
|
3803
3922
|
if (screen !== void 0) {
|
|
3804
|
-
if (this.guideUI) {
|
|
3805
|
-
this.guideUI.currentVideoId = null;
|
|
3806
|
-
}
|
|
3807
3923
|
const fallbackUrl = this.config.fallbackVideoUrl;
|
|
3808
3924
|
const fallbackDisabled = fallbackUrl === "";
|
|
3809
3925
|
if (fallbackDisabled) {
|
|
@@ -3893,7 +4009,7 @@ var StaticTVClient = class {
|
|
|
3893
4009
|
this.log(`Stream verification timeout for: ${this._pendingVideoData.name}`);
|
|
3894
4010
|
this._handleStreamOffline();
|
|
3895
4011
|
}
|
|
3896
|
-
},
|
|
4012
|
+
}, 5e3);
|
|
3897
4013
|
}
|
|
3898
4014
|
/**
|
|
3899
4015
|
* Handle stream that's offline or failed to verify
|
|
@@ -3959,20 +4075,60 @@ var StaticTVClient = class {
|
|
|
3959
4075
|
}
|
|
3960
4076
|
/**
|
|
3961
4077
|
* Play video with stream verification for live content
|
|
4078
|
+
* Works with both videoScreen (SDK-managed) and onVideoPlay (user-managed) modes.
|
|
3962
4079
|
* @internal
|
|
3963
4080
|
*/
|
|
3964
4081
|
_playVideoWithVerification(video, isLiveStream) {
|
|
3965
4082
|
const screen = this.config.videoScreen;
|
|
4083
|
+
const hasCallback = this.config.onVideoPlay !== void 0;
|
|
4084
|
+
this.log(`Playing video: ${video.src} (live: ${isLiveStream}, screen: ${screen !== void 0}, callback: ${hasCallback})`);
|
|
4085
|
+
this._currentVideoUrl = video.src;
|
|
4086
|
+
this._clearVerificationTimeout();
|
|
4087
|
+
this._streamVerified = false;
|
|
3966
4088
|
if (screen !== void 0) {
|
|
3967
|
-
this.log(`Playing video: ${video.src} (live: ${isLiveStream})`);
|
|
3968
|
-
this._currentVideoUrl = video.src;
|
|
3969
4089
|
this._playVideoInternal(video.src, false, isLiveStream);
|
|
3970
|
-
if (this.guideUI) {
|
|
3971
|
-
this.guideUI.currentVideoId = video.id;
|
|
3972
|
-
}
|
|
3973
4090
|
}
|
|
3974
|
-
if (
|
|
4091
|
+
if (hasCallback) {
|
|
3975
4092
|
this.config.onVideoPlay(video.src);
|
|
4093
|
+
if (isLiveStream) {
|
|
4094
|
+
this._startCallbackVerification(video);
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
if (this.guideUI) {
|
|
4098
|
+
this.guideUI.currentVideoId = video.id;
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
/**
|
|
4102
|
+
* Start stream verification for callback-based video playback
|
|
4103
|
+
* Shows CONNECTING state and triggers fallback if verification times out
|
|
4104
|
+
* @internal
|
|
4105
|
+
*/
|
|
4106
|
+
_startCallbackVerification(video) {
|
|
4107
|
+
this.showNotification(`Connecting to ${video.name}...`, 6e3);
|
|
4108
|
+
this._verificationTimeoutId = utils.timers.setTimeout(() => {
|
|
4109
|
+
if (!this._streamVerified && this._pendingVideoData) {
|
|
4110
|
+
this.log(`Stream verification timeout (callback mode): ${video.name}`);
|
|
4111
|
+
this._handleStreamOffline();
|
|
4112
|
+
}
|
|
4113
|
+
}, 5e3);
|
|
4114
|
+
}
|
|
4115
|
+
/**
|
|
4116
|
+
* Call this to confirm that a video stream is playing successfully.
|
|
4117
|
+
* Use this when you're managing video playback yourself (onVideoPlay callback).
|
|
4118
|
+
*
|
|
4119
|
+
* @example
|
|
4120
|
+
* ```typescript
|
|
4121
|
+
* // In your video player's onReady or similar event:
|
|
4122
|
+
* videoPlayer.events.on('playing', () => {
|
|
4123
|
+
* staticTV.confirmVideoPlaying()
|
|
4124
|
+
* })
|
|
4125
|
+
* ```
|
|
4126
|
+
*/
|
|
4127
|
+
confirmVideoPlaying() {
|
|
4128
|
+
if (this._pendingVideoData && !this._streamVerified) {
|
|
4129
|
+
this._streamVerified = true;
|
|
4130
|
+
this._clearVerificationTimeout();
|
|
4131
|
+
this.log(`Stream confirmed playing: ${this._pendingVideoData.name}`);
|
|
3976
4132
|
}
|
|
3977
4133
|
}
|
|
3978
4134
|
/**
|
|
@@ -4247,11 +4403,13 @@ var StaticTVClient = class {
|
|
|
4247
4403
|
InteractionsModule,
|
|
4248
4404
|
KEY_TYPE_CHANNEL,
|
|
4249
4405
|
KEY_TYPE_SCENE,
|
|
4406
|
+
NotificationBanner,
|
|
4250
4407
|
SessionModule,
|
|
4251
4408
|
StaticTVClient,
|
|
4252
4409
|
fetchUserData,
|
|
4253
4410
|
getPlayerDisplayName,
|
|
4254
4411
|
getPlayerWallet,
|
|
4412
|
+
hideNotification,
|
|
4255
4413
|
setupStaticUI,
|
|
4256
4414
|
showNotification
|
|
4257
4415
|
});
|