@digitalsamba/embedded-sdk 0.0.13 → 0.0.18

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.
Files changed (39) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/index.d.ts +16 -3
  3. package/dist/cjs/index.js +129 -17
  4. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  5. package/dist/cjs/types.d.ts +83 -15
  6. package/dist/cjs/types.js +0 -6
  7. package/dist/cjs/utils/PermissionManager/index.d.ts +13 -0
  8. package/dist/cjs/utils/PermissionManager/index.js +74 -0
  9. package/dist/cjs/utils/PermissionManager/types.d.ts +23 -0
  10. package/dist/cjs/utils/PermissionManager/types.js +2 -0
  11. package/dist/cjs/utils/proxy.d.ts +1 -0
  12. package/dist/cjs/utils/proxy.js +21 -0
  13. package/dist/cjs/utils/vars.d.ts +23 -0
  14. package/dist/cjs/utils/vars.js +48 -0
  15. package/dist/esm/index.d.ts +16 -3
  16. package/dist/esm/index.js +127 -15
  17. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  18. package/dist/esm/types.d.ts +83 -15
  19. package/dist/esm/types.js +1 -5
  20. package/dist/esm/utils/PermissionManager/index.d.ts +13 -0
  21. package/dist/esm/utils/PermissionManager/index.js +70 -0
  22. package/dist/esm/utils/PermissionManager/types.d.ts +23 -0
  23. package/dist/esm/utils/PermissionManager/types.js +1 -0
  24. package/dist/esm/utils/proxy.d.ts +1 -0
  25. package/dist/esm/utils/proxy.js +17 -0
  26. package/dist/esm/utils/vars.d.ts +23 -0
  27. package/dist/esm/utils/vars.js +45 -0
  28. package/dist/index.html +98 -3
  29. package/dist/initial-config-demo.html +303 -0
  30. package/dist/permissions-demo.html +289 -0
  31. package/dist/types/index.d.ts +16 -3
  32. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  33. package/dist/types/types.d.ts +83 -15
  34. package/dist/types/utils/PermissionManager/index.d.ts +13 -0
  35. package/dist/types/utils/PermissionManager/types.d.ts +23 -0
  36. package/dist/types/utils/proxy.d.ts +1 -0
  37. package/dist/types/utils/vars.d.ts +23 -0
  38. package/dist/umd/index.js +1 -1
  39. package/package.json +1 -1
package/dist/cjs/types.js CHANGED
@@ -1,8 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LayoutMode = void 0;
4
- var LayoutMode;
5
- (function (LayoutMode) {
6
- LayoutMode["tiled"] = "tiled";
7
- LayoutMode["auto"] = "auto";
8
- })(LayoutMode = exports.LayoutMode || (exports.LayoutMode = {}));
@@ -0,0 +1,13 @@
1
+ import { CheckPermissionsOptions, HasPermissionsOptions, LookupPermissionOptions, PermissionsMap, RefinePermissionsOptions } from './types';
2
+ import { PermissionTypes } from '../vars';
3
+ import { EmbeddedInstance } from '../../types';
4
+ export declare class PermissionManager {
5
+ parent: EmbeddedInstance;
6
+ permissionsMap: PermissionsMap;
7
+ constructor(parent: EmbeddedInstance);
8
+ lookupDynamicPermission: (permission: PermissionTypes, dynamicPermissions: PermissionTypes[] | undefined) => boolean;
9
+ lookupPermission: (options: LookupPermissionOptions) => boolean;
10
+ checkPermissions: ({ permissions, targetRole, permissionsMap, role, dynamicPermissions, }: CheckPermissionsOptions) => boolean;
11
+ refinePermissions: (permissions: PermissionTypes | PermissionTypes[], { targetRole, role, userId, users, permissionsMap, localUser }: RefinePermissionsOptions) => boolean;
12
+ hasPermissions: (permissions: PermissionTypes | PermissionTypes[], { targetRole, role, userId }?: HasPermissionsOptions) => boolean;
13
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PermissionManager = void 0;
4
+ class PermissionManager {
5
+ constructor(parent) {
6
+ this.permissionsMap = {};
7
+ this.lookupDynamicPermission = (permission, dynamicPermissions) => {
8
+ if (!dynamicPermissions) {
9
+ return false;
10
+ }
11
+ return dynamicPermissions.includes(permission);
12
+ };
13
+ this.lookupPermission = (options) => {
14
+ const { permissionsMap, permission, targetRole, role, dynamicPermissions } = options;
15
+ if (dynamicPermissions) {
16
+ const granted = this.lookupDynamicPermission(permission, dynamicPermissions);
17
+ if (granted) {
18
+ return true;
19
+ }
20
+ }
21
+ if (permissionsMap[role][permission]) {
22
+ return true;
23
+ }
24
+ return Boolean(permissionsMap[role][`${permission}_${targetRole}`]);
25
+ };
26
+ this.checkPermissions = ({ permissions, targetRole, permissionsMap, role, dynamicPermissions, }) => {
27
+ if (Array.isArray(permissions)) {
28
+ return permissions.some((permission) => this.lookupPermission({ permission, targetRole, role, permissionsMap, dynamicPermissions }));
29
+ }
30
+ return this.lookupPermission({
31
+ permission: permissions,
32
+ targetRole,
33
+ role,
34
+ permissionsMap,
35
+ dynamicPermissions,
36
+ });
37
+ };
38
+ this.refinePermissions = (permissions, { targetRole, role, userId, users, permissionsMap, localUser }) => {
39
+ const options = {
40
+ permissionsMap,
41
+ permissions,
42
+ targetRole,
43
+ role: localUser.role,
44
+ dynamicPermissions: localUser.dynamicPermissions,
45
+ };
46
+ if (role) {
47
+ options.role = role;
48
+ options.dynamicPermissions = undefined;
49
+ }
50
+ if (userId && users) {
51
+ options.role = users[userId].role;
52
+ options.dynamicPermissions = users[userId].dynamicPermissions;
53
+ }
54
+ return this.checkPermissions(options);
55
+ };
56
+ this.hasPermissions = (permissions, { targetRole, role, userId } = {}) => {
57
+ const users = this.parent.stored.users;
58
+ const localUser = this.parent.localUser;
59
+ if (!localUser) {
60
+ return false;
61
+ }
62
+ return this.refinePermissions(permissions, {
63
+ permissionsMap: this.permissionsMap,
64
+ role,
65
+ targetRole,
66
+ users,
67
+ userId,
68
+ localUser,
69
+ });
70
+ };
71
+ this.parent = parent;
72
+ }
73
+ }
74
+ exports.PermissionManager = PermissionManager;
@@ -0,0 +1,23 @@
1
+ import { User, UserId } from '../../types';
2
+ import { PermissionTypes } from '../vars';
3
+ export type PermissionsMap = Record<string, Record<string, boolean>>;
4
+ export interface HasPermissionsOptions {
5
+ targetRole?: string;
6
+ role?: string;
7
+ userId?: UserId;
8
+ }
9
+ export interface RefinePermissionsOptions extends HasPermissionsOptions {
10
+ permissionsMap: PermissionsMap;
11
+ localUser: User;
12
+ users?: Record<UserId, User>;
13
+ }
14
+ export interface LookupPermissionOptions {
15
+ permissionsMap: PermissionsMap;
16
+ permission: PermissionTypes;
17
+ role: string;
18
+ targetRole?: string;
19
+ dynamicPermissions?: PermissionTypes[];
20
+ }
21
+ export interface CheckPermissionsOptions extends Omit<LookupPermissionOptions, 'permission'> {
22
+ permissions: PermissionTypes | PermissionTypes[];
23
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare const createWatchedProxy: <G>(initialState: G, onChange: (newState: G) => void) => any;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createWatchedProxy = void 0;
4
+ const createHandler = (onChange) => {
5
+ const handler = {
6
+ get(target, key) {
7
+ if (typeof target[key] === 'object' && target[key] !== null) {
8
+ return new Proxy(target[key], handler);
9
+ }
10
+ return target[key];
11
+ },
12
+ set(target, prop, value) {
13
+ target[prop] = value;
14
+ onChange(target);
15
+ return target;
16
+ },
17
+ };
18
+ return handler;
19
+ };
20
+ const createWatchedProxy = (initialState, onChange) => new Proxy(initialState, createHandler(onChange));
21
+ exports.createWatchedProxy = createWatchedProxy;
@@ -0,0 +1,23 @@
1
+ import { Stored } from '../types';
2
+ export declare const CONNECT_TIMEOUT = 10000;
3
+ export declare const internalEvents: Record<string, boolean>;
4
+ export declare enum LayoutMode {
5
+ tiled = "tiled",
6
+ auto = "auto"
7
+ }
8
+ export declare enum PermissionTypes {
9
+ broadcast = "broadcast",
10
+ manageBroadcast = "manage_broadcast",
11
+ endSession = "end_session",
12
+ startSession = "start_session",
13
+ removeParticipant = "remove_participant",
14
+ screenshare = "screenshare",
15
+ manageScreenshare = "manage_screenshare",
16
+ recording = "recording",
17
+ generalChat = "general_chat",
18
+ remoteMuting = "remote_muting",
19
+ askRemoteUnmute = "ask_remote_unmute",
20
+ raiseHand = "raise_hand",
21
+ manageRoles = "manage_roles"
22
+ }
23
+ export declare const defaultStoredState: Stored;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultStoredState = exports.PermissionTypes = exports.LayoutMode = exports.internalEvents = exports.CONNECT_TIMEOUT = void 0;
4
+ exports.CONNECT_TIMEOUT = 10000;
5
+ exports.internalEvents = {
6
+ roomJoined: true,
7
+ };
8
+ var LayoutMode;
9
+ (function (LayoutMode) {
10
+ LayoutMode["tiled"] = "tiled";
11
+ LayoutMode["auto"] = "auto";
12
+ })(LayoutMode = exports.LayoutMode || (exports.LayoutMode = {}));
13
+ var PermissionTypes;
14
+ (function (PermissionTypes) {
15
+ PermissionTypes["broadcast"] = "broadcast";
16
+ PermissionTypes["manageBroadcast"] = "manage_broadcast";
17
+ PermissionTypes["endSession"] = "end_session";
18
+ PermissionTypes["startSession"] = "start_session";
19
+ PermissionTypes["removeParticipant"] = "remove_participant";
20
+ PermissionTypes["screenshare"] = "screenshare";
21
+ PermissionTypes["manageScreenshare"] = "manage_screenshare";
22
+ PermissionTypes["recording"] = "recording";
23
+ PermissionTypes["generalChat"] = "general_chat";
24
+ PermissionTypes["remoteMuting"] = "remote_muting";
25
+ PermissionTypes["askRemoteUnmute"] = "ask_remote_unmute";
26
+ PermissionTypes["raiseHand"] = "raise_hand";
27
+ PermissionTypes["manageRoles"] = "manage_roles";
28
+ })(PermissionTypes = exports.PermissionTypes || (exports.PermissionTypes = {}));
29
+ exports.defaultStoredState = {
30
+ userId: '',
31
+ roomState: {
32
+ media: {
33
+ micEnabled: false,
34
+ cameraEnabled: false,
35
+ },
36
+ layout: {
37
+ mode: LayoutMode.tiled,
38
+ showToolbar: true,
39
+ toolbarPosition: 'left',
40
+ },
41
+ captionsState: {
42
+ showCaptions: false,
43
+ spokenLanguage: 'en',
44
+ fontSize: 'medium',
45
+ },
46
+ },
47
+ users: {},
48
+ };
@@ -1,14 +1,18 @@
1
1
  /// <reference types="node" />
2
- import { InitOptions, InstanceProperties, LayoutMode, UserId, CaptionsOptions } from './types';
3
2
  import EventEmitter from 'events';
4
- export declare class DigitalSambaEmbedded extends EventEmitter {
3
+ import { PermissionManager } from './utils/PermissionManager';
4
+ import { LayoutMode } from './utils/vars';
5
+ import { CaptionsOptions, EmbeddedInstance, InitialRoomSettings, InitOptions, InstanceProperties, Stored, UserId } from './types';
6
+ export declare class DigitalSambaEmbedded extends EventEmitter implements EmbeddedInstance {
5
7
  initOptions: Partial<InitOptions>;
8
+ roomSettings: Partial<InitialRoomSettings>;
6
9
  savedIframeSrc: string;
7
10
  allowedOrigin: string;
8
11
  connected: boolean;
9
12
  frame: HTMLIFrameElement;
10
13
  reportErrors: boolean;
11
- private stored;
14
+ stored: Stored;
15
+ permissionManager: PermissionManager;
12
16
  constructor(options?: Partial<InitOptions>, instanceProperties?: Partial<InstanceProperties>, loadImmediately?: boolean);
13
17
  static createControl: (initOptions: InitOptions) => DigitalSambaEmbedded;
14
18
  private mountFrame;
@@ -18,11 +22,14 @@ export declare class DigitalSambaEmbedded extends EventEmitter {
18
22
  private _emit;
19
23
  private handleInternalMessage;
20
24
  private emitUsersUpdated;
25
+ private emitRoomStateUpdated;
21
26
  private setFrameSrc;
22
27
  private checkTarget;
23
28
  private sendMessage;
24
29
  private logError;
25
30
  private applyFrameProperties;
31
+ get roomState(): import("./types").RoomState;
32
+ get localUser(): import("./types").User;
26
33
  enableVideo: () => void;
27
34
  disableVideo: () => void;
28
35
  toggleVideo: (enable?: boolean) => void;
@@ -48,4 +55,10 @@ export declare class DigitalSambaEmbedded extends EventEmitter {
48
55
  hideCaptions: () => void;
49
56
  toggleCaptions: (show?: boolean) => void;
50
57
  configureCaptions: (options: Partial<CaptionsOptions>) => void;
58
+ raiseHand: () => void;
59
+ lowerHand: (target?: UserId) => void;
60
+ allowBroadcast: (userId: UserId) => void;
61
+ disallowBroadcast: (userId: UserId) => void;
62
+ allowScreenshare: (userId: UserId) => void;
63
+ disallowScreenshare: (userId: UserId) => void;
51
64
  }
package/dist/esm/index.js CHANGED
@@ -1,22 +1,20 @@
1
1
  var _a;
2
- import { ALLOW_ATTRIBUTE_MISSING, INVALID_CONFIG, INVALID_URL, UNKNOWN_TARGET, } from './utils/errors';
3
2
  import EventEmitter from 'events';
4
- const CONNECT_TIMEOUT = 10000;
5
- const internalEvents = {
6
- roomJoined: true,
7
- };
3
+ import { PermissionManager } from './utils/PermissionManager';
4
+ import { CONNECT_TIMEOUT, defaultStoredState, internalEvents, } from './utils/vars';
5
+ import { createWatchedProxy } from './utils/proxy';
6
+ import { ALLOW_ATTRIBUTE_MISSING, INVALID_CONFIG, INVALID_URL, UNKNOWN_TARGET, } from './utils/errors';
8
7
  export class DigitalSambaEmbedded extends EventEmitter {
9
8
  constructor(options = {}, instanceProperties = {}, loadImmediately = true) {
10
9
  super();
10
+ this.roomSettings = {};
11
11
  this.savedIframeSrc = '';
12
12
  this.allowedOrigin = '*';
13
13
  this.connected = false;
14
14
  this.frame = document.createElement('iframe');
15
15
  this.reportErrors = false;
16
- this.stored = {
17
- users: {},
18
- localUserPermissions: {},
19
- };
16
+ this.stored = Object.assign({}, defaultStoredState);
17
+ this.permissionManager = new PermissionManager(this);
20
18
  this.mountFrame = (loadImmediately) => {
21
19
  const { url, frame, root } = this.initOptions;
22
20
  if (root) {
@@ -74,6 +72,9 @@ export class DigitalSambaEmbedded extends EventEmitter {
74
72
  this.on('userJoined', (event) => {
75
73
  const { user, type } = event.data;
76
74
  this.stored.users[user.id] = Object.assign(Object.assign({}, user), { kind: type });
75
+ if (type === 'local') {
76
+ this.stored.userId = user.id;
77
+ }
77
78
  this.emitUsersUpdated();
78
79
  });
79
80
  this.on('userLeft', (event) => {
@@ -84,7 +85,58 @@ export class DigitalSambaEmbedded extends EventEmitter {
84
85
  this.emitUsersUpdated();
85
86
  });
86
87
  this.on('permissionsChanged', (event) => {
87
- this.stored.localUserPermissions = Object.assign(Object.assign({}, this.stored.localUserPermissions), (event.data || {}));
88
+ if (this.stored.users[this.stored.userId]) {
89
+ let modifiedPermissions = [
90
+ ...(this.stored.users[this.stored.userId].dynamicPermissions || []),
91
+ ];
92
+ Object.entries(event.data).forEach(([permission, enabled]) => {
93
+ if (enabled && !modifiedPermissions.includes(permission)) {
94
+ modifiedPermissions.push(permission);
95
+ }
96
+ if (!enabled) {
97
+ modifiedPermissions = modifiedPermissions.filter((userPermission) => userPermission !== permission);
98
+ }
99
+ });
100
+ this.stored.users[this.stored.userId].dynamicPermissions =
101
+ modifiedPermissions;
102
+ }
103
+ });
104
+ this.on('activeSpeakerChanged', (event) => {
105
+ var _b, _c;
106
+ this.stored.activeSpeaker = (_c = (_b = event.data) === null || _b === void 0 ? void 0 : _b.user) === null || _c === void 0 ? void 0 : _c.id;
107
+ });
108
+ this.on('videoEnabled', (event) => {
109
+ var _b;
110
+ if (((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'local') {
111
+ this.stored.roomState.media.cameraEnabled = true;
112
+ }
113
+ });
114
+ this.on('videoDisabled', (event) => {
115
+ var _b;
116
+ if (((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'local') {
117
+ this.stored.roomState.media.cameraEnabled = false;
118
+ }
119
+ });
120
+ this.on('audioEnabled', (event) => {
121
+ var _b;
122
+ if (((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'local') {
123
+ this.stored.roomState.media.micEnabled = true;
124
+ }
125
+ });
126
+ this.on('audioDisabled', (event) => {
127
+ var _b;
128
+ if (((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'local') {
129
+ this.stored.roomState.media.micEnabled = false;
130
+ }
131
+ });
132
+ this.on('layoutModeChanged', (event) => {
133
+ this.stored.roomState.layout.mode = event.data.mode;
134
+ });
135
+ this.on('captionsSpokenLanguageChanged', (event) => {
136
+ this.stored.roomState.captionsState.spokenLanguage = event.data.language;
137
+ });
138
+ this.on('captionsFontSizeChanged', (event) => {
139
+ this.stored.roomState.captionsState.fontSize = event.data.fontSize;
88
140
  });
89
141
  };
90
142
  this._emit = (eventName, ...args) => {
@@ -95,8 +147,14 @@ export class DigitalSambaEmbedded extends EventEmitter {
95
147
  const message = event.DSPayload;
96
148
  switch (message.type) {
97
149
  case 'roomJoined': {
98
- this.stored.users = message.data.users;
150
+ const { users, roomState, activeSpeaker, permissionsMap } = message.data;
151
+ this.stored.users = Object.assign(Object.assign({}, this.stored.users), users);
152
+ this.stored.roomState = createWatchedProxy(Object.assign({}, roomState), this.emitRoomStateUpdated);
153
+ this.stored.activeSpeaker = activeSpeaker;
154
+ this.permissionManager.permissionsMap = permissionsMap;
99
155
  this.emitUsersUpdated();
156
+ this.emitRoomStateUpdated();
157
+ this._emit('roomJoined', { type: 'roomJoined' });
100
158
  break;
101
159
  }
102
160
  default: {
@@ -107,15 +165,21 @@ export class DigitalSambaEmbedded extends EventEmitter {
107
165
  this.emitUsersUpdated = () => {
108
166
  this._emit('usersUpdated', { type: 'usersUpdated', data: { users: this.listUsers() } });
109
167
  };
168
+ this.emitRoomStateUpdated = () => {
169
+ this._emit('roomStateUpdated', { type: 'roomStateUpdated', data: { state: this.roomState } });
170
+ };
110
171
  this.setFrameSrc = () => {
111
172
  let url = this.savedIframeSrc;
112
173
  const { team, room, token } = this.initOptions;
113
174
  if (team && room) {
114
175
  url = `https://${team}.digitalsamba.com/${room}`;
115
176
  }
116
- if (url && token) {
177
+ if (url) {
117
178
  const urlObj = new URL(url);
118
- urlObj.searchParams.append('token', token);
179
+ urlObj.searchParams.append('dsEmbedFrame', 'true');
180
+ if (token) {
181
+ urlObj.searchParams.append('token', token);
182
+ }
119
183
  url = urlObj.toString();
120
184
  }
121
185
  if (url) {
@@ -127,7 +191,10 @@ export class DigitalSambaEmbedded extends EventEmitter {
127
191
  }
128
192
  const allowedURL = new URL(this.frame.src);
129
193
  this.allowedOrigin = allowedURL.origin;
130
- this.frame.onload = () => this.checkTarget();
194
+ this.frame.onload = () => {
195
+ this._emit('frameLoaded');
196
+ this.checkTarget();
197
+ };
131
198
  };
132
199
  this.logError = (error) => {
133
200
  if (this.reportErrors) {
@@ -152,9 +219,11 @@ export class DigitalSambaEmbedded extends EventEmitter {
152
219
  };
153
220
  // commands
154
221
  this.enableVideo = () => {
222
+ this.roomSettings.cameraEnabled = true;
155
223
  this.sendMessage({ type: 'enableVideo' });
156
224
  };
157
225
  this.disableVideo = () => {
226
+ this.roomSettings.cameraEnabled = false;
158
227
  this.sendMessage({ type: 'disableVideo' });
159
228
  };
160
229
  this.toggleVideo = (enable) => {
@@ -169,9 +238,11 @@ export class DigitalSambaEmbedded extends EventEmitter {
169
238
  }
170
239
  };
171
240
  this.enableAudio = () => {
241
+ this.roomSettings.micEnabled = true;
172
242
  this.sendMessage({ type: 'enableAudio' });
173
243
  };
174
244
  this.disableAudio = () => {
245
+ this.roomSettings.micEnabled = false;
175
246
  this.sendMessage({ type: 'disableAudio' });
176
247
  };
177
248
  this.toggleAudio = (enable) => {
@@ -198,12 +269,17 @@ export class DigitalSambaEmbedded extends EventEmitter {
198
269
  this.sendMessage({ type: 'stopRecording' });
199
270
  };
200
271
  this.showToolbar = () => {
272
+ this.roomSettings.showToolbar = true;
273
+ this.stored.roomState.layout.showToolbar = true;
201
274
  this.sendMessage({ type: 'showToolbar' });
202
275
  };
203
276
  this.hideToolbar = () => {
277
+ this.roomSettings.showToolbar = false;
278
+ this.stored.roomState.layout.showToolbar = false;
204
279
  this.sendMessage({ type: 'hideToolbar' });
205
280
  };
206
281
  this.changeLayoutMode = (mode) => {
282
+ this.roomSettings.layoutMode = mode;
207
283
  this.sendMessage({ type: 'changeLayoutMode', data: mode });
208
284
  };
209
285
  this.leaveSession = () => {
@@ -214,6 +290,7 @@ export class DigitalSambaEmbedded extends EventEmitter {
214
290
  };
215
291
  this.toggleToolbar = (show) => {
216
292
  if (typeof show === 'undefined') {
293
+ this.stored.roomState.layout.showToolbar = !this.stored.roomState.layout.showToolbar;
217
294
  this.sendMessage({ type: 'toggleToolbar' });
218
295
  }
219
296
  else if (show) {
@@ -245,13 +322,19 @@ export class DigitalSambaEmbedded extends EventEmitter {
245
322
  };
246
323
  this.listUsers = () => Object.values(this.stored.users);
247
324
  this.showCaptions = () => {
325
+ this.roomSettings.showCaptions = true;
326
+ this.stored.roomState.captionsState.showCaptions = true;
248
327
  this.sendMessage({ type: 'showCaptions' });
249
328
  };
250
329
  this.hideCaptions = () => {
330
+ this.roomSettings.showCaptions = false;
331
+ this.stored.roomState.captionsState.showCaptions = false;
251
332
  this.sendMessage({ type: 'hideCaptions' });
252
333
  };
253
334
  this.toggleCaptions = (show) => {
254
335
  if (typeof show === 'undefined') {
336
+ this.stored.roomState.captionsState.showCaptions =
337
+ !this.stored.roomState.captionsState.showCaptions;
255
338
  this.sendMessage({ type: 'toggleCaptions' });
256
339
  }
257
340
  else if (show) {
@@ -264,7 +347,26 @@ export class DigitalSambaEmbedded extends EventEmitter {
264
347
  this.configureCaptions = (options) => {
265
348
  this.sendMessage({ type: 'configureCaptions', data: options || {} });
266
349
  };
350
+ this.raiseHand = () => {
351
+ this.sendMessage({ type: 'raiseHand' });
352
+ };
353
+ this.lowerHand = (target) => {
354
+ this.sendMessage({ type: 'lowerHand', data: target });
355
+ };
356
+ this.allowBroadcast = (userId) => {
357
+ this.sendMessage({ type: 'allowBroadcast', data: userId });
358
+ };
359
+ this.disallowBroadcast = (userId) => {
360
+ this.sendMessage({ type: 'disallowBroadcast', data: userId });
361
+ };
362
+ this.allowScreenshare = (userId) => {
363
+ this.sendMessage({ type: 'allowScreenshare', data: userId });
364
+ };
365
+ this.disallowScreenshare = (userId) => {
366
+ this.sendMessage({ type: 'disallowScreenshare', data: userId });
367
+ };
267
368
  this.initOptions = options;
369
+ this.roomSettings = options.roomSettings || {};
268
370
  this.reportErrors = instanceProperties.reportErrors || false;
269
371
  this.frame.allow = 'camera; microphone; display-capture; autoplay;';
270
372
  this.frame.setAttribute('allowFullscreen', 'true');
@@ -279,7 +381,7 @@ export class DigitalSambaEmbedded extends EventEmitter {
279
381
  this.setupInternalEventListeners();
280
382
  }
281
383
  checkTarget() {
282
- this.sendMessage({ type: 'connect' });
384
+ this.sendMessage({ type: 'connect', data: this.roomSettings || {} });
283
385
  const confirmationTimeout = window.setTimeout(() => {
284
386
  this.logError(UNKNOWN_TARGET);
285
387
  }, CONNECT_TIMEOUT);
@@ -290,11 +392,21 @@ export class DigitalSambaEmbedded extends EventEmitter {
290
392
  }
291
393
  sendMessage(message) {
292
394
  if (this.frame.contentWindow) {
395
+ if (!this.connected && message.type !== 'connect') {
396
+ return;
397
+ }
293
398
  this.frame.contentWindow.postMessage(message, {
294
399
  targetOrigin: this.allowedOrigin,
295
400
  });
296
401
  }
297
402
  }
403
+ // getters
404
+ get roomState() {
405
+ return this.stored.roomState;
406
+ }
407
+ get localUser() {
408
+ return this.stored.users[this.stored.userId];
409
+ }
298
410
  }
299
411
  _a = DigitalSambaEmbedded;
300
412
  DigitalSambaEmbedded.createControl = (initOptions) => new _a(initOptions, {}, false);