@reactoo/watchtogether-sdk-js 2.5.35 → 2.5.37

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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- import {wait} from "../modules/wt-utils";
3
+ import {decodeJanusDisplay, wait} from "../modules/wt-utils";
4
4
  import _emitter_ from "../modules/wt-emitter";
5
5
 
6
6
  // SYNCHRONISATION MODULES
@@ -17,7 +17,7 @@ import syncDisabled from "../modules/sync-modules/sync-disabled";
17
17
  import syncDaznDash from "../modules/sync-modules/sync-dazn-dash";
18
18
  import syncUniversal from "../modules/sync-modules/sync-universal";
19
19
 
20
- let roomSession = function ({roomId, pinHash, isTalkback, isMonitor, isInstructor}, room, wt) {
20
+ let roomSession = function ({roomId, pinHash, isTalkback, isInstructor}, room, wt) {
21
21
 
22
22
  let primaryRoomId = roomId;
23
23
  let publicCustomEvents = ['changePlayerSource', 'chatMessage', 'userUpdate', 'reconnecting', 'connecting', 'remoteMuted', 'scaling'];
@@ -88,13 +88,13 @@ let roomSession = function ({roomId, pinHash, isTalkback, isMonitor, isInstructo
88
88
  emitter.emit('connecting', true);
89
89
  clearTimeout(alpTimeoutId);
90
90
  abortController = new AbortController();
91
- return Promise.all([wt.room.__joinRoom({
92
- roomId: reactooRoomId || primaryRoomId,
93
- pinHash,
94
- isTalkback,
95
- isMonitor,
96
- isInstructor
97
- }, abortController?.signal), wt.user.getUserSelf()])
91
+ return Promise.all([
92
+ wt.room.__joinRoom({
93
+ roomId: reactooRoomId || primaryRoomId,
94
+ pinHash,
95
+ isTalkback,
96
+ isInstructor}, abortController?.signal),
97
+ wt.user.getUserSelf()])
98
98
  .then(([roomData, userData]) => {
99
99
  // Happens when we reroute user to a different room
100
100
  if(roomData?.data?.reactooRoomId !== roomId) {
@@ -104,7 +104,21 @@ let roomSession = function ({roomId, pinHash, isTalkback, isMonitor, isInstructo
104
104
  return Promise.all([roomData, userData])
105
105
  })
106
106
  .then(([roomData, userData]) => Promise.all([roomData, userData, this.setRoomVars()]))
107
- .then(([roomData, userData, _]) => Promise.all([roomData, userData, room.connect(roomData.data.roomId, roomData.data.pin, roomData.data.href, roomData.data.iceServers, roomData.data.accessToken, roomData.data.display, roomData.data.userId, roomData.data.webrtcVersion, (roomData.data.bitrate ? parseInt(roomData.data.bitrate) : 0), isMonitor, roomData.data.recordingFilename)]))
107
+ .then(([roomData, userData, _]) => Promise.all([
108
+ roomData,
109
+ userData,
110
+ room.connect(
111
+ roomData.data.roomId,
112
+ roomData.data.pin,
113
+ roomData.data.href,
114
+ roomData.data.iceServers,
115
+ roomData.data.accessToken,
116
+ roomData.data.display,
117
+ roomData.data.userId,
118
+ roomData.data.webrtcVersion,
119
+ (roomData.data.bitrate ? parseInt(roomData.data.bitrate) : 0),
120
+ roomData.data.recordingFilename)
121
+ ]))
108
122
  .finally(() => {
109
123
  emitter.emit('connecting', false);
110
124
  })
@@ -182,7 +196,7 @@ let roomSession = function ({roomId, pinHash, isTalkback, isMonitor, isInstructo
182
196
  emitter.emit('chatMessage', msg);
183
197
  } else if (msg.user_action === 'remote_muted') {
184
198
  if (msg.from !== room.userId) {
185
- emitter.emit('remoteMuted', {userId: msg.from, ...(msg.text && JSON.parse(msg.text))})
199
+ emitter.emit('remoteMuted', {userId: decodeJanusDisplay(msg.from)?.userId, ...(msg.text && JSON.parse(msg.text))})
186
200
  }
187
201
  } else if (msg.user_action === 'remote_muted_request') {
188
202
  if (msg.from !== room.userId) {
@@ -293,9 +307,10 @@ let roomSession = function ({roomId, pinHash, isTalkback, isMonitor, isInstructo
293
307
  return wt.room.getRoomById(roomId, pinHash, undefined, false, abortController?.signal)
294
308
  .then(r => {
295
309
  // setting observers userId's so we can ignore them when creating participant
310
+ room.setRoomType(r.data.type);
296
311
  room.setObserverIds(r.data.allowedObservers);
297
312
  room.setTalkbackIds(r.data.allowedTalkbacks);
298
- room.setInstructorId(r.data.classroom?.instructorUserId);
313
+ room.setInstructorId(r.data.classroom?.instructorUserId || r.data.videowall?.hostUserId);
299
314
  });
300
315
  },
301
316
 
@@ -205,14 +205,13 @@ let room = function () {
205
205
  }))
206
206
  },
207
207
 
208
- __joinRoom: ({roomId, pinHash, instanceType = this.__instanceType, isTalkback = undefined, isMonitor = undefined, isInstructor = undefined, customBearer = undefined} = {}, signal) => {
208
+ __joinRoom: ({roomId, pinHash, instanceType = this.__instanceType, isTalkback = undefined, isInstructor = undefined, customBearer = undefined} = {}, signal) => {
209
209
  return this.__privates.auth.__client
210
210
  .then(client => client.apis.wt.join({
211
211
  roomId,
212
212
  pinHash,
213
213
  instanceType,
214
214
  isTalkback,
215
- isMonitor,
216
215
  isInstructor,
217
216
  platform: this.browser === 'firefox' ? 'web-firefox' : 'web'
218
217
  }, {
@@ -1,6 +1,7 @@
1
1
 
2
2
  import {device} from 'aws-iot-device-sdk';
3
3
  import emitter from './wt-emitter';
4
+ import {decodeJanusDisplay} from "./wt-utils";
4
5
 
5
6
  class Iot {
6
7
 
@@ -68,14 +69,14 @@ class Iot {
68
69
  this.startCredentialsExpirationCheck(expiration);
69
70
 
70
71
  let __s = () => {
71
- this.device.off('connect', __s);
72
- this.device.off('error', __e);
72
+ this.device?.off('connect', __s);
73
+ this.device?.off('error', __e);
73
74
  resolve(this.device)
74
75
  };
75
76
 
76
77
  let __e = (e) => {
77
- this.device.off('connect', __s);
78
- this.device.off('error', __e);
78
+ this.device?.off('connect', __s);
79
+ this.device?.off('error', __e);
79
80
  reject(e);
80
81
  };
81
82
 
@@ -156,10 +157,16 @@ class Iot {
156
157
  }
157
158
 
158
159
  __messageCb(t, message, packet) {
159
-
160
160
  const topic = t.split('/');
161
- const payload = JSON.parse(this.decoder.decode(message));
162
-
161
+ let payload = JSON.parse(this.decoder.decode(message));
162
+
163
+ if(payload.display) {
164
+ const decodedDisplay = decodeJanusDisplay(payload.display);
165
+ if(decodedDisplay.userId) {
166
+ payload = {...payload, userId: decodedDisplay.userId}
167
+ }
168
+ }
169
+
163
170
  if(topic[0] === 'user') { // user
164
171
  const userId = topic[1].replace("_", ':');
165
172
  this.emit('message', {userId, ...payload, event: payload.event ? `user:${payload.event}` : 'user'});
@@ -2,7 +2,7 @@
2
2
 
3
3
  import adapter from 'webrtc-adapter';
4
4
  import emitter from './wt-emitter';
5
- import {generateUUID} from "./wt-utils";
5
+ import {decodeJanusDisplay, generateUUID} from "./wt-utils";
6
6
 
7
7
  class Room {
8
8
 
@@ -96,24 +96,39 @@ class RoomSession {
96
96
 
97
97
  static subscriptionRules = {
98
98
  participant: {
99
- watchTogether: ['participant', 'talkback'],
100
- videoWall: ['instructor', 'observer', 'talkback']
99
+ "watchparty": ['participant', 'talkback'],
100
+ "commentary": ['participant', 'talkback'],
101
+ "videowall": ['instructor', 'observer', 'talkback'],
102
+ "videowall-queue": ['instructor', 'observer', 'talkback'],
103
+ "videowall-queue-video": ['instructor', 'observer', 'talkback']
101
104
  },
102
105
  monitor: {
103
- watchTogether: ['participant'],
104
- videoWall: ['instructor', 'participant'],
106
+ "watchparty": ['participant'],
107
+ "commentary": ['participant'],
108
+ "videowall": ['instructor', 'participant'],
109
+ "videowall-queue": ['instructor', 'participant'],
110
+ "videowall-queue-video": ['instructor', 'participant'],
105
111
  },
106
112
  talkback: {
107
- watchTogether: ['participant'],
108
- videoWall: ['instructor', 'participant'],
113
+ "watchparty": ['participant'],
114
+ "commentary": ['participant'],
115
+ "videowall": ['instructor', 'participant'],
116
+ "videowall-queue": ['instructor', 'participant'],
117
+ "videowall-queue-video": ['instructor', 'participant'],
109
118
  },
110
119
  observer: {
111
- watchTogether: ['participant'],
112
- videoWall: ['participant'],
120
+ "watchparty": ['participant'],
121
+ "commentary": ['participant'],
122
+ "videowall": ['participant'],
123
+ "videowall-queue": ['participant'],
124
+ "videowall-queue-video": ['participant'],
113
125
  },
114
126
  instructor: {
115
- watchTogether: [],
116
- videoWall: [],
127
+ "watchparty": [],
128
+ "commentary": [],
129
+ "videowall": [],
130
+ "videowall-queue": [],
131
+ "videowall-queue-video": [],
117
132
  },
118
133
  };
119
134
 
@@ -130,8 +145,6 @@ class RoomSession {
130
145
  this.userId = null;
131
146
  this.sessiontype = type;
132
147
  this.initialBitrate = 0;
133
- //TODO: remove this
134
- this.isMonitor = false; // currently used just for classroom context so monitor user only subscribes to participants and not trainer (for other monitor this flag is not necessary)
135
148
  this.recordingFilename = null;
136
149
  this.pluginName = RoomSession.sessionTypes[type];
137
150
  this.options = options;
@@ -158,6 +171,7 @@ class RoomSession {
158
171
  this._observerIds = [];
159
172
  this._talkbackIds = [];
160
173
  this._instuctorId = null;
174
+ this._roomType = 'watchparty';
161
175
  this._isDataChannelOpen = false;
162
176
  this._abortController = null;
163
177
 
@@ -209,29 +223,29 @@ class RoomSession {
209
223
  }
210
224
 
211
225
  _participantShouldSubscribe(userId) {
226
+ const myUserId = decodeJanusDisplay(this.userId)?.userId;
227
+ const remoteUserId = decodeJanusDisplay(userId)?.userId;
228
+
212
229
  let allowedObservers = this._observerIds || [];
213
230
  let allowedTalkback = this._talkbackIds || [];
214
231
  let allowedInstructor = this._instuctorId || null;
215
232
  let localUserRole = 'participant';
216
- if(this.isMonitor) {
217
- localUserRole = 'monitor';
218
- } else if(allowedObservers.indexOf(this.userId) > -1) {
233
+ if(allowedObservers.indexOf(myUserId) > -1) {
219
234
  localUserRole = 'observer';
220
- } else if(allowedTalkback.indexOf(this.userId) > -1) {
235
+ } else if(allowedTalkback.indexOf(myUserId) > -1) {
221
236
  localUserRole = 'talkback';
222
- } else if(this.userId === allowedInstructor) {
237
+ } else if(myUserId === allowedInstructor) {
223
238
  localUserRole = 'instructor';
224
239
  }
225
240
  let remoteUserRole = 'participant';
226
- if(allowedObservers.indexOf(userId) > -1) {
241
+ if(allowedObservers.indexOf(remoteUserId) > -1) {
227
242
  remoteUserRole = 'observer';
228
- } else if(allowedTalkback.indexOf(userId) > -1) {
243
+ } else if(allowedTalkback.indexOf(remoteUserId) > -1) {
229
244
  remoteUserRole = 'talkback';
230
- } else if(userId === allowedInstructor) {
245
+ } else if(remoteUserId === allowedInstructor) {
231
246
  remoteUserRole = 'instructor';
232
247
  }
233
- let mode = allowedInstructor !== null ? 'videoWall' : 'watchTogether';
234
- return this.subscriptionRules[localUserRole][mode].indexOf(remoteUserRole) > -1;
248
+ return this.subscriptionRules[localUserRole][this._roomType].indexOf(remoteUserRole) > -1;
235
249
  }
236
250
 
237
251
  _getAddParticipantEventName(handleId) {
@@ -246,17 +260,19 @@ class RoomSession {
246
260
  });
247
261
  }
248
262
 
263
+ const decodedUserId = decodeJanusDisplay(handle.userId)?.userId;
264
+
249
265
  let allowedTalkback = this._talkbackIds || [];
250
266
  let allowedObservers = this._observerIds || [];
251
267
  let allowedInstructor = this._instuctorId || null;
252
268
  let eventName = 'addRemoteParticipant';
253
- if(handle.userId === allowedInstructor) {
269
+ if(decodedUserId === allowedInstructor) {
254
270
  eventName = 'addRemoteInstructor';
255
271
  }
256
- if (allowedTalkback.indexOf(handle.userId) > -1) {
272
+ if (allowedTalkback.indexOf(decodedUserId) > -1) {
257
273
  eventName = 'addRemoteTalkback';
258
274
  }
259
- if (allowedObservers.indexOf(handle.userId) > -1) {
275
+ if (allowedObservers.indexOf(decodedUserId) > -1) {
260
276
  eventName = 'addRemoteObserver';
261
277
  }
262
278
  return eventName
@@ -274,17 +290,19 @@ class RoomSession {
274
290
  });
275
291
  }
276
292
 
293
+ const decodedUserId = decodeJanusDisplay(handle.userId)?.userId;
294
+
277
295
  let allowedTalkback = this._talkbackIds || [];
278
296
  let allowedObservers = this._observerIds || [];
279
297
  let allowedInstructor = this._instuctorId || null;
280
298
  let eventName = 'removeRemoteParticipant';
281
- if(handle.userId === allowedInstructor) {
299
+ if(decodedUserId === allowedInstructor) {
282
300
  eventName = 'removeRemoteInstructor';
283
301
  }
284
- if (allowedTalkback.indexOf(handle.userId) > -1) {
302
+ if (allowedTalkback.indexOf(decodedUserId) > -1) {
285
303
  eventName = 'removeRemoteTalkback';
286
304
  }
287
- if (allowedObservers.indexOf(handle.userId) > -1) {
305
+ if (allowedObservers.indexOf(decodedUserId) > -1) {
288
306
  eventName = 'removeRemoteObserver';
289
307
  }
290
308
  return eventName
@@ -658,7 +676,7 @@ class RoomSession {
658
676
  this.emit(this._getAddParticipantEventName(handle.handleId), {
659
677
  tid: generateUUID(),
660
678
  id: handle.handleId,
661
- userId: handle.userId,
679
+ userId: decodeJanusDisplay(handle.userId)?.userId,
662
680
  stream: null,
663
681
  track: null,
664
682
  adding: false,
@@ -795,9 +813,9 @@ class RoomSession {
795
813
  this._isDataChannelOpen = false;
796
814
  this.isPublished = false;
797
815
  this.emit('published', {status: false, hasStream: false});
798
- this.emit('removeLocalParticipant', {id: handleId, userId: handle.userId});
816
+ this.emit('removeLocalParticipant', {id: handleId, userId: decodeJanusDisplay(handle.userId)?.userId});
799
817
  } else {
800
- this.emit(this._getRemoveParticipantEventName(handleId), {id: handleId, userId: handle.userId});
818
+ this.emit(this._getRemoveParticipantEventName(handleId), {id: handleId, userId: decodeJanusDisplay(handle.userId)?.userId});
801
819
  }
802
820
 
803
821
  if (removeHandle) {
@@ -928,7 +946,7 @@ class RoomSession {
928
946
  });
929
947
  }
930
948
 
931
- connect(roomId, pin, server, iceServers, token, display, userId, webrtcVersion = 0, initialBitrate = 0, isMonitor, recordingFilename) {
949
+ connect(roomId, pin, server, iceServers, token, display, userId, webrtcVersion = 0, initialBitrate = 0, recordingFilename) {
932
950
 
933
951
  if (this.isConnecting) {
934
952
  return Promise.reject({type: 'warning', id: 16, message: 'connection already in progress'});
@@ -949,7 +967,6 @@ class RoomSession {
949
967
  this.userId = userId;
950
968
  this.webrtcVersion = webrtcVersion;
951
969
  this.initialBitrate = initialBitrate;
952
- this.isMonitor = isMonitor;
953
970
  this.recordingFilename = recordingFilename;
954
971
  this.isConnecting = true;
955
972
  this.emit('joining', true);
@@ -1235,7 +1252,7 @@ class RoomSession {
1235
1252
  this.emit(this._getAddParticipantEventName(handle.handleId), {
1236
1253
  tid: generateUUID(),
1237
1254
  id: handle.handleId,
1238
- userId: handle.userId,
1255
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1239
1256
  stream: config.stream,
1240
1257
  track: null,
1241
1258
  optional: true,
@@ -1256,7 +1273,7 @@ class RoomSession {
1256
1273
  this.emit(this._getAddParticipantEventName(handle.handleId), {
1257
1274
  tid: generateUUID(),
1258
1275
  id: handle.handleId,
1259
- userId: handle.userId,
1276
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1260
1277
  stream: config.stream,
1261
1278
  track: null,
1262
1279
  optional: true,
@@ -1309,7 +1326,7 @@ class RoomSession {
1309
1326
  tid: generateUUID(),
1310
1327
  mid,
1311
1328
  id: handle.handleId,
1312
- userId: handle.userId,
1329
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1313
1330
  stream: config.stream,
1314
1331
  track: event.track,
1315
1332
  constructId: this.constructId,
@@ -1337,7 +1354,7 @@ class RoomSession {
1337
1354
  tid: generateUUID(),
1338
1355
  id: handle.handleId,
1339
1356
  mid,
1340
- userId: handle.userId,
1357
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1341
1358
  stream: config.stream,
1342
1359
  track: ev.target,
1343
1360
  constructId: this.constructId,
@@ -1363,7 +1380,7 @@ class RoomSession {
1363
1380
  this.emit('remoteTrackMuted', {
1364
1381
  id: handle.handleId,
1365
1382
  mid,
1366
- userId: handle.userId,
1383
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1367
1384
  stream: config.stream,
1368
1385
  kind: ev.target.kind,
1369
1386
  track: ev.target,
@@ -1384,7 +1401,7 @@ class RoomSession {
1384
1401
  this.emit('remoteTrackMuted', {
1385
1402
  id: handle.handleId,
1386
1403
  mid,
1387
- userId: handle.userId,
1404
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1388
1405
  stream: config.stream,
1389
1406
  kind: ev.target.kind,
1390
1407
  track: ev.target,
@@ -1988,7 +2005,7 @@ class RoomSession {
1988
2005
  this.emit('addLocalParticipant', {
1989
2006
  tid: generateUUID(),
1990
2007
  id: handle.handleId,
1991
- userId: handle.userId,
2008
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1992
2009
  track,
1993
2010
  stream: config.stream,
1994
2011
  adding: true,
@@ -2001,7 +2018,7 @@ class RoomSession {
2001
2018
  this.emit('addLocalParticipant', {
2002
2019
  tid:generateUUID(),
2003
2020
  id: handle.handleId,
2004
- userId: handle.userId,
2021
+ userId: decodeJanusDisplay(handle.userId)?.userId,
2005
2022
  track: ev.target,
2006
2023
  stream: config.stream,
2007
2024
  adding: false,
@@ -2018,7 +2035,7 @@ class RoomSession {
2018
2035
  this.emit('addLocalParticipant', {
2019
2036
  tid: generateUUID(),
2020
2037
  id: handle.handleId,
2021
- userId: handle.userId,
2038
+ userId: decodeJanusDisplay(handle.userId)?.userId,
2022
2039
  stream: null,
2023
2040
  adding: false,
2024
2041
  constructId: this.constructId,
@@ -2117,6 +2134,11 @@ class RoomSession {
2117
2134
  return this._talkbackIds;
2118
2135
  }
2119
2136
 
2137
+ setRoomType(type = 'watchparty') {
2138
+ this._roomType = type;
2139
+ return this._roomType;
2140
+ }
2141
+
2120
2142
  }
2121
2143
 
2122
2144
  export default Room;
@@ -27,6 +27,26 @@ let generateUUID = function () {
27
27
  });
28
28
  };
29
29
 
30
+
31
+ const janusDisplayDelimiter = ',';
32
+ const decodeJanusDisplay = display => {
33
+ let output = { userId: null, role: "participant", start: Date.now(), displayName: "?" };
34
+ if(display && typeof display === "string") {
35
+ if(display.indexOf(janusDisplayDelimiter) >= 0) {
36
+ let values = display
37
+ .split( new RegExp(`\\${janusDisplayDelimiter}(?=(?:(?:[^"]*"){2})*[^"]*$)`, 'mi') )
38
+ .map(v => (v && v.startsWith('"') || v.endsWith('"')) ? v.substring(1, v.length-1) : ( /^\d+$/.test(v) ? parseInt(v) : v ));
39
+ Object.keys(output).forEach((key, i) => values[i] ? output[key] = values[i] : null);
40
+ } else {
41
+ output.userId = display;
42
+ }
43
+ return output;
44
+ } else if(display && typeof display === "object") {
45
+ return Object.assign({}, output, display);
46
+ }
47
+ return null;
48
+ }
49
+
30
50
  const setExactTimeout = function(callback, duration, resolution) {
31
51
  const start = (new Date()).getTime();
32
52
  const timeout = setInterval(function(){
@@ -43,4 +63,6 @@ const clearExactTimeout = function(timeout) {
43
63
  clearInterval(timeout);
44
64
  };
45
65
 
46
- export {wait, getBrowserFingerprint, generateUUID, setExactTimeout, clearExactTimeout}
66
+
67
+
68
+ export {wait, getBrowserFingerprint, generateUUID, decodeJanusDisplay, setExactTimeout, clearExactTimeout}