@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.mjs
CHANGED
|
@@ -625,6 +625,17 @@ var UI_DIMENSIONS = {
|
|
|
625
625
|
buttonHeightSmall: 30,
|
|
626
626
|
inputHeight: 36
|
|
627
627
|
},
|
|
628
|
+
// Notification banner - centered, aligned with toggle buttons
|
|
629
|
+
notification: {
|
|
630
|
+
width: 340,
|
|
631
|
+
height: 36,
|
|
632
|
+
// Same as toggle buttons
|
|
633
|
+
bottom: 10,
|
|
634
|
+
// Same as toggle buttons
|
|
635
|
+
borderWidth: 2,
|
|
636
|
+
fontSize: 14
|
|
637
|
+
// Same as toggle buttons (14)
|
|
638
|
+
},
|
|
628
639
|
// Shared
|
|
629
640
|
closeButton: {
|
|
630
641
|
size: 40,
|
|
@@ -2252,12 +2263,144 @@ var ChatUIModule = class {
|
|
|
2252
2263
|
};
|
|
2253
2264
|
|
|
2254
2265
|
// src/ui/admin-panel-ui.tsx
|
|
2255
|
-
import
|
|
2266
|
+
import ReactEcs5, { UiEntity as UiEntity5, Button as Button3, Label as Label5, Input as Input4 } from "@dcl/sdk/react-ecs";
|
|
2256
2267
|
import { Color4 as Color45, Vector3 } from "@dcl/sdk/math";
|
|
2257
2268
|
import { getPlayer as getPlayer2 } from "@dcl/sdk/players";
|
|
2258
2269
|
import { movePlayerTo, openExternalUrl as openExternalUrl3 } from "~system/RestrictedActions";
|
|
2270
|
+
|
|
2271
|
+
// src/ui/ui-renderer.tsx
|
|
2272
|
+
import ReactEcs4, { ReactEcsRenderer, UiEntity as UiEntity4, Label as Label4 } from "@dcl/sdk/react-ecs";
|
|
2273
|
+
import { engine as engine2 } from "@dcl/sdk/ecs";
|
|
2274
|
+
var notificationText = "";
|
|
2275
|
+
var notificationVisible = false;
|
|
2276
|
+
var notificationEndTime = 0;
|
|
2277
|
+
var notificationInitialized = false;
|
|
2278
|
+
var C = THEME.colors;
|
|
2279
|
+
var N = UI_DIMENSIONS.notification;
|
|
2280
|
+
function showNotification(message, durationMs = 5e3) {
|
|
2281
|
+
notificationText = message;
|
|
2282
|
+
notificationVisible = true;
|
|
2283
|
+
notificationEndTime = Date.now() + durationMs;
|
|
2284
|
+
}
|
|
2285
|
+
function hideNotification() {
|
|
2286
|
+
notificationVisible = false;
|
|
2287
|
+
}
|
|
2288
|
+
function initNotificationSystem() {
|
|
2289
|
+
if (notificationInitialized) return;
|
|
2290
|
+
notificationInitialized = true;
|
|
2291
|
+
engine2.addSystem(() => {
|
|
2292
|
+
if (notificationVisible && Date.now() > notificationEndTime) {
|
|
2293
|
+
notificationVisible = false;
|
|
2294
|
+
}
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
function NotificationBanner() {
|
|
2298
|
+
initNotificationSystem();
|
|
2299
|
+
if (!notificationVisible) return null;
|
|
2300
|
+
return (
|
|
2301
|
+
// Full-width container to center the notification
|
|
2302
|
+
/* @__PURE__ */ ReactEcs4.createElement(
|
|
2303
|
+
UiEntity4,
|
|
2304
|
+
{
|
|
2305
|
+
uiTransform: {
|
|
2306
|
+
positionType: "absolute",
|
|
2307
|
+
position: { bottom: N.bottom, left: 0, right: 0 },
|
|
2308
|
+
height: N.height,
|
|
2309
|
+
justifyContent: "center",
|
|
2310
|
+
alignItems: "center"
|
|
2311
|
+
}
|
|
2312
|
+
},
|
|
2313
|
+
/* @__PURE__ */ ReactEcs4.createElement(
|
|
2314
|
+
UiEntity4,
|
|
2315
|
+
{
|
|
2316
|
+
uiTransform: {
|
|
2317
|
+
width: N.width,
|
|
2318
|
+
height: N.height,
|
|
2319
|
+
flexDirection: "row",
|
|
2320
|
+
alignItems: "center"
|
|
2321
|
+
},
|
|
2322
|
+
uiBackground: { color: C.panel }
|
|
2323
|
+
},
|
|
2324
|
+
/* @__PURE__ */ ReactEcs4.createElement(
|
|
2325
|
+
UiEntity4,
|
|
2326
|
+
{
|
|
2327
|
+
uiTransform: {
|
|
2328
|
+
width: N.borderWidth,
|
|
2329
|
+
height: "100%"
|
|
2330
|
+
},
|
|
2331
|
+
uiBackground: { color: C.cyan }
|
|
2332
|
+
}
|
|
2333
|
+
),
|
|
2334
|
+
/* @__PURE__ */ ReactEcs4.createElement(
|
|
2335
|
+
UiEntity4,
|
|
2336
|
+
{
|
|
2337
|
+
uiTransform: {
|
|
2338
|
+
flexGrow: 1,
|
|
2339
|
+
height: "100%",
|
|
2340
|
+
padding: { left: 10, right: 10 },
|
|
2341
|
+
justifyContent: "center",
|
|
2342
|
+
alignItems: "flex-start"
|
|
2343
|
+
}
|
|
2344
|
+
},
|
|
2345
|
+
/* @__PURE__ */ ReactEcs4.createElement(
|
|
2346
|
+
Label4,
|
|
2347
|
+
{
|
|
2348
|
+
value: notificationText,
|
|
2349
|
+
fontSize: N.fontSize,
|
|
2350
|
+
color: C.white,
|
|
2351
|
+
textAlign: "middle-left"
|
|
2352
|
+
}
|
|
2353
|
+
)
|
|
2354
|
+
),
|
|
2355
|
+
/* @__PURE__ */ ReactEcs4.createElement(
|
|
2356
|
+
UiEntity4,
|
|
2357
|
+
{
|
|
2358
|
+
uiTransform: {
|
|
2359
|
+
width: 5,
|
|
2360
|
+
height: 5,
|
|
2361
|
+
margin: { right: 10 }
|
|
2362
|
+
},
|
|
2363
|
+
uiBackground: { color: C.cyan }
|
|
2364
|
+
}
|
|
2365
|
+
)
|
|
2366
|
+
)
|
|
2367
|
+
)
|
|
2368
|
+
);
|
|
2369
|
+
}
|
|
2370
|
+
function createStaticUI(client) {
|
|
2371
|
+
initNotificationSystem();
|
|
2372
|
+
return function StaticUI() {
|
|
2373
|
+
const currentScale = client.uiScale;
|
|
2374
|
+
const guideComponent = client.guideUI?.getComponent() ?? null;
|
|
2375
|
+
const chatComponent = client.chatUI?.getComponent() ?? null;
|
|
2376
|
+
const adminComponent = client.adminPanel?.getComponent() ?? null;
|
|
2377
|
+
return /* @__PURE__ */ ReactEcs4.createElement(
|
|
2378
|
+
UiEntity4,
|
|
2379
|
+
{
|
|
2380
|
+
key: `static-ui-root-${currentScale}`,
|
|
2381
|
+
uiTransform: {
|
|
2382
|
+
width: "100%",
|
|
2383
|
+
height: "100%",
|
|
2384
|
+
positionType: "absolute",
|
|
2385
|
+
flexDirection: "column",
|
|
2386
|
+
alignItems: "center"
|
|
2387
|
+
}
|
|
2388
|
+
},
|
|
2389
|
+
/* @__PURE__ */ ReactEcs4.createElement(NotificationBanner, null),
|
|
2390
|
+
guideComponent,
|
|
2391
|
+
chatComponent,
|
|
2392
|
+
adminComponent
|
|
2393
|
+
);
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
function setupStaticUI(client) {
|
|
2397
|
+
const StaticUI = createStaticUI(client);
|
|
2398
|
+
ReactEcsRenderer.setUiRenderer(StaticUI);
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
// src/ui/admin-panel-ui.tsx
|
|
2259
2402
|
var BAN_KICK_POSITION = Vector3.create(16, -50, 16);
|
|
2260
|
-
var
|
|
2403
|
+
var C2 = {
|
|
2261
2404
|
bg: Color45.create(0.08, 0.08, 0.12, 0.98),
|
|
2262
2405
|
header: Color45.create(0.9, 0.15, 0.15, 1),
|
|
2263
2406
|
tabActive: Color45.create(0, 0.7, 0.7, 1),
|
|
@@ -2298,6 +2441,8 @@ var AdminPanelUIModule = class {
|
|
|
2298
2441
|
this.streamControlling = false;
|
|
2299
2442
|
this.streamControlStatus = "";
|
|
2300
2443
|
this.pollIntervalId = null;
|
|
2444
|
+
this.commandPollIntervalId = null;
|
|
2445
|
+
this.lastCommandTimestamp = 0;
|
|
2301
2446
|
this.trialClaiming = false;
|
|
2302
2447
|
this.trialClaimError = "";
|
|
2303
2448
|
// Mod tab state
|
|
@@ -2309,22 +2454,22 @@ var AdminPanelUIModule = class {
|
|
|
2309
2454
|
this.modStatus = "";
|
|
2310
2455
|
this.modsFetched = false;
|
|
2311
2456
|
// --- UI Components ---
|
|
2312
|
-
this.SectionHead = ({ label, color }) => /* @__PURE__ */
|
|
2313
|
-
|
|
2457
|
+
this.SectionHead = ({ label, color }) => /* @__PURE__ */ ReactEcs5.createElement(
|
|
2458
|
+
UiEntity5,
|
|
2314
2459
|
{
|
|
2315
2460
|
uiTransform: { width: "100%", height: this.s(UI_DIMENSIONS.admin.sectionHeadHeight), margin: { bottom: 8 }, padding: { left: 10 }, alignItems: "center" },
|
|
2316
2461
|
uiBackground: { color: Color45.create(color.r * 0.3, color.g * 0.3, color.b * 0.3, 0.5) }
|
|
2317
2462
|
},
|
|
2318
|
-
/* @__PURE__ */
|
|
2463
|
+
/* @__PURE__ */ ReactEcs5.createElement(Label5, { value: label, fontSize: this.theme.sectionHead, color })
|
|
2319
2464
|
);
|
|
2320
|
-
this.TabBtn = ({ label, tab }) => /* @__PURE__ */
|
|
2465
|
+
this.TabBtn = ({ label, tab }) => /* @__PURE__ */ ReactEcs5.createElement(
|
|
2321
2466
|
Button3,
|
|
2322
2467
|
{
|
|
2323
2468
|
uiTransform: { flexGrow: 1, height: this.s(UI_DIMENSIONS.admin.tabHeight), justifyContent: "center", alignItems: "center" },
|
|
2324
|
-
uiBackground: { color: this.activeTab === tab ?
|
|
2469
|
+
uiBackground: { color: this.activeTab === tab ? C2.tabActive : C2.tabInactive },
|
|
2325
2470
|
value: label,
|
|
2326
2471
|
fontSize: this.theme.tabButton,
|
|
2327
|
-
color: this.activeTab === tab ? Color45.Black() :
|
|
2472
|
+
color: this.activeTab === tab ? Color45.Black() : C2.text,
|
|
2328
2473
|
textAlign: "middle-center",
|
|
2329
2474
|
onMouseDown: () => this.setActiveTab(tab)
|
|
2330
2475
|
}
|
|
@@ -2334,365 +2479,368 @@ var AdminPanelUIModule = class {
|
|
|
2334
2479
|
this.fetchStreamData();
|
|
2335
2480
|
}
|
|
2336
2481
|
const t = this.theme;
|
|
2337
|
-
return /* @__PURE__ */
|
|
2482
|
+
return /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", width: "100%", padding: 10 } }, !this.streamData?.hasChannel && /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "LIVE STREAM", color: C2.btn }), /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "No streaming channel linked", fontSize: t.labelSmall, color: C2.textDim, uiTransform: { margin: { bottom: 8 } } }), this.isOwner && /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column" } }, this.streamData?.trialAvailable && /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 10 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2338
2483
|
Button3,
|
|
2339
2484
|
{
|
|
2340
2485
|
uiTransform: { width: this.s(200), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: { bottom: 6 } },
|
|
2341
|
-
uiBackground: { color: this.trialClaiming ?
|
|
2486
|
+
uiBackground: { color: this.trialClaiming ? C2.btn : C2.green },
|
|
2342
2487
|
value: this.trialClaiming ? "Claiming..." : "Start Free 4-Hour Trial",
|
|
2343
2488
|
fontSize: t.button,
|
|
2344
|
-
color:
|
|
2489
|
+
color: C2.text,
|
|
2345
2490
|
onMouseDown: () => this.claimTrial()
|
|
2346
2491
|
}
|
|
2347
|
-
), this.trialClaimError && /* @__PURE__ */
|
|
2492
|
+
), this.trialClaimError && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: this.trialClaimError, fontSize: t.status, color: C2.red }), /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "One-time trial \u2022 4 hours of streaming", fontSize: t.labelSmall, color: C2.textDim, uiTransform: { margin: { top: 4 } } })), !this.streamData?.trialAvailable && /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column" } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2348
2493
|
Button3,
|
|
2349
2494
|
{
|
|
2350
2495
|
uiTransform: { width: this.s(170), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: { bottom: 6 } },
|
|
2351
|
-
uiBackground: { color: this.channelCreating ?
|
|
2496
|
+
uiBackground: { color: this.channelCreating ? C2.btn : C2.cyan },
|
|
2352
2497
|
value: this.channelCreating ? "Creating..." : "+ Create Channel",
|
|
2353
2498
|
fontSize: t.button,
|
|
2354
|
-
color:
|
|
2499
|
+
color: C2.text,
|
|
2355
2500
|
onMouseDown: () => this.createChannel()
|
|
2356
2501
|
}
|
|
2357
|
-
), this.channelCreateError && /* @__PURE__ */
|
|
2358
|
-
|
|
2502
|
+
), this.channelCreateError && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: this.channelCreateError, fontSize: t.status, color: C2.red }), /* @__PURE__ */ ReactEcs5.createElement(Label5, { 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__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: this.streamData.isLive ? "LIVE STREAM" : "STREAM SETTINGS", color: this.streamData.isLive ? C2.red : C2.yellow }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 8 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2503
|
+
Label5,
|
|
2359
2504
|
{
|
|
2360
2505
|
value: this.streamData.isLive ? `LIVE \u2022 ${this.streamData.currentViewers || 0} viewers` : "OFFLINE",
|
|
2361
2506
|
fontSize: t.label,
|
|
2362
|
-
color: this.streamData.isLive ?
|
|
2507
|
+
color: this.streamData.isLive ? C2.red : C2.textDim
|
|
2363
2508
|
}
|
|
2364
|
-
), /* @__PURE__ */
|
|
2365
|
-
|
|
2509
|
+
), /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: ` \u2022 ${this.streamData.tier?.toUpperCase() || "RELAY"}`, fontSize: t.labelSmall, color: C2.cyan }), /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: ` \u2022 ${this.streamData.sparksBalance || 0} Sparks`, fontSize: t.labelSmall, color: C2.textDim })), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2510
|
+
Label5,
|
|
2366
2511
|
{
|
|
2367
2512
|
value: `Channel: ${this.streamData.channelName || this.streamData.channelId}`,
|
|
2368
2513
|
fontSize: t.labelSmall,
|
|
2369
|
-
color:
|
|
2514
|
+
color: C2.textDim,
|
|
2370
2515
|
uiTransform: { margin: { bottom: 10 } }
|
|
2371
2516
|
}
|
|
2372
|
-
), /* @__PURE__ */
|
|
2373
|
-
|
|
2517
|
+
), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "RTMP Server:", fontSize: t.labelSmall, color: C2.textDim }), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2518
|
+
Label5,
|
|
2374
2519
|
{
|
|
2375
2520
|
value: this.streamData.rtmpUrl || "Loading...",
|
|
2376
2521
|
fontSize: t.label,
|
|
2377
|
-
color: this.streamData.rtmpUrl ?
|
|
2522
|
+
color: this.streamData.rtmpUrl ? C2.text : C2.textDim,
|
|
2378
2523
|
uiTransform: { margin: { left: 6 } }
|
|
2379
2524
|
}
|
|
2380
|
-
)), /* @__PURE__ */
|
|
2381
|
-
|
|
2525
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Stream Key:", fontSize: t.labelSmall, color: C2.textDim }), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2526
|
+
Label5,
|
|
2382
2527
|
{
|
|
2383
2528
|
value: this.streamData.streamKey || "Loading...",
|
|
2384
2529
|
fontSize: t.label,
|
|
2385
|
-
color: this.streamData.streamKey ?
|
|
2530
|
+
color: this.streamData.streamKey ? C2.cyan : C2.textDim,
|
|
2386
2531
|
uiTransform: { margin: { left: 6 } }
|
|
2387
2532
|
}
|
|
2388
|
-
)), /* @__PURE__ */
|
|
2389
|
-
|
|
2533
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 10 } } }, /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "HLS Playback:", fontSize: t.labelSmall, color: C2.textDim }), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2534
|
+
Label5,
|
|
2390
2535
|
{
|
|
2391
2536
|
value: this.streamData.hlsUrl || "Not available",
|
|
2392
2537
|
fontSize: t.label,
|
|
2393
|
-
color: this.streamData.hlsUrl ?
|
|
2538
|
+
color: this.streamData.hlsUrl ? C2.green : C2.textDim,
|
|
2394
2539
|
uiTransform: { margin: { left: 6 } }
|
|
2395
2540
|
}
|
|
2396
|
-
)), /* @__PURE__ */
|
|
2541
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 6 } } }, !this.streamData.isLive && /* @__PURE__ */ ReactEcs5.createElement(
|
|
2397
2542
|
Button3,
|
|
2398
2543
|
{
|
|
2399
2544
|
uiTransform: { width: this.s(110), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2400
|
-
uiBackground: { color: this.streamControlling ?
|
|
2545
|
+
uiBackground: { color: this.streamControlling ? C2.btn : C2.green },
|
|
2401
2546
|
value: this.streamControlling ? "Starting..." : "Start Stream",
|
|
2402
2547
|
fontSize: t.buttonSmall,
|
|
2403
|
-
color:
|
|
2548
|
+
color: C2.text,
|
|
2404
2549
|
onMouseDown: () => this.startStream()
|
|
2405
2550
|
}
|
|
2406
|
-
), this.streamData.isLive && /* @__PURE__ */
|
|
2551
|
+
), this.streamData.isLive && /* @__PURE__ */ ReactEcs5.createElement(
|
|
2407
2552
|
Button3,
|
|
2408
2553
|
{
|
|
2409
2554
|
uiTransform: { width: this.s(110), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2410
|
-
uiBackground: { color: this.streamControlling ?
|
|
2555
|
+
uiBackground: { color: this.streamControlling ? C2.btn : C2.red },
|
|
2411
2556
|
value: this.streamControlling ? "Stopping..." : "Stop Stream",
|
|
2412
2557
|
fontSize: t.buttonSmall,
|
|
2413
|
-
color:
|
|
2558
|
+
color: C2.text,
|
|
2414
2559
|
onMouseDown: () => this.stopStream()
|
|
2415
2560
|
}
|
|
2416
|
-
), this.streamData.isLive && this.streamData.hlsUrl && /* @__PURE__ */
|
|
2561
|
+
), this.streamData.isLive && this.streamData.hlsUrl && /* @__PURE__ */ ReactEcs5.createElement(
|
|
2417
2562
|
Button3,
|
|
2418
2563
|
{
|
|
2419
2564
|
uiTransform: { width: this.s(100), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2420
|
-
uiBackground: { color:
|
|
2565
|
+
uiBackground: { color: C2.cyan },
|
|
2421
2566
|
value: "Play on Screen",
|
|
2422
2567
|
fontSize: t.buttonSmall,
|
|
2423
|
-
color:
|
|
2568
|
+
color: C2.text,
|
|
2424
2569
|
onMouseDown: () => this.config.onVideoPlay?.(this.streamData.hlsUrl)
|
|
2425
2570
|
}
|
|
2426
|
-
)), /* @__PURE__ */
|
|
2571
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 6 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2427
2572
|
Button3,
|
|
2428
2573
|
{
|
|
2429
2574
|
uiTransform: { width: this.s(80), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2430
|
-
uiBackground: { color:
|
|
2575
|
+
uiBackground: { color: C2.btn },
|
|
2431
2576
|
value: "Refresh",
|
|
2432
2577
|
fontSize: t.buttonSmall,
|
|
2433
|
-
color:
|
|
2578
|
+
color: C2.text,
|
|
2434
2579
|
onMouseDown: () => this.refreshStreamStatus()
|
|
2435
2580
|
}
|
|
2436
|
-
), /* @__PURE__ */
|
|
2581
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2437
2582
|
Button3,
|
|
2438
2583
|
{
|
|
2439
2584
|
uiTransform: { width: this.s(95), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2440
|
-
uiBackground: { color: this.keyRotating ?
|
|
2585
|
+
uiBackground: { color: this.keyRotating ? C2.btn : C2.yellow },
|
|
2441
2586
|
value: this.keyRotating ? "..." : "Rotate Key",
|
|
2442
2587
|
fontSize: t.buttonSmall,
|
|
2443
|
-
color:
|
|
2588
|
+
color: C2.text,
|
|
2444
2589
|
onMouseDown: () => this.rotateStreamKey()
|
|
2445
2590
|
}
|
|
2446
|
-
), !this.streamData.isLive && /* @__PURE__ */
|
|
2591
|
+
), !this.streamData.isLive && /* @__PURE__ */ ReactEcs5.createElement(
|
|
2447
2592
|
Button3,
|
|
2448
2593
|
{
|
|
2449
2594
|
uiTransform: { width: this.s(70), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2450
|
-
uiBackground: { color: this.channelDeleting ?
|
|
2595
|
+
uiBackground: { color: this.channelDeleting ? C2.btn : C2.red },
|
|
2451
2596
|
value: this.channelDeleting ? "..." : "Delete",
|
|
2452
2597
|
fontSize: t.buttonSmall,
|
|
2453
|
-
color:
|
|
2598
|
+
color: C2.text,
|
|
2454
2599
|
onMouseDown: () => this.deleteChannel()
|
|
2455
2600
|
}
|
|
2456
|
-
)), this.streamControlStatus === "started" && /* @__PURE__ */
|
|
2601
|
+
)), this.streamControlStatus === "started" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Stream started - begin broadcasting in OBS", fontSize: t.status, color: C2.green }), this.streamControlStatus === "stopped" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Stream stopped", fontSize: t.status, color: C2.textDim }), this.keyRotateStatus === "success" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Key rotated! Update OBS", fontSize: t.status, color: C2.green }), this.keyRotateStatus === "error" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Failed to rotate key", fontSize: t.status, color: C2.red }), this.channelDeleteError && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: this.channelDeleteError, fontSize: t.status, color: C2.red }), this.streamControlStatus === "error" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Stream control failed", fontSize: t.status, color: C2.red })), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "PLAY NOW", color: C2.orange }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2457
2602
|
Input4,
|
|
2458
2603
|
{
|
|
2459
2604
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2460
2605
|
uiBackground: { color: Color45.create(0.15, 0.15, 0.2, 1) },
|
|
2461
2606
|
placeholder: "Video URL...",
|
|
2462
|
-
placeholderColor:
|
|
2463
|
-
color:
|
|
2607
|
+
placeholderColor: C2.textDim,
|
|
2608
|
+
color: C2.text,
|
|
2464
2609
|
fontSize: t.input,
|
|
2465
2610
|
value: this.customVideoUrl,
|
|
2466
2611
|
onChange: (val) => {
|
|
2467
2612
|
this.customVideoUrl = val;
|
|
2468
2613
|
}
|
|
2469
2614
|
}
|
|
2470
|
-
), /* @__PURE__ */
|
|
2615
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2471
2616
|
Button3,
|
|
2472
2617
|
{
|
|
2473
2618
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2474
|
-
uiBackground: { color:
|
|
2619
|
+
uiBackground: { color: C2.green },
|
|
2475
2620
|
value: "Play",
|
|
2476
2621
|
fontSize: t.button,
|
|
2477
|
-
color:
|
|
2622
|
+
color: C2.text,
|
|
2478
2623
|
onMouseDown: () => {
|
|
2479
2624
|
if (this.customVideoUrl) this.config.onVideoPlay?.(this.customVideoUrl);
|
|
2480
2625
|
}
|
|
2481
2626
|
}
|
|
2482
|
-
), /* @__PURE__ */
|
|
2627
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2483
2628
|
Button3,
|
|
2484
2629
|
{
|
|
2485
2630
|
uiTransform: { width: this.s(65), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 6 } },
|
|
2486
|
-
uiBackground: { color:
|
|
2631
|
+
uiBackground: { color: C2.btn },
|
|
2487
2632
|
value: "Clear",
|
|
2488
2633
|
fontSize: t.button,
|
|
2489
|
-
color:
|
|
2634
|
+
color: C2.text,
|
|
2490
2635
|
onMouseDown: () => {
|
|
2491
2636
|
this.customVideoUrl = "";
|
|
2492
2637
|
}
|
|
2493
2638
|
}
|
|
2494
|
-
)), /* @__PURE__ */
|
|
2639
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "PLAYBACK", color: C2.green }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2495
2640
|
Button3,
|
|
2496
2641
|
{
|
|
2497
2642
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2498
|
-
uiBackground: { color:
|
|
2643
|
+
uiBackground: { color: C2.green },
|
|
2499
2644
|
value: "Play",
|
|
2500
2645
|
fontSize: t.button,
|
|
2501
|
-
color:
|
|
2646
|
+
color: C2.text,
|
|
2502
2647
|
onMouseDown: () => this.config.onCommand?.("videoPlay", { playing: true })
|
|
2503
2648
|
}
|
|
2504
|
-
), /* @__PURE__ */
|
|
2649
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2505
2650
|
Button3,
|
|
2506
2651
|
{
|
|
2507
2652
|
uiTransform: { width: this.s(75), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2508
|
-
uiBackground: { color:
|
|
2653
|
+
uiBackground: { color: C2.red },
|
|
2509
2654
|
value: "Stop",
|
|
2510
2655
|
fontSize: t.button,
|
|
2511
|
-
color:
|
|
2656
|
+
color: C2.text,
|
|
2512
2657
|
onMouseDown: () => this.config.onVideoStop?.()
|
|
2513
2658
|
}
|
|
2514
|
-
), /* @__PURE__ */
|
|
2659
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2515
2660
|
Button3,
|
|
2516
2661
|
{
|
|
2517
2662
|
uiTransform: { width: this.s(100), height: this.s(UI_DIMENSIONS.admin.buttonHeightSmall), margin: 4 },
|
|
2518
|
-
uiBackground: { color:
|
|
2663
|
+
uiBackground: { color: C2.btn },
|
|
2519
2664
|
value: "Reset Default",
|
|
2520
2665
|
fontSize: t.buttonSmall,
|
|
2521
|
-
color:
|
|
2666
|
+
color: C2.text,
|
|
2522
2667
|
onMouseDown: () => this.config.onCommand?.("videoClear", {})
|
|
2523
2668
|
}
|
|
2524
|
-
)), /* @__PURE__ */
|
|
2669
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "VIDEO SLOTS", color: C2.cyan }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 10 } } }, /* @__PURE__ */ ReactEcs5.createElement(Button3, { 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__ */ ReactEcs5.createElement(Button3, { 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__ */ ReactEcs5.createElement(Button3, { 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__ */ ReactEcs5.createElement(Button3, { 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__ */ ReactEcs5.createElement(Button3, { 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__ */ ReactEcs5.createElement(
|
|
2525
2670
|
Button3,
|
|
2526
2671
|
{
|
|
2527
2672
|
uiTransform: { height: this.s(24) },
|
|
2528
2673
|
uiBackground: { color: Color45.create(0, 0, 0, 0) },
|
|
2529
2674
|
value: "Edit slots at thestatic.tv",
|
|
2530
2675
|
fontSize: t.labelSmall,
|
|
2531
|
-
color:
|
|
2676
|
+
color: C2.cyan,
|
|
2532
2677
|
onMouseDown: () => openExternalUrl3({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2533
2678
|
}
|
|
2534
2679
|
));
|
|
2535
2680
|
};
|
|
2536
2681
|
this.ModTab = () => {
|
|
2537
2682
|
const t = this.theme;
|
|
2538
|
-
return /* @__PURE__ */
|
|
2683
|
+
return /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", width: "100%", padding: 10 } }, this.modStatus === "loading" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Loading...", fontSize: t.status, color: C2.yellow }), this.modStatus === "saved" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Saved!", fontSize: t.status, color: C2.green }), this.modStatus === "error" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "Error - check input", fontSize: t.status, color: C2.red }), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "BROADCAST", color: C2.orange }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2539
2684
|
Input4,
|
|
2540
2685
|
{
|
|
2541
2686
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2542
2687
|
uiBackground: { color: Color45.create(0.15, 0.15, 0.2, 1) },
|
|
2543
2688
|
placeholder: "Message to all players...",
|
|
2544
|
-
placeholderColor:
|
|
2545
|
-
color:
|
|
2689
|
+
placeholderColor: C2.textDim,
|
|
2690
|
+
color: C2.text,
|
|
2546
2691
|
fontSize: t.input,
|
|
2547
2692
|
value: this.broadcastText,
|
|
2548
2693
|
onChange: (val) => {
|
|
2549
2694
|
this.broadcastText = val;
|
|
2550
2695
|
}
|
|
2551
2696
|
}
|
|
2552
|
-
), /* @__PURE__ */
|
|
2697
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2553
2698
|
Button3,
|
|
2554
2699
|
{
|
|
2555
2700
|
uiTransform: { width: this.s(65), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2556
|
-
uiBackground: { color:
|
|
2701
|
+
uiBackground: { color: C2.orange },
|
|
2557
2702
|
value: "Send",
|
|
2558
2703
|
fontSize: t.button,
|
|
2559
|
-
color:
|
|
2704
|
+
color: C2.text,
|
|
2560
2705
|
onMouseDown: () => this.sendBroadcast()
|
|
2561
2706
|
}
|
|
2562
|
-
)), /* @__PURE__ */
|
|
2707
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "CHAOS MODE", color: C2.red }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", flexWrap: "wrap", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2563
2708
|
Button3,
|
|
2564
2709
|
{
|
|
2565
2710
|
uiTransform: { width: this.s(130), height: this.s(UI_DIMENSIONS.admin.buttonHeight), margin: 4 },
|
|
2566
|
-
uiBackground: { color:
|
|
2711
|
+
uiBackground: { color: C2.red },
|
|
2567
2712
|
value: "KICK ALL",
|
|
2568
2713
|
fontSize: t.button,
|
|
2569
|
-
color:
|
|
2714
|
+
color: C2.text,
|
|
2570
2715
|
onMouseDown: () => {
|
|
2571
2716
|
this.log("KICK ALL clicked");
|
|
2572
2717
|
this.config.onCommand?.("kickAll", {});
|
|
2573
2718
|
}
|
|
2574
2719
|
}
|
|
2575
|
-
)), /* @__PURE__ */
|
|
2576
|
-
|
|
2720
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "SCENE ADMINS", color: C2.purple }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, this.sceneAdmins.length === 0 && this.modStatus !== "loading" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "No scene admins", fontSize: t.labelSmall, color: C2.textDim }), this.sceneAdmins.map((wallet, i) => /* @__PURE__ */ ReactEcs5.createElement(
|
|
2721
|
+
UiEntity5,
|
|
2577
2722
|
{
|
|
2578
2723
|
key: `admin-${i}`,
|
|
2579
2724
|
uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 5 }, width: "100%" }
|
|
2580
2725
|
},
|
|
2581
|
-
/* @__PURE__ */
|
|
2582
|
-
|
|
2726
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2727
|
+
Label5,
|
|
2583
2728
|
{
|
|
2584
2729
|
value: `${wallet.slice(0, 6)}...${wallet.slice(-4)}`,
|
|
2585
2730
|
fontSize: t.label,
|
|
2586
|
-
color:
|
|
2731
|
+
color: C2.text,
|
|
2587
2732
|
uiTransform: { width: this.s(130) }
|
|
2588
2733
|
}
|
|
2589
2734
|
),
|
|
2590
|
-
/* @__PURE__ */
|
|
2735
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2591
2736
|
Button3,
|
|
2592
2737
|
{
|
|
2593
2738
|
uiTransform: { width: this.s(70), height: this.s(28), margin: { left: 8 } },
|
|
2594
|
-
uiBackground: { color:
|
|
2739
|
+
uiBackground: { color: C2.btn },
|
|
2595
2740
|
value: "Remove",
|
|
2596
2741
|
fontSize: t.buttonSmall,
|
|
2597
|
-
color:
|
|
2742
|
+
color: C2.text,
|
|
2598
2743
|
onMouseDown: () => this.removeSceneAdmin(wallet)
|
|
2599
2744
|
}
|
|
2600
2745
|
)
|
|
2601
|
-
))), /* @__PURE__ */
|
|
2746
|
+
))), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 14 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2602
2747
|
Input4,
|
|
2603
2748
|
{
|
|
2604
2749
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2605
2750
|
uiBackground: { color: Color45.create(0.15, 0.15, 0.2, 1) },
|
|
2606
2751
|
placeholder: "0x... add admin",
|
|
2607
|
-
placeholderColor:
|
|
2608
|
-
color:
|
|
2752
|
+
placeholderColor: C2.textDim,
|
|
2753
|
+
color: C2.text,
|
|
2609
2754
|
fontSize: t.input,
|
|
2610
2755
|
value: this.newAdminWallet,
|
|
2611
2756
|
onChange: (val) => {
|
|
2612
2757
|
this.newAdminWallet = val;
|
|
2613
2758
|
}
|
|
2614
2759
|
}
|
|
2615
|
-
), /* @__PURE__ */
|
|
2760
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2616
2761
|
Button3,
|
|
2617
2762
|
{
|
|
2618
2763
|
uiTransform: { width: this.s(60), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2619
|
-
uiBackground: { color:
|
|
2764
|
+
uiBackground: { color: C2.purple },
|
|
2620
2765
|
value: "Add",
|
|
2621
2766
|
fontSize: t.button,
|
|
2622
|
-
color:
|
|
2767
|
+
color: C2.text,
|
|
2623
2768
|
onMouseDown: () => {
|
|
2624
2769
|
if (this.newAdminWallet) this.addSceneAdmin(this.newAdminWallet);
|
|
2625
2770
|
}
|
|
2626
2771
|
}
|
|
2627
|
-
)), /* @__PURE__ */
|
|
2628
|
-
|
|
2772
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(this.SectionHead, { label: "BANNED WALLETS", color: C2.red }), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "column", margin: { bottom: 6 } } }, this.bannedWallets.length === 0 && this.modStatus !== "loading" && /* @__PURE__ */ ReactEcs5.createElement(Label5, { value: "No banned wallets", fontSize: t.labelSmall, color: C2.textDim }), this.bannedWallets.map((wallet, i) => /* @__PURE__ */ ReactEcs5.createElement(
|
|
2773
|
+
UiEntity5,
|
|
2629
2774
|
{
|
|
2630
2775
|
key: `ban-${i}`,
|
|
2631
2776
|
uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 5 }, width: "100%" }
|
|
2632
2777
|
},
|
|
2633
|
-
/* @__PURE__ */
|
|
2634
|
-
|
|
2778
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2779
|
+
Label5,
|
|
2635
2780
|
{
|
|
2636
2781
|
value: `${wallet.slice(0, 6)}...${wallet.slice(-4)}`,
|
|
2637
2782
|
fontSize: t.label,
|
|
2638
|
-
color:
|
|
2783
|
+
color: C2.red,
|
|
2639
2784
|
uiTransform: { width: this.s(130) }
|
|
2640
2785
|
}
|
|
2641
2786
|
),
|
|
2642
|
-
/* @__PURE__ */
|
|
2787
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2643
2788
|
Button3,
|
|
2644
2789
|
{
|
|
2645
2790
|
uiTransform: { width: this.s(70), height: this.s(28), margin: { left: 8 } },
|
|
2646
|
-
uiBackground: { color:
|
|
2791
|
+
uiBackground: { color: C2.green },
|
|
2647
2792
|
value: "Unban",
|
|
2648
2793
|
fontSize: t.buttonSmall,
|
|
2649
|
-
color:
|
|
2794
|
+
color: C2.text,
|
|
2650
2795
|
onMouseDown: () => this.unbanWallet(wallet)
|
|
2651
2796
|
}
|
|
2652
2797
|
)
|
|
2653
|
-
))), /* @__PURE__ */
|
|
2798
|
+
))), /* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { flexDirection: "row", alignItems: "center", margin: { bottom: 10 } } }, /* @__PURE__ */ ReactEcs5.createElement(
|
|
2654
2799
|
Input4,
|
|
2655
2800
|
{
|
|
2656
2801
|
uiTransform: { width: this.s(230), height: this.s(UI_DIMENSIONS.admin.inputHeight) },
|
|
2657
2802
|
uiBackground: { color: Color45.create(0.15, 0.15, 0.2, 1) },
|
|
2658
2803
|
placeholder: "0x... ban wallet",
|
|
2659
|
-
placeholderColor:
|
|
2660
|
-
color:
|
|
2804
|
+
placeholderColor: C2.textDim,
|
|
2805
|
+
color: C2.text,
|
|
2661
2806
|
fontSize: t.input,
|
|
2662
2807
|
value: this.newBanWallet,
|
|
2663
2808
|
onChange: (val) => {
|
|
2664
2809
|
this.newBanWallet = val;
|
|
2665
2810
|
}
|
|
2666
2811
|
}
|
|
2667
|
-
), /* @__PURE__ */
|
|
2812
|
+
), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2668
2813
|
Button3,
|
|
2669
2814
|
{
|
|
2670
2815
|
uiTransform: { width: this.s(60), height: this.s(UI_DIMENSIONS.admin.inputHeight), margin: { left: 8 } },
|
|
2671
|
-
uiBackground: { color:
|
|
2816
|
+
uiBackground: { color: C2.red },
|
|
2672
2817
|
value: "Ban",
|
|
2673
2818
|
fontSize: t.button,
|
|
2674
|
-
color:
|
|
2819
|
+
color: C2.text,
|
|
2675
2820
|
onMouseDown: () => {
|
|
2676
2821
|
if (this.newBanWallet) this.banWallet(this.newBanWallet);
|
|
2677
2822
|
}
|
|
2678
2823
|
}
|
|
2679
|
-
)), /* @__PURE__ */
|
|
2824
|
+
)), /* @__PURE__ */ ReactEcs5.createElement(
|
|
2680
2825
|
Button3,
|
|
2681
2826
|
{
|
|
2682
2827
|
uiTransform: { height: this.s(24) },
|
|
2683
2828
|
uiBackground: { color: Color45.create(0, 0, 0, 0) },
|
|
2684
2829
|
value: "Manage at thestatic.tv",
|
|
2685
2830
|
fontSize: t.labelSmall,
|
|
2686
|
-
color:
|
|
2831
|
+
color: C2.cyan,
|
|
2687
2832
|
onMouseDown: () => openExternalUrl3({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2688
2833
|
}
|
|
2689
2834
|
));
|
|
2690
2835
|
};
|
|
2691
2836
|
/**
|
|
2692
2837
|
* Get the React-ECS component for the admin panel
|
|
2838
|
+
* Always renders NotificationBanner (for broadcasts), admin panel only for admins
|
|
2693
2839
|
*/
|
|
2694
2840
|
this.getComponent = () => {
|
|
2695
|
-
if (!this.isAdmin)
|
|
2841
|
+
if (!this.isAdmin) {
|
|
2842
|
+
return /* @__PURE__ */ ReactEcs5.createElement(NotificationBanner, null);
|
|
2843
|
+
}
|
|
2696
2844
|
const t = this.theme;
|
|
2697
2845
|
const tabs = [];
|
|
2698
2846
|
if (this.config.sceneTabs && this.config.sceneTabs.length > 0) {
|
|
@@ -2707,8 +2855,8 @@ var AdminPanelUIModule = class {
|
|
|
2707
2855
|
if (!tabs.find((tab) => tab.id === this.activeTab) && tabs.length > 0) {
|
|
2708
2856
|
this.activeTab = tabs[0].id;
|
|
2709
2857
|
}
|
|
2710
|
-
return /* @__PURE__ */
|
|
2711
|
-
|
|
2858
|
+
return /* @__PURE__ */ ReactEcs5.createElement(
|
|
2859
|
+
UiEntity5,
|
|
2712
2860
|
{
|
|
2713
2861
|
uiTransform: {
|
|
2714
2862
|
width: "100%",
|
|
@@ -2716,28 +2864,29 @@ var AdminPanelUIModule = class {
|
|
|
2716
2864
|
positionType: "absolute"
|
|
2717
2865
|
}
|
|
2718
2866
|
},
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
|
|
2867
|
+
/* @__PURE__ */ ReactEcs5.createElement(NotificationBanner, null),
|
|
2868
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2869
|
+
UiEntity5,
|
|
2721
2870
|
{
|
|
2722
2871
|
uiTransform: {
|
|
2723
2872
|
position: { right: 20 + this.s(100) + 10 + this.s(100) + 10, bottom: 10 },
|
|
2724
2873
|
positionType: "absolute"
|
|
2725
2874
|
}
|
|
2726
2875
|
},
|
|
2727
|
-
/* @__PURE__ */
|
|
2876
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2728
2877
|
Button3,
|
|
2729
2878
|
{
|
|
2730
2879
|
uiTransform: { width: this.s(100), height: this.s(45) },
|
|
2731
|
-
uiBackground: { color: this.panelOpen ?
|
|
2880
|
+
uiBackground: { color: this.panelOpen ? C2.btn : C2.header },
|
|
2732
2881
|
value: this.panelOpen ? "CLOSE" : "ADMIN",
|
|
2733
2882
|
fontSize: this.s(14),
|
|
2734
|
-
color:
|
|
2883
|
+
color: C2.text,
|
|
2735
2884
|
onMouseDown: () => this.toggle()
|
|
2736
2885
|
}
|
|
2737
2886
|
)
|
|
2738
2887
|
),
|
|
2739
|
-
this.panelOpen && /* @__PURE__ */
|
|
2740
|
-
|
|
2888
|
+
this.panelOpen && /* @__PURE__ */ ReactEcs5.createElement(
|
|
2889
|
+
UiEntity5,
|
|
2741
2890
|
{
|
|
2742
2891
|
key: `admin-panel-${this.client.uiScale}`,
|
|
2743
2892
|
uiTransform: {
|
|
@@ -2748,10 +2897,10 @@ var AdminPanelUIModule = class {
|
|
|
2748
2897
|
positionType: "absolute",
|
|
2749
2898
|
flexDirection: "column"
|
|
2750
2899
|
},
|
|
2751
|
-
uiBackground: { color:
|
|
2900
|
+
uiBackground: { color: C2.bg }
|
|
2752
2901
|
},
|
|
2753
|
-
/* @__PURE__ */
|
|
2754
|
-
|
|
2902
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2903
|
+
UiEntity5,
|
|
2755
2904
|
{
|
|
2756
2905
|
uiTransform: {
|
|
2757
2906
|
width: "100%",
|
|
@@ -2761,10 +2910,10 @@ var AdminPanelUIModule = class {
|
|
|
2761
2910
|
flexDirection: "row",
|
|
2762
2911
|
padding: { left: 12, right: 8 }
|
|
2763
2912
|
},
|
|
2764
|
-
uiBackground: { color:
|
|
2913
|
+
uiBackground: { color: C2.header }
|
|
2765
2914
|
},
|
|
2766
|
-
/* @__PURE__ */
|
|
2767
|
-
/* @__PURE__ */
|
|
2915
|
+
/* @__PURE__ */ ReactEcs5.createElement(Label5, { value: this.config.title || "ADMIN PANEL", fontSize: t.header, color: C2.text }),
|
|
2916
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2768
2917
|
Button3,
|
|
2769
2918
|
{
|
|
2770
2919
|
uiTransform: { width: this.s(28), height: this.s(28) },
|
|
@@ -2776,9 +2925,9 @@ var AdminPanelUIModule = class {
|
|
|
2776
2925
|
}
|
|
2777
2926
|
)
|
|
2778
2927
|
),
|
|
2779
|
-
/* @__PURE__ */
|
|
2780
|
-
/* @__PURE__ */
|
|
2781
|
-
|
|
2928
|
+
/* @__PURE__ */ ReactEcs5.createElement(UiEntity5, { uiTransform: { width: "100%", height: this.s(UI_DIMENSIONS.admin.tabHeight), flexDirection: "row" } }, tabs.map((tab) => /* @__PURE__ */ ReactEcs5.createElement(this.TabBtn, { label: tab.label, tab: tab.id }))),
|
|
2929
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2930
|
+
UiEntity5,
|
|
2782
2931
|
{
|
|
2783
2932
|
uiTransform: {
|
|
2784
2933
|
width: "100%",
|
|
@@ -2787,12 +2936,12 @@ var AdminPanelUIModule = class {
|
|
|
2787
2936
|
flexDirection: "column"
|
|
2788
2937
|
}
|
|
2789
2938
|
},
|
|
2790
|
-
this.activeTab === "video" && /* @__PURE__ */
|
|
2791
|
-
this.activeTab === "mod" && this.isOwner && /* @__PURE__ */
|
|
2939
|
+
this.activeTab === "video" && /* @__PURE__ */ ReactEcs5.createElement(this.VideoTab, null),
|
|
2940
|
+
this.activeTab === "mod" && this.isOwner && /* @__PURE__ */ ReactEcs5.createElement(this.ModTab, null),
|
|
2792
2941
|
this.config.sceneTabs?.map((tab) => this.activeTab === tab.id && tab.render())
|
|
2793
2942
|
),
|
|
2794
|
-
/* @__PURE__ */
|
|
2795
|
-
|
|
2943
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2944
|
+
UiEntity5,
|
|
2796
2945
|
{
|
|
2797
2946
|
uiTransform: {
|
|
2798
2947
|
width: "100%",
|
|
@@ -2800,16 +2949,16 @@ var AdminPanelUIModule = class {
|
|
|
2800
2949
|
justifyContent: "center",
|
|
2801
2950
|
alignItems: "center"
|
|
2802
2951
|
},
|
|
2803
|
-
uiBackground: { color:
|
|
2952
|
+
uiBackground: { color: C2.section }
|
|
2804
2953
|
},
|
|
2805
|
-
/* @__PURE__ */
|
|
2954
|
+
/* @__PURE__ */ ReactEcs5.createElement(
|
|
2806
2955
|
Button3,
|
|
2807
2956
|
{
|
|
2808
2957
|
uiTransform: { height: this.s(24) },
|
|
2809
2958
|
uiBackground: { color: Color45.create(0, 0, 0, 0) },
|
|
2810
2959
|
value: `thestatic.tv/scene/${this.config.sceneId}`,
|
|
2811
2960
|
fontSize: t.labelSmall,
|
|
2812
|
-
color:
|
|
2961
|
+
color: C2.cyan,
|
|
2813
2962
|
onMouseDown: () => openExternalUrl3({ url: this.config.footerLink || `https://thestatic.tv/scene/${this.config.sceneId}` })
|
|
2814
2963
|
}
|
|
2815
2964
|
)
|
|
@@ -2832,7 +2981,7 @@ var AdminPanelUIModule = class {
|
|
|
2832
2981
|
};
|
|
2833
2982
|
this.baseUrl = client.getBaseUrl();
|
|
2834
2983
|
if (config.headerColor) {
|
|
2835
|
-
|
|
2984
|
+
C2.header = Color45.create(
|
|
2836
2985
|
config.headerColor.r,
|
|
2837
2986
|
config.headerColor.g,
|
|
2838
2987
|
config.headerColor.b,
|
|
@@ -2860,6 +3009,7 @@ var AdminPanelUIModule = class {
|
|
|
2860
3009
|
await this.checkAdminStatus();
|
|
2861
3010
|
await this.fetchVideoState();
|
|
2862
3011
|
this.autoPlayDefault();
|
|
3012
|
+
this.startCommandPolling();
|
|
2863
3013
|
this.log("Initialized");
|
|
2864
3014
|
}
|
|
2865
3015
|
/**
|
|
@@ -2965,6 +3115,61 @@ var AdminPanelUIModule = class {
|
|
|
2965
3115
|
this.log("Stream polling stopped");
|
|
2966
3116
|
}
|
|
2967
3117
|
}
|
|
3118
|
+
// --- Command Polling (receives broadcasts from website) ---
|
|
3119
|
+
startCommandPolling() {
|
|
3120
|
+
if (this.commandPollIntervalId !== null) return;
|
|
3121
|
+
this.commandPollIntervalId = dclSetInterval(() => {
|
|
3122
|
+
this.pollCommands();
|
|
3123
|
+
}, 5e3);
|
|
3124
|
+
this.pollCommands();
|
|
3125
|
+
this.log("Command polling started");
|
|
3126
|
+
}
|
|
3127
|
+
stopCommandPolling() {
|
|
3128
|
+
if (this.commandPollIntervalId !== null) {
|
|
3129
|
+
dclClearInterval(this.commandPollIntervalId);
|
|
3130
|
+
this.commandPollIntervalId = null;
|
|
3131
|
+
this.log("Command polling stopped");
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3134
|
+
async pollCommands() {
|
|
3135
|
+
try {
|
|
3136
|
+
const res = await fetch(`${this.baseUrl}/scene/${this.config.sceneId}/commands`);
|
|
3137
|
+
if (!res.ok) return;
|
|
3138
|
+
const data = await res.json();
|
|
3139
|
+
const commands = data.commands || [];
|
|
3140
|
+
for (const cmd of commands) {
|
|
3141
|
+
if (cmd.timestamp <= this.lastCommandTimestamp) continue;
|
|
3142
|
+
this.lastCommandTimestamp = cmd.timestamp;
|
|
3143
|
+
if (cmd.type === "broadcast" && cmd.payload?.text) {
|
|
3144
|
+
const msg = cmd.payload.from ? `${cmd.payload.from}: ${cmd.payload.text}` : cmd.payload.text;
|
|
3145
|
+
this.log("Received broadcast:", msg);
|
|
3146
|
+
this.config.onBroadcast?.(msg);
|
|
3147
|
+
} else if (cmd.type === "clearBroadcast") {
|
|
3148
|
+
this.log("Received clearBroadcast");
|
|
3149
|
+
hideNotification();
|
|
3150
|
+
} else if ((cmd.type === "videoPlay" || cmd.type === "videoSetUrl") && cmd.payload?.url) {
|
|
3151
|
+
this.log("Received video play:", cmd.type, cmd.payload.url);
|
|
3152
|
+
this.config.onVideoPlay?.(cmd.payload.url);
|
|
3153
|
+
} else if (cmd.type === "videoStop" || cmd.type === "videoClear") {
|
|
3154
|
+
this.log("Received video stop/clear:", cmd.type);
|
|
3155
|
+
this.config.onVideoStop?.();
|
|
3156
|
+
} else if (cmd.type === "videoPlaySlot" && cmd.payload?.slot) {
|
|
3157
|
+
const slotId = cmd.payload.slot;
|
|
3158
|
+
if (cmd.payload.url) {
|
|
3159
|
+
this.log("Received videoPlaySlot with URL:", slotId, cmd.payload.url);
|
|
3160
|
+
this.config.onVideoPlay?.(cmd.payload.url);
|
|
3161
|
+
} else {
|
|
3162
|
+
this.log("Received videoPlaySlot:", slotId);
|
|
3163
|
+
this.playSlot(slotId);
|
|
3164
|
+
}
|
|
3165
|
+
} else if (this.config.onCommand) {
|
|
3166
|
+
this.log("Received command:", cmd.type, cmd.payload);
|
|
3167
|
+
this.config.onCommand(cmd.type, cmd.payload);
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
} catch (err) {
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
2968
3173
|
// --- Stream API Calls ---
|
|
2969
3174
|
async fetchStreamData() {
|
|
2970
3175
|
if (this.streamFetched || !this.playerWallet) return;
|
|
@@ -3396,87 +3601,6 @@ var AdminPanelUIModule = class {
|
|
|
3396
3601
|
}
|
|
3397
3602
|
};
|
|
3398
3603
|
|
|
3399
|
-
// src/ui/ui-renderer.tsx
|
|
3400
|
-
import ReactEcs5, { ReactEcsRenderer, UiEntity as UiEntity5, Label as Label5 } from "@dcl/sdk/react-ecs";
|
|
3401
|
-
import { Color4 as Color46 } from "@dcl/sdk/math";
|
|
3402
|
-
import { engine as engine2 } from "@dcl/sdk/ecs";
|
|
3403
|
-
var notificationText = "";
|
|
3404
|
-
var notificationVisible = false;
|
|
3405
|
-
var notificationEndTime = 0;
|
|
3406
|
-
var notificationInitialized = false;
|
|
3407
|
-
function showNotification(message, durationMs = 5e3) {
|
|
3408
|
-
notificationText = message;
|
|
3409
|
-
notificationVisible = true;
|
|
3410
|
-
notificationEndTime = Date.now() + durationMs;
|
|
3411
|
-
}
|
|
3412
|
-
function initNotificationSystem() {
|
|
3413
|
-
if (notificationInitialized) return;
|
|
3414
|
-
notificationInitialized = true;
|
|
3415
|
-
engine2.addSystem(() => {
|
|
3416
|
-
if (notificationVisible && Date.now() > notificationEndTime) {
|
|
3417
|
-
notificationVisible = false;
|
|
3418
|
-
}
|
|
3419
|
-
});
|
|
3420
|
-
}
|
|
3421
|
-
function NotificationBanner() {
|
|
3422
|
-
if (!notificationVisible) return null;
|
|
3423
|
-
return /* @__PURE__ */ ReactEcs5.createElement(
|
|
3424
|
-
UiEntity5,
|
|
3425
|
-
{
|
|
3426
|
-
uiTransform: {
|
|
3427
|
-
positionType: "absolute",
|
|
3428
|
-
position: { top: 80 },
|
|
3429
|
-
width: 500,
|
|
3430
|
-
height: 60,
|
|
3431
|
-
padding: 16,
|
|
3432
|
-
alignSelf: "center",
|
|
3433
|
-
justifyContent: "center",
|
|
3434
|
-
alignItems: "center"
|
|
3435
|
-
},
|
|
3436
|
-
uiBackground: { color: Color46.create(0.1, 0.1, 0.15, 0.95) }
|
|
3437
|
-
},
|
|
3438
|
-
/* @__PURE__ */ ReactEcs5.createElement(
|
|
3439
|
-
Label5,
|
|
3440
|
-
{
|
|
3441
|
-
value: notificationText,
|
|
3442
|
-
fontSize: 18,
|
|
3443
|
-
color: Color46.create(0, 1, 1, 1),
|
|
3444
|
-
textAlign: "middle-center"
|
|
3445
|
-
}
|
|
3446
|
-
)
|
|
3447
|
-
);
|
|
3448
|
-
}
|
|
3449
|
-
function createStaticUI(client) {
|
|
3450
|
-
initNotificationSystem();
|
|
3451
|
-
return function StaticUI() {
|
|
3452
|
-
const currentScale = client.uiScale;
|
|
3453
|
-
const guideComponent = client.guideUI?.getComponent() ?? null;
|
|
3454
|
-
const chatComponent = client.chatUI?.getComponent() ?? null;
|
|
3455
|
-
const adminComponent = client.adminPanel?.getComponent() ?? null;
|
|
3456
|
-
return /* @__PURE__ */ ReactEcs5.createElement(
|
|
3457
|
-
UiEntity5,
|
|
3458
|
-
{
|
|
3459
|
-
key: `static-ui-root-${currentScale}`,
|
|
3460
|
-
uiTransform: {
|
|
3461
|
-
width: "100%",
|
|
3462
|
-
height: "100%",
|
|
3463
|
-
positionType: "absolute",
|
|
3464
|
-
flexDirection: "column",
|
|
3465
|
-
alignItems: "center"
|
|
3466
|
-
}
|
|
3467
|
-
},
|
|
3468
|
-
/* @__PURE__ */ ReactEcs5.createElement(NotificationBanner, null),
|
|
3469
|
-
guideComponent,
|
|
3470
|
-
chatComponent,
|
|
3471
|
-
adminComponent
|
|
3472
|
-
);
|
|
3473
|
-
};
|
|
3474
|
-
}
|
|
3475
|
-
function setupStaticUI(client) {
|
|
3476
|
-
const StaticUI = createStaticUI(client);
|
|
3477
|
-
ReactEcsRenderer.setUiRenderer(StaticUI);
|
|
3478
|
-
}
|
|
3479
|
-
|
|
3480
3604
|
// src/StaticTVClient.ts
|
|
3481
3605
|
import { VideoPlayer, videoEventsSystem, VideoState } from "@dcl/sdk/ecs";
|
|
3482
3606
|
import * as utils from "@dcl-sdk/utils";
|
|
@@ -3757,10 +3881,13 @@ var StaticTVClient = class {
|
|
|
3757
3881
|
*/
|
|
3758
3882
|
stopVideo() {
|
|
3759
3883
|
const screen = this.config.videoScreen;
|
|
3884
|
+
this._pendingVideoData = null;
|
|
3885
|
+
this._streamVerified = false;
|
|
3886
|
+
this._clearVerificationTimeout();
|
|
3887
|
+
if (this.guideUI) {
|
|
3888
|
+
this.guideUI.currentVideoId = null;
|
|
3889
|
+
}
|
|
3760
3890
|
if (screen !== void 0) {
|
|
3761
|
-
if (this.guideUI) {
|
|
3762
|
-
this.guideUI.currentVideoId = null;
|
|
3763
|
-
}
|
|
3764
3891
|
const fallbackUrl = this.config.fallbackVideoUrl;
|
|
3765
3892
|
const fallbackDisabled = fallbackUrl === "";
|
|
3766
3893
|
if (fallbackDisabled) {
|
|
@@ -3916,20 +4043,60 @@ var StaticTVClient = class {
|
|
|
3916
4043
|
}
|
|
3917
4044
|
/**
|
|
3918
4045
|
* Play video with stream verification for live content
|
|
4046
|
+
* Works with both videoScreen (SDK-managed) and onVideoPlay (user-managed) modes.
|
|
3919
4047
|
* @internal
|
|
3920
4048
|
*/
|
|
3921
4049
|
_playVideoWithVerification(video, isLiveStream) {
|
|
3922
4050
|
const screen = this.config.videoScreen;
|
|
4051
|
+
const hasCallback = this.config.onVideoPlay !== void 0;
|
|
4052
|
+
this.log(`Playing video: ${video.src} (live: ${isLiveStream}, screen: ${screen !== void 0}, callback: ${hasCallback})`);
|
|
4053
|
+
this._currentVideoUrl = video.src;
|
|
4054
|
+
this._clearVerificationTimeout();
|
|
4055
|
+
this._streamVerified = false;
|
|
3923
4056
|
if (screen !== void 0) {
|
|
3924
|
-
this.log(`Playing video: ${video.src} (live: ${isLiveStream})`);
|
|
3925
|
-
this._currentVideoUrl = video.src;
|
|
3926
4057
|
this._playVideoInternal(video.src, false, isLiveStream);
|
|
3927
|
-
if (this.guideUI) {
|
|
3928
|
-
this.guideUI.currentVideoId = video.id;
|
|
3929
|
-
}
|
|
3930
4058
|
}
|
|
3931
|
-
if (
|
|
4059
|
+
if (hasCallback) {
|
|
3932
4060
|
this.config.onVideoPlay(video.src);
|
|
4061
|
+
if (isLiveStream) {
|
|
4062
|
+
this._startCallbackVerification(video);
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
if (this.guideUI) {
|
|
4066
|
+
this.guideUI.currentVideoId = video.id;
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
4069
|
+
/**
|
|
4070
|
+
* Start stream verification for callback-based video playback
|
|
4071
|
+
* Shows CONNECTING state and triggers fallback if verification times out
|
|
4072
|
+
* @internal
|
|
4073
|
+
*/
|
|
4074
|
+
_startCallbackVerification(video) {
|
|
4075
|
+
this.showNotification(`Connecting to ${video.name}...`, 6e3);
|
|
4076
|
+
this._verificationTimeoutId = utils.timers.setTimeout(() => {
|
|
4077
|
+
if (!this._streamVerified && this._pendingVideoData) {
|
|
4078
|
+
this.log(`Stream verification timeout (callback mode): ${video.name}`);
|
|
4079
|
+
this._handleStreamOffline();
|
|
4080
|
+
}
|
|
4081
|
+
}, 5e3);
|
|
4082
|
+
}
|
|
4083
|
+
/**
|
|
4084
|
+
* Call this to confirm that a video stream is playing successfully.
|
|
4085
|
+
* Use this when you're managing video playback yourself (onVideoPlay callback).
|
|
4086
|
+
*
|
|
4087
|
+
* @example
|
|
4088
|
+
* ```typescript
|
|
4089
|
+
* // In your video player's onReady or similar event:
|
|
4090
|
+
* videoPlayer.events.on('playing', () => {
|
|
4091
|
+
* staticTV.confirmVideoPlaying()
|
|
4092
|
+
* })
|
|
4093
|
+
* ```
|
|
4094
|
+
*/
|
|
4095
|
+
confirmVideoPlaying() {
|
|
4096
|
+
if (this._pendingVideoData && !this._streamVerified) {
|
|
4097
|
+
this._streamVerified = true;
|
|
4098
|
+
this._clearVerificationTimeout();
|
|
4099
|
+
this.log(`Stream confirmed playing: ${this._pendingVideoData.name}`);
|
|
3933
4100
|
}
|
|
3934
4101
|
}
|
|
3935
4102
|
/**
|
|
@@ -4203,11 +4370,13 @@ export {
|
|
|
4203
4370
|
InteractionsModule,
|
|
4204
4371
|
KEY_TYPE_CHANNEL,
|
|
4205
4372
|
KEY_TYPE_SCENE,
|
|
4373
|
+
NotificationBanner,
|
|
4206
4374
|
SessionModule,
|
|
4207
4375
|
StaticTVClient,
|
|
4208
4376
|
fetchUserData,
|
|
4209
4377
|
getPlayerDisplayName,
|
|
4210
4378
|
getPlayerWallet,
|
|
4379
|
+
hideNotification,
|
|
4211
4380
|
setupStaticUI,
|
|
4212
4381
|
showNotification
|
|
4213
4382
|
};
|