@webex/plugin-meetings 3.9.0-webinar5k.1 → 3.10.0

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 (138) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +24 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/controls-options-manager/index.js +22 -5
  6. package/dist/controls-options-manager/index.js.map +1 -1
  7. package/dist/index.js +2 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/interceptors/index.js +7 -0
  10. package/dist/interceptors/index.js.map +1 -1
  11. package/dist/interceptors/locusRouteToken.js +116 -0
  12. package/dist/interceptors/locusRouteToken.js.map +1 -0
  13. package/dist/interpretation/index.js +1 -1
  14. package/dist/interpretation/siLanguage.js +1 -1
  15. package/dist/locus-info/controlsUtils.js +11 -2
  16. package/dist/locus-info/controlsUtils.js.map +1 -1
  17. package/dist/locus-info/index.js +76 -322
  18. package/dist/locus-info/index.js.map +1 -1
  19. package/dist/locus-info/parser.js +4 -1
  20. package/dist/locus-info/parser.js.map +1 -1
  21. package/dist/media/properties.js +53 -5
  22. package/dist/media/properties.js.map +1 -1
  23. package/dist/meeting/in-meeting-actions.js +14 -0
  24. package/dist/meeting/in-meeting-actions.js.map +1 -1
  25. package/dist/meeting/index.js +467 -277
  26. package/dist/meeting/index.js.map +1 -1
  27. package/dist/meeting/request.js +177 -14
  28. package/dist/meeting/request.js.map +1 -1
  29. package/dist/meeting/type.js +7 -0
  30. package/dist/meeting/type.js.map +1 -0
  31. package/dist/meeting/util.js +100 -3
  32. package/dist/meeting/util.js.map +1 -1
  33. package/dist/meeting-info/meeting-info-v2.js +29 -21
  34. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  35. package/dist/meetings/index.js +20 -16
  36. package/dist/meetings/index.js.map +1 -1
  37. package/dist/member/index.js +9 -0
  38. package/dist/member/index.js.map +1 -1
  39. package/dist/member/util.js +10 -0
  40. package/dist/member/util.js.map +1 -1
  41. package/dist/members/index.js +10 -7
  42. package/dist/members/index.js.map +1 -1
  43. package/dist/members/util.js +7 -2
  44. package/dist/members/util.js.map +1 -1
  45. package/dist/metrics/constants.js +2 -1
  46. package/dist/metrics/constants.js.map +1 -1
  47. package/dist/multistream/mediaRequestManager.js +1 -1
  48. package/dist/multistream/mediaRequestManager.js.map +1 -1
  49. package/dist/multistream/remoteMedia.js +34 -5
  50. package/dist/multistream/remoteMedia.js.map +1 -1
  51. package/dist/multistream/remoteMediaGroup.js +42 -2
  52. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  53. package/dist/reachability/index.js +3 -3
  54. package/dist/reachability/index.js.map +1 -1
  55. package/dist/types/constants.d.ts +23 -0
  56. package/dist/types/controls-options-manager/index.d.ts +9 -1
  57. package/dist/types/interceptors/index.d.ts +2 -1
  58. package/dist/types/interceptors/locusRouteToken.d.ts +38 -0
  59. package/dist/types/locus-info/index.d.ts +9 -54
  60. package/dist/types/media/properties.d.ts +21 -0
  61. package/dist/types/meeting/in-meeting-actions.d.ts +14 -0
  62. package/dist/types/meeting/index.d.ts +64 -29
  63. package/dist/types/meeting/request.d.ts +42 -0
  64. package/dist/types/meeting/type.d.ts +9 -0
  65. package/dist/types/meeting/util.d.ts +13 -0
  66. package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
  67. package/dist/types/meetings/index.d.ts +3 -1
  68. package/dist/types/member/index.d.ts +1 -0
  69. package/dist/types/member/util.d.ts +5 -0
  70. package/dist/types/members/index.d.ts +12 -11
  71. package/dist/types/members/util.d.ts +8 -4
  72. package/dist/types/metrics/constants.d.ts +1 -0
  73. package/dist/types/multistream/remoteMedia.d.ts +20 -1
  74. package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
  75. package/dist/webinar/index.js +1 -1
  76. package/package.json +25 -27
  77. package/src/constants.ts +26 -2
  78. package/src/controls-options-manager/index.ts +26 -5
  79. package/src/index.ts +2 -1
  80. package/src/interceptors/index.ts +2 -1
  81. package/src/interceptors/locusRouteToken.ts +80 -0
  82. package/src/locus-info/controlsUtils.ts +18 -0
  83. package/src/locus-info/index.ts +69 -357
  84. package/src/locus-info/parser.ts +5 -1
  85. package/src/media/properties.ts +43 -0
  86. package/src/meeting/in-meeting-actions.ts +29 -0
  87. package/src/meeting/index.ts +296 -87
  88. package/src/meeting/request.ts +141 -0
  89. package/src/meeting/type.ts +9 -0
  90. package/src/meeting/util.ts +107 -3
  91. package/src/meeting-info/meeting-info-v2.ts +24 -5
  92. package/src/meetings/index.ts +15 -22
  93. package/src/member/index.ts +10 -0
  94. package/src/member/util.ts +14 -0
  95. package/src/members/index.ts +20 -10
  96. package/src/members/util.ts +20 -3
  97. package/src/metrics/constants.ts +1 -0
  98. package/src/multistream/mediaRequestManager.ts +7 -7
  99. package/src/multistream/remoteMedia.ts +34 -4
  100. package/src/multistream/remoteMediaGroup.ts +37 -2
  101. package/src/reachability/index.ts +3 -3
  102. package/test/unit/spec/common/browser-detection.js +0 -24
  103. package/test/unit/spec/controls-options-manager/index.js +47 -0
  104. package/test/unit/spec/fixture/locus.js +1 -0
  105. package/test/unit/spec/interceptors/locusRouteToken.ts +87 -0
  106. package/test/unit/spec/locus-info/index.js +80 -361
  107. package/test/unit/spec/locus-info/parser.js +3 -2
  108. package/test/unit/spec/media/properties.ts +137 -0
  109. package/test/unit/spec/meeting/in-meeting-actions.ts +14 -0
  110. package/test/unit/spec/meeting/index.js +637 -53
  111. package/test/unit/spec/meeting/muteState.js +32 -6
  112. package/test/unit/spec/meeting/request.js +21 -0
  113. package/test/unit/spec/meeting/utils.js +171 -18
  114. package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
  115. package/test/unit/spec/meetings/index.js +12 -5
  116. package/test/unit/spec/member/util.js +24 -0
  117. package/test/unit/spec/members/collection.js +120 -0
  118. package/test/unit/spec/members/index.js +107 -2
  119. package/test/unit/spec/members/request.js +55 -0
  120. package/test/unit/spec/members/utils.js +116 -14
  121. package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
  122. package/test/unit/spec/multistream/remoteMedia.ts +66 -2
  123. package/test/unit/spec/reachability/index.ts +158 -3
  124. package/test/unit/spec/roap/turnDiscovery.ts +3 -3
  125. package/dist/hashTree/constants.js +0 -23
  126. package/dist/hashTree/constants.js.map +0 -1
  127. package/dist/hashTree/hashTree.js +0 -516
  128. package/dist/hashTree/hashTree.js.map +0 -1
  129. package/dist/hashTree/hashTreeParser.js +0 -521
  130. package/dist/hashTree/hashTreeParser.js.map +0 -1
  131. package/dist/types/hashTree/constants.d.ts +0 -8
  132. package/dist/types/hashTree/hashTree.d.ts +0 -128
  133. package/dist/types/hashTree/hashTreeParser.d.ts +0 -152
  134. package/src/hashTree/constants.ts +0 -12
  135. package/src/hashTree/hashTree.ts +0 -460
  136. package/src/hashTree/hashTreeParser.ts +0 -556
  137. package/test/unit/spec/hashTree/hashTree.ts +0 -394
  138. package/test/unit/spec/hashTree/hashTreeParser.ts +0 -156
@@ -4,6 +4,7 @@ import MembersCollection from './collection';
4
4
  import { ReceiveSlotManager } from '../multistream/receiveSlotManager';
5
5
  import { MediaRequestManager } from '../multistream/mediaRequestManager';
6
6
  import { ServerRoleShape } from './types';
7
+ import { Invitee } from '../meeting/type';
7
8
  /**
8
9
  * @class Members
9
10
  */
@@ -76,7 +77,9 @@ export default class Members extends StatelessWebexPlugin {
76
77
  * when new participant updates come in, both delta and full participants, update them in members collection
77
78
  * delta object in the event will have {updated, added} and full will be the full membersCollection
78
79
  * @param {Object} payload
79
- * @param {Object} payload.participants
80
+ * @param {Object} payload.participants new/updated participants
81
+ * @param {Boolean} payload.isReplace whether to replace the whole members collection
82
+ * @param {Object} payload.removedParticipantIds ids of the removed participants
80
83
  * @returns {undefined}
81
84
  * @private
82
85
  * @memberof Members
@@ -219,31 +222,28 @@ export default class Members extends StatelessWebexPlugin {
219
222
  private update;
220
223
  /**
221
224
  * Adds a guest Member to the associated meeting
222
- * @param {String} invitee
225
+ * @param {Invitee} invitee
223
226
  * @param {Boolean} [alertIfActive]
224
227
  * @returns {Promise}
225
228
  * @memberof Members
226
229
  */
227
- addMember(invitee: any, alertIfActive?: boolean): any;
230
+ addMember(invitee: Invitee, alertIfActive?: boolean): any;
228
231
  /**
229
232
  * Cancels an outgoing PSTN call to the associated meeting
230
- * @param {String} invitee
233
+ * @param {Invitee} invitee
231
234
  * @returns {Promise}
232
235
  * @memberof Members
233
236
  */
234
- cancelPhoneInvite(invitee: any): any;
237
+ cancelPhoneInvite(invitee: Invitee): any;
235
238
  /**
236
239
  * Cancels an SIP/phone call to the associated meeting
237
- * @param {Object} invitee
240
+ * @param {Invitee} invitee
238
241
  * @param {String} invitee.memberId - The memberId of the invitee
239
242
  * @param {Boolean} [invitee.isInternalNumber] - When cancel phone invitation, if the number is internal
240
243
  * @returns {Promise}
241
244
  * @memberof Members
242
245
  */
243
- cancelInviteByMemberId(invitee: {
244
- memberId: string;
245
- isInternalNumber?: boolean;
246
- }): any;
246
+ cancelInviteByMemberId(invitee: Invitee): any;
247
247
  /**
248
248
  * Admits waiting members (invited guests to meeting)
249
249
  * @param {Array} memberIds
@@ -347,9 +347,10 @@ export default class Members extends StatelessWebexPlugin {
347
347
  * @param {string} memberId - id of the participant who is receiving request
348
348
  * @param {string} requestingParticipantId - id of the participant who is sending request (optional)
349
349
  * @param {string} [alias] - alias name
350
+ * @param {string} [suffix] - name suffix (optional)
350
351
  * @returns {Promise}
351
352
  * @public
352
353
  * @memberof Members
353
354
  */
354
- editDisplayName(memberId: string, requestingParticipantId: string, alias: string): any;
355
+ editDisplayName(memberId: string, requestingParticipantId: string, alias: string, suffix?: string): any;
355
356
  }
@@ -1,4 +1,5 @@
1
1
  import { RoleAssignmentOptions, RoleAssignmentRequest, ServerRoleShape } from './types';
2
+ import { Invitee } from '../meeting/type';
2
3
  declare const MembersUtil: {
3
4
  /**
4
5
  * @param {Object} invitee with emailAddress, email or phoneNumber
@@ -63,7 +64,7 @@ declare const MembersUtil: {
63
64
  alertIfActive: any;
64
65
  };
65
66
  };
66
- isInvalidInvitee: (invitee: any) => boolean;
67
+ isInvalidInvitee: (invitee: Invitee) => boolean;
67
68
  getRemoveMemberRequestParams: (options: any) => {
68
69
  method: string;
69
70
  uri: string;
@@ -109,13 +110,15 @@ declare const MembersUtil: {
109
110
  * @param {String} requestingParticipantId id of the participant who is sending request (optional)
110
111
  * @param {String} alias alias name
111
112
  * @param {String} locusUrl url
113
+ * @param {String} suffix optional suffix
112
114
  * @returns {Object} consists of {memberID: string, requestingParticipantId: string, alias: string, locusUrl: string}
113
115
  */
114
- generateEditDisplayNameMemberOptions: (memberId: any, requestingParticipantId: any, alias: any, locusUrl: any) => {
116
+ generateEditDisplayNameMemberOptions: (memberId: any, requestingParticipantId: any, alias: any, locusUrl: any, suffix: any) => {
115
117
  memberId: any;
116
118
  requestingParticipantId: any;
117
119
  alias: any;
118
120
  locusUrl: any;
121
+ suffix: any;
119
122
  };
120
123
  getMuteMemberRequestParams: (options: any) => {
121
124
  method: string;
@@ -177,8 +180,9 @@ declare const MembersUtil: {
177
180
  method: string;
178
181
  uri: string;
179
182
  body: {
180
- aliasValue: any;
181
- requestingParticipantId: any;
183
+ aliasValue: string;
184
+ requestingParticipantId: string;
185
+ suffixValue?: string;
182
186
  };
183
187
  };
184
188
  getTransferHostToMemberRequestParams: (options: any) => {
@@ -83,5 +83,6 @@ declare const BEHAVIORAL_METRICS: {
83
83
  VERIFY_REGISTRATION_ID_SUCCESS: string;
84
84
  VERIFY_REGISTRATION_ID_ERROR: string;
85
85
  JOIN_FORBIDDEN_ERROR: string;
86
+ MEDIA_ISSUE_DETECTED: string;
86
87
  };
87
88
  export { BEHAVIORAL_METRICS as default };
@@ -7,9 +7,17 @@ export declare const RemoteMediaEvents: {
7
7
  Stopped: string;
8
8
  };
9
9
  export type RemoteVideoResolution = 'thumbnail' | 'very small' | 'small' | 'medium' | 'large' | 'best';
10
+ export declare const MAX_FS_VALUES: {
11
+ '90p': number;
12
+ '180p': number;
13
+ '360p': number;
14
+ '540p': number;
15
+ '720p': number;
16
+ '1080p': number;
17
+ };
10
18
  /**
11
19
  * Converts pane size into h264 maxFs
12
- * @param {PaneSize} paneSize
20
+ * @param {RemoteVideoResolution} paneSize
13
21
  * @returns {number}
14
22
  */
15
23
  export declare function getMaxFs(paneSize: RemoteVideoResolution): number;
@@ -29,6 +37,12 @@ export declare class RemoteMedia extends EventsScope {
29
37
  private readonly options;
30
38
  private mediaRequestId?;
31
39
  readonly id: RemoteMediaId;
40
+ /**
41
+ * The max frame size of the media request, used for logging and media requests.
42
+ * Set by setSizeHint() based on video element dimensions.
43
+ * When > 0, this value takes precedence over options.resolution in sendMediaRequest().
44
+ */
45
+ private maxFrameSize;
32
46
  /**
33
47
  * Constructs RemoteMedia instance
34
48
  *
@@ -45,6 +59,11 @@ export declare class RemoteMedia extends EventsScope {
45
59
  * @note width/height of 0 will be ignored
46
60
  */
47
61
  setSizeHint(width: any, height: any): void;
62
+ /**
63
+ * Get the current effective maxFs value that would be used in media requests
64
+ * @returns {number | undefined} The maxFs value, or undefined if no constraints
65
+ */
66
+ getEffectiveMaxFs(): number | undefined;
48
67
  /**
49
68
  * registers event listeners on the receive slot and forwards all the events
50
69
  */
@@ -45,5 +45,16 @@ export declare class RemoteMediaGroup {
45
45
  * @returns true if remote media is found
46
46
  */
47
47
  includes(remoteMedia: RemoteMedia, filter?: 'all' | 'pinned' | 'unpinned'): boolean;
48
+ /**
49
+ * Calculate the effective maxFs for the active speaker media request based on unpinned RemoteMedia instances
50
+ * @returns {number | undefined} The calculated maxFs value, or undefined if no constraints
51
+ * @private
52
+ */
53
+ private getEffectiveMaxFsForActiveSpeaker;
54
+ /**
55
+ * Get the current effective maxFs that would be used for the active speaker media request
56
+ * @returns {number | undefined} The effective maxFs value
57
+ */
58
+ getEffectiveMaxFs(): number | undefined;
48
59
  }
49
60
  export {};
@@ -458,7 +458,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
458
458
  }, _callee7);
459
459
  }))();
460
460
  },
461
- version: "3.9.0-webinar5k.1"
461
+ version: "3.10.0"
462
462
  });
463
463
  var _default = exports.default = Webinar;
464
464
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
3
  "description": "",
4
- "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
4
+ "license": "Cisco's General Terms (https://www.cisco.com/site/us/en/about/legal/contract-experience/index.html)",
5
5
  "contributors": [
6
6
  "Adam Weeks <adweeks@cisco.com> (https://adamweeks.com/)",
7
7
  "Arun Ganeshan <arungane@cisco.com>",
@@ -19,7 +19,7 @@
19
19
  "directory": "packages/@webex/plugin-meetings"
20
20
  },
21
21
  "engines": {
22
- "node": ">=16"
22
+ "node": ">=18"
23
23
  },
24
24
  "browserify": {
25
25
  "transform": [
@@ -43,13 +43,12 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.9.0-webinar5k.1",
47
- "@webex/plugin-rooms": "3.9.0-webinar5k.1",
48
- "@webex/test-helper-chai": "3.9.0-webinar5k.1",
49
- "@webex/test-helper-mocha": "3.9.0-webinar5k.1",
50
- "@webex/test-helper-mock-webex": "3.9.0-webinar5k.1",
51
- "@webex/test-helper-retry": "3.9.0-webinar5k.1",
52
- "@webex/test-helper-test-users": "3.9.0-webinar5k.1",
46
+ "@webex/plugin-rooms": "3.10.0",
47
+ "@webex/test-helper-chai": "3.10.0",
48
+ "@webex/test-helper-mocha": "3.10.0",
49
+ "@webex/test-helper-mock-webex": "3.10.0",
50
+ "@webex/test-helper-retry": "3.10.0",
51
+ "@webex/test-helper-test-users": "3.10.0",
53
52
  "chai": "^4.3.4",
54
53
  "chai-as-promised": "^7.1.1",
55
54
  "eslint": "^8.24.0",
@@ -61,23 +60,23 @@
61
60
  "typescript": "^4.7.4"
62
61
  },
63
62
  "dependencies": {
64
- "@webex/common": "3.9.0-webinar5k.1",
65
- "@webex/event-dictionary-ts": "^1.0.1819",
66
- "@webex/internal-media-core": "2.18.5",
67
- "@webex/internal-plugin-conversation": "3.9.0-webinar5k.1",
68
- "@webex/internal-plugin-device": "3.9.0-webinar5k.1",
69
- "@webex/internal-plugin-llm": "3.9.0-webinar5k.1",
70
- "@webex/internal-plugin-mercury": "3.9.0-webinar5k.1",
71
- "@webex/internal-plugin-metrics": "3.9.0-webinar5k.1",
72
- "@webex/internal-plugin-support": "3.9.0-webinar5k.1",
73
- "@webex/internal-plugin-user": "3.9.0-webinar5k.1",
74
- "@webex/internal-plugin-voicea": "3.9.0-webinar5k.1",
75
- "@webex/media-helpers": "3.9.0-webinar5k.1",
76
- "@webex/plugin-people": "3.9.0-webinar5k.1",
77
- "@webex/plugin-rooms": "3.9.0-webinar5k.1",
63
+ "@webex/common": "3.10.0",
64
+ "@webex/event-dictionary-ts": "^1.0.1930",
65
+ "@webex/internal-media-core": "2.20.0",
66
+ "@webex/internal-plugin-conversation": "3.10.0",
67
+ "@webex/internal-plugin-device": "3.10.0",
68
+ "@webex/internal-plugin-llm": "3.10.0",
69
+ "@webex/internal-plugin-mercury": "3.10.0",
70
+ "@webex/internal-plugin-metrics": "3.10.0",
71
+ "@webex/internal-plugin-support": "3.10.0",
72
+ "@webex/internal-plugin-user": "3.10.0",
73
+ "@webex/internal-plugin-voicea": "3.10.0",
74
+ "@webex/media-helpers": "3.10.0",
75
+ "@webex/plugin-people": "3.10.0",
76
+ "@webex/plugin-rooms": "3.10.0",
78
77
  "@webex/ts-sdp": "^1.8.1",
79
78
  "@webex/web-capabilities": "^1.6.0",
80
- "@webex/webex-core": "3.9.0-webinar5k.1",
79
+ "@webex/webex-core": "3.10.0",
81
80
  "ampersand-collection": "^2.0.2",
82
81
  "bowser": "^2.11.0",
83
82
  "btoa": "^1.2.1",
@@ -88,11 +87,10 @@
88
87
  "jwt-decode": "3.1.2",
89
88
  "lodash": "^4.17.21",
90
89
  "uuid": "^3.3.2",
91
- "webrtc-adapter": "^8.1.2",
92
- "xxh3-ts": "^2.0.1"
90
+ "webrtc-adapter": "^8.1.2"
93
91
  },
94
92
  "//": [
95
93
  "TODO: upgrade jwt-decode when moving to node 18"
96
94
  ],
97
- "version": "3.9.0-webinar5k.1"
95
+ "version": "3.10.0"
98
96
  }
package/src/constants.ts CHANGED
@@ -263,7 +263,6 @@ export const RECORDING_STATE = {
263
263
  PAUSED: 'paused',
264
264
  RESUMED: 'resumed',
265
265
  };
266
-
267
266
  export const SHARE_STATUS = {
268
267
  NO_SHARE: 'no_share',
269
268
  REMOTE_SHARE_ACTIVE: 'remote_share_active',
@@ -348,6 +347,7 @@ export const EVENT_TRIGGERS = {
348
347
  MEETING_SELF_LEFT: 'meeting:self:left',
349
348
  NETWORK_QUALITY: 'network:quality',
350
349
  MEDIA_NEGOTIATED: 'media:negotiated',
350
+ MEDIA_INBOUND_AUDIO_ISSUE_DETECTED: 'media:inboundAudio:issueDetected',
351
351
  // the following events apply only to multistream media connections
352
352
  ACTIVE_SPEAKER_CHANGED: 'media:activeSpeakerChanged',
353
353
  REMOTE_VIDEO_SOURCE_COUNT_CHANGED: 'media:remoteVideoSourceCountChanged',
@@ -374,6 +374,8 @@ export const EVENT_TRIGGERS = {
374
374
  MEETING_CONTROLS_REMOTE_DESKTOP_CONTROL_UPDATED:
375
375
  'meeting:controls:remote-desktop-control:updated',
376
376
  MEETING_CONTROLS_POLLING_QA_UPDATED: 'meeting:controls:polling-qa:updated',
377
+ MEETING_CONTROLS_AUTO_END_MEETING_WARNING_UPDATED:
378
+ 'meeting:controls:auto-end-meeting-warning:updated',
377
379
  // Locus URL changed
378
380
  MEETING_LOCUS_URL_UPDATE: 'meeting:locus:locusUrl:update',
379
381
  MEETING_STREAM_PUBLISH_STATE_CHANGED: 'meeting:streamPublishStateChanged',
@@ -727,6 +729,7 @@ export const LOCUSINFO = {
727
729
  SELF_ADMITTED_GUEST: 'SELF_ADMITTED_GUEST',
728
730
  SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED: 'SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED',
729
731
  SELF_REMOTE_MUTE_STATUS_UPDATED: 'SELF_REMOTE_MUTE_STATUS_UPDATED',
732
+ CONTROLS_AUTO_END_MEETING_WARNING_CHANGED: 'CONTROLS_AUTO_END_MEETING_WARNING_CHANGED',
730
733
  LOCAL_UNMUTE_REQUESTED: 'LOCAL_UNMUTE_REQUESTED',
731
734
  LOCAL_UNMUTE_REQUIRED: 'LOCAL_UNMUTE_REQUIRED',
732
735
  SELF_MODERATOR_CHANGED: 'SELF_MODERATOR_CHANGED',
@@ -949,6 +952,9 @@ export const DISPLAY_HINTS = {
949
952
  PREMISE_RECORDING_CONTROL_PAUSE: 'PREMISE_RECORDING_CONTROL_PAUSE',
950
953
  PREMISE_RECORDING_CONTROL_STOP: 'PREMISE_RECORDING_CONTROL_STOP',
951
954
  PREMISE_RECORDING_CONTROL_RESUME: 'PREMISE_RECORDING_CONTROL_RESUME',
955
+ LOCAL_RECORDING_STATUS_STARTED: 'LOCAL_RECORDING_STATUS_STARTED',
956
+ LOCAL_RECORDING_STATUS_STOPPED: 'LOCAL_RECORDING_STATUS_STOPPED',
957
+ LOCAL_RECORDING_STATUS_PAUSED: 'LOCAL_RECORDING_STATUS_PAUSED',
952
958
  LOCK_CONTROL_UNLOCK: 'LOCK_CONTROL_UNLOCK',
953
959
  LOCK_CONTROL_LOCK: 'LOCK_CONTROL_LOCK',
954
960
  LOCK_STATUS_LOCKED: 'LOCK_STATUS_LOCKED',
@@ -958,12 +964,15 @@ export const DISPLAY_HINTS = {
958
964
  LOWER_SOMEONE_ELSES_HAND: 'LOWER_SOMEONE_ELSES_HAND',
959
965
  LEAVE_TRANSFER_HOST_END_MEETING: 'LEAVE_TRANSFER_HOST_END_MEETING',
960
966
  LEAVE_END_MEETING: 'LEAVE_END_MEETING',
967
+ STREAMING_STATUS_STARTED: 'STREAMING_STATUS_STARTED',
968
+ STREAMING_STATUS_STOPPED: 'STREAMING_STATUS_STOPPED',
961
969
  CAPTION_START: 'CAPTION_START',
962
970
  CAPTION_STATUS_ACTIVE: 'CAPTION_STATUS_ACTIVE',
963
971
  MANUAL_CAPTION_START: 'MANUAL_CAPTION_START',
964
972
  MANUAL_CAPTION_STOP: 'MANUAL_CAPTION_STOP',
965
973
  MANUAL_CAPTION_STATUS_ACTIVE: 'MANUAL_CAPTION_STATUS_ACTIVE',
966
974
  DISPLAY_REAL_TIME_TRANSLATION: 'DISPLAY_REAL_TIME_TRANSLATION',
975
+ SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED',
967
976
  ENABLE_CAPTION_PANEL: 'ENABLE_CAPTION_PANEL',
968
977
  DISPLAY_NON_ENGLISH_ASR: 'DISPLAY_NON_ENGLISH_ASR',
969
978
  TRANSCRIPTION_CONTROL_START: 'TRANSCRIPTION_CONTROL_START',
@@ -988,7 +997,6 @@ export const DISPLAY_HINTS = {
988
997
  CAN_RENAME_SELF_AND_OBSERVED: 'CAN_RENAME_SELF_AND_OBSERVED',
989
998
  CAN_RENAME_OTHERS: 'CAN_RENAME_OTHERS',
990
999
  MOVE_TO_LOBBY: 'MOVE_TO_LOBBY',
991
-
992
1000
  // breakout session
993
1001
  BREAKOUT_MANAGEMENT: 'BREAKOUT_MANAGEMENT',
994
1002
  BROADCAST_MESSAGE_TO_BREAKOUT: 'BROADCAST_MESSAGE_TO_BREAKOUT',
@@ -1049,6 +1057,9 @@ export const DISPLAY_HINTS = {
1049
1057
  ENABLE_ANNOTATION_MEETING_OPTION: 'ENABLE_ANNOTATION_MEETING_OPTION',
1050
1058
  DISABLE_ANNOTATION_MEETING_OPTION: 'DISABLE_ANNOTATION_MEETING_OPTION',
1051
1059
 
1060
+ // Auto End Meeting Warning
1061
+ SHOW_AUTO_END_MEETING_WARNING: 'SHOW_AUTO_END_MEETING_WARNING',
1062
+
1052
1063
  // Remote Desktop Control
1053
1064
  ENABLE_RDC_MEETING_OPTION: 'ENABLE_RDC_MEETING_OPTION',
1054
1065
  DISABLE_RDC_MEETING_OPTION: 'DISABLE_RDC_MEETING_OPTION',
@@ -1189,6 +1200,7 @@ export const QUALITY_LEVELS = {
1189
1200
  HIGH: 'HIGH',
1190
1201
  '360p': '360p',
1191
1202
  '480p': '480p',
1203
+ '540p': '540p',
1192
1204
  '720p': '720p',
1193
1205
  '1080p': '1080p',
1194
1206
  };
@@ -1218,6 +1230,18 @@ export const AVAILABLE_RESOLUTIONS = {
1218
1230
  },
1219
1231
  },
1220
1232
  },
1233
+ '540p': {
1234
+ video: {
1235
+ width: {
1236
+ max: 960,
1237
+ ideal: 960,
1238
+ },
1239
+ height: {
1240
+ max: 540,
1241
+ ideal: 540,
1242
+ },
1243
+ },
1244
+ },
1221
1245
  '720p': {
1222
1246
  video: {
1223
1247
  width: {
@@ -48,6 +48,14 @@ export default class ControlsOptionsManager {
48
48
  */
49
49
  private locusUrl: string;
50
50
 
51
+ /**
52
+ * @instance
53
+ * @type {string}
54
+ * @private
55
+ * @memberof ControlsOptionsManager
56
+ */
57
+ private mainLocusUrl: string;
58
+
51
59
  /**
52
60
  * @param {MeetingRequest} request
53
61
  * @param {Object} options
@@ -87,12 +95,16 @@ export default class ControlsOptionsManager {
87
95
 
88
96
  /**
89
97
  * @param {string} url
98
+ * @param {boolean} isMainLocus
90
99
  * @returns {void}
91
100
  * @public
92
101
  * @memberof ControlsOptionsManager
93
102
  */
94
- public setLocusUrl(url: string) {
103
+ public setLocusUrl(url: string, isMainLocus?: boolean) {
95
104
  this.locusUrl = url;
105
+ if (isMainLocus) {
106
+ this.mainLocusUrl = url;
107
+ }
96
108
  }
97
109
 
98
110
  /**
@@ -160,11 +172,16 @@ export default class ControlsOptionsManager {
160
172
  });
161
173
 
162
174
  return payloads.reduce((previous, payload) => {
175
+ const extraBody =
176
+ this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl
177
+ ? {authorizingLocusUrl: this.locusUrl}
178
+ : {};
179
+
163
180
  return previous.then(() =>
164
181
  // @ts-ignore
165
182
  this.request.request({
166
- uri: `${this.locusUrl}/${CONTROLS}`,
167
- body: payload,
183
+ uri: `${this.mainLocusUrl || this.locusUrl}/${CONTROLS}`,
184
+ body: {...payload, ...extraBody},
168
185
  method: HTTP_VERBS.PATCH,
169
186
  })
170
187
  );
@@ -241,11 +258,15 @@ export default class ControlsOptionsManager {
241
258
  if (error) {
242
259
  return Promise.reject(error);
243
260
  }
261
+ const extraBody =
262
+ this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl
263
+ ? {authorizingLocusUrl: this.locusUrl}
264
+ : {};
244
265
 
245
266
  // @ts-ignore
246
267
  return this.request.request({
247
- uri: `${this.locusUrl}/${CONTROLS}`,
248
- body,
268
+ uri: `${this.mainLocusUrl || this.locusUrl}/${CONTROLS}`,
269
+ body: {...body, ...extraBody},
249
270
  method: HTTP_VERBS.PATCH,
250
271
  });
251
272
  }
package/src/index.ts CHANGED
@@ -3,7 +3,7 @@ import {registerPlugin} from '@webex/webex-core';
3
3
 
4
4
  import Meetings from './meetings';
5
5
  import config from './config';
6
- import {LocusRetryStatusInterceptor} from './interceptors';
6
+ import {LocusRetryStatusInterceptor, LocusRouteTokenInterceptor} from './interceptors';
7
7
  import CaptchaError from './common/errors/captcha-error';
8
8
  import IntentToJoinError from './common/errors/intent-to-join';
9
9
  import PasswordError from './common/errors/password-error';
@@ -23,6 +23,7 @@ registerPlugin('meetings', Meetings, {
23
23
  config,
24
24
  interceptors: {
25
25
  LocusRetryStatusInterceptor: LocusRetryStatusInterceptor.create,
26
+ LocusRouteTokenInterceptor: LocusRouteTokenInterceptor.create,
26
27
  },
27
28
  });
28
29
 
@@ -1,3 +1,4 @@
1
1
  import LocusRetryStatusInterceptor from './locusRetry';
2
+ import LocusRouteTokenInterceptor from './locusRouteToken';
2
3
 
3
- export {LocusRetryStatusInterceptor};
4
+ export {LocusRetryStatusInterceptor, LocusRouteTokenInterceptor};
@@ -0,0 +1,80 @@
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import {Interceptor} from '@webex/http-core';
6
+ import {has} from 'lodash';
7
+
8
+ const LOCUS_ID_REGEX = /\/locus\/api\/v1\/loci\/([a-f0-9-]{36})/i;
9
+ const X_CISCO_PART_ROUTE_TOKEN = 'X-Cisco-Part-Route-Token';
10
+ const ROUTE_TOKEN = {};
11
+
12
+ /**
13
+ * @class LocusRouteTokenInterceptor
14
+ */
15
+ export default class LocusRouteTokenInterceptor extends Interceptor {
16
+ /**
17
+ * @returns {LocusRouteTokenInterceptor}
18
+ */
19
+ static create() {
20
+ // @ts-ignore
21
+ return new LocusRouteTokenInterceptor({webex: this});
22
+ }
23
+
24
+ getLocusIdByRequestUrl(url: string) {
25
+ return url?.match(LOCUS_ID_REGEX)?.[1];
26
+ }
27
+
28
+ /**
29
+ * @param {Object} options
30
+ * @param {HttpResponse} response
31
+ * @returns {Promise<HttpResponse>}
32
+ */
33
+ onResponse(options, response) {
34
+ const locusId = this.getLocusIdByRequestUrl(options.uri);
35
+ if (locusId) {
36
+ const hasRouteToken = has(response.headers, X_CISCO_PART_ROUTE_TOKEN);
37
+ const token = response.headers[X_CISCO_PART_ROUTE_TOKEN];
38
+ if (hasRouteToken) {
39
+ this.updateToken(locusId, token);
40
+ }
41
+ }
42
+
43
+ return Promise.resolve(response);
44
+ }
45
+
46
+ /**
47
+ * @param {Object} options
48
+ * @returns {Promise<Object>} options
49
+ */
50
+ onRequest(options) {
51
+ const locusId = this.getLocusIdByRequestUrl(options.uri);
52
+ if (locusId) {
53
+ const token = this.getToken(locusId);
54
+ if (token) {
55
+ options.headers[X_CISCO_PART_ROUTE_TOKEN] = token;
56
+ }
57
+ }
58
+
59
+ return Promise.resolve(options);
60
+ }
61
+
62
+ /**
63
+ * Update the meeting route token
64
+ * @param {string} locusId
65
+ * @param {string} token
66
+ * @returns {void}
67
+ */
68
+ updateToken(locusId, token) {
69
+ ROUTE_TOKEN[locusId] = token;
70
+ }
71
+
72
+ /**
73
+ * Get the meeting route token
74
+ * @param {string} locusId
75
+ * @returns {string|undefined}
76
+ */
77
+ getToken(locusId) {
78
+ return ROUTE_TOKEN[locusId];
79
+ }
80
+ }
@@ -130,6 +130,15 @@ ControlsUtils.parse = (controls: any) => {
130
130
  };
131
131
  }
132
132
 
133
+ if (controls?.autoEndMeetingWarning) {
134
+ parsedControls.autoEndMeetingWarning = {
135
+ enabled: controls.autoEndMeetingWarning.enabled,
136
+ extensionDurationMinutes: controls.autoEndMeetingWarning.extensionDurationMinutes,
137
+ countdownDurationMinutes: controls.autoEndMeetingWarning.countdownDurationMinutes,
138
+ countdownStartedAt: controls.autoEndMeetingWarning.countdownStartedAt,
139
+ };
140
+ }
141
+
133
142
  return parsedControls;
134
143
  };
135
144
 
@@ -244,6 +253,15 @@ ControlsUtils.getControls = (oldControls: any, newControls: any) => {
244
253
 
245
254
  hasPollingQAControlChanged:
246
255
  current?.pollingQAControl?.enabled !== previous?.pollingQAControl?.enabled,
256
+
257
+ hasAutoEndMeetingChanged:
258
+ current?.autoEndMeetingWarning?.enabled !== previous?.autoEndMeetingWarning?.enabled ||
259
+ current?.autoEndMeetingWarning?.extensionDurationMinutes !==
260
+ previous?.autoEndMeetingWarning?.extensionDurationMinutes ||
261
+ current?.autoEndMeetingWarning?.countdownDurationMinutes !==
262
+ previous?.autoEndMeetingWarning?.countdownDurationMinutes ||
263
+ current?.autoEndMeetingWarning?.countdownStartedAt !==
264
+ previous?.autoEndMeetingWarning?.countdownStartedAt,
247
265
  },
248
266
  };
249
267
  };