@webex/plugin-meetings 3.0.0-beta.42 → 3.0.0-beta.421
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.
- package/README.md +58 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +94 -15
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +625 -123
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +27 -8
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +6 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.js +247 -34
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +116 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +380 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +386 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +71 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +65 -102
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +135 -330
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +86 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +4525 -2997
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +236 -136
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +189 -155
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +676 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +172 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +201 -57
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +8 -7
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +44 -40
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +484 -119
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +73 -7
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +57 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +132 -25
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +100 -5
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +18 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -446
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +223 -32
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +10 -0
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +20 -4
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +3 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +76 -5
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +366 -104
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +255 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +263 -390
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +16 -12
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reconnection-manager/index.js +266 -202
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +66 -28
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +50 -66
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +407 -79
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +179 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +389 -304
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +296 -156
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/utils.d.ts +9 -2
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +2 -7
- package/dist/types/constants.d.ts +204 -32
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -5
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +66 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -49
- package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
- package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
- package/dist/types/meeting/index.d.ts +631 -505
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +88 -26
- package/dist/types/meeting/request.d.ts +67 -43
- package/dist/types/meeting/util.d.ts +118 -1
- package/dist/types/meeting/voicea-meeting.d.ts +16 -0
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +17 -0
- package/dist/types/meetings/index.d.ts +114 -21
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +17 -0
- package/dist/types/metrics/index.d.ts +4 -111
- package/dist/types/multistream/mediaRequestManager.d.ts +71 -3
- package/dist/types/multistream/receiveSlot.d.ts +7 -3
- package/dist/types/multistream/receiveSlotManager.d.ts +7 -0
- package/dist/types/multistream/remoteMedia.d.ts +3 -31
- package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +61 -2
- package/dist/types/multistream/sendSlotManager.d.ts +69 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +60 -95
- package/dist/types/reachability/request.d.ts +3 -1
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reconnection-manager/index.d.ts +19 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/index.d.ts +11 -2
- package/dist/types/roap/request.d.ts +9 -8
- package/dist/types/roap/turnDiscovery.d.ts +90 -9
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +61 -0
- package/dist/types/statsAnalyzer/index.d.ts +34 -12
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +22 -19
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +27 -6
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +494 -73
- package/src/breakouts/utils.ts +26 -8
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +6 -13
- package/src/constants.ts +234 -22
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +45 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +349 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +417 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +80 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +100 -108
- package/src/media/properties.ts +88 -117
- package/src/mediaQualityMetrics/config.ts +103 -238
- package/src/meeting/in-meeting-actions.ts +171 -3
- package/src/meeting/index.ts +3869 -2574
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +237 -136
- package/src/meeting/request.ts +173 -122
- package/src/meeting/util.ts +690 -395
- package/src/meeting/voicea-meeting.ts +122 -0
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +166 -16
- package/src/meeting-info/util.ts +13 -10
- package/src/meeting-info/utilv2.ts +47 -37
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +507 -127
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +81 -12
- package/src/member/index.ts +57 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +133 -7
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +17 -0
- package/src/metrics/index.ts +1 -469
- package/src/multistream/mediaRequestManager.ts +271 -56
- package/src/multistream/receiveSlot.ts +11 -4
- package/src/multistream/receiveSlotManager.ts +16 -4
- package/src/multistream/remoteMedia.ts +5 -3
- package/src/multistream/remoteMediaGroup.ts +78 -0
- package/src/multistream/remoteMediaManager.ts +248 -45
- package/src/multistream/sendSlotManager.ts +198 -0
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +229 -346
- package/src/reachability/request.ts +22 -14
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +128 -97
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +76 -25
- package/src/roap/request.ts +50 -69
- package/src/roap/turnDiscovery.ts +331 -67
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +166 -0
- package/src/statsAnalyzer/index.ts +496 -419
- package/src/statsAnalyzer/mqaUtil.ts +317 -170
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +321 -262
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +119 -28
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1204 -118
- package/test/unit/spec/breakouts/utils.js +27 -2
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +625 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1372 -37
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +203 -17
- package/test/unit/spec/media/index.ts +178 -81
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
- package/test/unit/spec/meeting/index.js +7775 -2521
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +549 -207
- package/test/unit/spec/meeting/request.js +494 -54
- package/test/unit/spec/meeting/utils.js +827 -74
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +535 -9
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1496 -219
- package/test/unit/spec/meetings/utils.js +229 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +2 -52
- package/test/unit/spec/multistream/mediaRequestManager.ts +782 -114
- package/test/unit/spec/multistream/receiveSlot.ts +9 -1
- package/test/unit/spec/multistream/receiveSlotManager.ts +11 -3
- package/test/unit/spec/multistream/remoteMedia.ts +2 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +344 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +524 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +551 -14
- package/test/unit/spec/reachability/request.js +18 -8
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +171 -11
- package/test/unit/spec/recording-controller/index.js +293 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +233 -81
- package/test/unit/spec/roap/request.ts +100 -62
- package/test/unit/spec/roap/turnDiscovery.ts +682 -108
- package/test/unit/spec/rtcMetrics/index.ts +122 -0
- package/test/unit/spec/stats-analyzer/index.js +1431 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -57
- package/test/utils/webex-test-users.js +12 -4
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/metrics/config.d.ts +0 -169
- package/src/index.js +0 -18
- package/src/metrics/config.ts +0 -485
package/src/meeting/util.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {LocalCameraTrack, LocalMicrophoneTrack} from '@webex/internal-media-core';
|
|
1
|
+
import {LocalCameraStream, LocalMicrophoneStream} from '@webex/media-helpers';
|
|
3
2
|
|
|
3
|
+
import {cloneDeep} from 'lodash';
|
|
4
4
|
import {MeetingNotActiveError, UserNotJoinedError} from '../common/errors/webex-errors';
|
|
5
|
-
import Metrics from '../metrics';
|
|
6
|
-
import {eventType, trigger} from '../metrics/config';
|
|
7
|
-
import Media from '../media';
|
|
8
5
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
9
6
|
import {
|
|
10
7
|
INTENT_TO_JOIN,
|
|
@@ -14,491 +11,789 @@ import {
|
|
|
14
11
|
PASSWORD_STATUS,
|
|
15
12
|
DISPLAY_HINTS,
|
|
16
13
|
FULL_STATE,
|
|
14
|
+
SELF_POLICY,
|
|
15
|
+
EVENT_TRIGGERS,
|
|
16
|
+
LOCAL_SHARE_ERRORS,
|
|
17
|
+
IP_VERSION,
|
|
17
18
|
} from '../constants';
|
|
19
|
+
import BrowserDetection from '../common/browser-detection';
|
|
18
20
|
import IntentToJoinError from '../common/errors/intent-to-join';
|
|
19
21
|
import JoinMeetingError from '../common/errors/join-meeting';
|
|
20
22
|
import ParameterError from '../common/errors/parameter';
|
|
21
23
|
import PermissionError from '../common/errors/permission';
|
|
22
24
|
import PasswordError from '../common/errors/password-error';
|
|
23
25
|
import CaptchaError from '../common/errors/captcha-error';
|
|
26
|
+
import Trigger from '../common/events/trigger-proxy';
|
|
27
|
+
|
|
28
|
+
const MeetingUtil = {
|
|
29
|
+
parseLocusJoin: (response) => {
|
|
30
|
+
const parsed: any = {};
|
|
31
|
+
|
|
32
|
+
// First todo: add check for existance
|
|
33
|
+
parsed.locus = response.body.locus;
|
|
34
|
+
parsed.mediaConnections = response.body.mediaConnections;
|
|
35
|
+
parsed.locusUrl = parsed.locus.url;
|
|
36
|
+
parsed.locusId = parsed.locus.url.split('/').pop();
|
|
37
|
+
parsed.selfId = parsed.locus.self.id;
|
|
38
|
+
|
|
39
|
+
// we need mediaId before making roap calls
|
|
40
|
+
parsed.mediaConnections.forEach((mediaConnection) => {
|
|
41
|
+
if (mediaConnection.mediaId) {
|
|
42
|
+
parsed.mediaId = mediaConnection.mediaId;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return parsed;
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
remoteUpdateAudioVideo: (meeting, audioMuted?: boolean, videoMuted?: boolean) => {
|
|
50
|
+
const webex = meeting.getWebexObject();
|
|
51
|
+
if (!meeting) {
|
|
52
|
+
return Promise.reject(new ParameterError('You need a meeting object.'));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!meeting.locusMediaRequest) {
|
|
56
|
+
return Promise.reject(
|
|
57
|
+
new ParameterError(
|
|
58
|
+
'You need a meeting with a media connection, call Meeting.addMedia() first.'
|
|
59
|
+
)
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
65
|
+
name: 'client.locus.media.request',
|
|
66
|
+
options: {meetingId: meeting.id},
|
|
67
|
+
});
|
|
24
68
|
|
|
25
|
-
|
|
69
|
+
return meeting.locusMediaRequest
|
|
70
|
+
.send({
|
|
71
|
+
type: 'LocalMute',
|
|
72
|
+
selfUrl: meeting.selfUrl,
|
|
73
|
+
mediaId: meeting.mediaId,
|
|
74
|
+
sequence: meeting.locusInfo.sequence,
|
|
75
|
+
muteOptions: {
|
|
76
|
+
audioMuted,
|
|
77
|
+
videoMuted,
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
.then((response) => {
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
83
|
+
name: 'client.locus.media.response',
|
|
84
|
+
options: {meetingId: meeting.id},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return response?.body?.locus;
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
hasOwner: (info) => info && info.owner,
|
|
26
92
|
|
|
27
|
-
|
|
28
|
-
const parsed: any = {};
|
|
93
|
+
isOwnerSelf: (owner, selfId) => owner === selfId,
|
|
29
94
|
|
|
30
|
-
|
|
31
|
-
parsed.locus = response.body.locus;
|
|
32
|
-
parsed.mediaConnections = response.body.mediaConnections;
|
|
33
|
-
parsed.locusUrl = parsed.locus.url;
|
|
34
|
-
parsed.locusId = parsed.locus.url.split('/').pop();
|
|
35
|
-
parsed.selfId = parsed.locus.self.id;
|
|
95
|
+
isPinOrGuest: (err) => err?.body?.errorCode && INTENT_TO_JOIN.includes(err.body.errorCode),
|
|
36
96
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Returns the current state of knowledge about whether we are on an ipv4-only or ipv6-only or mixed (ipv4 and ipv6) network.
|
|
99
|
+
* The return value matches the possible values of "ipver" parameter used by the backend APIs.
|
|
100
|
+
*
|
|
101
|
+
* @param {Object} webex webex instance
|
|
102
|
+
* @returns {IP_VERSION|undefined} ipver value to be passed to the backend APIs or undefined if we should not pass any value to the backend
|
|
103
|
+
*/
|
|
104
|
+
getIpVersion(webex: any): IP_VERSION | undefined {
|
|
105
|
+
const {supportsIpV4, supportsIpV6} = webex.internal.device.ipNetworkDetector;
|
|
106
|
+
|
|
107
|
+
if (BrowserDetection().isBrowser('firefox')) {
|
|
108
|
+
// our ipv6 solution relies on FQDN ICE candidates, but Firefox doesn't support them,
|
|
109
|
+
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1713128
|
|
110
|
+
// so for Firefox we don't want the backend to activate the "ipv6 feature"
|
|
111
|
+
return undefined;
|
|
41
112
|
}
|
|
42
|
-
});
|
|
43
113
|
|
|
44
|
-
|
|
45
|
-
|
|
114
|
+
if (supportsIpV4 && supportsIpV6) {
|
|
115
|
+
return IP_VERSION.ipv4_and_ipv6;
|
|
116
|
+
}
|
|
46
117
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
const localMedias = Media.generateLocalMedias(meeting.mediaId, audioMuted, videoMuted);
|
|
118
|
+
if (supportsIpV4) {
|
|
119
|
+
return IP_VERSION.only_ipv4;
|
|
120
|
+
}
|
|
52
121
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
122
|
+
if (supportsIpV6) {
|
|
123
|
+
return IP_VERSION.only_ipv6;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return IP_VERSION.unknown;
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
joinMeeting: (meeting, options) => {
|
|
130
|
+
if (!meeting) {
|
|
131
|
+
return Promise.reject(new ParameterError('You need a meeting object.'));
|
|
132
|
+
}
|
|
133
|
+
const webex = meeting.getWebexObject();
|
|
134
|
+
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
137
|
+
name: 'client.locus.join.request',
|
|
138
|
+
options: {meetingId: meeting.id},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// eslint-disable-next-line no-warning-comments
|
|
142
|
+
// TODO: check if the meeting is in JOINING state
|
|
143
|
+
// if Joining state termintate the request as user might click multiple times
|
|
144
|
+
return meeting.meetingRequest
|
|
145
|
+
.joinMeeting({
|
|
146
|
+
inviteeAddress: meeting.meetingJoinUrl || meeting.sipUri,
|
|
147
|
+
meetingNumber: meeting.meetingNumber,
|
|
148
|
+
deviceUrl: meeting.deviceUrl,
|
|
149
|
+
locusUrl: meeting.locusUrl,
|
|
150
|
+
locusClusterUrl: meeting.meetingInfo?.locusClusterUrl,
|
|
151
|
+
correlationId: meeting.correlationId,
|
|
152
|
+
reachability: options.reachability,
|
|
153
|
+
roapMessage: options.roapMessage,
|
|
154
|
+
permissionToken: meeting.permissionToken,
|
|
155
|
+
resourceId: options.resourceId || null,
|
|
156
|
+
moderator: options.moderator,
|
|
157
|
+
pin: options.pin,
|
|
158
|
+
moveToResource: options.moveToResource,
|
|
159
|
+
preferTranscoding: !meeting.isMultistream,
|
|
160
|
+
asResourceOccupant: options.asResourceOccupant,
|
|
161
|
+
breakoutsSupported: options.breakoutsSupported,
|
|
162
|
+
locale: options.locale,
|
|
163
|
+
deviceCapabilities: options.deviceCapabilities,
|
|
164
|
+
liveAnnotationSupported: options.liveAnnotationSupported,
|
|
165
|
+
ipVersion: MeetingUtil.getIpVersion(meeting.getWebexObject()),
|
|
166
|
+
})
|
|
167
|
+
.then((res) => {
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
170
|
+
name: 'client.locus.join.response',
|
|
171
|
+
payload: {
|
|
172
|
+
trigger: 'loci-update',
|
|
173
|
+
identifiers: {
|
|
174
|
+
trackingId: res.headers.trackingid,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
options: {
|
|
178
|
+
meetingId: meeting.id,
|
|
179
|
+
mediaConnections: res.body.mediaConnections,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
58
182
|
|
|
59
|
-
|
|
183
|
+
return MeetingUtil.parseLocusJoin(res);
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
cleanUp: (meeting) => {
|
|
188
|
+
meeting.breakouts.cleanUp();
|
|
189
|
+
meeting.simultaneousInterpretation.cleanUp();
|
|
190
|
+
|
|
191
|
+
// make sure we send last metrics before we close the peerconnection
|
|
192
|
+
const stopStatsAnalyzer = meeting.statsAnalyzer
|
|
193
|
+
? meeting.statsAnalyzer.stopAnalyzer()
|
|
194
|
+
: Promise.resolve();
|
|
195
|
+
|
|
196
|
+
return stopStatsAnalyzer
|
|
197
|
+
.then(() => meeting.closeRemoteStreams())
|
|
198
|
+
.then(() => meeting.closePeerConnections())
|
|
199
|
+
.then(() => {
|
|
200
|
+
meeting.cleanupLocalStreams();
|
|
201
|
+
meeting.unsetRemoteStreams();
|
|
202
|
+
meeting.unsetPeerConnections();
|
|
203
|
+
meeting.reconnectionManager.cleanUp();
|
|
204
|
+
})
|
|
205
|
+
.then(() => meeting.stopKeepAlive())
|
|
206
|
+
.then(() => {
|
|
207
|
+
if (meeting.config?.enableAutomaticLLM) {
|
|
208
|
+
meeting.updateLLMConnection();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
},
|
|
60
212
|
|
|
61
|
-
|
|
62
|
-
.
|
|
213
|
+
disconnectPhoneAudio: (meeting, phoneUrl) => {
|
|
214
|
+
if (meeting.meetingState === FULL_STATE.INACTIVE) {
|
|
215
|
+
return Promise.reject(new MeetingNotActiveError());
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const options = {
|
|
63
219
|
locusUrl: meeting.locusUrl,
|
|
64
220
|
selfId: meeting.selfId,
|
|
65
|
-
localMedias,
|
|
66
|
-
deviceUrl: meeting.deviceUrl,
|
|
67
221
|
correlationId: meeting.correlationId,
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
.then((response) => {
|
|
71
|
-
Metrics.postEvent({event: eventType.MEDIA_RESPONSE, meeting});
|
|
222
|
+
phoneUrl,
|
|
223
|
+
};
|
|
72
224
|
|
|
73
|
-
|
|
225
|
+
return meeting.meetingRequest.disconnectPhoneAudio(options).catch((err) => {
|
|
226
|
+
LoggerProxy.logger.error(
|
|
227
|
+
`Meeting:util#disconnectPhoneAudio --> An error occured while disconnecting phone audio in meeting ${meeting.id}, error: ${err}`
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
return Promise.reject(err);
|
|
74
231
|
});
|
|
75
|
-
}
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Returns options for leaving a meeting.
|
|
236
|
+
* @param {any} meeting
|
|
237
|
+
* @param {any} options
|
|
238
|
+
* @returns {any} leave options
|
|
239
|
+
*/
|
|
240
|
+
prepareLeaveMeetingOptions: (meeting, options: any = {}) => {
|
|
241
|
+
const defaultOptions = {
|
|
242
|
+
locusUrl: meeting.locusUrl,
|
|
243
|
+
selfId: meeting.selfId,
|
|
244
|
+
correlationId: meeting.correlationId,
|
|
245
|
+
resourceId: meeting.resourceId,
|
|
246
|
+
deviceUrl: meeting.deviceUrl,
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
return {...defaultOptions, ...options};
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
// by default will leave on meeting's resourceId
|
|
253
|
+
// if you explicity want it not to leave on resource id, pass
|
|
254
|
+
// {resourceId: null}
|
|
255
|
+
// TODO: chris, you can modify this however you want
|
|
256
|
+
leaveMeeting: (meeting, options: any = {}) => {
|
|
257
|
+
if (meeting.meetingState === FULL_STATE.INACTIVE) {
|
|
258
|
+
// TODO: clean up if the meeting is already inactive
|
|
259
|
+
return Promise.reject(new MeetingNotActiveError());
|
|
260
|
+
}
|
|
76
261
|
|
|
77
|
-
MeetingUtil.
|
|
262
|
+
if (MeetingUtil.isUserInLeftState(meeting.locusInfo)) {
|
|
263
|
+
return Promise.reject(new UserNotJoinedError());
|
|
264
|
+
}
|
|
78
265
|
|
|
79
|
-
|
|
266
|
+
const leaveOptions = MeetingUtil.prepareLeaveMeetingOptions(meeting, options);
|
|
267
|
+
|
|
268
|
+
return meeting.meetingRequest
|
|
269
|
+
.leaveMeeting(leaveOptions)
|
|
270
|
+
.then(() => {
|
|
271
|
+
if (options.moveMeeting) {
|
|
272
|
+
return Promise.resolve();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return MeetingUtil.cleanUp(meeting);
|
|
276
|
+
})
|
|
277
|
+
.catch((err) => {
|
|
278
|
+
// TODO: If the meeting state comes as LEFT or INACTIVE as response then
|
|
279
|
+
// 1) on leave clean up the meeting or simply do a sync on the meeting
|
|
280
|
+
// 2) If the error says meeting is inactive then destroy the meeting object
|
|
281
|
+
LoggerProxy.logger.error(
|
|
282
|
+
`Meeting:util#leaveMeeting --> An error occured while trying to leave meeting with an id of ${meeting.id}, error: ${err}`
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
return Promise.reject(err);
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
declineMeeting: (meeting, reason) =>
|
|
289
|
+
meeting.meetingRequest.declineMeeting({
|
|
290
|
+
locusUrl: meeting.locusUrl,
|
|
291
|
+
deviceUrl: meeting.deviceUrl,
|
|
292
|
+
reason,
|
|
293
|
+
}),
|
|
80
294
|
|
|
81
|
-
|
|
82
|
-
err?.body?.errorCode && INTENT_TO_JOIN.includes(err.body.errorCode);
|
|
295
|
+
isUserInLeftState: (locusInfo) => locusInfo.parsedLocus?.self?.state === _LEFT_,
|
|
83
296
|
|
|
84
|
-
|
|
85
|
-
if (!meeting) {
|
|
86
|
-
return Promise.reject(new ParameterError('You need a meeting object.'));
|
|
87
|
-
}
|
|
297
|
+
isUserInIdleState: (locusInfo) => locusInfo.parsedLocus?.self?.state === _IDLE_,
|
|
88
298
|
|
|
89
|
-
|
|
299
|
+
isUserInJoinedState: (locusInfo) => locusInfo.parsedLocus?.self?.state === _JOINED_,
|
|
90
300
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
event: eventType.LOCUS_JOIN_RESPONSE,
|
|
114
|
-
meeting,
|
|
115
|
-
data: {
|
|
116
|
-
trigger: trigger.LOCI_UPDATE,
|
|
117
|
-
locus: res.body.locus,
|
|
118
|
-
mediaConnections: res.body.mediaConnections,
|
|
119
|
-
trackingId: res.headers.trackingid,
|
|
301
|
+
isMediaEstablished: (currentMediaStatus) =>
|
|
302
|
+
currentMediaStatus &&
|
|
303
|
+
(currentMediaStatus.audio || currentMediaStatus.video || currentMediaStatus.share),
|
|
304
|
+
|
|
305
|
+
joinMeetingOptions: (meeting, options: any = {}) => {
|
|
306
|
+
const webex = meeting.getWebexObject();
|
|
307
|
+
|
|
308
|
+
meeting.resourceId = meeting.resourceId || options.resourceId;
|
|
309
|
+
|
|
310
|
+
if (meeting.requiredCaptcha) {
|
|
311
|
+
return Promise.reject(new CaptchaError());
|
|
312
|
+
}
|
|
313
|
+
if (meeting.passwordStatus === PASSWORD_STATUS.REQUIRED) {
|
|
314
|
+
return Promise.reject(new PasswordError());
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (options.pin) {
|
|
318
|
+
// @ts-ignore
|
|
319
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
320
|
+
name: 'client.pin.collected',
|
|
321
|
+
options: {
|
|
322
|
+
meetingId: meeting.id,
|
|
120
323
|
},
|
|
121
324
|
});
|
|
325
|
+
}
|
|
122
326
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
327
|
+
// normal join meeting, scenario A, D
|
|
328
|
+
return MeetingUtil.joinMeeting(meeting, options)
|
|
329
|
+
.then((response) => {
|
|
330
|
+
meeting.setLocus(response);
|
|
331
|
+
|
|
332
|
+
return Promise.resolve(response);
|
|
333
|
+
})
|
|
334
|
+
.catch((err) => {
|
|
335
|
+
// joining a claimed PMR that is not my own, scenario B
|
|
336
|
+
if (MeetingUtil.isPinOrGuest(err)) {
|
|
337
|
+
// @ts-ignore
|
|
338
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
339
|
+
name: 'client.pin.prompt',
|
|
340
|
+
options: {
|
|
341
|
+
meetingId: meeting.id,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// request host pin or non host for unclaimed PMR, start of Scenario C
|
|
346
|
+
// see https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-Lobby-and--IVR-Feature
|
|
347
|
+
return Promise.reject(new IntentToJoinError('Error Joining Meeting', err));
|
|
348
|
+
}
|
|
349
|
+
LoggerProxy.logger.error(
|
|
350
|
+
'Meeting:util#joinMeetingOptions --> Error joining the call, ',
|
|
351
|
+
err
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
return Promise.reject(new JoinMeetingError(options, 'Error Joining Meeting', err));
|
|
355
|
+
});
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Returns request options for leaving a meeting.
|
|
360
|
+
* @param {any} meeting
|
|
361
|
+
* @param {any} options
|
|
362
|
+
* @returns {any} request options
|
|
363
|
+
*/
|
|
364
|
+
buildLeaveFetchRequestOptions: (meeting, options: any = {}) => {
|
|
365
|
+
const leaveOptions = MeetingUtil.prepareLeaveMeetingOptions(meeting, options);
|
|
366
|
+
|
|
367
|
+
return meeting.meetingRequest.buildLeaveMeetingRequestOptions(leaveOptions);
|
|
368
|
+
},
|
|
369
|
+
|
|
370
|
+
getTrack: (stream) => {
|
|
371
|
+
let audioTrack = null;
|
|
372
|
+
let videoTrack = null;
|
|
373
|
+
let audioTracks = null;
|
|
374
|
+
let videoTracks = null;
|
|
375
|
+
|
|
376
|
+
if (!stream) {
|
|
377
|
+
return {audioTrack: null, videoTrack: null};
|
|
378
|
+
}
|
|
379
|
+
if (stream.getAudioTracks) {
|
|
380
|
+
audioTracks = stream.getAudioTracks();
|
|
381
|
+
}
|
|
382
|
+
if (stream.getVideoTracks) {
|
|
383
|
+
videoTracks = stream.getVideoTracks();
|
|
384
|
+
}
|
|
126
385
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// make sure we send last metrics before we close the peerconnection
|
|
131
|
-
const stopStatsAnalyzer = meeting.statsAnalyzer
|
|
132
|
-
? meeting.statsAnalyzer.stopAnalyzer()
|
|
133
|
-
: Promise.resolve();
|
|
134
|
-
|
|
135
|
-
return stopStatsAnalyzer
|
|
136
|
-
.then(() => meeting.closeLocalStream())
|
|
137
|
-
.then(() => meeting.closeLocalShare())
|
|
138
|
-
.then(() => meeting.closeRemoteTracks())
|
|
139
|
-
.then(() => meeting.closePeerConnections())
|
|
140
|
-
.then(() => {
|
|
141
|
-
meeting.unsetLocalVideoTrack();
|
|
142
|
-
meeting.unsetLocalShareTrack();
|
|
143
|
-
meeting.unsetRemoteTracks();
|
|
144
|
-
meeting.unsetPeerConnections();
|
|
145
|
-
meeting.reconnectionManager.cleanUp();
|
|
146
|
-
})
|
|
147
|
-
.then(() => meeting.stopKeepAlive())
|
|
148
|
-
.then(() => meeting.updateLLMConnection());
|
|
149
|
-
};
|
|
386
|
+
if (audioTracks && audioTracks.length > 0) {
|
|
387
|
+
[audioTrack] = audioTracks;
|
|
388
|
+
}
|
|
150
389
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const options = {
|
|
157
|
-
locusUrl: meeting.locusUrl,
|
|
158
|
-
selfId: meeting.selfId,
|
|
159
|
-
correlationId: meeting.correlationId,
|
|
160
|
-
phoneUrl,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
return meeting.meetingRequest
|
|
164
|
-
.disconnectPhoneAudio(options)
|
|
165
|
-
.then((response) => {
|
|
166
|
-
if (response?.body?.locus) {
|
|
167
|
-
meeting.locusInfo.onFullLocus(response.body.locus);
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
.catch((err) => {
|
|
171
|
-
LoggerProxy.logger.error(
|
|
172
|
-
`Meeting:util#disconnectPhoneAudio --> An error occured while disconnecting phone audio in meeting ${meeting.id}, error: ${err}`
|
|
173
|
-
);
|
|
390
|
+
if (videoTracks && videoTracks.length > 0) {
|
|
391
|
+
[videoTrack] = videoTracks;
|
|
392
|
+
}
|
|
174
393
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
};
|
|
394
|
+
return {audioTrack, videoTrack};
|
|
395
|
+
},
|
|
178
396
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// TODO: clean up if the meeting is already inactive
|
|
186
|
-
return Promise.reject(new MeetingNotActiveError());
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (MeetingUtil.isUserInLeftState(meeting.locusInfo)) {
|
|
190
|
-
return Promise.reject(new UserNotJoinedError());
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const defaultOptions = {
|
|
194
|
-
locusUrl: meeting.locusUrl,
|
|
195
|
-
selfId: meeting.selfId,
|
|
196
|
-
correlationId: meeting.correlationId,
|
|
197
|
-
resourceId: meeting.resourceId,
|
|
198
|
-
deviceUrl: meeting.deviceUrl,
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const leaveOptions = {...defaultOptions, ...options};
|
|
202
|
-
|
|
203
|
-
return meeting.meetingRequest
|
|
204
|
-
.leaveMeeting(leaveOptions)
|
|
205
|
-
.then((response) => {
|
|
206
|
-
if (response && response.body && response.body.locus) {
|
|
207
|
-
// && !options.moveMeeting) {
|
|
208
|
-
meeting.locusInfo.onFullLocus(response.body.locus);
|
|
209
|
-
}
|
|
397
|
+
getModeratorFromLocusInfo: (locusInfo) =>
|
|
398
|
+
locusInfo &&
|
|
399
|
+
locusInfo.parsedLocus &&
|
|
400
|
+
locusInfo.parsedLocus.info &&
|
|
401
|
+
locusInfo.parsedLocus.info &&
|
|
402
|
+
locusInfo.parsedLocus.info.moderator,
|
|
210
403
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
404
|
+
getPolicyFromLocusInfo: (locusInfo) =>
|
|
405
|
+
locusInfo &&
|
|
406
|
+
locusInfo.parsedLocus &&
|
|
407
|
+
locusInfo.parsedLocus.info &&
|
|
408
|
+
locusInfo.parsedLocus.info &&
|
|
409
|
+
locusInfo.parsedLocus.info.policy,
|
|
217
410
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
.catch((err) => {
|
|
221
|
-
// TODO: If the meeting state comes as LEFT or INACTIVE as response then
|
|
222
|
-
// 1) on leave clean up the meeting or simply do a sync on the meeting
|
|
223
|
-
// 2) If the error says meeting is inactive then destroy the meeting object
|
|
224
|
-
LoggerProxy.logger.error(
|
|
225
|
-
`Meeting:util#leaveMeeting --> An error occured while trying to leave meeting with an id of ${meeting.id}, error: ${err}`
|
|
226
|
-
);
|
|
411
|
+
getUserDisplayHintsFromLocusInfo: (locusInfo) =>
|
|
412
|
+
locusInfo?.parsedLocus?.info?.userDisplayHints || [],
|
|
227
413
|
|
|
228
|
-
|
|
229
|
-
});
|
|
230
|
-
};
|
|
231
|
-
MeetingUtil.declineMeeting = (meeting, reason) =>
|
|
232
|
-
meeting.meetingRequest.declineMeeting({
|
|
233
|
-
locusUrl: meeting.locusUrl,
|
|
234
|
-
deviceUrl: meeting.deviceUrl,
|
|
235
|
-
reason,
|
|
236
|
-
});
|
|
414
|
+
canInviteNewParticipants: (displayHints) => displayHints.includes(DISPLAY_HINTS.ADD_GUEST),
|
|
237
415
|
|
|
238
|
-
|
|
416
|
+
canAdmitParticipant: (displayHints) =>
|
|
417
|
+
displayHints.includes(DISPLAY_HINTS.ROSTER_WAITING_TO_JOIN),
|
|
239
418
|
|
|
240
|
-
|
|
419
|
+
canUserLock: (displayHints) =>
|
|
420
|
+
displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_LOCK) &&
|
|
421
|
+
displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_UNLOCKED),
|
|
241
422
|
|
|
242
|
-
|
|
423
|
+
canUserUnlock: (displayHints) =>
|
|
424
|
+
displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_UNLOCK) &&
|
|
425
|
+
displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_LOCKED),
|
|
243
426
|
|
|
244
|
-
|
|
245
|
-
currentMediaStatus &&
|
|
246
|
-
(currentMediaStatus.audio || currentMediaStatus.video || currentMediaStatus.share);
|
|
427
|
+
canUserRaiseHand: (displayHints) => displayHints.includes(DISPLAY_HINTS.RAISE_HAND),
|
|
247
428
|
|
|
248
|
-
|
|
249
|
-
meeting.resourceId = meeting.resourceId || options.resourceId;
|
|
429
|
+
canUserLowerAllHands: (displayHints) => displayHints.includes(DISPLAY_HINTS.LOWER_ALL_HANDS),
|
|
250
430
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
if (meeting.passwordStatus === PASSWORD_STATUS.REQUIRED) {
|
|
255
|
-
return Promise.reject(new PasswordError());
|
|
256
|
-
}
|
|
431
|
+
canUserLowerSomeoneElsesHand: (displayHints) =>
|
|
432
|
+
displayHints.includes(DISPLAY_HINTS.LOWER_SOMEONE_ELSES_HAND),
|
|
257
433
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
meeting,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// normal join meeting, scenario A, D
|
|
266
|
-
return MeetingUtil.joinMeeting(meeting, options)
|
|
267
|
-
.then((response) => {
|
|
268
|
-
meeting.setLocus(response);
|
|
269
|
-
|
|
270
|
-
return Promise.resolve(response);
|
|
271
|
-
})
|
|
272
|
-
.catch((err) => {
|
|
273
|
-
// joining a claimed PMR that is not my own, scenario B
|
|
274
|
-
if (MeetingUtil.isPinOrGuest(err)) {
|
|
275
|
-
Metrics.postEvent({
|
|
276
|
-
event: eventType.PIN_PROMPT,
|
|
277
|
-
meeting,
|
|
278
|
-
});
|
|
434
|
+
bothLeaveAndEndMeetingAvailable: (displayHints) =>
|
|
435
|
+
displayHints.includes(DISPLAY_HINTS.LEAVE_TRANSFER_HOST_END_MEETING) ||
|
|
436
|
+
displayHints.includes(DISPLAY_HINTS.LEAVE_END_MEETING),
|
|
279
437
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
LoggerProxy.logger.error('Meeting:util#joinMeetingOptions --> Error joining the call, ', err);
|
|
438
|
+
canManageBreakout: (displayHints) => displayHints.includes(DISPLAY_HINTS.BREAKOUT_MANAGEMENT),
|
|
439
|
+
canBroadcastMessageToBreakout: (displayHints, policies = {}) =>
|
|
440
|
+
displayHints.includes(DISPLAY_HINTS.BROADCAST_MESSAGE_TO_BREAKOUT) &&
|
|
441
|
+
!!policies[SELF_POLICY.SUPPORT_BROADCAST_MESSAGE],
|
|
285
442
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
};
|
|
443
|
+
isSuppressBreakoutSupport: (displayHints) =>
|
|
444
|
+
displayHints.includes(DISPLAY_HINTS.UCF_SUPPRESS_BREAKOUTS_SUPPORT),
|
|
289
445
|
|
|
290
|
-
|
|
291
|
-
|
|
446
|
+
canAdmitLobbyToBreakout: (displayHints) =>
|
|
447
|
+
!displayHints.includes(DISPLAY_HINTS.DISABLE_LOBBY_TO_BREAKOUT),
|
|
292
448
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
449
|
+
isBreakoutPreassignmentsEnabled: (displayHints) =>
|
|
450
|
+
!displayHints.includes(DISPLAY_HINTS.DISABLE_BREAKOUT_PREASSIGNMENTS),
|
|
296
451
|
|
|
297
|
-
|
|
298
|
-
return Promise.reject(new ParameterError('please pass valid audio streams'));
|
|
299
|
-
}
|
|
452
|
+
canUserAskForHelp: (displayHints) => !displayHints.includes(DISPLAY_HINTS.DISABLE_ASK_FOR_HELP),
|
|
300
453
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
454
|
+
lockMeeting: (actions, request, locusUrl) => {
|
|
455
|
+
if (actions && actions.canLock) {
|
|
456
|
+
return request.lockMeeting({locusUrl, lock: true});
|
|
457
|
+
}
|
|
304
458
|
|
|
305
|
-
|
|
306
|
-
}
|
|
459
|
+
return Promise.reject(new PermissionError('Lock not allowed, due to joined property.'));
|
|
460
|
+
},
|
|
307
461
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
let videoTracks = null;
|
|
313
|
-
|
|
314
|
-
if (!stream) {
|
|
315
|
-
return {audioTrack: null, videoTrack: null};
|
|
316
|
-
}
|
|
317
|
-
if (stream.getAudioTracks) {
|
|
318
|
-
audioTracks = stream.getAudioTracks();
|
|
319
|
-
}
|
|
320
|
-
if (stream.getVideoTracks) {
|
|
321
|
-
videoTracks = stream.getVideoTracks();
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (audioTracks && audioTracks.length > 0) {
|
|
325
|
-
[audioTrack] = audioTracks;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (videoTracks && videoTracks.length > 0) {
|
|
329
|
-
[videoTrack] = videoTracks;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
return {audioTrack, videoTrack};
|
|
333
|
-
};
|
|
462
|
+
unlockMeeting: (actions, request, locusUrl) => {
|
|
463
|
+
if (actions && actions.canUnlock) {
|
|
464
|
+
return request.lockMeeting({locusUrl, lock: false});
|
|
465
|
+
}
|
|
334
466
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
locusInfo.parsedLocus &&
|
|
338
|
-
locusInfo.parsedLocus.info &&
|
|
339
|
-
locusInfo.parsedLocus.info &&
|
|
340
|
-
locusInfo.parsedLocus.info.moderator;
|
|
467
|
+
return Promise.reject(new PermissionError('Unlock not allowed, due to joined property.'));
|
|
468
|
+
},
|
|
341
469
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
locusInfo.parsedLocus &&
|
|
345
|
-
locusInfo.parsedLocus.info &&
|
|
346
|
-
locusInfo.parsedLocus.info &&
|
|
347
|
-
locusInfo.parsedLocus.info.policy;
|
|
470
|
+
handleAudioLogging: (audioStream?: LocalMicrophoneStream) => {
|
|
471
|
+
const LOG_HEADER = 'MeetingUtil#handleAudioLogging -->';
|
|
348
472
|
|
|
349
|
-
|
|
350
|
-
|
|
473
|
+
if (audioStream) {
|
|
474
|
+
const settings = audioStream.getSettings();
|
|
475
|
+
const {deviceId} = settings;
|
|
351
476
|
|
|
352
|
-
|
|
353
|
-
|
|
477
|
+
LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${deviceId}`);
|
|
478
|
+
LoggerProxy.logger.log(LOG_HEADER, 'settings =', JSON.stringify(settings));
|
|
479
|
+
}
|
|
480
|
+
},
|
|
354
481
|
|
|
355
|
-
|
|
356
|
-
|
|
482
|
+
handleVideoLogging: (videoStream?: LocalCameraStream) => {
|
|
483
|
+
const LOG_HEADER = 'MeetingUtil#handleVideoLogging -->';
|
|
357
484
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
485
|
+
if (videoStream) {
|
|
486
|
+
const settings = videoStream.getSettings();
|
|
487
|
+
const {deviceId} = settings;
|
|
361
488
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
489
|
+
LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${deviceId}`);
|
|
490
|
+
LoggerProxy.logger.log(LOG_HEADER, 'settings =', JSON.stringify(settings));
|
|
491
|
+
}
|
|
492
|
+
},
|
|
365
493
|
|
|
366
|
-
|
|
494
|
+
handleDeviceLogging: (devices = []) => {
|
|
495
|
+
const LOG_HEADER = 'MeetingUtil#handleDeviceLogging -->';
|
|
367
496
|
|
|
368
|
-
|
|
369
|
-
|
|
497
|
+
devices.forEach((device) => {
|
|
498
|
+
LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${device.deviceId}`);
|
|
499
|
+
LoggerProxy.logger.log(LOG_HEADER, 'settings', JSON.stringify(device));
|
|
500
|
+
});
|
|
501
|
+
},
|
|
370
502
|
|
|
371
|
-
|
|
372
|
-
|
|
503
|
+
endMeetingForAll: (meeting) => {
|
|
504
|
+
if (meeting.meetingState === FULL_STATE.INACTIVE) {
|
|
505
|
+
return Promise.reject(new MeetingNotActiveError());
|
|
506
|
+
}
|
|
373
507
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
508
|
+
const endOptions = {
|
|
509
|
+
locusUrl: meeting.locusUrl,
|
|
510
|
+
};
|
|
377
511
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
512
|
+
return meeting.meetingRequest
|
|
513
|
+
.endMeetingForAll(endOptions)
|
|
514
|
+
.then(() => MeetingUtil.cleanUp(meeting))
|
|
515
|
+
.catch((err) => {
|
|
516
|
+
LoggerProxy.logger.error(
|
|
517
|
+
`Meeting:util#endMeetingForAll An error occured while trying to end meeting for all with an id of ${meeting.id}, error: ${err}`
|
|
518
|
+
);
|
|
382
519
|
|
|
383
|
-
|
|
384
|
-
};
|
|
520
|
+
return Promise.reject(err);
|
|
521
|
+
});
|
|
522
|
+
},
|
|
385
523
|
|
|
386
|
-
|
|
387
|
-
if (actions && actions.canUnlock) {
|
|
388
|
-
return request.lockMeeting({locusUrl, lock: false});
|
|
389
|
-
}
|
|
524
|
+
canEnableClosedCaption: (displayHints) => displayHints.includes(DISPLAY_HINTS.CAPTION_START),
|
|
390
525
|
|
|
391
|
-
|
|
392
|
-
|
|
526
|
+
isSaveTranscriptsEnabled: (displayHints) =>
|
|
527
|
+
displayHints.includes(DISPLAY_HINTS.SAVE_TRANSCRIPTS_ENABLED),
|
|
393
528
|
|
|
394
|
-
|
|
395
|
-
|
|
529
|
+
canStartTranscribing: (displayHints) =>
|
|
530
|
+
displayHints.includes(DISPLAY_HINTS.TRANSCRIPTION_CONTROL_START),
|
|
396
531
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const {deviceId} = settings;
|
|
532
|
+
canStopTranscribing: (displayHints) =>
|
|
533
|
+
displayHints.includes(DISPLAY_HINTS.TRANSCRIPTION_CONTROL_STOP),
|
|
400
534
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
};
|
|
535
|
+
isClosedCaptionActive: (displayHints) =>
|
|
536
|
+
displayHints.includes(DISPLAY_HINTS.CAPTION_STATUS_ACTIVE),
|
|
405
537
|
|
|
406
|
-
|
|
407
|
-
|
|
538
|
+
isWebexAssistantActive: (displayHints) =>
|
|
539
|
+
displayHints.includes(DISPLAY_HINTS.WEBEX_ASSISTANT_STATUS_ACTIVE),
|
|
408
540
|
|
|
409
|
-
|
|
410
|
-
const settings = videoTrack.underlyingTrack.getSettings();
|
|
411
|
-
const {deviceId} = settings;
|
|
541
|
+
canViewCaptionPanel: (displayHints) => displayHints.includes(DISPLAY_HINTS.ENABLE_CAPTION_PANEL),
|
|
412
542
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
};
|
|
543
|
+
isRealTimeTranslationEnabled: (displayHints) =>
|
|
544
|
+
displayHints.includes(DISPLAY_HINTS.DISPLAY_REAL_TIME_TRANSLATION),
|
|
417
545
|
|
|
418
|
-
|
|
419
|
-
|
|
546
|
+
canSelectSpokenLanguages: (displayHints) =>
|
|
547
|
+
displayHints.includes(DISPLAY_HINTS.DISPLAY_NON_ENGLISH_ASR),
|
|
420
548
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
549
|
+
waitingForOthersToJoin: (displayHints) => displayHints.includes(DISPLAY_HINTS.WAITING_FOR_OTHERS),
|
|
550
|
+
|
|
551
|
+
canSendReactions: (originalValue, displayHints) => {
|
|
552
|
+
if (displayHints.includes(DISPLAY_HINTS.REACTIONS_ACTIVE)) {
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
555
|
+
if (displayHints.includes(DISPLAY_HINTS.REACTIONS_INACTIVE)) {
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
return originalValue;
|
|
560
|
+
},
|
|
561
|
+
canUserRenameSelfAndObserved: (displayHints) =>
|
|
562
|
+
displayHints.includes(DISPLAY_HINTS.CAN_RENAME_SELF_AND_OBSERVED),
|
|
426
563
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
564
|
+
canUserRenameOthers: (displayHints) => displayHints.includes(DISPLAY_HINTS.CAN_RENAME_OTHERS),
|
|
565
|
+
|
|
566
|
+
canShareWhiteBoard: (displayHints) => displayHints.includes(DISPLAY_HINTS.SHARE_WHITEBOARD),
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Adds the current locus sequence information to a request body
|
|
570
|
+
* @param {Object} meeting The meeting object
|
|
571
|
+
* @param {Object} requestBody The body of a request to locus
|
|
572
|
+
* @returns {void}
|
|
573
|
+
*/
|
|
574
|
+
addSequence: (meeting, requestBody) => {
|
|
575
|
+
const sequence = meeting?.locusInfo?.sequence;
|
|
576
|
+
|
|
577
|
+
if (!sequence) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
requestBody.sequence = sequence;
|
|
582
|
+
},
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Updates the locus info for the meeting with the delta locus
|
|
586
|
+
* returned from requests that include the sequence information
|
|
587
|
+
* Returns the original response object
|
|
588
|
+
* @param {Object} meeting The meeting object
|
|
589
|
+
* @param {Object} response The response of the http request
|
|
590
|
+
* @returns {Object}
|
|
591
|
+
*/
|
|
592
|
+
updateLocusWithDelta: (meeting, response) => {
|
|
593
|
+
if (!meeting) {
|
|
594
|
+
return response;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const locus = response?.body?.locus;
|
|
598
|
+
|
|
599
|
+
if (locus) {
|
|
600
|
+
meeting.locusInfo.handleLocusDelta(locus, meeting);
|
|
601
|
+
}
|
|
431
602
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
};
|
|
603
|
+
return response;
|
|
604
|
+
},
|
|
435
605
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
606
|
+
generateBuildLocusDeltaRequestOptions: (originalMeeting) => {
|
|
607
|
+
const meetingRef = new WeakRef(originalMeeting);
|
|
608
|
+
|
|
609
|
+
const buildLocusDeltaRequestOptions = (originalOptions) => {
|
|
610
|
+
const meeting = meetingRef.deref();
|
|
611
|
+
|
|
612
|
+
if (!meeting) {
|
|
613
|
+
return originalOptions;
|
|
441
614
|
}
|
|
442
615
|
|
|
443
|
-
|
|
444
|
-
})
|
|
445
|
-
.then(() => MeetingUtil.cleanUp(meeting))
|
|
446
|
-
.catch((err) => {
|
|
447
|
-
LoggerProxy.logger.error(
|
|
448
|
-
`Meeting:util#endMeetingForAll An error occured while trying to end meeting for all with an id of ${meeting.id}, error: ${err}`
|
|
449
|
-
);
|
|
616
|
+
const options = cloneDeep(originalOptions);
|
|
450
617
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
618
|
+
if (!options.body) {
|
|
619
|
+
options.body = {};
|
|
620
|
+
}
|
|
454
621
|
|
|
455
|
-
MeetingUtil.
|
|
456
|
-
displayHints.includes(DISPLAY_HINTS.CAPTION_START);
|
|
622
|
+
MeetingUtil.addSequence(meeting, options.body);
|
|
457
623
|
|
|
458
|
-
|
|
459
|
-
|
|
624
|
+
return options;
|
|
625
|
+
};
|
|
460
626
|
|
|
461
|
-
|
|
462
|
-
|
|
627
|
+
return buildLocusDeltaRequestOptions;
|
|
628
|
+
},
|
|
463
629
|
|
|
464
|
-
|
|
465
|
-
|
|
630
|
+
generateLocusDeltaRequest: (originalMeeting) => {
|
|
631
|
+
const meetingRef = new WeakRef(originalMeeting);
|
|
466
632
|
|
|
467
|
-
|
|
468
|
-
|
|
633
|
+
const buildLocusDeltaRequestOptions =
|
|
634
|
+
MeetingUtil.generateBuildLocusDeltaRequestOptions(originalMeeting);
|
|
469
635
|
|
|
470
|
-
|
|
471
|
-
|
|
636
|
+
const locusDeltaRequest = (originalOptions) => {
|
|
637
|
+
const meeting = meetingRef.deref();
|
|
472
638
|
|
|
473
|
-
|
|
474
|
-
|
|
639
|
+
if (!meeting) {
|
|
640
|
+
return Promise.resolve();
|
|
641
|
+
}
|
|
475
642
|
|
|
476
|
-
|
|
477
|
-
displayHints.includes(DISPLAY_HINTS.DISPLAY_NON_ENGLISH_ASR);
|
|
643
|
+
const options = buildLocusDeltaRequestOptions(originalOptions);
|
|
478
644
|
|
|
479
|
-
|
|
480
|
-
|
|
645
|
+
return meeting
|
|
646
|
+
.request(options)
|
|
647
|
+
.then((response) => MeetingUtil.updateLocusWithDelta(meeting, response));
|
|
648
|
+
};
|
|
481
649
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
return true;
|
|
485
|
-
}
|
|
486
|
-
if (displayHints.includes(DISPLAY_HINTS.DISABLE_REACTIONS)) {
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
650
|
+
return locusDeltaRequest;
|
|
651
|
+
},
|
|
489
652
|
|
|
490
|
-
|
|
491
|
-
|
|
653
|
+
selfSupportsFeature: (feature: SELF_POLICY, userPolicies: Record<SELF_POLICY, boolean>) => {
|
|
654
|
+
if (!userPolicies) {
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return userPolicies[feature];
|
|
659
|
+
},
|
|
492
660
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
661
|
+
parseInterpretationInfo: (meeting, meetingInfo) => {
|
|
662
|
+
if (!meeting || !meetingInfo) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
const siInfo = meetingInfo.simultaneousInterpretation;
|
|
666
|
+
meeting.simultaneousInterpretation.updateMeetingSIEnabled(
|
|
667
|
+
!!meetingInfo.turnOnSimultaneousInterpretation,
|
|
668
|
+
!!siInfo?.currentSIInterpreter
|
|
669
|
+
);
|
|
670
|
+
const hostSIEnabled = !!(
|
|
671
|
+
meetingInfo.turnOnSimultaneousInterpretation &&
|
|
672
|
+
meetingInfo?.meetingSiteSetting?.enableHostInterpreterControlSI
|
|
673
|
+
);
|
|
674
|
+
meeting.simultaneousInterpretation.updateHostSIEnabled(hostSIEnabled);
|
|
675
|
+
|
|
676
|
+
function renameKey(obj, oldKey, newKey) {
|
|
677
|
+
if (oldKey in obj) {
|
|
678
|
+
obj[newKey] = obj[oldKey];
|
|
679
|
+
delete obj[oldKey];
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
if (siInfo) {
|
|
683
|
+
const lanuagesInfo = cloneDeep(siInfo.siLanguages);
|
|
684
|
+
for (const language of lanuagesInfo) {
|
|
685
|
+
renameKey(language, 'languageCode', 'languageName');
|
|
686
|
+
renameKey(language, 'languageGroupId', 'languageCode');
|
|
687
|
+
}
|
|
688
|
+
if (!meeting.simultaneousInterpretation?.siLanguages?.length) {
|
|
689
|
+
meeting.simultaneousInterpretation.updateInterpretation({siLanguages: lanuagesInfo});
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
Trigger.trigger(
|
|
693
|
+
meeting,
|
|
694
|
+
{
|
|
695
|
+
file: 'meeting/util',
|
|
696
|
+
function: 'parseInterpretationInfo',
|
|
697
|
+
},
|
|
698
|
+
EVENT_TRIGGERS.MEETING_INTERPRETATION_UPDATE
|
|
699
|
+
);
|
|
700
|
+
},
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Returns a CA-recognized error payload for the specified raw error message/reason.
|
|
704
|
+
*
|
|
705
|
+
* New errors can be added to this function for handling in the future
|
|
706
|
+
*
|
|
707
|
+
* @param {String} reason the raw error message
|
|
708
|
+
* @returns {Array<object>} an array of payload objects
|
|
709
|
+
*/
|
|
710
|
+
getChangeMeetingFloorErrorPayload: (reason: string) => {
|
|
711
|
+
const errorPayload = {
|
|
712
|
+
errorDescription: reason,
|
|
713
|
+
name: 'locus.response',
|
|
714
|
+
shownToUser: false,
|
|
715
|
+
};
|
|
716
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.UNDEFINED)) {
|
|
717
|
+
return [
|
|
718
|
+
{
|
|
719
|
+
...errorPayload,
|
|
720
|
+
fatal: true,
|
|
721
|
+
category: 'signaling',
|
|
722
|
+
errorCode: 1100,
|
|
723
|
+
},
|
|
724
|
+
];
|
|
725
|
+
}
|
|
726
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED)) {
|
|
727
|
+
return [
|
|
728
|
+
{
|
|
729
|
+
...errorPayload,
|
|
730
|
+
fatal: true,
|
|
731
|
+
category: 'signaling',
|
|
732
|
+
errorCode: 4050,
|
|
733
|
+
},
|
|
734
|
+
];
|
|
735
|
+
}
|
|
736
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.NO_MEDIA_FOR_DEVICE)) {
|
|
737
|
+
return [
|
|
738
|
+
{
|
|
739
|
+
...errorPayload,
|
|
740
|
+
fatal: true,
|
|
741
|
+
category: 'media',
|
|
742
|
+
errorCode: 2048,
|
|
743
|
+
},
|
|
744
|
+
];
|
|
745
|
+
}
|
|
746
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.NO_CONFLUENCE_ID)) {
|
|
747
|
+
return [
|
|
748
|
+
{
|
|
749
|
+
...errorPayload,
|
|
750
|
+
fatal: true,
|
|
751
|
+
category: 'signaling',
|
|
752
|
+
errorCode: 4064,
|
|
753
|
+
},
|
|
754
|
+
];
|
|
755
|
+
}
|
|
756
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.CONTENT_SHARING_DISABLED)) {
|
|
757
|
+
return [
|
|
758
|
+
{
|
|
759
|
+
...errorPayload,
|
|
760
|
+
fatal: true,
|
|
761
|
+
category: 'expected',
|
|
762
|
+
errorCode: 4065,
|
|
763
|
+
},
|
|
764
|
+
];
|
|
765
|
+
}
|
|
766
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.LOCUS_PARTICIPANT_DNE)) {
|
|
767
|
+
return [
|
|
768
|
+
{
|
|
769
|
+
...errorPayload,
|
|
770
|
+
fatal: true,
|
|
771
|
+
category: 'signaling',
|
|
772
|
+
errorCode: 4066,
|
|
773
|
+
},
|
|
774
|
+
];
|
|
775
|
+
}
|
|
776
|
+
if (reason.includes(LOCAL_SHARE_ERRORS.CONTENT_REQUEST_WHILE_PENDING_WHITEBOARD)) {
|
|
777
|
+
return [
|
|
778
|
+
{
|
|
779
|
+
...errorPayload,
|
|
780
|
+
fatal: true,
|
|
781
|
+
category: 'expected',
|
|
782
|
+
errorCode: 4067,
|
|
783
|
+
},
|
|
784
|
+
];
|
|
785
|
+
}
|
|
500
786
|
|
|
501
|
-
|
|
787
|
+
// return unknown error
|
|
788
|
+
return [
|
|
789
|
+
{
|
|
790
|
+
...errorPayload,
|
|
791
|
+
fatal: true,
|
|
792
|
+
category: 'signaling',
|
|
793
|
+
errorCode: 1100,
|
|
794
|
+
},
|
|
795
|
+
];
|
|
796
|
+
},
|
|
502
797
|
};
|
|
503
798
|
|
|
504
799
|
export default MeetingUtil;
|