@digitalsamba/embedded-sdk 0.0.19 → 0.0.21

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.
@@ -0,0 +1,286 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ <title>Initial settings</title>
8
+ <script src="./index.js"></script>
9
+ <script src="./helper.js"></script>
10
+ <link rel="stylesheet" href="./style.css">
11
+ </head>
12
+
13
+ <body>
14
+ <nav class="topbar">
15
+ <div class="container">
16
+ <img class="logo" src="logo.png" alt="DigitalSamba">
17
+ <a href="https://github.com/digitalsamba/embedded-sdk" target="_blank" rel="noopener nofollow">View on GitHub</a>
18
+ </div>
19
+ </nav>
20
+
21
+ <div class="screen room-url-field show">
22
+ <div class="container">
23
+ <div class="vertical">
24
+ <label for="custom-room-url">
25
+ <span><b>Room URL</b></span>
26
+ <span>Can be found in <a href="https://dashboard.digitalsamba.com/" target="_blank" rel="noopener nofollow">dashboard</a></span>.
27
+ </label>
28
+ <div>
29
+ <input type="text" id="custom-room-url" name="custom-room-url" onkeydown="onURLChange()">
30
+ <!-- kicks off loading -->
31
+ <button onclick="loadCustomRoom()">load room</button>
32
+ </div>
33
+ <p class="room-url-error"></p>
34
+ <p style="margin-top: 30px;" class="init-settings-title">Predefined settings</p>
35
+ <p style="margin-bottom: 15px">These options can be applied prior to joining the room. For
36
+ instance,<br> if you pre-set a username, participant won't be prompted for it.
37
+ <br>
38
+ You can also set defaults for media devices and room UI.
39
+ </p>
40
+
41
+ <div>
42
+ <label for="initial-settings-username">
43
+ Username
44
+ </label>
45
+ <div>
46
+ <input type="text" id="initial-settings-username" onchange="initialSettings.username = this.value">
47
+ </div>
48
+ <div style="display: flex">
49
+ <label class="checkbox-label" for="initial-settings-video">
50
+ <span>Video enabled</span>
51
+ <input type="checkbox" id="initial-settings-video" checked onchange="initialSettings.videoEnabled = !initialSettings.videoEnabled" />
52
+ </label>
53
+ <label class="checkbox-label" for="initial-settings-audio">
54
+ <span>Audio enabled</span>
55
+ <input type="checkbox" id="initial-settings-audio" checked onchange="initialSettings.audioEnabled = !initialSettings.audioEnabled" />
56
+ </label>
57
+ </div>
58
+ <div>
59
+ <label class="checkbox-label" for="initial-settings-toolbar">
60
+ <span>Show toolbar</span>
61
+ <input type="checkbox" id="initial-settings-toolbar" onchange="initialSettings.showToolbar = !initialSettings.showToolbar" />
62
+ </label>
63
+ </div>
64
+ <fieldset style="margin-bottom: 10px;">
65
+ <div style="display: flex;">
66
+ <legend style="margin-right: 8px;">Layout mode</legend>
67
+ <div style="display: flex; align-items: center; justify-content: center">
68
+ <input type="radio" id="prep-layout-mode-auto" checked name="layout-mode" value="auto" onchange="initialSettings.layoutMode = 'auto'" />
69
+ <label class="radio-label" for="prep-layout-mode-auto">Auto</label>
70
+
71
+ <input type="radio" id="prep-layout-mode-tiled" name="layout-mode" value="tiled" onchange="initialSettings.layoutMode = 'tiled'" />
72
+ <label class="radio-label" for="prep-layout-mode-tiled">Tiled</label>
73
+ </div>
74
+ </div>
75
+ </fieldset>
76
+ <div>
77
+ <label class="checkbox-label" for="initial-settings-vb">
78
+ <span>Enable virtual background</span>
79
+ <input type="checkbox" id="initial-settings-vb" onchange="toggleVirtualBackground(this.checked)" />
80
+ </label>
81
+ </div>
82
+ <div class="vb-options" style ="display: none">
83
+ <div style="display: flex; align-items: center; justify-content: flex-start">
84
+ <label style="margin-right: 8px;" for="vb-type">Virtual background type</label>
85
+ <select name="vb-type" id="vb-type" onchange="updateVBType(this.value)">
86
+ <option value="blur">blur</option>
87
+ <option value="image">predefined image</option>
88
+ <option value="imageUrl">custom image</option>
89
+ </select>
90
+ </div>
91
+ <div class="vb-value vb-value-blur show">
92
+ <div style="display: flex; align-items: center; justify-content: flex-start">
93
+ <label style="margin-right: 8px;" for="vb-blur-value">Blur strength</label>
94
+ <select name="vb-blur-value" id="vb-blur-value" onchange="VBstate.value = this.value; VBvalues.blur = this.value">
95
+ <option value="balanced">balanced</option>
96
+ <option value="strong">strong</option>
97
+ </select>
98
+ </div>
99
+ </div>
100
+ <div class="vb-value vb-value-image">
101
+ <div style="display: flex; align-items: center; justify-content: flex-start">
102
+ <label style="margin-right: 8px;" for="vb-image-value">Preset name</label>
103
+ <select name="vb-image-value" id="vb-image-value" onchange="VBstate.value = this.value; VBvalues.image = this.value;">
104
+ <option value="office">office</option>
105
+ <option value="office2">office2</option>
106
+ <option value="beach">beach</option>
107
+ <option value="fireworks">fireworks</option>
108
+ <option value="bookshelf">bookshelf</option>
109
+ <option value="forest">forest</option>
110
+ <option value="mountain">mountain</option>
111
+ <option value="savannah">savannah</option>
112
+ </select>
113
+ </div>
114
+ </div>
115
+ <div class="vb-value vb-value-imageUrl">
116
+ <label for="vb-image-url">
117
+ Custom image URL
118
+ </label>
119
+ <div>
120
+ <input type="text" id="vb-image-url" onchange="VBstate.value = this.value; VBvalues.imageUrl = this.value">
121
+ </div>
122
+ </div>
123
+ <div>
124
+ <label class="checkbox-label" for="initial-settings-enforce-vb">
125
+ <span>Allow changing virtual background</span>
126
+ <input type="checkbox" id="initial-settings-enforce-vb" onchange="VBstate.enforce = !this.checked" />
127
+ </label>
128
+ </div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ <div class="screen room-frame">
135
+ <div class="container">
136
+ <div class="room-content">
137
+ <div class="frame-area">
138
+ <div class="frame-parent">
139
+ <!-- our frame will load here -->
140
+ </div>
141
+ <div class="frame-controls" style="display: none">
142
+ <button onclick="sambaEmbedded.toggleVideo()">toggle video</button>
143
+ <button onclick="sambaEmbedded.toggleAudio()">toggle audio</button>
144
+ <button onclick="sambaEmbedded.toggleToolbar()">toggle toolbar</button>
145
+ </div>
146
+ </div>
147
+ <div class="sidebar"></div>
148
+ </div>
149
+ </div>
150
+
151
+ </div>
152
+
153
+ <script async defer>
154
+ let ROOM_URL = "https://localhost:3000/Public";
155
+
156
+ var sambaEmbedded;
157
+
158
+ // defaults for pre-configured state;
159
+ var initialSettings = {
160
+ username: "",
161
+ audioEnabled: true,
162
+ videoEnabled: true,
163
+ showToolbar: false,
164
+ showCaptions: false,
165
+ layoutMode: "auto",
166
+ virtualBackground: undefined
167
+ };
168
+
169
+ var VBstate = {
170
+ type: "blur",
171
+ value: "balanced",
172
+ enforce: false
173
+ };
174
+
175
+ var VBvalues = {
176
+ blur: 'balanced',
177
+ image: 'office',
178
+ imageUrl: 'string'
179
+ }
180
+
181
+
182
+ // if room is predefined in search params, skip room URL field;
183
+ checkDynamicRoomURL();
184
+
185
+ function loadCustomRoom() {
186
+ const input = document.querySelector("#custom-room-url");
187
+
188
+ if (input.value) {
189
+ ROOM_URL = input.value;
190
+
191
+ initialSettings.virtualBackground = vbStateToInitState(initialSettings.virtualBackground);
192
+
193
+ loadRoom();
194
+ } else {
195
+ updateError("Please enter room URL");
196
+ }
197
+ }
198
+
199
+ function loadRoom() {
200
+ try {
201
+ const parent = document.querySelector(".frame-parent");
202
+ parent.innerHTML = null;
203
+
204
+ // create pre-configured controller instance using given URL;
205
+ // if no frame specified, this pre-creates a frame but doesn't load it yet;
206
+ // other init strategies are available, along with more detailed customization
207
+ // see https://docs.digitalsamba.com/reference/sdk/digitalsambaembedded-class
208
+ sambaEmbedded = DigitalSambaEmbedded.createControl(
209
+ {
210
+ url: ROOM_URL, root: parent,
211
+ // apply predefined room settings
212
+ roomSettings: initialSettings
213
+ },
214
+ { reportErrors: true }
215
+ );
216
+
217
+ // controller instance exposes the frame, so we can customize it a little bit
218
+ sambaEmbedded.frame.width = 1000;
219
+ sambaEmbedded.frame.height = 700;
220
+ sambaEmbedded.frame.style.border = "5px solid #f06859";
221
+ sambaEmbedded.frame.style.borderRadius = "8px";
222
+
223
+ // load samba frame
224
+ sambaEmbedded.load();
225
+
226
+ addJoiningHint(ROOM_URL);
227
+ initializeLogs();
228
+
229
+ // after loading, controller will start emitting events
230
+ // event listeners can be set up prior to loading;
231
+ setupCustomEventListeners();
232
+
233
+ showScreen(".room-frame");
234
+ } catch (e) {
235
+ updateError(e.message);
236
+ }
237
+ }
238
+
239
+ function setupCustomEventListeners() {
240
+ // catch all events. Useful for logging or debugging;
241
+ sambaEmbedded.on("*", (data) => {
242
+ const logList = document.querySelector(".log-list");
243
+
244
+ if (logList) {
245
+ logList.innerHTML += `<div>
246
+ <p>[${(new Date).toLocaleTimeString()}] event: <b>${data?.type}</b></p>
247
+ ${data.data ? `<p>payload: ${JSON.stringify(data.data)}</p>` : ""}
248
+ </div>`;
249
+
250
+ logList.scrollTop = logList.scrollHeight;
251
+ }
252
+ });
253
+
254
+ // `roomJoined` is fired when local user has joined the room
255
+ // this listener is used to display media device controls after joining
256
+ sambaEmbedded.on("roomJoined", () => {
257
+ const controls = document.querySelector(".frame-controls");
258
+
259
+ controls.style.display = "flex";
260
+ });
261
+ }
262
+
263
+ function toggleVirtualBackground(shouldEnable) {
264
+ const vbOptions = document.querySelector(".vb-options");
265
+
266
+ if (shouldEnable) {
267
+ initialSettings.virtualBackground = VBstate;
268
+ vbOptions.style.display = "block";
269
+ } else {
270
+ initialSettings.virtualBackground = undefined;
271
+ vbOptions.style.display = "none";
272
+ }
273
+ }
274
+
275
+ function updateVBType(newType) {
276
+ VBstate.type = newType;
277
+ const currentOption = document.querySelector(".vb-value.show");
278
+ const newOption = document.querySelector(".vb-value-" + newType);
279
+ currentOption.className = currentOption.className.replace(" show", "");
280
+ newOption.className += " show";
281
+
282
+ VBstate.value = VBvalues[newType];
283
+ }
284
+ </script>
285
+ </body>
286
+ </html>
Binary file
@@ -0,0 +1,278 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ <title>Managed state</title>
8
+ <!-- <script src="https://unpkg.com/@digitalsamba/embedded-sdk"></script>-->
9
+ <script src="./index.js"></script>
10
+ <script src="./helper.js"></script>
11
+ <link rel="stylesheet" href="./style.css">
12
+ </head>
13
+
14
+ <body>
15
+ <nav class="topbar">
16
+ <div class="container">
17
+ <img class="logo" src="logo.png" alt="DigitalSamba">
18
+ <a href="https://github.com/digitalsamba/embedded-sdk" target="_blank" rel="noopener nofollow">View on GitHub</a>
19
+ </div>
20
+ </nav>
21
+
22
+ <div class="screen room-url-field show">
23
+ <div class="container">
24
+ <div class="vertical">
25
+ <label for="custom-room-url">
26
+ <span><b>Room URL</b></span>
27
+ <span>Can be found in <a href="https://dashboard.digitalsamba.com/" target="_blank" rel="noopener nofollow">dashboard</a></span>.
28
+ </label>
29
+ <div>
30
+ <input type="text" id="custom-room-url" name="custom-room-url" onkeydown="onURLChange()">
31
+ <!-- kicks off loading -->
32
+ <button onclick="loadCustomRoom()">load room</button>
33
+ </div>
34
+ <p class="room-url-error"></p>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ <div class="screen room-frame">
39
+ <div class="container">
40
+ <div class="room-content">
41
+ <div class="frame-area">
42
+ <div class="frame-parent">
43
+ <!-- our frame will load here -->
44
+ </div>
45
+ <div class="frame-controls" style="display: none">
46
+ <button onclick="sambaEmbedded.toggleVideo()">toggle video</button>
47
+ <button onclick="sambaEmbedded.toggleAudio()">toggle audio</button>
48
+ <button onclick="sambaEmbedded.toggleToolbar()">toggle toolbar</button>
49
+ </div>
50
+ </div>
51
+ <div class="sidebar">
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ </div>
57
+
58
+ <script async defer>
59
+ let ROOM_URL = "https://localhost:3000/Public";
60
+
61
+ var sambaEmbedded;
62
+
63
+ // if room is predefined in search params, skip room URL field;
64
+ checkDynamicRoomURL();
65
+
66
+ function loadCustomRoom() {
67
+ const input = document.querySelector("#custom-room-url");
68
+
69
+ if (input.value) {
70
+ ROOM_URL = input.value;
71
+ loadRoom();
72
+ } else {
73
+ updateError("Please enter room URL");
74
+ }
75
+ }
76
+
77
+ function loadRoom() {
78
+ try {
79
+ const parent = document.querySelector(".frame-parent");
80
+ parent.innerHTML = null;
81
+
82
+ // create pre-configured controller instance using given URL;
83
+ // if no frame specified, this pre-creates a frame but doesn't load it yet;
84
+ // other init strategies are available, along with more detailed customization
85
+ // see https://docs.digitalsamba.com/reference/sdk/digitalsambaembedded-class
86
+ sambaEmbedded = DigitalSambaEmbedded.createControl(
87
+ { url: ROOM_URL, root: parent, roomSettings: { showToolbar: false } },
88
+ { reportErrors: true }
89
+ );
90
+
91
+ // controller instance exposes the frame, so we can customize it a little bit
92
+ sambaEmbedded.frame.width = 1000;
93
+ sambaEmbedded.frame.height = 700;
94
+ sambaEmbedded.frame.style.border = "5px solid #f06859";
95
+ sambaEmbedded.frame.style.borderRadius = "8px";
96
+
97
+ // load samba frame
98
+ sambaEmbedded.load();
99
+
100
+ addJoiningHint(ROOM_URL);
101
+ initializeParticipantList();
102
+ initializeLogs();
103
+
104
+ // after loading, controller will start emitting events
105
+ // event listeners can be set up prior to loading;
106
+ setupCustomEventListeners();
107
+
108
+ showScreen(".room-frame");
109
+ } catch (e) {
110
+ updateError(e.message);
111
+ }
112
+ }
113
+
114
+ function setupCustomEventListeners() {
115
+ // catch all events. Useful for logging or debugging;
116
+ sambaEmbedded.on("*", (data) => {
117
+ const logList = document.querySelector(".log-list");
118
+
119
+ if (logList) {
120
+ logList.innerHTML += `<div>
121
+ <p>[${(new Date).toLocaleTimeString()}] event: <b>${data?.type}</b></p>
122
+ ${data.data ? `<p>payload: ${JSON.stringify(data.data)}</p>` : ""}
123
+ </div>`;
124
+
125
+ logList.scrollTop = logList.scrollHeight;
126
+ }
127
+ });
128
+
129
+ // `roomJoined` is fired when local user has joined the room
130
+ // this listener is used to display media device controls after joining
131
+ sambaEmbedded.on("roomJoined", () => {
132
+ const controls = document.querySelector(".frame-controls");
133
+
134
+ controls.style.display = "flex";
135
+ });
136
+
137
+ sambaEmbedded.on('usersUpdated', ({ data: { users } }) => {
138
+ const participantList = document.querySelector(".participants");
139
+ participantList.innerHTML = "";
140
+ participantList.className += " show";
141
+
142
+ users.forEach(user => {
143
+ const row = document.createElement('div');
144
+ row.className = 'user-list-row';
145
+ const subButtons = document.createElement('div')
146
+ row.appendChild(subButtons);
147
+
148
+ const avatar = document.createElement('span');
149
+ avatar.className = 'user-list-avatar';
150
+ avatar.style.background = user.avatarColor;
151
+ avatar.innerHTML = user.name[0];
152
+ row.appendChild(avatar);
153
+
154
+
155
+ const name = document.createElement('span');
156
+ name.className = 'user-list-name';
157
+ name.innerText = user.name;
158
+ row.appendChild(name);
159
+
160
+ const speakerIndicator = document.createElement('span')
161
+ speakerIndicator.className = `speaker-indicator speaker-indicator-${user.id}`;
162
+ row.appendChild(speakerIndicator);
163
+
164
+
165
+ if (user.kind === 'local') {
166
+ const label = document.createElement('span');
167
+ label.className = 'user-list-label';
168
+ label.innerText = '(you)'
169
+ label.style.color = '#777';
170
+ row.appendChild(label);
171
+ } else {
172
+ const micControl = document.createElement('button');
173
+ micControl.innerHTML = 'toggle mic'
174
+ micControl.style.margin = '0 4px';
175
+ micControl.onclick = () => {
176
+ sambaEmbedded.requestToggleAudio(user.id)
177
+ }
178
+ row.appendChild(micControl);
179
+
180
+ if (sambaEmbedded.permissionManager.hasPermissions('remove_participant', { targetRole: user.role })) {
181
+ const kickControl = document.createElement('button');
182
+ kickControl.innerHTML = 'kick'
183
+ kickControl.style.margin = '0 4px';
184
+ kickControl.onclick = () => {
185
+ sambaEmbedded.removeUser(user.id)
186
+ }
187
+ row.appendChild(kickControl);
188
+ }
189
+
190
+ if (sambaEmbedded.permissionManager.hasPermissions("manage_broadcast", { targetRole: user.role })) {
191
+ if (sambaEmbedded.permissionManager.hasPermissions("broadcast", { userId: user.id })) {
192
+ const disallowBroadcastControl = document.createElement("button");
193
+ disallowBroadcastControl.innerHTML = "disallow broadcast";
194
+ disallowBroadcastControl.style.margin = "0 4px";
195
+ disallowBroadcastControl.onclick = () => {
196
+ sambaEmbedded.disallowBroadcast(user.id);
197
+ };
198
+ subButtons.appendChild(disallowBroadcastControl);
199
+ } else {
200
+ const allowBroadcastControl = document.createElement("button");
201
+ allowBroadcastControl.innerHTML = "allow broadcast";
202
+ allowBroadcastControl.style.margin = "0 4px";
203
+ allowBroadcastControl.onclick = () => {
204
+ sambaEmbedded.allowBroadcast(user.id);
205
+ };
206
+ subButtons.appendChild(allowBroadcastControl);
207
+ }
208
+
209
+ if (sambaEmbedded.permissionManager.hasPermissions("manage_screenshare", { targetRole: user.role })) {
210
+ if (sambaEmbedded.permissionManager.hasPermissions("screenshare", { userId: user.id })) {
211
+ const disallowScreenshareControl = document.createElement("button");
212
+ disallowScreenshareControl.innerHTML = "disallow screenshare";
213
+ disallowScreenshareControl.style.margin = "0 4px";
214
+ disallowScreenshareControl.onclick = () => {
215
+ sambaEmbedded.disallowScreenshare(user.id);
216
+ };
217
+ subButtons.appendChild(disallowScreenshareControl);
218
+ } else {
219
+ const allowScreenshareControl = document.createElement("button");
220
+ allowScreenshareControl.innerHTML = "allow screenshare";
221
+ allowScreenshareControl.style.margin = "0 4px";
222
+ allowScreenshareControl.onclick = () => {
223
+ sambaEmbedded.allowScreenshare(user.id);
224
+ };
225
+ subButtons.appendChild(allowScreenshareControl);
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ const raisedHandControl = document.createElement('button');
232
+ raisedHandControl.id = 'lower-hand-' + user.id;
233
+ raisedHandControl.innerHTML = 'lower hand'
234
+ raisedHandControl.style.margin = '0 4px';
235
+ raisedHandControl.style.display = 'none';
236
+ raisedHandControl.onclick = () => {
237
+ sambaEmbedded.lowerHand(user.id)
238
+ }
239
+ row.appendChild(raisedHandControl);
240
+
241
+ participantList.appendChild(row);
242
+ participantList.appendChild(subButtons);
243
+
244
+ });
245
+ });
246
+
247
+ sambaEmbedded.on("activeSpeakerChanged", ({ data }) => {
248
+ const currentIndicator = document.querySelector(".speaker-indicator.show");
249
+ if (currentIndicator) {
250
+ currentIndicator.className = currentIndicator.className.replace(" show", "");
251
+ }
252
+
253
+ const newIndicator = document.querySelector(`.speaker-indicator-${data.user.id}`);
254
+ newIndicator.className = newIndicator.className + " show";
255
+ });
256
+
257
+ sambaEmbedded.on("audioDisabled", ({ data }) => {
258
+ const currentIndicator = document.querySelector(`.speaker-indicator-${data.user.id}`);
259
+
260
+ if (currentIndicator && currentIndicator.className.includes(' show')) {
261
+ currentIndicator.className = currentIndicator.className.replace(" show", "");
262
+ }
263
+ });
264
+
265
+ sambaEmbedded.on("audioEnabled", ({ data }) => {
266
+ if(data.user.id === sambaEmbedded.stored.activeSpeaker) {
267
+ const currentIndicator = document.querySelector(`.speaker-indicator-${sambaEmbedded.stored.activeSpeaker}`);
268
+
269
+ if (currentIndicator ) {
270
+ currentIndicator.className += " show";
271
+ }
272
+ }
273
+ });
274
+ }
275
+
276
+ </script>
277
+ </body>
278
+ </html>