@thestatic-tv/dcl-sdk 2.3.0-beta.1 → 2.3.0-beta.3
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 +111 -24
- package/dist/index.d.ts +111 -24
- package/dist/index.js +156 -36
- package/dist/index.mjs +156 -36
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Entity as Entity$1 } from '@dcl/sdk/ecs';
|
|
1
2
|
import ReactEcs from '@dcl/sdk/react-ecs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -19,12 +20,57 @@ interface PlayerData {
|
|
|
19
20
|
/** Player's display name */
|
|
20
21
|
name?: string;
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
type Entity = Entity$1;
|
|
22
25
|
/**
|
|
23
26
|
* Configuration options for StaticTVClient
|
|
24
27
|
*/
|
|
25
28
|
interface StaticTVConfig {
|
|
26
29
|
/** Your channel's API key from thestatic.tv studio */
|
|
27
30
|
apiKey: string;
|
|
31
|
+
/**
|
|
32
|
+
* Video screen entity - SDK automatically manages VideoPlayer on this entity.
|
|
33
|
+
* When user selects a video from Guide or Admin plays a URL, it plays here.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const screen = engine.addEntity()
|
|
38
|
+
* Transform.create(screen, { position: Vector3.create(8, 3, 14), scale: Vector3.create(8, 4.5, 0.1) })
|
|
39
|
+
* MeshRenderer.setPlane(screen)
|
|
40
|
+
*
|
|
41
|
+
* const staticTV = new StaticTVClient({
|
|
42
|
+
* apiKey: 'dcls_...',
|
|
43
|
+
* videoScreen: screen // SDK handles all video playback!
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
videoScreen?: Entity;
|
|
48
|
+
/**
|
|
49
|
+
* Scene ID for Admin Panel API calls.
|
|
50
|
+
* Optional - defaults to API key ID if not provided.
|
|
51
|
+
*/
|
|
52
|
+
sceneId?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Callback when video URL should be played (Pro tier).
|
|
55
|
+
* If videoScreen is set, this is called AFTER SDK plays the video.
|
|
56
|
+
* Use for custom logic like logging, UI updates, etc.
|
|
57
|
+
*/
|
|
58
|
+
onVideoPlay?: (url: string) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Callback when video playback should stop (Pro tier).
|
|
61
|
+
* If videoScreen is set, this is called AFTER SDK stops the video.
|
|
62
|
+
*/
|
|
63
|
+
onVideoStop?: () => void;
|
|
64
|
+
/**
|
|
65
|
+
* Callback for broadcast messages (Pro tier).
|
|
66
|
+
* Default: shows notification via staticTV.showNotification()
|
|
67
|
+
*/
|
|
68
|
+
onBroadcast?: (text: string) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Command handler for scene-specific commands (Pro tier).
|
|
71
|
+
* Called when admin triggers a command from the panel.
|
|
72
|
+
*/
|
|
73
|
+
onCommand?: (type: string, payload?: Record<string, unknown>) => void;
|
|
28
74
|
/** Automatically start session tracking on init (default: true) */
|
|
29
75
|
autoStartSession?: boolean;
|
|
30
76
|
/** Interval for session heartbeats in ms (default: 30000) */
|
|
@@ -47,11 +93,11 @@ interface StaticTVConfig {
|
|
|
47
93
|
*/
|
|
48
94
|
player?: PlayerData;
|
|
49
95
|
/**
|
|
50
|
-
* Guide UI configuration
|
|
96
|
+
* Guide UI configuration
|
|
51
97
|
*/
|
|
52
98
|
guideUI?: GuideUIConfig;
|
|
53
99
|
/**
|
|
54
|
-
* Chat UI configuration
|
|
100
|
+
* Chat UI configuration
|
|
55
101
|
*/
|
|
56
102
|
chatUI?: ChatUIConfig;
|
|
57
103
|
}
|
|
@@ -840,16 +886,28 @@ declare class StaticTVClient {
|
|
|
840
886
|
*
|
|
841
887
|
* @param config Configuration options
|
|
842
888
|
*
|
|
843
|
-
* @example
|
|
889
|
+
* @example Free tier (session tracking only):
|
|
844
890
|
* ```typescript
|
|
845
|
-
*
|
|
891
|
+
* const staticTV = new StaticTVClient({
|
|
892
|
+
* apiKey: 'dcls_your_key_here'
|
|
893
|
+
* })
|
|
894
|
+
* ```
|
|
895
|
+
*
|
|
896
|
+
* @example Standard/Pro with video screen (SDK handles playback):
|
|
897
|
+
* ```typescript
|
|
898
|
+
* // Create your video screen
|
|
899
|
+
* const screen = engine.addEntity()
|
|
900
|
+
* Transform.create(screen, { position: Vector3.create(8, 3, 14), scale: Vector3.create(8, 4.5, 0.1) })
|
|
901
|
+
* MeshRenderer.setPlane(screen)
|
|
902
|
+
*
|
|
903
|
+
* // SDK handles everything - Guide selection + Pro admin controls just work
|
|
904
|
+
* const staticTV = new StaticTVClient({
|
|
905
|
+
* apiKey: 'dcls_your_key_here',
|
|
906
|
+
* videoScreen: screen // That's it! SDK manages video playback
|
|
907
|
+
* })
|
|
846
908
|
*
|
|
847
909
|
* export function main() {
|
|
848
|
-
*
|
|
849
|
-
* staticTV = new StaticTVClient({
|
|
850
|
-
* apiKey: 'dcls_your_key_here'
|
|
851
|
-
* })
|
|
852
|
-
* // Session tracking starts automatically!
|
|
910
|
+
* staticTV.setupUI()
|
|
853
911
|
* }
|
|
854
912
|
* ```
|
|
855
913
|
*/
|
|
@@ -900,6 +958,33 @@ declare class StaticTVClient {
|
|
|
900
958
|
* @internal
|
|
901
959
|
*/
|
|
902
960
|
getConfig(): StaticTVConfig;
|
|
961
|
+
private _currentVideoUrl;
|
|
962
|
+
/**
|
|
963
|
+
* Play a video on the configured videoScreen entity.
|
|
964
|
+
* Called by Guide UI and Admin Panel.
|
|
965
|
+
*
|
|
966
|
+
* @param url Video URL to play
|
|
967
|
+
*/
|
|
968
|
+
playVideo(url: string): void;
|
|
969
|
+
/**
|
|
970
|
+
* Stop video playback on the configured videoScreen entity.
|
|
971
|
+
* Called by Admin Panel.
|
|
972
|
+
*/
|
|
973
|
+
stopVideo(): void;
|
|
974
|
+
/**
|
|
975
|
+
* Get the currently playing video URL
|
|
976
|
+
*/
|
|
977
|
+
get currentVideoUrl(): string;
|
|
978
|
+
/**
|
|
979
|
+
* Internal handler for Guide video selection
|
|
980
|
+
* @internal
|
|
981
|
+
*/
|
|
982
|
+
_handleGuideVideoSelect(video: GuideVideo): void;
|
|
983
|
+
/**
|
|
984
|
+
* Internal handler for broadcast messages
|
|
985
|
+
* @internal
|
|
986
|
+
*/
|
|
987
|
+
_handleBroadcast(text: string): void;
|
|
903
988
|
/**
|
|
904
989
|
* Initialize standard feature modules (guide, heartbeat, interactions, UI)
|
|
905
990
|
* @internal
|
|
@@ -939,28 +1024,30 @@ declare class StaticTVClient {
|
|
|
939
1024
|
get sdkType(): 'lite' | 'full';
|
|
940
1025
|
/**
|
|
941
1026
|
* Configure Pro features (Admin Panel with Video + Mod tabs)
|
|
942
|
-
* Call this after creating the client to configure admin panel.
|
|
943
|
-
* The panel will auto-enable when server confirms Pro tier.
|
|
944
1027
|
*
|
|
945
|
-
*
|
|
1028
|
+
* **OPTIONAL**: If you set `videoScreen` in the constructor, you don't need
|
|
1029
|
+
* to call this method - the Admin Panel will auto-enable with sensible defaults.
|
|
946
1030
|
*
|
|
947
|
-
*
|
|
948
|
-
*
|
|
949
|
-
*
|
|
1031
|
+
* Use this method only if you need:
|
|
1032
|
+
* - Custom scene tab UI
|
|
1033
|
+
* - Custom panel title/styling
|
|
1034
|
+
* - Advanced command handlers
|
|
950
1035
|
*
|
|
951
|
-
*
|
|
952
|
-
*
|
|
953
|
-
*
|
|
954
|
-
*
|
|
1036
|
+
* @param config Admin panel configuration
|
|
1037
|
+
*
|
|
1038
|
+
* @example Using videoScreen (recommended - no enableProFeatures needed):
|
|
1039
|
+
* ```typescript
|
|
1040
|
+
* const staticTV = new StaticTVClient({
|
|
1041
|
+
* apiKey: 'dcls_...',
|
|
1042
|
+
* videoScreen: myScreen // Admin Panel auto-enabled for Pro tier!
|
|
955
1043
|
* })
|
|
1044
|
+
* ```
|
|
956
1045
|
*
|
|
957
|
-
*
|
|
1046
|
+
* @example Advanced: Custom scene tabs
|
|
1047
|
+
* ```typescript
|
|
958
1048
|
* staticTV.enableProFeatures({
|
|
959
|
-
* sceneId: 'my-scene', // optional - defaults to API key ID
|
|
960
1049
|
* title: 'MY SCENE ADMIN',
|
|
961
|
-
*
|
|
962
|
-
* onVideoStop: () => videoPlayer.stop(),
|
|
963
|
-
* onBroadcast: (text) => showNotification(text)
|
|
1050
|
+
* sceneTabs: [{ label: 'LIGHTS', id: 'lights', render: () => <LightsTab /> }]
|
|
964
1051
|
* })
|
|
965
1052
|
* ```
|
|
966
1053
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Entity as Entity$1 } from '@dcl/sdk/ecs';
|
|
1
2
|
import ReactEcs from '@dcl/sdk/react-ecs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -19,12 +20,57 @@ interface PlayerData {
|
|
|
19
20
|
/** Player's display name */
|
|
20
21
|
name?: string;
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
type Entity = Entity$1;
|
|
22
25
|
/**
|
|
23
26
|
* Configuration options for StaticTVClient
|
|
24
27
|
*/
|
|
25
28
|
interface StaticTVConfig {
|
|
26
29
|
/** Your channel's API key from thestatic.tv studio */
|
|
27
30
|
apiKey: string;
|
|
31
|
+
/**
|
|
32
|
+
* Video screen entity - SDK automatically manages VideoPlayer on this entity.
|
|
33
|
+
* When user selects a video from Guide or Admin plays a URL, it plays here.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const screen = engine.addEntity()
|
|
38
|
+
* Transform.create(screen, { position: Vector3.create(8, 3, 14), scale: Vector3.create(8, 4.5, 0.1) })
|
|
39
|
+
* MeshRenderer.setPlane(screen)
|
|
40
|
+
*
|
|
41
|
+
* const staticTV = new StaticTVClient({
|
|
42
|
+
* apiKey: 'dcls_...',
|
|
43
|
+
* videoScreen: screen // SDK handles all video playback!
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
videoScreen?: Entity;
|
|
48
|
+
/**
|
|
49
|
+
* Scene ID for Admin Panel API calls.
|
|
50
|
+
* Optional - defaults to API key ID if not provided.
|
|
51
|
+
*/
|
|
52
|
+
sceneId?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Callback when video URL should be played (Pro tier).
|
|
55
|
+
* If videoScreen is set, this is called AFTER SDK plays the video.
|
|
56
|
+
* Use for custom logic like logging, UI updates, etc.
|
|
57
|
+
*/
|
|
58
|
+
onVideoPlay?: (url: string) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Callback when video playback should stop (Pro tier).
|
|
61
|
+
* If videoScreen is set, this is called AFTER SDK stops the video.
|
|
62
|
+
*/
|
|
63
|
+
onVideoStop?: () => void;
|
|
64
|
+
/**
|
|
65
|
+
* Callback for broadcast messages (Pro tier).
|
|
66
|
+
* Default: shows notification via staticTV.showNotification()
|
|
67
|
+
*/
|
|
68
|
+
onBroadcast?: (text: string) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Command handler for scene-specific commands (Pro tier).
|
|
71
|
+
* Called when admin triggers a command from the panel.
|
|
72
|
+
*/
|
|
73
|
+
onCommand?: (type: string, payload?: Record<string, unknown>) => void;
|
|
28
74
|
/** Automatically start session tracking on init (default: true) */
|
|
29
75
|
autoStartSession?: boolean;
|
|
30
76
|
/** Interval for session heartbeats in ms (default: 30000) */
|
|
@@ -47,11 +93,11 @@ interface StaticTVConfig {
|
|
|
47
93
|
*/
|
|
48
94
|
player?: PlayerData;
|
|
49
95
|
/**
|
|
50
|
-
* Guide UI configuration
|
|
96
|
+
* Guide UI configuration
|
|
51
97
|
*/
|
|
52
98
|
guideUI?: GuideUIConfig;
|
|
53
99
|
/**
|
|
54
|
-
* Chat UI configuration
|
|
100
|
+
* Chat UI configuration
|
|
55
101
|
*/
|
|
56
102
|
chatUI?: ChatUIConfig;
|
|
57
103
|
}
|
|
@@ -840,16 +886,28 @@ declare class StaticTVClient {
|
|
|
840
886
|
*
|
|
841
887
|
* @param config Configuration options
|
|
842
888
|
*
|
|
843
|
-
* @example
|
|
889
|
+
* @example Free tier (session tracking only):
|
|
844
890
|
* ```typescript
|
|
845
|
-
*
|
|
891
|
+
* const staticTV = new StaticTVClient({
|
|
892
|
+
* apiKey: 'dcls_your_key_here'
|
|
893
|
+
* })
|
|
894
|
+
* ```
|
|
895
|
+
*
|
|
896
|
+
* @example Standard/Pro with video screen (SDK handles playback):
|
|
897
|
+
* ```typescript
|
|
898
|
+
* // Create your video screen
|
|
899
|
+
* const screen = engine.addEntity()
|
|
900
|
+
* Transform.create(screen, { position: Vector3.create(8, 3, 14), scale: Vector3.create(8, 4.5, 0.1) })
|
|
901
|
+
* MeshRenderer.setPlane(screen)
|
|
902
|
+
*
|
|
903
|
+
* // SDK handles everything - Guide selection + Pro admin controls just work
|
|
904
|
+
* const staticTV = new StaticTVClient({
|
|
905
|
+
* apiKey: 'dcls_your_key_here',
|
|
906
|
+
* videoScreen: screen // That's it! SDK manages video playback
|
|
907
|
+
* })
|
|
846
908
|
*
|
|
847
909
|
* export function main() {
|
|
848
|
-
*
|
|
849
|
-
* staticTV = new StaticTVClient({
|
|
850
|
-
* apiKey: 'dcls_your_key_here'
|
|
851
|
-
* })
|
|
852
|
-
* // Session tracking starts automatically!
|
|
910
|
+
* staticTV.setupUI()
|
|
853
911
|
* }
|
|
854
912
|
* ```
|
|
855
913
|
*/
|
|
@@ -900,6 +958,33 @@ declare class StaticTVClient {
|
|
|
900
958
|
* @internal
|
|
901
959
|
*/
|
|
902
960
|
getConfig(): StaticTVConfig;
|
|
961
|
+
private _currentVideoUrl;
|
|
962
|
+
/**
|
|
963
|
+
* Play a video on the configured videoScreen entity.
|
|
964
|
+
* Called by Guide UI and Admin Panel.
|
|
965
|
+
*
|
|
966
|
+
* @param url Video URL to play
|
|
967
|
+
*/
|
|
968
|
+
playVideo(url: string): void;
|
|
969
|
+
/**
|
|
970
|
+
* Stop video playback on the configured videoScreen entity.
|
|
971
|
+
* Called by Admin Panel.
|
|
972
|
+
*/
|
|
973
|
+
stopVideo(): void;
|
|
974
|
+
/**
|
|
975
|
+
* Get the currently playing video URL
|
|
976
|
+
*/
|
|
977
|
+
get currentVideoUrl(): string;
|
|
978
|
+
/**
|
|
979
|
+
* Internal handler for Guide video selection
|
|
980
|
+
* @internal
|
|
981
|
+
*/
|
|
982
|
+
_handleGuideVideoSelect(video: GuideVideo): void;
|
|
983
|
+
/**
|
|
984
|
+
* Internal handler for broadcast messages
|
|
985
|
+
* @internal
|
|
986
|
+
*/
|
|
987
|
+
_handleBroadcast(text: string): void;
|
|
903
988
|
/**
|
|
904
989
|
* Initialize standard feature modules (guide, heartbeat, interactions, UI)
|
|
905
990
|
* @internal
|
|
@@ -939,28 +1024,30 @@ declare class StaticTVClient {
|
|
|
939
1024
|
get sdkType(): 'lite' | 'full';
|
|
940
1025
|
/**
|
|
941
1026
|
* Configure Pro features (Admin Panel with Video + Mod tabs)
|
|
942
|
-
* Call this after creating the client to configure admin panel.
|
|
943
|
-
* The panel will auto-enable when server confirms Pro tier.
|
|
944
1027
|
*
|
|
945
|
-
*
|
|
1028
|
+
* **OPTIONAL**: If you set `videoScreen` in the constructor, you don't need
|
|
1029
|
+
* to call this method - the Admin Panel will auto-enable with sensible defaults.
|
|
946
1030
|
*
|
|
947
|
-
*
|
|
948
|
-
*
|
|
949
|
-
*
|
|
1031
|
+
* Use this method only if you need:
|
|
1032
|
+
* - Custom scene tab UI
|
|
1033
|
+
* - Custom panel title/styling
|
|
1034
|
+
* - Advanced command handlers
|
|
950
1035
|
*
|
|
951
|
-
*
|
|
952
|
-
*
|
|
953
|
-
*
|
|
954
|
-
*
|
|
1036
|
+
* @param config Admin panel configuration
|
|
1037
|
+
*
|
|
1038
|
+
* @example Using videoScreen (recommended - no enableProFeatures needed):
|
|
1039
|
+
* ```typescript
|
|
1040
|
+
* const staticTV = new StaticTVClient({
|
|
1041
|
+
* apiKey: 'dcls_...',
|
|
1042
|
+
* videoScreen: myScreen // Admin Panel auto-enabled for Pro tier!
|
|
955
1043
|
* })
|
|
1044
|
+
* ```
|
|
956
1045
|
*
|
|
957
|
-
*
|
|
1046
|
+
* @example Advanced: Custom scene tabs
|
|
1047
|
+
* ```typescript
|
|
958
1048
|
* staticTV.enableProFeatures({
|
|
959
|
-
* sceneId: 'my-scene', // optional - defaults to API key ID
|
|
960
1049
|
* title: 'MY SCENE ADMIN',
|
|
961
|
-
*
|
|
962
|
-
* onVideoStop: () => videoPlayer.stop(),
|
|
963
|
-
* onBroadcast: (text) => showNotification(text)
|
|
1050
|
+
* sceneTabs: [{ label: 'LIGHTS', id: 'lights', render: () => <LightsTab /> }]
|
|
964
1051
|
* })
|
|
965
1052
|
* ```
|
|
966
1053
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1049,7 +1049,7 @@ var GuideUIModule = class {
|
|
|
1049
1049
|
renderLeftPanel() {
|
|
1050
1050
|
const sidebarW = this.s(UI_DIMENSIONS.guide.sidebar.width);
|
|
1051
1051
|
const liveCount = this.liveVideos.length;
|
|
1052
|
-
const signalCount = this.videos.filter((v) => !v.isLive).length;
|
|
1052
|
+
const signalCount = this.videos.filter((v) => !v.isLive && !v.isCreator).length;
|
|
1053
1053
|
const nodesPlaylist = this.featuredPlaylists.find((p) => p.name === "NODES");
|
|
1054
1054
|
const nodesCount = nodesPlaylist ? nodesPlaylist.videos.filter((v) => v.isCreator).length : 0;
|
|
1055
1055
|
const displayedPlaylists = this.featuredPlaylists.filter((p) => p.name !== "NODES").slice(0, 6);
|
|
@@ -1146,7 +1146,7 @@ var GuideUIModule = class {
|
|
|
1146
1146
|
}),
|
|
1147
1147
|
// Menu buttons
|
|
1148
1148
|
this.renderMenuButton("LIVE NOW", liveCount, THEME.colors.red, liveCount > 0 ? "\u25CF" : void 0, "ACTIVE STREAMS"),
|
|
1149
|
-
this.renderMenuButton("SIGNALS", signalCount, THEME.colors.white, void 0, "
|
|
1149
|
+
this.renderMenuButton("SIGNALS", signalCount, THEME.colors.white, void 0, "VODS & RECORDINGS"),
|
|
1150
1150
|
this.renderMenuButton("NODES", nodesCount, THEME.colors.magenta, void 0, "CHANNELS & CREATORS"),
|
|
1151
1151
|
// Divider
|
|
1152
1152
|
import_react_ecs2.default.createElement(import_react_ecs2.UiEntity, {
|
|
@@ -1228,7 +1228,7 @@ var GuideUIModule = class {
|
|
|
1228
1228
|
let videosToShow = [];
|
|
1229
1229
|
const nodePl = this.featuredPlaylists.find((p) => p.name === "NODES");
|
|
1230
1230
|
if (this.activeTab === "SIGNALS") {
|
|
1231
|
-
videosToShow = this.videos.filter((v) => !v.isLive);
|
|
1231
|
+
videosToShow = this.videos.filter((v) => !v.isLive && !v.isCreator);
|
|
1232
1232
|
} else if (this.activeTab === "NODES") {
|
|
1233
1233
|
videosToShow = nodePl ? nodePl.videos.filter((v) => v.isCreator) : [];
|
|
1234
1234
|
} else if (this.activeTab === "LIVE NOW") {
|
|
@@ -3492,6 +3492,7 @@ function setupStaticUI(client) {
|
|
|
3492
3492
|
}
|
|
3493
3493
|
|
|
3494
3494
|
// src/StaticTVClient.ts
|
|
3495
|
+
var import_ecs3 = require("@dcl/sdk/ecs");
|
|
3495
3496
|
var DEFAULT_BASE_URL = "https://thestatic.tv/api/v1/dcl";
|
|
3496
3497
|
var KEY_TYPE_CHANNEL = "channel";
|
|
3497
3498
|
var KEY_TYPE_SCENE = "scene";
|
|
@@ -3501,16 +3502,28 @@ var StaticTVClient = class {
|
|
|
3501
3502
|
*
|
|
3502
3503
|
* @param config Configuration options
|
|
3503
3504
|
*
|
|
3504
|
-
* @example
|
|
3505
|
+
* @example Free tier (session tracking only):
|
|
3506
|
+
* ```typescript
|
|
3507
|
+
* const staticTV = new StaticTVClient({
|
|
3508
|
+
* apiKey: 'dcls_your_key_here'
|
|
3509
|
+
* })
|
|
3510
|
+
* ```
|
|
3511
|
+
*
|
|
3512
|
+
* @example Standard/Pro with video screen (SDK handles playback):
|
|
3505
3513
|
* ```typescript
|
|
3506
|
-
*
|
|
3514
|
+
* // Create your video screen
|
|
3515
|
+
* const screen = engine.addEntity()
|
|
3516
|
+
* Transform.create(screen, { position: Vector3.create(8, 3, 14), scale: Vector3.create(8, 4.5, 0.1) })
|
|
3517
|
+
* MeshRenderer.setPlane(screen)
|
|
3518
|
+
*
|
|
3519
|
+
* // SDK handles everything - Guide selection + Pro admin controls just work
|
|
3520
|
+
* const staticTV = new StaticTVClient({
|
|
3521
|
+
* apiKey: 'dcls_your_key_here',
|
|
3522
|
+
* videoScreen: screen // That's it! SDK manages video playback
|
|
3523
|
+
* })
|
|
3507
3524
|
*
|
|
3508
3525
|
* export function main() {
|
|
3509
|
-
*
|
|
3510
|
-
* staticTV = new StaticTVClient({
|
|
3511
|
-
* apiKey: 'dcls_your_key_here'
|
|
3512
|
-
* })
|
|
3513
|
-
* // Session tracking starts automatically!
|
|
3526
|
+
* staticTV.setupUI()
|
|
3514
3527
|
* }
|
|
3515
3528
|
* ```
|
|
3516
3529
|
*/
|
|
@@ -3538,6 +3551,10 @@ var StaticTVClient = class {
|
|
|
3538
3551
|
this.adminPanel = null;
|
|
3539
3552
|
/** UI scale - fixed at 1.0. DCL's UI system auto-scales based on viewport. */
|
|
3540
3553
|
this.uiScale = 1;
|
|
3554
|
+
// =============================================================================
|
|
3555
|
+
// --- VIDEO PLAYBACK (Internal handler for videoScreen) ---
|
|
3556
|
+
// =============================================================================
|
|
3557
|
+
this._currentVideoUrl = "";
|
|
3541
3558
|
this.config = {
|
|
3542
3559
|
autoStartSession: true,
|
|
3543
3560
|
sessionHeartbeatInterval: 3e4,
|
|
@@ -3667,6 +3684,84 @@ var StaticTVClient = class {
|
|
|
3667
3684
|
getConfig() {
|
|
3668
3685
|
return this.config;
|
|
3669
3686
|
}
|
|
3687
|
+
/**
|
|
3688
|
+
* Play a video on the configured videoScreen entity.
|
|
3689
|
+
* Called by Guide UI and Admin Panel.
|
|
3690
|
+
*
|
|
3691
|
+
* @param url Video URL to play
|
|
3692
|
+
*/
|
|
3693
|
+
playVideo(url) {
|
|
3694
|
+
const screen = this.config.videoScreen;
|
|
3695
|
+
if (screen !== void 0) {
|
|
3696
|
+
this.log(`Playing video: ${url}`);
|
|
3697
|
+
this._currentVideoUrl = url;
|
|
3698
|
+
if (import_ecs3.VideoPlayer.has(screen)) {
|
|
3699
|
+
import_ecs3.VideoPlayer.deleteFrom(screen);
|
|
3700
|
+
}
|
|
3701
|
+
import_ecs3.VideoPlayer.create(screen, {
|
|
3702
|
+
src: url,
|
|
3703
|
+
playing: true,
|
|
3704
|
+
volume: 1
|
|
3705
|
+
});
|
|
3706
|
+
import_ecs3.Material.setBasicMaterial(screen, {
|
|
3707
|
+
texture: import_ecs3.Material.Texture.Video({ videoPlayerEntity: screen })
|
|
3708
|
+
});
|
|
3709
|
+
if (this.guideUI) {
|
|
3710
|
+
const videos = this.guideUI.getVideos();
|
|
3711
|
+
const video = videos.find((v) => v.src === url);
|
|
3712
|
+
if (video) {
|
|
3713
|
+
this.guideUI.currentVideoId = video.id;
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3717
|
+
if (this.config.onVideoPlay) {
|
|
3718
|
+
this.config.onVideoPlay(url);
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
/**
|
|
3722
|
+
* Stop video playback on the configured videoScreen entity.
|
|
3723
|
+
* Called by Admin Panel.
|
|
3724
|
+
*/
|
|
3725
|
+
stopVideo() {
|
|
3726
|
+
const screen = this.config.videoScreen;
|
|
3727
|
+
if (screen !== void 0 && import_ecs3.VideoPlayer.has(screen)) {
|
|
3728
|
+
this.log("Stopping video");
|
|
3729
|
+
import_ecs3.VideoPlayer.getMutable(screen).playing = false;
|
|
3730
|
+
this._currentVideoUrl = "";
|
|
3731
|
+
if (this.guideUI) {
|
|
3732
|
+
this.guideUI.currentVideoId = null;
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
if (this.config.onVideoStop) {
|
|
3736
|
+
this.config.onVideoStop();
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
/**
|
|
3740
|
+
* Get the currently playing video URL
|
|
3741
|
+
*/
|
|
3742
|
+
get currentVideoUrl() {
|
|
3743
|
+
return this._currentVideoUrl;
|
|
3744
|
+
}
|
|
3745
|
+
/**
|
|
3746
|
+
* Internal handler for Guide video selection
|
|
3747
|
+
* @internal
|
|
3748
|
+
*/
|
|
3749
|
+
_handleGuideVideoSelect(video) {
|
|
3750
|
+
if (video.src) {
|
|
3751
|
+
this.playVideo(video.src);
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
/**
|
|
3755
|
+
* Internal handler for broadcast messages
|
|
3756
|
+
* @internal
|
|
3757
|
+
*/
|
|
3758
|
+
_handleBroadcast(text) {
|
|
3759
|
+
if (this.config.onBroadcast) {
|
|
3760
|
+
this.config.onBroadcast(text);
|
|
3761
|
+
} else {
|
|
3762
|
+
this.showNotification(text);
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3670
3765
|
/**
|
|
3671
3766
|
* Initialize standard feature modules (guide, heartbeat, interactions, UI)
|
|
3672
3767
|
* @internal
|
|
@@ -3676,7 +3771,18 @@ var StaticTVClient = class {
|
|
|
3676
3771
|
this.guide = new GuideModule(this);
|
|
3677
3772
|
this.heartbeat = new HeartbeatModule(this);
|
|
3678
3773
|
this.interactions = new InteractionsModule(this);
|
|
3679
|
-
|
|
3774
|
+
const guideConfig = {
|
|
3775
|
+
...this.config.guideUI,
|
|
3776
|
+
onVideoSelect: (video) => {
|
|
3777
|
+
if (this.config.videoScreen !== void 0 || this.config.onVideoPlay) {
|
|
3778
|
+
this._handleGuideVideoSelect(video);
|
|
3779
|
+
}
|
|
3780
|
+
if (this.config.guideUI?.onVideoSelect) {
|
|
3781
|
+
this.config.guideUI.onVideoSelect(video);
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
};
|
|
3785
|
+
this.guideUI = new GuideUIModule(this, guideConfig);
|
|
3680
3786
|
this.chatUI = new ChatUIModule(this, this.config.chatUI);
|
|
3681
3787
|
this._standardFeaturesEnabled = true;
|
|
3682
3788
|
this.chatUI.init().catch((err) => {
|
|
@@ -3689,21 +3795,28 @@ var StaticTVClient = class {
|
|
|
3689
3795
|
* @internal
|
|
3690
3796
|
*/
|
|
3691
3797
|
_initProModules() {
|
|
3692
|
-
if (this._proFeaturesEnabled
|
|
3693
|
-
const
|
|
3694
|
-
|
|
3695
|
-
sceneId: this._pendingProConfig.sceneId || this._keyId || void 0
|
|
3696
|
-
};
|
|
3697
|
-
if (!configWithDefaults.sceneId) {
|
|
3798
|
+
if (this._proFeaturesEnabled) return;
|
|
3799
|
+
const sceneId = this._pendingProConfig?.sceneId || this.config.sceneId || this._keyId || void 0;
|
|
3800
|
+
if (!sceneId) {
|
|
3698
3801
|
this.log("Pro features: No sceneId and no keyId available - admin panel disabled");
|
|
3699
3802
|
return;
|
|
3700
3803
|
}
|
|
3701
|
-
|
|
3804
|
+
const adminConfig = {
|
|
3805
|
+
sceneId,
|
|
3806
|
+
// Use internal handlers that manage videoScreen + call user callbacks
|
|
3807
|
+
onVideoPlay: (url) => this.playVideo(url),
|
|
3808
|
+
onVideoStop: () => this.stopVideo(),
|
|
3809
|
+
onBroadcast: (text) => this._handleBroadcast(text),
|
|
3810
|
+
onCommand: this.config.onCommand || this._pendingProConfig?.onCommand,
|
|
3811
|
+
// Merge other settings from enableProFeatures if provided
|
|
3812
|
+
...this._pendingProConfig
|
|
3813
|
+
};
|
|
3814
|
+
this.adminPanel = new AdminPanelUIModule(this, adminConfig);
|
|
3702
3815
|
this._proFeaturesEnabled = true;
|
|
3703
3816
|
this.adminPanel.init().catch((err) => {
|
|
3704
3817
|
this.log(`Admin panel init failed: ${err}`);
|
|
3705
3818
|
});
|
|
3706
|
-
this.log(`Pro features enabled (admin panel) - sceneId: ${
|
|
3819
|
+
this.log(`Pro features enabled (admin panel) - sceneId: ${sceneId}`);
|
|
3707
3820
|
}
|
|
3708
3821
|
/**
|
|
3709
3822
|
* Called by SessionModule when server returns the tier
|
|
@@ -3718,8 +3831,13 @@ var StaticTVClient = class {
|
|
|
3718
3831
|
if (tier === "standard" || tier === "pro") {
|
|
3719
3832
|
this._initStandardModules();
|
|
3720
3833
|
}
|
|
3721
|
-
if (tier === "pro"
|
|
3722
|
-
this.
|
|
3834
|
+
if (tier === "pro") {
|
|
3835
|
+
const hasVideoConfig = this.config.videoScreen !== void 0 || this.config.onVideoPlay !== void 0 || this.config.sceneId !== void 0 || this._pendingProConfig !== null;
|
|
3836
|
+
if (hasVideoConfig) {
|
|
3837
|
+
this._initProModules();
|
|
3838
|
+
} else {
|
|
3839
|
+
this.log("Pro tier detected but no video config - call enableProFeatures() or set videoScreen to enable admin panel");
|
|
3840
|
+
}
|
|
3723
3841
|
}
|
|
3724
3842
|
}
|
|
3725
3843
|
/**
|
|
@@ -3755,28 +3873,30 @@ var StaticTVClient = class {
|
|
|
3755
3873
|
}
|
|
3756
3874
|
/**
|
|
3757
3875
|
* Configure Pro features (Admin Panel with Video + Mod tabs)
|
|
3758
|
-
* Call this after creating the client to configure admin panel.
|
|
3759
|
-
* The panel will auto-enable when server confirms Pro tier.
|
|
3760
3876
|
*
|
|
3761
|
-
*
|
|
3877
|
+
* **OPTIONAL**: If you set `videoScreen` in the constructor, you don't need
|
|
3878
|
+
* to call this method - the Admin Panel will auto-enable with sensible defaults.
|
|
3762
3879
|
*
|
|
3763
|
-
*
|
|
3764
|
-
*
|
|
3765
|
-
*
|
|
3880
|
+
* Use this method only if you need:
|
|
3881
|
+
* - Custom scene tab UI
|
|
3882
|
+
* - Custom panel title/styling
|
|
3883
|
+
* - Advanced command handlers
|
|
3766
3884
|
*
|
|
3767
|
-
*
|
|
3768
|
-
*
|
|
3769
|
-
*
|
|
3770
|
-
*
|
|
3885
|
+
* @param config Admin panel configuration
|
|
3886
|
+
*
|
|
3887
|
+
* @example Using videoScreen (recommended - no enableProFeatures needed):
|
|
3888
|
+
* ```typescript
|
|
3889
|
+
* const staticTV = new StaticTVClient({
|
|
3890
|
+
* apiKey: 'dcls_...',
|
|
3891
|
+
* videoScreen: myScreen // Admin Panel auto-enabled for Pro tier!
|
|
3771
3892
|
* })
|
|
3893
|
+
* ```
|
|
3772
3894
|
*
|
|
3773
|
-
*
|
|
3895
|
+
* @example Advanced: Custom scene tabs
|
|
3896
|
+
* ```typescript
|
|
3774
3897
|
* staticTV.enableProFeatures({
|
|
3775
|
-
* sceneId: 'my-scene', // optional - defaults to API key ID
|
|
3776
3898
|
* title: 'MY SCENE ADMIN',
|
|
3777
|
-
*
|
|
3778
|
-
* onVideoStop: () => videoPlayer.stop(),
|
|
3779
|
-
* onBroadcast: (text) => showNotification(text)
|
|
3899
|
+
* sceneTabs: [{ label: 'LIGHTS', id: 'lights', render: () => <LightsTab /> }]
|
|
3780
3900
|
* })
|
|
3781
3901
|
* ```
|
|
3782
3902
|
*/
|
package/dist/index.mjs
CHANGED
|
@@ -1006,7 +1006,7 @@ var GuideUIModule = class {
|
|
|
1006
1006
|
renderLeftPanel() {
|
|
1007
1007
|
const sidebarW = this.s(UI_DIMENSIONS.guide.sidebar.width);
|
|
1008
1008
|
const liveCount = this.liveVideos.length;
|
|
1009
|
-
const signalCount = this.videos.filter((v) => !v.isLive).length;
|
|
1009
|
+
const signalCount = this.videos.filter((v) => !v.isLive && !v.isCreator).length;
|
|
1010
1010
|
const nodesPlaylist = this.featuredPlaylists.find((p) => p.name === "NODES");
|
|
1011
1011
|
const nodesCount = nodesPlaylist ? nodesPlaylist.videos.filter((v) => v.isCreator).length : 0;
|
|
1012
1012
|
const displayedPlaylists = this.featuredPlaylists.filter((p) => p.name !== "NODES").slice(0, 6);
|
|
@@ -1103,7 +1103,7 @@ var GuideUIModule = class {
|
|
|
1103
1103
|
}),
|
|
1104
1104
|
// Menu buttons
|
|
1105
1105
|
this.renderMenuButton("LIVE NOW", liveCount, THEME.colors.red, liveCount > 0 ? "\u25CF" : void 0, "ACTIVE STREAMS"),
|
|
1106
|
-
this.renderMenuButton("SIGNALS", signalCount, THEME.colors.white, void 0, "
|
|
1106
|
+
this.renderMenuButton("SIGNALS", signalCount, THEME.colors.white, void 0, "VODS & RECORDINGS"),
|
|
1107
1107
|
this.renderMenuButton("NODES", nodesCount, THEME.colors.magenta, void 0, "CHANNELS & CREATORS"),
|
|
1108
1108
|
// Divider
|
|
1109
1109
|
ReactEcs2.createElement(UiEntity2, {
|
|
@@ -1185,7 +1185,7 @@ var GuideUIModule = class {
|
|
|
1185
1185
|
let videosToShow = [];
|
|
1186
1186
|
const nodePl = this.featuredPlaylists.find((p) => p.name === "NODES");
|
|
1187
1187
|
if (this.activeTab === "SIGNALS") {
|
|
1188
|
-
videosToShow = this.videos.filter((v) => !v.isLive);
|
|
1188
|
+
videosToShow = this.videos.filter((v) => !v.isLive && !v.isCreator);
|
|
1189
1189
|
} else if (this.activeTab === "NODES") {
|
|
1190
1190
|
videosToShow = nodePl ? nodePl.videos.filter((v) => v.isCreator) : [];
|
|
1191
1191
|
} else if (this.activeTab === "LIVE NOW") {
|
|
@@ -3449,6 +3449,7 @@ function setupStaticUI(client) {
|
|
|
3449
3449
|
}
|
|
3450
3450
|
|
|
3451
3451
|
// src/StaticTVClient.ts
|
|
3452
|
+
import { VideoPlayer, Material } from "@dcl/sdk/ecs";
|
|
3452
3453
|
var DEFAULT_BASE_URL = "https://thestatic.tv/api/v1/dcl";
|
|
3453
3454
|
var KEY_TYPE_CHANNEL = "channel";
|
|
3454
3455
|
var KEY_TYPE_SCENE = "scene";
|
|
@@ -3458,16 +3459,28 @@ var StaticTVClient = class {
|
|
|
3458
3459
|
*
|
|
3459
3460
|
* @param config Configuration options
|
|
3460
3461
|
*
|
|
3461
|
-
* @example
|
|
3462
|
+
* @example Free tier (session tracking only):
|
|
3463
|
+
* ```typescript
|
|
3464
|
+
* const staticTV = new StaticTVClient({
|
|
3465
|
+
* apiKey: 'dcls_your_key_here'
|
|
3466
|
+
* })
|
|
3467
|
+
* ```
|
|
3468
|
+
*
|
|
3469
|
+
* @example Standard/Pro with video screen (SDK handles playback):
|
|
3462
3470
|
* ```typescript
|
|
3463
|
-
*
|
|
3471
|
+
* // Create your video screen
|
|
3472
|
+
* const screen = engine.addEntity()
|
|
3473
|
+
* Transform.create(screen, { position: Vector3.create(8, 3, 14), scale: Vector3.create(8, 4.5, 0.1) })
|
|
3474
|
+
* MeshRenderer.setPlane(screen)
|
|
3475
|
+
*
|
|
3476
|
+
* // SDK handles everything - Guide selection + Pro admin controls just work
|
|
3477
|
+
* const staticTV = new StaticTVClient({
|
|
3478
|
+
* apiKey: 'dcls_your_key_here',
|
|
3479
|
+
* videoScreen: screen // That's it! SDK manages video playback
|
|
3480
|
+
* })
|
|
3464
3481
|
*
|
|
3465
3482
|
* export function main() {
|
|
3466
|
-
*
|
|
3467
|
-
* staticTV = new StaticTVClient({
|
|
3468
|
-
* apiKey: 'dcls_your_key_here'
|
|
3469
|
-
* })
|
|
3470
|
-
* // Session tracking starts automatically!
|
|
3483
|
+
* staticTV.setupUI()
|
|
3471
3484
|
* }
|
|
3472
3485
|
* ```
|
|
3473
3486
|
*/
|
|
@@ -3495,6 +3508,10 @@ var StaticTVClient = class {
|
|
|
3495
3508
|
this.adminPanel = null;
|
|
3496
3509
|
/** UI scale - fixed at 1.0. DCL's UI system auto-scales based on viewport. */
|
|
3497
3510
|
this.uiScale = 1;
|
|
3511
|
+
// =============================================================================
|
|
3512
|
+
// --- VIDEO PLAYBACK (Internal handler for videoScreen) ---
|
|
3513
|
+
// =============================================================================
|
|
3514
|
+
this._currentVideoUrl = "";
|
|
3498
3515
|
this.config = {
|
|
3499
3516
|
autoStartSession: true,
|
|
3500
3517
|
sessionHeartbeatInterval: 3e4,
|
|
@@ -3624,6 +3641,84 @@ var StaticTVClient = class {
|
|
|
3624
3641
|
getConfig() {
|
|
3625
3642
|
return this.config;
|
|
3626
3643
|
}
|
|
3644
|
+
/**
|
|
3645
|
+
* Play a video on the configured videoScreen entity.
|
|
3646
|
+
* Called by Guide UI and Admin Panel.
|
|
3647
|
+
*
|
|
3648
|
+
* @param url Video URL to play
|
|
3649
|
+
*/
|
|
3650
|
+
playVideo(url) {
|
|
3651
|
+
const screen = this.config.videoScreen;
|
|
3652
|
+
if (screen !== void 0) {
|
|
3653
|
+
this.log(`Playing video: ${url}`);
|
|
3654
|
+
this._currentVideoUrl = url;
|
|
3655
|
+
if (VideoPlayer.has(screen)) {
|
|
3656
|
+
VideoPlayer.deleteFrom(screen);
|
|
3657
|
+
}
|
|
3658
|
+
VideoPlayer.create(screen, {
|
|
3659
|
+
src: url,
|
|
3660
|
+
playing: true,
|
|
3661
|
+
volume: 1
|
|
3662
|
+
});
|
|
3663
|
+
Material.setBasicMaterial(screen, {
|
|
3664
|
+
texture: Material.Texture.Video({ videoPlayerEntity: screen })
|
|
3665
|
+
});
|
|
3666
|
+
if (this.guideUI) {
|
|
3667
|
+
const videos = this.guideUI.getVideos();
|
|
3668
|
+
const video = videos.find((v) => v.src === url);
|
|
3669
|
+
if (video) {
|
|
3670
|
+
this.guideUI.currentVideoId = video.id;
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
if (this.config.onVideoPlay) {
|
|
3675
|
+
this.config.onVideoPlay(url);
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3679
|
+
* Stop video playback on the configured videoScreen entity.
|
|
3680
|
+
* Called by Admin Panel.
|
|
3681
|
+
*/
|
|
3682
|
+
stopVideo() {
|
|
3683
|
+
const screen = this.config.videoScreen;
|
|
3684
|
+
if (screen !== void 0 && VideoPlayer.has(screen)) {
|
|
3685
|
+
this.log("Stopping video");
|
|
3686
|
+
VideoPlayer.getMutable(screen).playing = false;
|
|
3687
|
+
this._currentVideoUrl = "";
|
|
3688
|
+
if (this.guideUI) {
|
|
3689
|
+
this.guideUI.currentVideoId = null;
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
if (this.config.onVideoStop) {
|
|
3693
|
+
this.config.onVideoStop();
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
/**
|
|
3697
|
+
* Get the currently playing video URL
|
|
3698
|
+
*/
|
|
3699
|
+
get currentVideoUrl() {
|
|
3700
|
+
return this._currentVideoUrl;
|
|
3701
|
+
}
|
|
3702
|
+
/**
|
|
3703
|
+
* Internal handler for Guide video selection
|
|
3704
|
+
* @internal
|
|
3705
|
+
*/
|
|
3706
|
+
_handleGuideVideoSelect(video) {
|
|
3707
|
+
if (video.src) {
|
|
3708
|
+
this.playVideo(video.src);
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
/**
|
|
3712
|
+
* Internal handler for broadcast messages
|
|
3713
|
+
* @internal
|
|
3714
|
+
*/
|
|
3715
|
+
_handleBroadcast(text) {
|
|
3716
|
+
if (this.config.onBroadcast) {
|
|
3717
|
+
this.config.onBroadcast(text);
|
|
3718
|
+
} else {
|
|
3719
|
+
this.showNotification(text);
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3627
3722
|
/**
|
|
3628
3723
|
* Initialize standard feature modules (guide, heartbeat, interactions, UI)
|
|
3629
3724
|
* @internal
|
|
@@ -3633,7 +3728,18 @@ var StaticTVClient = class {
|
|
|
3633
3728
|
this.guide = new GuideModule(this);
|
|
3634
3729
|
this.heartbeat = new HeartbeatModule(this);
|
|
3635
3730
|
this.interactions = new InteractionsModule(this);
|
|
3636
|
-
|
|
3731
|
+
const guideConfig = {
|
|
3732
|
+
...this.config.guideUI,
|
|
3733
|
+
onVideoSelect: (video) => {
|
|
3734
|
+
if (this.config.videoScreen !== void 0 || this.config.onVideoPlay) {
|
|
3735
|
+
this._handleGuideVideoSelect(video);
|
|
3736
|
+
}
|
|
3737
|
+
if (this.config.guideUI?.onVideoSelect) {
|
|
3738
|
+
this.config.guideUI.onVideoSelect(video);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
};
|
|
3742
|
+
this.guideUI = new GuideUIModule(this, guideConfig);
|
|
3637
3743
|
this.chatUI = new ChatUIModule(this, this.config.chatUI);
|
|
3638
3744
|
this._standardFeaturesEnabled = true;
|
|
3639
3745
|
this.chatUI.init().catch((err) => {
|
|
@@ -3646,21 +3752,28 @@ var StaticTVClient = class {
|
|
|
3646
3752
|
* @internal
|
|
3647
3753
|
*/
|
|
3648
3754
|
_initProModules() {
|
|
3649
|
-
if (this._proFeaturesEnabled
|
|
3650
|
-
const
|
|
3651
|
-
|
|
3652
|
-
sceneId: this._pendingProConfig.sceneId || this._keyId || void 0
|
|
3653
|
-
};
|
|
3654
|
-
if (!configWithDefaults.sceneId) {
|
|
3755
|
+
if (this._proFeaturesEnabled) return;
|
|
3756
|
+
const sceneId = this._pendingProConfig?.sceneId || this.config.sceneId || this._keyId || void 0;
|
|
3757
|
+
if (!sceneId) {
|
|
3655
3758
|
this.log("Pro features: No sceneId and no keyId available - admin panel disabled");
|
|
3656
3759
|
return;
|
|
3657
3760
|
}
|
|
3658
|
-
|
|
3761
|
+
const adminConfig = {
|
|
3762
|
+
sceneId,
|
|
3763
|
+
// Use internal handlers that manage videoScreen + call user callbacks
|
|
3764
|
+
onVideoPlay: (url) => this.playVideo(url),
|
|
3765
|
+
onVideoStop: () => this.stopVideo(),
|
|
3766
|
+
onBroadcast: (text) => this._handleBroadcast(text),
|
|
3767
|
+
onCommand: this.config.onCommand || this._pendingProConfig?.onCommand,
|
|
3768
|
+
// Merge other settings from enableProFeatures if provided
|
|
3769
|
+
...this._pendingProConfig
|
|
3770
|
+
};
|
|
3771
|
+
this.adminPanel = new AdminPanelUIModule(this, adminConfig);
|
|
3659
3772
|
this._proFeaturesEnabled = true;
|
|
3660
3773
|
this.adminPanel.init().catch((err) => {
|
|
3661
3774
|
this.log(`Admin panel init failed: ${err}`);
|
|
3662
3775
|
});
|
|
3663
|
-
this.log(`Pro features enabled (admin panel) - sceneId: ${
|
|
3776
|
+
this.log(`Pro features enabled (admin panel) - sceneId: ${sceneId}`);
|
|
3664
3777
|
}
|
|
3665
3778
|
/**
|
|
3666
3779
|
* Called by SessionModule when server returns the tier
|
|
@@ -3675,8 +3788,13 @@ var StaticTVClient = class {
|
|
|
3675
3788
|
if (tier === "standard" || tier === "pro") {
|
|
3676
3789
|
this._initStandardModules();
|
|
3677
3790
|
}
|
|
3678
|
-
if (tier === "pro"
|
|
3679
|
-
this.
|
|
3791
|
+
if (tier === "pro") {
|
|
3792
|
+
const hasVideoConfig = this.config.videoScreen !== void 0 || this.config.onVideoPlay !== void 0 || this.config.sceneId !== void 0 || this._pendingProConfig !== null;
|
|
3793
|
+
if (hasVideoConfig) {
|
|
3794
|
+
this._initProModules();
|
|
3795
|
+
} else {
|
|
3796
|
+
this.log("Pro tier detected but no video config - call enableProFeatures() or set videoScreen to enable admin panel");
|
|
3797
|
+
}
|
|
3680
3798
|
}
|
|
3681
3799
|
}
|
|
3682
3800
|
/**
|
|
@@ -3712,28 +3830,30 @@ var StaticTVClient = class {
|
|
|
3712
3830
|
}
|
|
3713
3831
|
/**
|
|
3714
3832
|
* Configure Pro features (Admin Panel with Video + Mod tabs)
|
|
3715
|
-
* Call this after creating the client to configure admin panel.
|
|
3716
|
-
* The panel will auto-enable when server confirms Pro tier.
|
|
3717
3833
|
*
|
|
3718
|
-
*
|
|
3834
|
+
* **OPTIONAL**: If you set `videoScreen` in the constructor, you don't need
|
|
3835
|
+
* to call this method - the Admin Panel will auto-enable with sensible defaults.
|
|
3719
3836
|
*
|
|
3720
|
-
*
|
|
3721
|
-
*
|
|
3722
|
-
*
|
|
3837
|
+
* Use this method only if you need:
|
|
3838
|
+
* - Custom scene tab UI
|
|
3839
|
+
* - Custom panel title/styling
|
|
3840
|
+
* - Advanced command handlers
|
|
3723
3841
|
*
|
|
3724
|
-
*
|
|
3725
|
-
*
|
|
3726
|
-
*
|
|
3727
|
-
*
|
|
3842
|
+
* @param config Admin panel configuration
|
|
3843
|
+
*
|
|
3844
|
+
* @example Using videoScreen (recommended - no enableProFeatures needed):
|
|
3845
|
+
* ```typescript
|
|
3846
|
+
* const staticTV = new StaticTVClient({
|
|
3847
|
+
* apiKey: 'dcls_...',
|
|
3848
|
+
* videoScreen: myScreen // Admin Panel auto-enabled for Pro tier!
|
|
3728
3849
|
* })
|
|
3850
|
+
* ```
|
|
3729
3851
|
*
|
|
3730
|
-
*
|
|
3852
|
+
* @example Advanced: Custom scene tabs
|
|
3853
|
+
* ```typescript
|
|
3731
3854
|
* staticTV.enableProFeatures({
|
|
3732
|
-
* sceneId: 'my-scene', // optional - defaults to API key ID
|
|
3733
3855
|
* title: 'MY SCENE ADMIN',
|
|
3734
|
-
*
|
|
3735
|
-
* onVideoStop: () => videoPlayer.stop(),
|
|
3736
|
-
* onBroadcast: (text) => showNotification(text)
|
|
3856
|
+
* sceneTabs: [{ label: 'LIGHTS', id: 'lights', render: () => <LightsTab /> }]
|
|
3737
3857
|
* })
|
|
3738
3858
|
* ```
|
|
3739
3859
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thestatic-tv/dcl-sdk",
|
|
3
|
-
"version": "2.3.0-beta.
|
|
3
|
+
"version": "2.3.0-beta.3",
|
|
4
4
|
"description": "Connect your Decentraland scene to thestatic.tv - full channel lineup, metrics tracking, and interactions",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|