@webex/plugin-meetings 3.8.0-next.6 → 3.8.0-next.61

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 (156) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/common/errors/webex-errors.js +12 -2
  4. package/dist/common/errors/webex-errors.js.map +1 -1
  5. package/dist/config.js +1 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/constants.js +17 -121
  8. package/dist/constants.js.map +1 -1
  9. package/dist/controls-options-manager/enums.js +2 -0
  10. package/dist/controls-options-manager/enums.js.map +1 -1
  11. package/dist/controls-options-manager/types.js.map +1 -1
  12. package/dist/controls-options-manager/util.js +52 -0
  13. package/dist/controls-options-manager/util.js.map +1 -1
  14. package/dist/interpretation/index.js +1 -1
  15. package/dist/interpretation/siLanguage.js +1 -1
  16. package/dist/locus-info/controlsUtils.js +28 -10
  17. package/dist/locus-info/controlsUtils.js.map +1 -1
  18. package/dist/locus-info/index.js +20 -1
  19. package/dist/locus-info/index.js.map +1 -1
  20. package/dist/locus-info/selfUtils.js +405 -418
  21. package/dist/locus-info/selfUtils.js.map +1 -1
  22. package/dist/media/index.js +8 -16
  23. package/dist/media/index.js.map +1 -1
  24. package/dist/meeting/in-meeting-actions.js +17 -1
  25. package/dist/meeting/in-meeting-actions.js.map +1 -1
  26. package/dist/meeting/index.js +556 -288
  27. package/dist/meeting/index.js.map +1 -1
  28. package/dist/meeting/locusMediaRequest.js +0 -17
  29. package/dist/meeting/locusMediaRequest.js.map +1 -1
  30. package/dist/meeting/muteState.js +0 -2
  31. package/dist/meeting/muteState.js.map +1 -1
  32. package/dist/meeting/request.js +30 -0
  33. package/dist/meeting/request.js.map +1 -1
  34. package/dist/meeting/request.type.js.map +1 -1
  35. package/dist/meeting/util.js +13 -2
  36. package/dist/meeting/util.js.map +1 -1
  37. package/dist/meeting-info/meeting-info-v2.js +359 -60
  38. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  39. package/dist/meetings/index.js +91 -1
  40. package/dist/meetings/index.js.map +1 -1
  41. package/dist/meetings/util.js +14 -0
  42. package/dist/meetings/util.js.map +1 -1
  43. package/dist/member/index.js +10 -0
  44. package/dist/member/index.js.map +1 -1
  45. package/dist/member/util.js +3 -0
  46. package/dist/member/util.js.map +1 -1
  47. package/dist/members/index.js +23 -0
  48. package/dist/members/index.js.map +1 -1
  49. package/dist/members/request.js +21 -0
  50. package/dist/members/request.js.map +1 -1
  51. package/dist/members/util.js +15 -0
  52. package/dist/members/util.js.map +1 -1
  53. package/dist/metrics/constants.js +9 -0
  54. package/dist/metrics/constants.js.map +1 -1
  55. package/dist/reachability/clusterReachability.js +63 -27
  56. package/dist/reachability/clusterReachability.js.map +1 -1
  57. package/dist/reachability/index.js +112 -47
  58. package/dist/reachability/index.js.map +1 -1
  59. package/dist/reachability/reachability.types.js +14 -0
  60. package/dist/reachability/reachability.types.js.map +1 -1
  61. package/dist/reachability/request.js +19 -3
  62. package/dist/reachability/request.js.map +1 -1
  63. package/dist/reconnection-manager/index.js +2 -2
  64. package/dist/reconnection-manager/index.js.map +1 -1
  65. package/dist/recording-controller/util.js +5 -5
  66. package/dist/recording-controller/util.js.map +1 -1
  67. package/dist/roap/index.js.map +1 -1
  68. package/dist/roap/turnDiscovery.js +45 -27
  69. package/dist/roap/turnDiscovery.js.map +1 -1
  70. package/dist/roap/types.js +17 -0
  71. package/dist/roap/types.js.map +1 -0
  72. package/dist/types/common/errors/webex-errors.d.ts +7 -1
  73. package/dist/types/config.d.ts +1 -0
  74. package/dist/types/constants.d.ts +12 -85
  75. package/dist/types/controls-options-manager/enums.d.ts +3 -1
  76. package/dist/types/controls-options-manager/types.d.ts +7 -1
  77. package/dist/types/locus-info/index.d.ts +1 -0
  78. package/dist/types/locus-info/selfUtils.d.ts +247 -1
  79. package/dist/types/meeting/in-meeting-actions.d.ts +16 -0
  80. package/dist/types/meeting/index.d.ts +54 -1
  81. package/dist/types/meeting/muteState.d.ts +0 -1
  82. package/dist/types/meeting/request.d.ts +12 -1
  83. package/dist/types/meeting/request.type.d.ts +6 -0
  84. package/dist/types/meeting/util.d.ts +3 -1
  85. package/dist/types/meeting-info/meeting-info-v2.d.ts +80 -0
  86. package/dist/types/meetings/index.d.ts +38 -0
  87. package/dist/types/member/index.d.ts +1 -0
  88. package/dist/types/members/index.d.ts +8 -0
  89. package/dist/types/members/request.d.ts +19 -0
  90. package/dist/types/members/util.d.ts +13 -0
  91. package/dist/types/metrics/constants.d.ts +9 -0
  92. package/dist/types/reachability/clusterReachability.d.ts +15 -7
  93. package/dist/types/reachability/index.d.ts +10 -1
  94. package/dist/types/reachability/reachability.types.d.ts +5 -0
  95. package/dist/types/roap/index.d.ts +3 -2
  96. package/dist/types/roap/turnDiscovery.d.ts +5 -17
  97. package/dist/types/roap/types.d.ts +16 -0
  98. package/dist/webinar/index.js +1 -1
  99. package/package.json +23 -23
  100. package/src/common/errors/webex-errors.ts +8 -1
  101. package/src/config.ts +1 -0
  102. package/src/constants.ts +19 -90
  103. package/src/controls-options-manager/enums.ts +2 -0
  104. package/src/controls-options-manager/types.ts +11 -1
  105. package/src/controls-options-manager/util.ts +62 -0
  106. package/src/locus-info/controlsUtils.ts +44 -14
  107. package/src/locus-info/index.ts +23 -1
  108. package/src/locus-info/selfUtils.ts +451 -447
  109. package/src/media/index.ts +11 -21
  110. package/src/meeting/in-meeting-actions.ts +32 -0
  111. package/src/meeting/index.ts +372 -92
  112. package/src/meeting/locusMediaRequest.ts +0 -18
  113. package/src/meeting/muteState.ts +0 -2
  114. package/src/meeting/request.ts +36 -1
  115. package/src/meeting/request.type.ts +7 -0
  116. package/src/meeting/util.ts +11 -2
  117. package/src/meeting-info/meeting-info-v2.ts +247 -6
  118. package/src/meetings/index.ts +107 -1
  119. package/src/meetings/util.ts +18 -0
  120. package/src/member/index.ts +11 -0
  121. package/src/member/util.ts +3 -0
  122. package/src/members/index.ts +25 -0
  123. package/src/members/request.ts +26 -0
  124. package/src/members/util.ts +16 -0
  125. package/src/metrics/constants.ts +9 -0
  126. package/src/reachability/clusterReachability.ts +73 -26
  127. package/src/reachability/index.ts +70 -1
  128. package/src/reachability/reachability.types.ts +6 -0
  129. package/src/reachability/request.ts +7 -0
  130. package/src/reconnection-manager/index.ts +2 -2
  131. package/src/recording-controller/util.ts +17 -13
  132. package/src/roap/index.ts +3 -7
  133. package/src/roap/turnDiscovery.ts +34 -39
  134. package/src/roap/types.ts +23 -0
  135. package/test/unit/spec/controls-options-manager/util.js +120 -0
  136. package/test/unit/spec/locus-info/controlsUtils.js +103 -9
  137. package/test/unit/spec/locus-info/index.js +28 -0
  138. package/test/unit/spec/media/index.ts +36 -16
  139. package/test/unit/spec/meeting/in-meeting-actions.ts +19 -4
  140. package/test/unit/spec/meeting/index.js +528 -34
  141. package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
  142. package/test/unit/spec/meeting/muteState.js +0 -2
  143. package/test/unit/spec/meeting/request.js +32 -1
  144. package/test/unit/spec/meeting/utils.js +119 -18
  145. package/test/unit/spec/meeting-info/meetinginfov2.js +443 -114
  146. package/test/unit/spec/meetings/index.js +120 -2
  147. package/test/unit/spec/member/index.js +7 -0
  148. package/test/unit/spec/member/util.js +24 -0
  149. package/test/unit/spec/members/index.js +103 -26
  150. package/test/unit/spec/members/request.js +45 -22
  151. package/test/unit/spec/members/utils.js +33 -0
  152. package/test/unit/spec/reachability/clusterReachability.ts +88 -56
  153. package/test/unit/spec/reachability/index.ts +101 -0
  154. package/test/unit/spec/reachability/request.js +47 -2
  155. package/test/unit/spec/reconnection-manager/index.js +4 -4
  156. package/test/unit/spec/roap/turnDiscovery.ts +110 -28
package/package.json CHANGED
@@ -43,13 +43,13 @@
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.8.0-next.6",
47
- "@webex/plugin-rooms": "3.8.0-next.1",
48
- "@webex/test-helper-chai": "3.8.0-next.1",
49
- "@webex/test-helper-mocha": "3.8.0-next.1",
50
- "@webex/test-helper-mock-webex": "3.8.0-next.1",
51
- "@webex/test-helper-retry": "3.8.0-next.1",
52
- "@webex/test-helper-test-users": "3.8.0-next.1",
46
+ "@webex/plugin-meetings": "3.8.0-next.61",
47
+ "@webex/plugin-rooms": "3.8.0-next.21",
48
+ "@webex/test-helper-chai": "3.8.0-next.17",
49
+ "@webex/test-helper-mocha": "3.8.0-next.17",
50
+ "@webex/test-helper-mock-webex": "3.8.0-next.17",
51
+ "@webex/test-helper-retry": "3.8.0-next.17",
52
+ "@webex/test-helper-test-users": "3.8.0-next.17",
53
53
  "chai": "^4.3.4",
54
54
  "chai-as-promised": "^7.1.1",
55
55
  "eslint": "^8.24.0",
@@ -61,22 +61,22 @@
61
61
  "typescript": "^4.7.4"
62
62
  },
63
63
  "dependencies": {
64
- "@webex/common": "3.8.0-next.1",
65
- "@webex/event-dictionary-ts": "^1.0.1688",
66
- "@webex/internal-media-core": "2.14.4",
67
- "@webex/internal-plugin-conversation": "3.8.0-next.1",
68
- "@webex/internal-plugin-device": "3.8.0-next.1",
69
- "@webex/internal-plugin-llm": "3.8.0-next.2",
70
- "@webex/internal-plugin-mercury": "3.8.0-next.1",
71
- "@webex/internal-plugin-metrics": "3.8.0-next.1",
72
- "@webex/internal-plugin-support": "3.8.0-next.1",
73
- "@webex/internal-plugin-user": "3.8.0-next.1",
74
- "@webex/internal-plugin-voicea": "3.8.0-next.6",
75
- "@webex/media-helpers": "3.8.0-next.1",
76
- "@webex/plugin-people": "3.8.0-next.1",
77
- "@webex/plugin-rooms": "3.8.0-next.1",
64
+ "@webex/common": "3.8.0-next.17",
65
+ "@webex/event-dictionary-ts": "^1.0.1753",
66
+ "@webex/internal-media-core": "2.16.0",
67
+ "@webex/internal-plugin-conversation": "3.8.0-next.21",
68
+ "@webex/internal-plugin-device": "3.8.0-next.17",
69
+ "@webex/internal-plugin-llm": "3.8.0-next.20",
70
+ "@webex/internal-plugin-mercury": "3.8.0-next.19",
71
+ "@webex/internal-plugin-metrics": "3.8.0-next.17",
72
+ "@webex/internal-plugin-support": "3.8.0-next.21",
73
+ "@webex/internal-plugin-user": "3.8.0-next.17",
74
+ "@webex/internal-plugin-voicea": "3.8.0-next.61",
75
+ "@webex/media-helpers": "3.8.0-next.21",
76
+ "@webex/plugin-people": "3.8.0-next.19",
77
+ "@webex/plugin-rooms": "3.8.0-next.21",
78
78
  "@webex/web-capabilities": "^1.4.0",
79
- "@webex/webex-core": "3.8.0-next.1",
79
+ "@webex/webex-core": "3.8.0-next.17",
80
80
  "ampersand-collection": "^2.0.2",
81
81
  "bowser": "^2.11.0",
82
82
  "btoa": "^1.2.1",
@@ -92,5 +92,5 @@
92
92
  "//": [
93
93
  "TODO: upgrade jwt-decode when moving to node 18"
94
94
  ],
95
- "version": "3.8.0-next.6"
95
+ "version": "3.8.0-next.61"
96
96
  }
@@ -152,12 +152,19 @@ WebExMeetingsErrors[IceGatheringFailed.CODE] = IceGatheringFailed;
152
152
  * @extends WebexMeetingsError
153
153
  * @property {number} code - 30203
154
154
  * @property {string} message - 'Failed to add media'
155
+ * @property {Error} [cause] - The underlying error that caused the failure
155
156
  */
156
157
  class AddMediaFailed extends WebexMeetingsError {
157
158
  static CODE = 30203;
159
+ cause?: Error;
158
160
 
159
- constructor() {
161
+ /**
162
+ * Creates a new AddMediaFailed error
163
+ * @param {Error} [cause] - The underlying error that caused the media addition to fail
164
+ */
165
+ constructor(cause?: Error) {
160
166
  super(AddMediaFailed.CODE, 'Failed to add media');
167
+ this.cause = cause;
161
168
  }
162
169
  }
163
170
  export {AddMediaFailed};
package/src/config.ts CHANGED
@@ -95,6 +95,7 @@ export default {
95
95
  // This only applies to non-multistream meetings
96
96
  iceCandidatesGatheringTimeout: undefined,
97
97
  backendIpv6NativeSupport: false,
98
+ enableReachabilityChecks: true,
98
99
  reachabilityGetClusterTimeout: 5000,
99
100
  logUploadIntervalMultiplicationFactor: 0, // if set to 0 or undefined, logs won't be uploaded periodically, if you want periodic logs, recommended value is 1
100
101
  },
package/src/constants.ts CHANGED
@@ -369,6 +369,9 @@ export const EVENT_TRIGGERS = {
369
369
  MEETING_CONTROLS_MEETING_FULL_UPDATED: 'meeting:controls:meeting-full:updated',
370
370
  MEETING_CONTROLS_PRACTICE_SESSION_STATUS_UPDATED:
371
371
  'meeting:controls:practice-session-status:updated',
372
+ MEETING_CONTROLS_ANNOTATION_UPDATED: 'meeting:controls:annotation:updated',
373
+ MEETING_CONTROLS_REMOTE_DESKTOP_CONTROL_UPDATED:
374
+ 'meeting:controls:remote-desktop-control:updated',
372
375
  // Locus URL changed
373
376
  MEETING_LOCUS_URL_UPDATE: 'meeting:locus:locusUrl:update',
374
377
  MEETING_STREAM_PUBLISH_STATE_CHANGED: 'meeting:streamPublishStateChanged',
@@ -711,6 +714,8 @@ export const LOCUSINFO = {
711
714
  CONTROLS_PRACTICE_SESSION_STATUS_UPDATED: 'CONTROLS_PRACTICE_SESSION_STATUS_UPDATED',
712
715
  CONTROLS_VIDEO_CHANGED: 'CONTROLS_VIDEO_CHANGED',
713
716
  CONTROLS_STAGE_VIEW_UPDATED: 'CONTROLS_STAGE_VIEW_UPDATED',
717
+ CONTROLS_ANNOTATION_CHANGED: 'CONTROLS_ANNOTATION_CHANGED',
718
+ CONTROLS_REMOTE_DESKTOP_CONTROL_CHANGED: 'CONTROLS_REMOTE_DESKTOP_CONTROL_CHANGED',
714
719
  SELF_UNADMITTED_GUEST: 'SELF_UNADMITTED_GUEST',
715
720
  SELF_ADMITTED_GUEST: 'SELF_ADMITTED_GUEST',
716
721
  SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED: 'SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED',
@@ -904,7 +909,9 @@ export enum SELF_POLICY {
904
909
  ENFORCE_VIRTUAL_BACKGROUND = 'enforceVirtualBackground',
905
910
  SUPPORT_LOCAL_RECORD = 'supportLocalRecord',
906
911
  SUPPORT_NETWORK_BASED_RECORD = 'supportNetworkBasedRecord',
912
+ SUPPORT_PREMISE_RECORD = 'supportPremiseRecord',
907
913
  SUPPORT_REALTIME_CLOSE_CAPTION = 'supportRealtimeCloseCaption',
914
+ SUPPORT_REALTIME_CLOSE_CAPTION_MANUAL = 'supportRealtimeCloseCaptionManual',
908
915
  SUPPORT_CHAT = 'supportChat',
909
916
  SUPPORT_DESKTOP_SHARE_REMOTE = 'supportDesktopShareRemote',
910
917
  SUPPORT_DESKTOP_SHARE = 'supportDesktopShare',
@@ -972,6 +979,7 @@ export const DISPLAY_HINTS = {
972
979
  PRESENTER_CONTROL: 'PRESENTER_CONTROL',
973
980
  CAN_RENAME_SELF_AND_OBSERVED: 'CAN_RENAME_SELF_AND_OBSERVED',
974
981
  CAN_RENAME_OTHERS: 'CAN_RENAME_OTHERS',
982
+ MOVE_TO_LOBBY: 'MOVE_TO_LOBBY',
975
983
 
976
984
  // breakout session
977
985
  BREAKOUT_MANAGEMENT: 'BREAKOUT_MANAGEMENT',
@@ -1025,6 +1033,17 @@ export const DISPLAY_HINTS = {
1025
1033
  PRACTICE_SESSION_OFF: 'PRACTICE_SESSION_OFF',
1026
1034
  SHOW_PRACTICE_SESSION_START: 'SHOW_PRACTICE_SESSION_START',
1027
1035
  SHOW_PRACTICE_SESSION_STOP: 'SHOW_PRACTICE_SESSION_STOP',
1036
+
1037
+ // Explicit consent for post meeting data
1038
+ SHOW_POST_MEETING_DATA_CONSENT_PROMPT: 'SHOW_POST_MEETING_DATA_CONSENT_PROMPT',
1039
+
1040
+ // Annotations
1041
+ ENABLE_ANNOTATION_MEETING_OPTION: 'ENABLE_ANNOTATION_MEETING_OPTION',
1042
+ DISABLE_ANNOTATION_MEETING_OPTION: 'DISABLE_ANNOTATION_MEETING_OPTION',
1043
+
1044
+ // Remote Desktop Control
1045
+ ENABLE_RDC_MEETING_OPTION: 'ENABLE_RDC_MEETING_OPTION',
1046
+ DISABLE_RDC_MEETING_OPTION: 'DISABLE_RDC_MEETING_OPTION',
1028
1047
  };
1029
1048
 
1030
1049
  export const INTERSTITIAL_DISPLAY_HINTS = [DISPLAY_HINTS.VOIP_IS_ENABLED];
@@ -1149,96 +1168,6 @@ export const NETWORK_STATUS = {
1149
1168
 
1150
1169
  export type NETWORK_STATUS = Enum<typeof NETWORK_STATUS>;
1151
1170
 
1152
- export const NETWORK_TYPE = {
1153
- VPN: 'vpn',
1154
- UNKNOWN: 'unknown',
1155
- WIFI: 'wifi',
1156
- ETHERNET: 'ethernet',
1157
- };
1158
-
1159
- export const STATS = {
1160
- SEND_DIRECTION: 'send',
1161
- RECEIVE_DIRECTION: 'recv',
1162
- REMOTE: 'remote',
1163
- LOCAL: 'local',
1164
- };
1165
-
1166
- export const MQA_STATS = {
1167
- MQA_SIZE: 120, // MQA is done on 60 second intervals by server def, add a buffer for missed events
1168
- CA_TYPE: 'MQA',
1169
- DEFAULT_IP: '0.0.0.0',
1170
- DEFAULT_SHARE_SENDER_STATS: {
1171
- common: {
1172
- common: {
1173
- direction: 'sendrecv', // TODO: parse from SDP and save globally
1174
- isMain: false, // always true for share sender
1175
- mariFecEnabled: false, // unavailable
1176
- mariRtxEnabled: false, // unavailable
1177
- mariLiteEnabled: false, // unavailable
1178
- mariQosEnabled: false, // unavailable
1179
- multistreamEnabled: false, // unavailable
1180
- },
1181
- availableBitrate: 0,
1182
- dtlsBitrate: 0, // unavailable
1183
- dtlsPackets: 0, // unavailable
1184
- fecBitrate: 0, // unavailable
1185
- fecPackets: 0, // unavailable
1186
- maxBitrate: 0, // unavailable
1187
- queueDelay: 0, // unavailable
1188
- remoteJitter: 0, // unavailable
1189
- remoteLossRate: 0,
1190
- roundTripTime: 0,
1191
- rtcpBitrate: 0, // unavailable
1192
- rtcpPackets: 0, // unavailable
1193
- rtpBitrate: 0, // unavailable
1194
- rtpPackets: 0,
1195
- stunBitrate: 0, // unavailable
1196
- stunPackets: 0, // unavailable
1197
- transportType: 'UDP', // TODO: parse the transport type from the SDP and save globally
1198
- },
1199
- streams: [
1200
- {
1201
- common: {
1202
- codec: 'H264', // TODO: parse the codec from the SDP and save globally
1203
- duplicateSsci: 0, // unavailable
1204
- requestedBitrate: 0, // unavailable
1205
- requestedFrames: 0, // unavailable
1206
- rtpPackets: 0,
1207
- ssci: 0, // unavailable
1208
- transmittedBitrate: 0,
1209
- transmittedFrameRate: 0,
1210
- },
1211
- h264CodecProfile: 'BP', // TODO: parse the profile level from h264 in the SDP and save globally
1212
- localConfigurationChanges: 0, // unavailable
1213
- remoteConfigurationChanges: 0, // unavailable
1214
- requestedFrameSize: 0, // unavailable
1215
- requestedKeyFrames: 0, // unavailable
1216
- transmittedFrameSize: 0, // unavailable
1217
- transmittedHeight: 0,
1218
- transmittedKeyFrames: 0,
1219
- transmittedWidth: 0,
1220
- },
1221
- ],
1222
- },
1223
- intervalMetadata: {
1224
- memoryUsage: {
1225
- cpuBitWidth: 0,
1226
- mainProcessMaximumMemoryBytes: 0,
1227
- osBitWidth: 0,
1228
- processAverageMemoryUsage: 0,
1229
- processMaximumMemoryBytes: 0,
1230
- processMaximumMemoryUsage: 0,
1231
- systemAverageMemoryUsage: 0,
1232
- systemMaximumMemoryUsage: 0,
1233
- },
1234
- peerReflexiveIP: 'NULL', // TODO: save after ice trickling completes and use as a global variable
1235
- processAverageCPU: 0,
1236
- processMaximumCPU: 0,
1237
- systemAverageCPU: 0,
1238
- systemMaximumCPU: 0,
1239
- },
1240
- };
1241
-
1242
1171
  // ****** MEDIA QUALITY CONSTANTS ****** //
1243
1172
 
1244
1173
  // these values must match allowed values of RemoteQualityLevel from the @webex/internal-media-core lib
@@ -12,6 +12,8 @@ enum Control {
12
12
  shareControl = 'shareControl',
13
13
  video = 'video',
14
14
  viewTheParticipantList = 'viewTheParticipantList',
15
+ annotation = 'annotation',
16
+ rdc = 'rdc',
15
17
  }
16
18
 
17
19
  export {Control, Setting};
@@ -40,13 +40,23 @@ export interface ViewTheParticipantListProperties {
40
40
  attendeeCount?: boolean;
41
41
  }
42
42
 
43
+ export interface AnnotationProperties {
44
+ enabled?: boolean;
45
+ }
46
+
47
+ export interface RemoteDesktopControlProperties {
48
+ enabled?: boolean;
49
+ }
50
+
43
51
  export type Properties =
44
52
  | AudioProperties
45
53
  | RaiseHandProperties
46
54
  | ReactionsProperties
47
55
  | ShareControlProperties
48
56
  | VideoProperties
49
- | ViewTheParticipantListProperties;
57
+ | ViewTheParticipantListProperties
58
+ | AnnotationProperties
59
+ | RemoteDesktopControlProperties;
50
60
 
51
61
  export interface ControlConfig<Props = Properties> {
52
62
  /**
@@ -7,6 +7,8 @@ import {
7
7
  ReactionsProperties,
8
8
  ViewTheParticipantListProperties,
9
9
  VideoProperties,
10
+ type RemoteDesktopControlProperties,
11
+ type AnnotationProperties,
10
12
  } from './types';
11
13
 
12
14
  /**
@@ -256,6 +258,52 @@ class Utils {
256
258
  return Utils.hasHints({requiredHints, displayHints});
257
259
  }
258
260
 
261
+ /**
262
+ * Validate if a annotation-scoped control is allowed to be sent to the service.
263
+ *
264
+ * @param {ControlConfig<AnnotationProperties>} control - Annotation control config to validate
265
+ * @param {Array<string>} displayHints - All available hints
266
+ * @returns {boolean} - True if all of the actions are allowed.
267
+ */
268
+ public static canUpdateAnnotation(
269
+ control: ControlConfig<AnnotationProperties>,
270
+ displayHints: Array<string>
271
+ ): boolean {
272
+ const requiredHints = [];
273
+
274
+ if (control.properties.enabled === true) {
275
+ requiredHints.push(DISPLAY_HINTS.ENABLE_ANNOTATION_MEETING_OPTION);
276
+ }
277
+ if (control.properties.enabled === false) {
278
+ requiredHints.push(DISPLAY_HINTS.DISABLE_ANNOTATION_MEETING_OPTION);
279
+ }
280
+
281
+ return Utils.hasHints({requiredHints, displayHints});
282
+ }
283
+
284
+ /**
285
+ * Validate if a rdc-scoped control is allowed to be sent to the service.
286
+ *
287
+ * @param {ControlConfig<RemoteDesktopControlProperties>} control - Remote Desktop Control config to validate
288
+ * @param {Array<string>} displayHints - All available hints
289
+ * @returns {boolean} - True if all of the actions are allowed.
290
+ */
291
+ public static canUpdateRemoteDesktopControl(
292
+ control: ControlConfig<RemoteDesktopControlProperties>,
293
+ displayHints: Array<string>
294
+ ): boolean {
295
+ const requiredHints = [];
296
+
297
+ if (control.properties.enabled === true) {
298
+ requiredHints.push(DISPLAY_HINTS.ENABLE_RDC_MEETING_OPTION);
299
+ }
300
+ if (control.properties.enabled === false) {
301
+ requiredHints.push(DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION);
302
+ }
303
+
304
+ return Utils.hasHints({requiredHints, displayHints});
305
+ }
306
+
259
307
  /**
260
308
  * Validate that a control can be sent to the service based on the provided
261
309
  * display hints.
@@ -301,6 +349,20 @@ class Utils {
301
349
  );
302
350
  break;
303
351
 
352
+ case Control.annotation:
353
+ determinant = Utils.canUpdateAnnotation(
354
+ control as ControlConfig<AnnotationProperties>,
355
+ displayHints
356
+ );
357
+ break;
358
+
359
+ case Control.rdc:
360
+ determinant = Utils.canUpdateRemoteDesktopControl(
361
+ control as ControlConfig<RemoteDesktopControlProperties>,
362
+ displayHints
363
+ );
364
+ break;
365
+
304
366
  default:
305
367
  determinant = false;
306
368
  }
@@ -1,5 +1,5 @@
1
1
  import {isEqual} from 'lodash';
2
- import {BREAKOUTS} from '../constants';
2
+ import {BREAKOUTS, MEETING_STATE} from '../constants';
3
3
 
4
4
  const ControlsUtils: any = {};
5
5
 
@@ -111,6 +111,18 @@ ControlsUtils.parse = (controls: any) => {
111
111
  };
112
112
  }
113
113
 
114
+ if (controls?.annotationControl) {
115
+ parsedControls.annotationControl = {
116
+ enabled: controls.annotationControl.enabled,
117
+ };
118
+ }
119
+
120
+ if (controls?.rdcControl) {
121
+ parsedControls.rdcControl = {
122
+ enabled: controls.rdcControl.enabled,
123
+ };
124
+ }
125
+
114
126
  return parsedControls;
115
127
  };
116
128
 
@@ -206,11 +218,17 @@ ControlsUtils.getControls = (oldControls: any, newControls: any) => {
206
218
  ),
207
219
 
208
220
  hasPracticeSessionEnabledChanged: !isEqual(
209
- previous?.practiceSession?.enabled,
210
- current?.practiceSession?.enabled
221
+ !!previous?.practiceSession?.enabled,
222
+ !!current?.practiceSession?.enabled
211
223
  ),
212
224
 
213
225
  hasStageViewChanged: !isEqual(previous?.videoLayout, current?.videoLayout),
226
+
227
+ hasAnnotationControlChanged:
228
+ current?.annotationControl?.enabled !== previous?.annotationControl?.enabled,
229
+
230
+ hasRemoteDesktopControlChanged:
231
+ current?.rdcControl?.enabled !== previous?.rdcControl?.enabled,
214
232
  },
215
233
  };
216
234
  };
@@ -242,30 +260,42 @@ ControlsUtils.isNeedReplaceMembers = (oldControls: any, controls: any) => {
242
260
  }
243
261
 
244
262
  return (
245
- oldControls.breakout.groupId !== controls.breakout.groupId ||
246
- oldControls.breakout.sessionId !== controls.breakout.sessionId
263
+ oldControls?.breakout?.groupId !== controls?.breakout?.groupId ||
264
+ oldControls?.breakout?.sessionId !== controls?.breakout?.sessionId
247
265
  );
248
266
  };
249
267
 
250
268
  /**
251
269
  * determine the switch status between breakout session and main session.
252
- * @param {LocusControls} oldControls
253
- * @param {LocusControls} controls
270
+ * @param {LocusInfo} oldLocus
271
+ * @param {LocusInfo} newLocus
254
272
  * @returns {Object}
255
273
  */
256
- ControlsUtils.getSessionSwitchStatus = (oldControls: any, controls: any) => {
274
+ ControlsUtils.getSessionSwitchStatus = (oldLocus: any, newLocus: any) => {
257
275
  const status = {isReturnToMain: false, isJoinToBreakout: false};
258
276
  // no breakout case
259
- if (!oldControls?.breakout || !controls?.breakout) {
277
+ if (!oldLocus.controls?.breakout || !newLocus.controls?.breakout) {
260
278
  return status;
261
279
  }
262
280
 
263
- status.isReturnToMain =
264
- oldControls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT &&
265
- controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.MAIN;
281
+ // It is used to fix the timing issue triggered when the creator leaves session to ensure that the member list is complete
282
+ const needUseCache = !!(
283
+ oldLocus.self?.isCreator &&
284
+ newLocus.participants?.length === 1 &&
285
+ newLocus.participants?.[0].isCreator &&
286
+ newLocus.participants?.[0].state === MEETING_STATE.STATES.JOINED &&
287
+ newLocus.controls?.breakout?.sessionType === BREAKOUTS.SESSION_TYPES.MAIN &&
288
+ newLocus.controls?.breakout?.groups?.length
289
+ );
290
+
291
+ const isReturnToMain =
292
+ oldLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT &&
293
+ newLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.MAIN;
294
+
295
+ status.isReturnToMain = needUseCache || isReturnToMain;
266
296
  status.isJoinToBreakout =
267
- oldControls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.MAIN &&
268
- controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT;
297
+ oldLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.MAIN &&
298
+ newLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT;
269
299
 
270
300
  return status;
271
301
  };
@@ -17,7 +17,9 @@ import {
17
17
  MEETING_REMOVED_REASON,
18
18
  CALL_REMOVED_REASON,
19
19
  RECORDING_STATE,
20
+ BREAKOUTS,
20
21
  } from '../constants';
22
+
21
23
  import InfoUtils from './infoUtils';
22
24
  import FullState from './fullState';
23
25
  import SelfUtils from './selfUtils';
@@ -67,6 +69,7 @@ export default class LocusInfo extends EventsScope {
67
69
  services: any;
68
70
  resources: any;
69
71
  mainSessionLocusCache: any;
72
+ self: any;
70
73
  /**
71
74
  * Constructor
72
75
  * @param {function} updateMeeting callback to update the meeting object from an object
@@ -814,6 +817,8 @@ export default class LocusInfo extends EventsScope {
814
817
  hasMeetingFullChanged,
815
818
  hasPracticeSessionEnabledChanged,
816
819
  hasStageViewChanged,
820
+ hasAnnotationControlChanged,
821
+ hasRemoteDesktopControlChanged,
817
822
  },
818
823
  current,
819
824
  } = ControlsUtils.getControls(this.controls, controls);
@@ -1049,6 +1054,22 @@ export default class LocusInfo extends EventsScope {
1049
1054
  );
1050
1055
  }
1051
1056
 
1057
+ if (hasAnnotationControlChanged) {
1058
+ this.emitScoped(
1059
+ {file: 'locus-info', function: 'updateControls'},
1060
+ LOCUSINFO.EVENTS.CONTROLS_ANNOTATION_CHANGED,
1061
+ {state: current.annotationControl}
1062
+ );
1063
+ }
1064
+
1065
+ if (hasRemoteDesktopControlChanged) {
1066
+ this.emitScoped(
1067
+ {file: 'locus-info', function: 'updateControls'},
1068
+ LOCUSINFO.EVENTS.CONTROLS_REMOTE_DESKTOP_CONTROL_CHANGED,
1069
+ {state: current.rdcControl}
1070
+ );
1071
+ }
1072
+
1052
1073
  this.controls = controls;
1053
1074
  }
1054
1075
  }
@@ -1706,7 +1727,8 @@ export default class LocusInfo extends EventsScope {
1706
1727
  * @memberof LocusInfo
1707
1728
  */
1708
1729
  getTheLocusToUpdate(newLocus: any) {
1709
- const switchStatus = ControlsUtils.getSessionSwitchStatus(this.controls, newLocus?.controls);
1730
+ const switchStatus = ControlsUtils.getSessionSwitchStatus(this, newLocus);
1731
+
1710
1732
  if (switchStatus.isReturnToMain && this.mainSessionLocusCache) {
1711
1733
  return cloneDeep(this.mainSessionLocusCache);
1712
1734
  }