@webex/plugin-meetings 3.0.0-beta.27 → 3.0.0-beta.271
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 +46 -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 +114 -14
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +52 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +763 -31
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +78 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.js +67 -0
- package/dist/breakouts/utils.js.map +1 -0
- 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/webex-errors.js +28 -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/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.js +203 -28
- 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 +112 -1
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -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 +381 -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 +57 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +224 -63
- 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 +58 -116
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +72 -123
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +82 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +3118 -2814
- 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 +230 -124
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +256 -196
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +601 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +70 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +189 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +22 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +394 -94
- 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 +71 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +49 -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 +121 -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 +86 -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 +316 -233
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +12 -5
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -468
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +238 -49
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +49 -16
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +52 -34
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +44 -18
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +60 -3
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +209 -59
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/index.js +225 -59
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +17 -8
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +199 -154
- 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 +23 -29
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +112 -97
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +96 -36
- 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 +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +51 -34
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +6 -6
- 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/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/request.d.ts +22 -0
- package/dist/types/breakouts/utils.d.ts +15 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/webex-errors.d.ts +13 -1
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +1 -6
- package/dist/types/constants.d.ts +161 -21
- 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 -4
- 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 +65 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -48
- package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
- package/dist/types/meeting/index.d.ts +345 -507
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +99 -23
- package/dist/types/meeting/request.d.ts +72 -43
- package/dist/types/meeting/util.d.ts +101 -1
- 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 +8 -0
- package/dist/types/meetings/index.d.ts +88 -12
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +13 -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 +24 -0
- package/dist/types/members/util.d.ts +209 -1
- package/dist/types/metrics/constants.d.ts +11 -4
- package/dist/types/metrics/index.d.ts +4 -119
- package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
- package/dist/types/multistream/receiveSlot.d.ts +16 -12
- package/dist/types/multistream/receiveSlotManager.d.ts +19 -4
- package/dist/types/multistream/remoteMedia.d.ts +8 -29
- package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
- package/dist/types/multistream/sendSlotManager.d.ts +61 -0
- package/dist/types/reachability/index.d.ts +61 -7
- package/dist/types/reachability/request.d.ts +7 -3
- package/dist/types/reconnection-manager/index.d.ts +9 -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/request.d.ts +15 -11
- package/dist/types/roap/turnDiscovery.d.ts +18 -1
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +47 -0
- package/dist/types/statsAnalyzer/index.d.ts +6 -1
- package/package.json +23 -20
- 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 +44 -14
- package/src/breakouts/breakout.ts +87 -9
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +646 -18
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/webex-errors.ts +27 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -9
- package/src/constants.ts +184 -18
- 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 +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +412 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +231 -39
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +100 -122
- package/src/media/properties.ts +85 -108
- package/src/meeting/in-meeting-actions.ts +163 -3
- package/src/meeting/index.ts +2526 -2309
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +229 -131
- package/src/meeting/request.ts +172 -121
- package/src/meeting/util.ts +588 -394
- package/src/meeting-info/index.ts +79 -8
- package/src/meeting-info/meeting-info-v2.ts +168 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +20 -0
- package/src/meetings/index.ts +428 -108
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +79 -4
- package/src/member/index.ts +49 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +127 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +107 -6
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +28 -0
- package/src/members/util.ts +319 -240
- package/src/metrics/constants.ts +11 -4
- package/src/metrics/index.ts +1 -490
- package/src/multistream/mediaRequestManager.ts +289 -79
- package/src/multistream/receiveSlot.ts +55 -18
- package/src/multistream/receiveSlotManager.ts +46 -24
- package/src/multistream/remoteMedia.ts +27 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +148 -30
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/reachability/index.ts +228 -37
- package/src/reachability/request.ts +17 -8
- package/src/reconnection-manager/index.ts +81 -54
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +23 -30
- package/src/roap/request.ts +100 -104
- package/src/roap/turnDiscovery.ts +51 -25
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/index.ts +73 -35
- package/src/statsAnalyzer/mqaUtil.ts +8 -10
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- 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 +142 -24
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1488 -67
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- 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/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -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 +1283 -33
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +62 -22
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +104 -37
- package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
- package/test/unit/spec/meeting/index.js +4307 -1938
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +408 -208
- package/test/unit/spec/meeting/request.js +440 -45
- package/test/unit/spec/meeting/utils.js +679 -64
- package/test/unit/spec/meeting-info/index.js +293 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +517 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +14 -0
- package/test/unit/spec/meetings/index.js +1007 -177
- package/test/unit/spec/meetings/utils.js +206 -2
- package/test/unit/spec/member/index.js +58 -4
- package/test/unit/spec/member/util.js +479 -35
- package/test/unit/spec/members/index.js +319 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +184 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
- package/test/unit/spec/multistream/receiveSlot.ts +72 -13
- package/test/unit/spec/multistream/receiveSlotManager.ts +58 -28
- package/test/unit/spec/multistream/remoteMedia.ts +30 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/reachability/index.ts +549 -9
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +84 -9
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +31 -51
- package/test/unit/spec/roap/request.ts +203 -85
- package/test/unit/spec/roap/turnDiscovery.ts +48 -13
- package/test/unit/spec/rtcMetrics/index.ts +68 -0
- package/test/unit/spec/stats-analyzer/index.js +29 -2
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -52
- package/dist/meeting/effectsState.js +0 -262
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.js +0 -299
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/meeting/effectsState.d.ts +0 -42
- package/dist/types/metrics/config.d.ts +0 -178
- package/src/index.js +0 -16
- package/src/meeting/effectsState.ts +0 -211
- package/src/metrics/config.ts +0 -495
- package/test/unit/spec/meeting/effectsState.js +0 -285
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {SELF_ROLES, DISPLAY_HINTS} from '../constants';
|
|
1
|
+
import {SELF_ROLES, DISPLAY_HINTS, INTERSTITIAL_DISPLAY_HINTS} from '../constants';
|
|
2
2
|
|
|
3
3
|
const InfoUtils: any = {};
|
|
4
4
|
|
|
@@ -9,7 +9,15 @@ InfoUtils.parse = (info, roles, isJoined = true) => {
|
|
|
9
9
|
coHost: InfoUtils.parseCoHost(info),
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
let userDisplayHints = isJoined
|
|
12
|
+
let userDisplayHints = isJoined
|
|
13
|
+
? {...parsed.policy}
|
|
14
|
+
: {
|
|
15
|
+
...Object.fromEntries(
|
|
16
|
+
Object.entries(parsed.policy).filter(([hint]) =>
|
|
17
|
+
INTERSTITIAL_DISPLAY_HINTS.includes(hint)
|
|
18
|
+
)
|
|
19
|
+
),
|
|
20
|
+
};
|
|
13
21
|
|
|
14
22
|
if (roles.includes(SELF_ROLES.COHOST)) {
|
|
15
23
|
userDisplayHints = {...userDisplayHints, ...parsed.coHost};
|
|
@@ -13,6 +13,10 @@ MediaSharesUtils.parse = (mediaShares: object) => {
|
|
|
13
13
|
content: {
|
|
14
14
|
beneficiaryId: MediaSharesUtils.getContentBeneficiaryId(mediaShares),
|
|
15
15
|
disposition: MediaSharesUtils.getContentDisposition(mediaShares),
|
|
16
|
+
annotation: MediaSharesUtils.getContentAnnotation(mediaShares),
|
|
17
|
+
url: MediaSharesUtils.getContentUrl(mediaShares),
|
|
18
|
+
shareInstanceId: MediaSharesUtils.getShareInstanceId(mediaShares),
|
|
19
|
+
deviceUrlSharing: MediaSharesUtils.getContentBeneficiaryDeviceUrl(mediaShares),
|
|
16
20
|
},
|
|
17
21
|
whiteboard: {
|
|
18
22
|
beneficiaryId: MediaSharesUtils.getWhiteboardBeneficiaryId(mediaShares),
|
|
@@ -140,6 +144,66 @@ MediaSharesUtils.getContentBeneficiaryId = (mediaShares: object) => {
|
|
|
140
144
|
return contentFloor.beneficiary.id;
|
|
141
145
|
};
|
|
142
146
|
|
|
147
|
+
/**
|
|
148
|
+
* get live annotation is sharing from media shares (content)
|
|
149
|
+
* @param {Object} mediaShares
|
|
150
|
+
* @returns {Object}
|
|
151
|
+
*/
|
|
152
|
+
MediaSharesUtils.getContentAnnotation = (mediaShares: object) => {
|
|
153
|
+
const extractContent = MediaSharesUtils.extractContent(mediaShares);
|
|
154
|
+
|
|
155
|
+
if (!extractContent || !extractContent.annotation) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return extractContent.annotation;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* get url is sharing from media shares (content)
|
|
164
|
+
* @param {Object} mediaShares
|
|
165
|
+
* @returns {Object}
|
|
166
|
+
*/
|
|
167
|
+
MediaSharesUtils.getContentUrl = (mediaShares: object) => {
|
|
168
|
+
const extractContent = MediaSharesUtils.extractContent(mediaShares);
|
|
169
|
+
|
|
170
|
+
if (!extractContent || !extractContent.url) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return extractContent.url;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* get shareInstanceId is sharing from media shares (content)
|
|
179
|
+
* @param {Object} mediaShares
|
|
180
|
+
* @returns {Object}
|
|
181
|
+
*/
|
|
182
|
+
MediaSharesUtils.getShareInstanceId = (mediaShares: object) => {
|
|
183
|
+
const extractContent = MediaSharesUtils.extractContent(mediaShares);
|
|
184
|
+
|
|
185
|
+
if (!extractContent || !extractContent.floor || !extractContent.floor.shareInstanceId) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return extractContent.floor.shareInstanceId;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* get deviceUrl that is requesting the floor for media shares (content)
|
|
194
|
+
* @param {Object} mediaShares
|
|
195
|
+
* @returns {Object}
|
|
196
|
+
*/
|
|
197
|
+
MediaSharesUtils.getContentBeneficiaryDeviceUrl = (mediaShares: object) => {
|
|
198
|
+
const contentFloor = MediaSharesUtils.extractContentFloor(mediaShares);
|
|
199
|
+
|
|
200
|
+
if (!contentFloor || !contentFloor.beneficiary || !contentFloor.beneficiary.deviceUrl) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return contentFloor.beneficiary.deviceUrl;
|
|
205
|
+
};
|
|
206
|
+
|
|
143
207
|
/**
|
|
144
208
|
* get who is sharing from media shares (whiteboard)
|
|
145
209
|
* @param {Object} mediaShares
|
package/src/locus-info/parser.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
import {difference} from 'lodash';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import SortedQueue from '../common/queue';
|
|
4
4
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
5
5
|
|
|
6
|
+
import Metrics from '../metrics';
|
|
7
|
+
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
8
|
+
|
|
9
|
+
const MAX_OOO_DELTA_COUNT = 5; // when we receive an out-of-order delta and the queue builds up to MAX_OOO_DELTA_COUNT, we do a sync with Locus
|
|
10
|
+
const OOO_DELTA_WAIT_TIME = 10000; // [ms] minimum wait time before we do a sync if we get out-of-order deltas
|
|
11
|
+
const OOO_DELTA_WAIT_TIME_RANDOM_DELAY = 5000; // [ms] max random delay added to OOO_DELTA_WAIT_TIME
|
|
12
|
+
|
|
13
|
+
type LocusDeltaDto = {
|
|
14
|
+
baseSequence: {
|
|
15
|
+
rangeStart: number;
|
|
16
|
+
rangeEnd: number;
|
|
17
|
+
entries: number[];
|
|
18
|
+
};
|
|
19
|
+
sequence: {
|
|
20
|
+
rangeStart: number;
|
|
21
|
+
rangeEnd: number;
|
|
22
|
+
entries: number[];
|
|
23
|
+
};
|
|
24
|
+
syncUrl: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
6
27
|
/**
|
|
7
28
|
* Locus Delta Parser
|
|
8
29
|
* @private
|
|
@@ -10,11 +31,11 @@ import LoggerProxy from '../common/logs/logger-proxy';
|
|
|
10
31
|
*/
|
|
11
32
|
export default class Parser {
|
|
12
33
|
// processing status
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
34
|
+
status:
|
|
35
|
+
| 'IDLE' // not doing anything
|
|
36
|
+
| 'PAUSED' // paused, because we are doing a sync
|
|
37
|
+
| 'WORKING' // processing a delta event
|
|
38
|
+
| 'BLOCKED'; // received an out-of-order delta, so waiting for the missing one
|
|
18
39
|
|
|
19
40
|
// loci comparison states
|
|
20
41
|
static loci = {
|
|
@@ -24,21 +45,59 @@ export default class Parser {
|
|
|
24
45
|
DESYNC: 'DESYNC',
|
|
25
46
|
USE_INCOMING: 'USE_INCOMING',
|
|
26
47
|
USE_CURRENT: 'USE_CURRENT',
|
|
48
|
+
WAIT: 'WAIT',
|
|
27
49
|
ERROR: 'ERROR',
|
|
28
50
|
};
|
|
29
51
|
|
|
30
|
-
queue:
|
|
52
|
+
queue: SortedQueue<LocusDeltaDto>;
|
|
31
53
|
workingCopy: any;
|
|
54
|
+
syncTimer: null | number | NodeJS.Timeout;
|
|
32
55
|
|
|
33
56
|
/**
|
|
34
57
|
* @constructs Parser
|
|
35
58
|
*/
|
|
36
59
|
constructor() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
const deltaCompareFunc = (left: LocusDeltaDto, right: LocusDeltaDto) => {
|
|
61
|
+
const {LT, GT} = Parser.loci;
|
|
62
|
+
const {extractComparisonState: extract} = Parser;
|
|
63
|
+
|
|
64
|
+
if (Parser.isSequenceEmpty(left)) {
|
|
65
|
+
return -1;
|
|
66
|
+
}
|
|
67
|
+
if (Parser.isSequenceEmpty(right)) {
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
const result = extract(Parser.compareSequence(left.baseSequence, right.baseSequence));
|
|
71
|
+
|
|
72
|
+
if (result === LT) {
|
|
73
|
+
return -1;
|
|
74
|
+
}
|
|
75
|
+
if (result === GT) {
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return 0;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
this.queue = new SortedQueue<LocusDeltaDto>(deltaCompareFunc);
|
|
83
|
+
this.status = 'IDLE';
|
|
40
84
|
this.onDeltaAction = null;
|
|
41
85
|
this.workingCopy = null;
|
|
86
|
+
this.syncTimer = null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Returns a debug string representing a locus delta - useful for logging
|
|
91
|
+
*
|
|
92
|
+
* @param {LocusDeltaDto} locus Locus delta
|
|
93
|
+
* @returns {string}
|
|
94
|
+
*/
|
|
95
|
+
static locus2string(locus: LocusDeltaDto) {
|
|
96
|
+
if (!locus.sequence?.entries) {
|
|
97
|
+
return 'invalid';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return locus.sequence.entries.length ? `seq=${locus.sequence.entries.at(-1)}` : 'empty';
|
|
42
101
|
}
|
|
43
102
|
|
|
44
103
|
/**
|
|
@@ -208,7 +267,7 @@ export default class Parser {
|
|
|
208
267
|
* @returns {string} loci comparison state
|
|
209
268
|
*/
|
|
210
269
|
private static compareDelta(current, incoming) {
|
|
211
|
-
const {LT, GT, EQ, DESYNC, USE_INCOMING} = Parser.loci;
|
|
270
|
+
const {LT, GT, EQ, DESYNC, USE_INCOMING, WAIT} = Parser.loci;
|
|
212
271
|
|
|
213
272
|
const {extractComparisonState: extract} = Parser;
|
|
214
273
|
const {packComparisonResult: pack} = Parser;
|
|
@@ -228,6 +287,21 @@ export default class Parser {
|
|
|
228
287
|
comparison = USE_INCOMING;
|
|
229
288
|
break;
|
|
230
289
|
|
|
290
|
+
case LT:
|
|
291
|
+
if (extract(Parser.compareSequence(incoming.baseSequence, incoming.sequence)) === EQ) {
|
|
292
|
+
// special case where Locus sends a delta with baseSequence === sequence to trigger a sync,
|
|
293
|
+
// because the delta event is too large to be sent over mercury connection
|
|
294
|
+
comparison = DESYNC;
|
|
295
|
+
} else {
|
|
296
|
+
// the incoming locus has baseSequence from the future, so it is out-of-order,
|
|
297
|
+
// we are missing 1 or more locus that should be in front of it, we need to wait for it
|
|
298
|
+
comparison = WAIT;
|
|
299
|
+
|
|
300
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LOCUS_DELTA_OUT_OF_ORDER, {
|
|
301
|
+
stack: new Error().stack,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
break;
|
|
231
305
|
default:
|
|
232
306
|
comparison = DESYNC;
|
|
233
307
|
}
|
|
@@ -235,6 +309,49 @@ export default class Parser {
|
|
|
235
309
|
return pack(comparison, result);
|
|
236
310
|
}
|
|
237
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Compares Locus sequences - it should be called only for full Locus DTOs, not deltas
|
|
314
|
+
*
|
|
315
|
+
* @param {Types~Locus} current Current working copy
|
|
316
|
+
* @param {Types~Locus} incomingFullDto New Full Locus DTO
|
|
317
|
+
* @returns {string} either Parser.loci.USE_INCOMING or Parser.loci.USE_CURRENT
|
|
318
|
+
*/
|
|
319
|
+
static compareFullDtoSequence(current, incomingFullDto) {
|
|
320
|
+
if (Parser.isSequenceEmpty(current) || Parser.isSequenceEmpty(incomingFullDto)) {
|
|
321
|
+
return Parser.loci.USE_INCOMING;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// the sequence.entries list will always contain at least 1 entry
|
|
325
|
+
// https://sqbu-github.cisco.com/WebExSquared/cloud-apps/wiki/Locus-Sequence-Comparison-Algorithm
|
|
326
|
+
|
|
327
|
+
return incomingFullDto.sequence.entries.slice(-1)[0] > current.sequence.entries.slice(-1)[0]
|
|
328
|
+
? Parser.loci.USE_INCOMING
|
|
329
|
+
: Parser.loci.USE_CURRENT;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Returns true if the incoming full locus DTO is newer than the current working copy
|
|
334
|
+
*
|
|
335
|
+
* @param {Types~Locus} incomingFullDto New Full Locus DTO
|
|
336
|
+
* @returns {string} either Parser.loci.USE_INCOMING or Parser.loci.USE_CURRENT
|
|
337
|
+
*/
|
|
338
|
+
isNewFullLocus(incomingFullDto) {
|
|
339
|
+
if (!Parser.isLoci(incomingFullDto)) {
|
|
340
|
+
LoggerProxy.logger.info('Locus-info:parser#isNewFullLocus --> Ignoring non-locus object.');
|
|
341
|
+
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (!this.workingCopy) {
|
|
346
|
+
// we don't have a working copy yet, so any full locus is better than nothing
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const comparisonResult = Parser.compareFullDtoSequence(this.workingCopy, incomingFullDto);
|
|
351
|
+
|
|
352
|
+
return comparisonResult === Parser.loci.USE_INCOMING;
|
|
353
|
+
}
|
|
354
|
+
|
|
238
355
|
/**
|
|
239
356
|
* Compares Locus sequences
|
|
240
357
|
* @param {Types~Locus} current Current working copy
|
|
@@ -393,17 +510,10 @@ export default class Parser {
|
|
|
393
510
|
*/
|
|
394
511
|
isValidLocus(newLoci) {
|
|
395
512
|
let isValid = false;
|
|
396
|
-
const {IDLE} = Parser.status;
|
|
397
513
|
const {isLoci} = Parser;
|
|
398
|
-
// @ts-ignore
|
|
399
|
-
const setStatus = (status) => {
|
|
400
|
-
// @ts-ignore
|
|
401
|
-
this.status = status;
|
|
402
|
-
};
|
|
403
514
|
|
|
404
515
|
// one or both objects are not locus delta events
|
|
405
516
|
if (!isLoci(this.workingCopy) || !isLoci(newLoci)) {
|
|
406
|
-
setStatus(IDLE);
|
|
407
517
|
LoggerProxy.logger.info(
|
|
408
518
|
'Locus-info:parser#processDeltaEvent --> Ignoring non-locus object. workingCopy:',
|
|
409
519
|
this.workingCopy,
|
|
@@ -455,19 +565,25 @@ export default class Parser {
|
|
|
455
565
|
* @returns {undefined}
|
|
456
566
|
*/
|
|
457
567
|
nextEvent() {
|
|
458
|
-
|
|
459
|
-
if (this.status === Parser.status.PAUSED) {
|
|
568
|
+
if (this.status === 'PAUSED') {
|
|
460
569
|
LoggerProxy.logger.info('Locus-info:parser#nextEvent --> Locus parser paused.');
|
|
461
570
|
|
|
462
571
|
return;
|
|
463
572
|
}
|
|
464
573
|
|
|
574
|
+
if (this.status === 'BLOCKED') {
|
|
575
|
+
LoggerProxy.logger.info(
|
|
576
|
+
'Locus-info:parser#nextEvent --> Locus parser blocked by out-of-order delta.'
|
|
577
|
+
);
|
|
578
|
+
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
|
|
465
582
|
// continue processing until queue is empty
|
|
466
583
|
if (this.queue.size() > 0) {
|
|
467
584
|
this.processDeltaEvent();
|
|
468
585
|
} else {
|
|
469
|
-
|
|
470
|
-
this.status = Parser.status.IDLE;
|
|
586
|
+
this.status = 'IDLE';
|
|
471
587
|
}
|
|
472
588
|
}
|
|
473
589
|
|
|
@@ -478,7 +594,7 @@ export default class Parser {
|
|
|
478
594
|
* @param {Types~Locus} locus Locus delta
|
|
479
595
|
* @returns {undefined}
|
|
480
596
|
*/
|
|
481
|
-
// eslint-disable-next-line no-unused-vars
|
|
597
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
482
598
|
onDeltaAction(action: string, locus) {}
|
|
483
599
|
|
|
484
600
|
/**
|
|
@@ -489,15 +605,20 @@ export default class Parser {
|
|
|
489
605
|
onDeltaEvent(loci) {
|
|
490
606
|
// enqueue the new loci
|
|
491
607
|
this.queue.enqueue(loci);
|
|
492
|
-
// start processing events in the queue if idle
|
|
493
|
-
// and a function handler is defined
|
|
494
|
-
// @ts-ignore
|
|
495
|
-
if (this.status === Parser.status.IDLE && this.onDeltaAction) {
|
|
496
|
-
// Update status, ensure we only process one event at a time.
|
|
497
|
-
// @ts-ignore
|
|
498
|
-
this.status = Parser.status.WORKING;
|
|
499
608
|
|
|
500
|
-
|
|
609
|
+
if (this.onDeltaAction) {
|
|
610
|
+
if (this.status === 'BLOCKED') {
|
|
611
|
+
if (this.queue.size() > MAX_OOO_DELTA_COUNT) {
|
|
612
|
+
this.triggerSync('queue too big, blocked on out-of-order delta');
|
|
613
|
+
} else {
|
|
614
|
+
this.processDeltaEvent();
|
|
615
|
+
}
|
|
616
|
+
} else if (this.status === 'IDLE') {
|
|
617
|
+
// Update status, ensure we only process one event at a time.
|
|
618
|
+
this.status = 'WORKING';
|
|
619
|
+
|
|
620
|
+
this.processDeltaEvent();
|
|
621
|
+
}
|
|
501
622
|
}
|
|
502
623
|
}
|
|
503
624
|
|
|
@@ -516,11 +637,55 @@ export default class Parser {
|
|
|
516
637
|
* @returns {undefined}
|
|
517
638
|
*/
|
|
518
639
|
pause() {
|
|
519
|
-
|
|
520
|
-
this.status = Parser.status.PAUSED;
|
|
640
|
+
this.status = 'PAUSED';
|
|
521
641
|
LoggerProxy.logger.info('Locus-info:parser#pause --> Locus parser paused.');
|
|
522
642
|
}
|
|
523
643
|
|
|
644
|
+
/**
|
|
645
|
+
* Triggers a sync with Locus
|
|
646
|
+
*
|
|
647
|
+
* @param {string} reason used just for logging
|
|
648
|
+
* @returns {undefined}
|
|
649
|
+
*/
|
|
650
|
+
private triggerSync(reason: string) {
|
|
651
|
+
LoggerProxy.logger.info(`Locus-info:parser#triggerSync --> doing sync, reason: ${reason}`);
|
|
652
|
+
this.stopSyncTimer();
|
|
653
|
+
this.pause();
|
|
654
|
+
this.onDeltaAction(Parser.loci.DESYNC, this.workingCopy);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Starts a timer with a random delay. When that timer expires we will do a sync.
|
|
659
|
+
*
|
|
660
|
+
* The main purpose of this timer is to handle a case when we get some out-of-order deltas,
|
|
661
|
+
* so we start waiting to receive the missing delta. If that delta never arrives, this timer
|
|
662
|
+
* will trigger a sync with Locus.
|
|
663
|
+
*
|
|
664
|
+
* @returns {undefined}
|
|
665
|
+
*/
|
|
666
|
+
private startSyncTimer() {
|
|
667
|
+
if (this.syncTimer === null) {
|
|
668
|
+
const timeout = OOO_DELTA_WAIT_TIME + Math.random() * OOO_DELTA_WAIT_TIME_RANDOM_DELAY;
|
|
669
|
+
|
|
670
|
+
this.syncTimer = setTimeout(() => {
|
|
671
|
+
this.syncTimer = null;
|
|
672
|
+
this.triggerSync('timer expired, blocked on out-of-order delta');
|
|
673
|
+
}, timeout);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Stops the timer for triggering a sync
|
|
679
|
+
*
|
|
680
|
+
* @returns {undefined}
|
|
681
|
+
*/
|
|
682
|
+
private stopSyncTimer() {
|
|
683
|
+
if (this.syncTimer !== null) {
|
|
684
|
+
clearTimeout(this.syncTimer);
|
|
685
|
+
this.syncTimer = null;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
524
689
|
/**
|
|
525
690
|
* Processes next locus delta in the queue,
|
|
526
691
|
* continues until the queue is empty
|
|
@@ -528,11 +693,13 @@ export default class Parser {
|
|
|
528
693
|
* @returns {undefined}
|
|
529
694
|
*/
|
|
530
695
|
processDeltaEvent() {
|
|
531
|
-
const {DESYNC, USE_INCOMING} = Parser.loci;
|
|
696
|
+
const {DESYNC, USE_INCOMING, WAIT} = Parser.loci;
|
|
532
697
|
const {extractComparisonState: extract} = Parser;
|
|
533
698
|
const newLoci = this.queue.dequeue();
|
|
534
699
|
|
|
535
700
|
if (!this.isValidLocus(newLoci)) {
|
|
701
|
+
this.nextEvent();
|
|
702
|
+
|
|
536
703
|
return;
|
|
537
704
|
}
|
|
538
705
|
|
|
@@ -543,6 +710,8 @@ export default class Parser {
|
|
|
543
710
|
// for full debugging.
|
|
544
711
|
LoggerProxy.logger.debug(`Locus-info:parser#processDeltaEvent --> Locus Debug: ${result}`);
|
|
545
712
|
|
|
713
|
+
let needToWait = false;
|
|
714
|
+
|
|
546
715
|
if (lociComparison === DESYNC) {
|
|
547
716
|
// wait for desync response
|
|
548
717
|
this.pause();
|
|
@@ -551,15 +720,39 @@ export default class Parser {
|
|
|
551
720
|
// Note: The working copy of parser gets updated in .onFullLocus()
|
|
552
721
|
// and here when USE_INCOMING locus.
|
|
553
722
|
this.workingCopy = newLoci;
|
|
723
|
+
} else if (lociComparison === WAIT) {
|
|
724
|
+
// we've taken newLoci from the front of the queue, so put it back there as we have to wait
|
|
725
|
+
// for the one that should be in front of it, before we can process it
|
|
726
|
+
this.queue.enqueue(newLoci);
|
|
727
|
+
needToWait = true;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if (needToWait) {
|
|
731
|
+
this.status = 'BLOCKED';
|
|
732
|
+
this.startSyncTimer();
|
|
733
|
+
} else {
|
|
734
|
+
this.stopSyncTimer();
|
|
735
|
+
|
|
736
|
+
if (this.status === 'BLOCKED') {
|
|
737
|
+
// we are not blocked anymore
|
|
738
|
+
this.status = 'WORKING';
|
|
739
|
+
|
|
740
|
+
LoggerProxy.logger.info(
|
|
741
|
+
`Locus-info:parser#processDeltaEvent --> received delta that we were waiting for ${Parser.locus2string(
|
|
742
|
+
newLoci
|
|
743
|
+
)}, not blocked anymore`
|
|
744
|
+
);
|
|
745
|
+
}
|
|
554
746
|
}
|
|
555
747
|
|
|
556
748
|
if (this.onDeltaAction) {
|
|
557
749
|
LoggerProxy.logger.info(
|
|
558
|
-
`Locus-info:parser#processDeltaEvent --> Locus Delta
|
|
750
|
+
`Locus-info:parser#processDeltaEvent --> Locus Delta ${Parser.locus2string(
|
|
751
|
+
newLoci
|
|
752
|
+
)}, Action: ${lociComparison}`
|
|
559
753
|
);
|
|
560
754
|
|
|
561
|
-
|
|
562
|
-
this.onDeltaAction.call(this, lociComparison, newLoci);
|
|
755
|
+
this.onDeltaAction(lociComparison, newLoci);
|
|
563
756
|
}
|
|
564
757
|
|
|
565
758
|
this.nextEvent();
|
|
@@ -571,8 +764,7 @@ export default class Parser {
|
|
|
571
764
|
*/
|
|
572
765
|
resume() {
|
|
573
766
|
LoggerProxy.logger.info('Locus-info:parser#resume --> Locus parser resumed.');
|
|
574
|
-
|
|
575
|
-
this.status = Parser.status.WORKING;
|
|
767
|
+
this.status = 'WORKING';
|
|
576
768
|
this.nextEvent();
|
|
577
769
|
}
|
|
578
770
|
|
|
@@ -32,9 +32,11 @@ SelfUtils.parse = (self: any, deviceId: string) => {
|
|
|
32
32
|
const pstnDevices = self.devices.filter((device) => PSTN_DEVICE_TYPE === device.deviceType);
|
|
33
33
|
|
|
34
34
|
return {
|
|
35
|
+
remoteVideoMuted: SelfUtils.getRemoteVideoMuted(self),
|
|
35
36
|
remoteMuted: SelfUtils.getRemoteMuted(self),
|
|
36
37
|
unmuteAllowed: SelfUtils.getUnmuteAllowed(self),
|
|
37
38
|
localAudioUnmuteRequested: SelfUtils.getLocalAudioUnmuteRequested(self),
|
|
39
|
+
localAudioUnmuteRequestedTimeStamp: SelfUtils.getLocalAudioUnmuteRequestedTimeStamp(self),
|
|
38
40
|
localAudioUnmuteRequired: SelfUtils.getLocalAudioUnmuteRequired(self),
|
|
39
41
|
lastModified: SelfUtils.getLastModified(self),
|
|
40
42
|
modifiedBy: SelfUtils.getModifiedBy(self),
|
|
@@ -61,14 +63,18 @@ SelfUtils.parse = (self: any, deviceId: string) => {
|
|
|
61
63
|
layout: SelfUtils.getLayout(self),
|
|
62
64
|
canNotViewTheParticipantList: SelfUtils.canNotViewTheParticipantList(self),
|
|
63
65
|
isSharingBlocked: SelfUtils.isSharingBlocked(self),
|
|
64
|
-
breakoutSessions: SelfUtils.
|
|
66
|
+
breakoutSessions: SelfUtils.getBreakoutSessions(self),
|
|
67
|
+
breakout: SelfUtils.getBreakout(self),
|
|
68
|
+
interpretation: SelfUtils.getInterpretation(self),
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
return null;
|
|
69
73
|
};
|
|
70
74
|
|
|
71
|
-
SelfUtils.
|
|
75
|
+
SelfUtils.getBreakoutSessions = (self) => self?.controls?.breakout?.sessions;
|
|
76
|
+
SelfUtils.getBreakout = (self) => self?.controls?.breakout;
|
|
77
|
+
SelfUtils.getInterpretation = (self) => self?.controls?.interpretation;
|
|
72
78
|
|
|
73
79
|
SelfUtils.getLayout = (self) =>
|
|
74
80
|
Array.isArray(self?.controls?.layouts) ? self.controls.layouts[0].type : undefined;
|
|
@@ -93,6 +99,7 @@ SelfUtils.getSelves = (oldSelf, newSelf, deviceId) => {
|
|
|
93
99
|
|
|
94
100
|
updates.isUserUnadmitted = SelfUtils.isUserUnadmitted(current);
|
|
95
101
|
updates.isUserAdmitted = SelfUtils.isUserAdmitted(previous, current);
|
|
102
|
+
updates.isVideoMutedByOthersChanged = SelfUtils.videoMutedByOthersChanged(previous, current);
|
|
96
103
|
updates.isMutedByOthersChanged = SelfUtils.mutedByOthersChanged(previous, current);
|
|
97
104
|
updates.localAudioUnmuteRequestedByServer = SelfUtils.localAudioUnmuteRequestedByServer(
|
|
98
105
|
previous,
|
|
@@ -103,6 +110,7 @@ SelfUtils.getSelves = (oldSelf, newSelf, deviceId) => {
|
|
|
103
110
|
current
|
|
104
111
|
);
|
|
105
112
|
updates.moderatorChanged = SelfUtils.moderatorChanged(previous, current);
|
|
113
|
+
updates.isRolesChanged = SelfUtils.isRolesChanged(previous, current);
|
|
106
114
|
updates.isMediaInactiveOrReleased = SelfUtils.wasMediaInactiveOrReleased(previous, current);
|
|
107
115
|
updates.isUserObserving = SelfUtils.isDeviceObserving(previous, current);
|
|
108
116
|
updates.layoutChanged = SelfUtils.layoutChanged(previous, current);
|
|
@@ -119,6 +127,7 @@ SelfUtils.getSelves = (oldSelf, newSelf, deviceId) => {
|
|
|
119
127
|
previous?.canNotViewTheParticipantList !== current.canNotViewTheParticipantList;
|
|
120
128
|
updates.isSharingBlockedChanged = previous?.isSharingBlocked !== current.isSharingBlocked;
|
|
121
129
|
updates.breakoutsChanged = SelfUtils.breakoutsChanged(previous, current);
|
|
130
|
+
updates.interpretationChanged = SelfUtils.interpretationChanged(previous, current);
|
|
122
131
|
|
|
123
132
|
return {
|
|
124
133
|
previous,
|
|
@@ -139,13 +148,16 @@ SelfUtils.isJoined = (self: any) => self?.state === _JOINED_;
|
|
|
139
148
|
*
|
|
140
149
|
* @param {Self} previous - Previous self state
|
|
141
150
|
* @param {Self} current - Current self state [per event]
|
|
142
|
-
* @returns {boolean} - If the
|
|
151
|
+
* @returns {boolean} - If the Meeting Layout Controls Layout has changed.
|
|
143
152
|
*/
|
|
144
153
|
SelfUtils.layoutChanged = (previous: any, current: any) =>
|
|
145
154
|
current?.layout && previous?.layout !== current?.layout;
|
|
146
155
|
|
|
147
156
|
SelfUtils.breakoutsChanged = (previous, current) =>
|
|
148
|
-
!isEqual(previous?.breakoutSessions, current?.breakoutSessions);
|
|
157
|
+
!isEqual(previous?.breakoutSessions, current?.breakoutSessions) && !!current?.breakout;
|
|
158
|
+
|
|
159
|
+
SelfUtils.interpretationChanged = (previous, current) =>
|
|
160
|
+
!isEqual(previous?.interpretation, current?.interpretation) && !!current?.interpretation;
|
|
149
161
|
|
|
150
162
|
SelfUtils.isMediaInactive = (previous, current) => {
|
|
151
163
|
if (
|
|
@@ -236,6 +248,19 @@ SelfUtils.getSelfIdentity = (self: any) => {
|
|
|
236
248
|
return self.person.id;
|
|
237
249
|
};
|
|
238
250
|
|
|
251
|
+
/**
|
|
252
|
+
* get the "remote video mute" property from the self object
|
|
253
|
+
* @param {Object} self
|
|
254
|
+
* @returns {Boolean}
|
|
255
|
+
*/
|
|
256
|
+
SelfUtils.getRemoteVideoMuted = (self: any) => {
|
|
257
|
+
if (!self || !self.controls || !self.controls.video) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return self.controls.video.muted;
|
|
262
|
+
};
|
|
263
|
+
|
|
239
264
|
/**
|
|
240
265
|
* get the "remote mute" property from the self object
|
|
241
266
|
* @param {Object} self
|
|
@@ -251,6 +276,10 @@ SelfUtils.getRemoteMuted = (self: any) => {
|
|
|
251
276
|
|
|
252
277
|
SelfUtils.getLocalAudioUnmuteRequested = (self) => !!self?.controls?.audio?.requestedToUnmute;
|
|
253
278
|
|
|
279
|
+
// requestedToUnmute timestamp
|
|
280
|
+
SelfUtils.getLocalAudioUnmuteRequestedTimeStamp = (self) =>
|
|
281
|
+
Date.parse(self?.controls?.audio?.lastModifiedRequestedToUnmute) || 0;
|
|
282
|
+
|
|
254
283
|
SelfUtils.getUnmuteAllowed = (self) => {
|
|
255
284
|
if (!self || !self.controls || !self.controls.audio) {
|
|
256
285
|
return null;
|
|
@@ -275,6 +304,7 @@ SelfUtils.getStatus = (status) => ({
|
|
|
275
304
|
SelfUtils.wasMediaInactiveOrReleased = (oldSelf: any = {}, changedSelf: any) =>
|
|
276
305
|
oldSelf.joinedWith &&
|
|
277
306
|
oldSelf.joinedWith.state === _JOINED_ &&
|
|
307
|
+
changedSelf.joinedWith &&
|
|
278
308
|
changedSelf.joinedWith.state === _LEFT_ &&
|
|
279
309
|
(changedSelf.joinedWith.reason === MEETING_END_REASON.INACTIVE ||
|
|
280
310
|
changedSelf.joinedWith.reason === MEETING_END_REASON.MEDIA_RELEASED);
|
|
@@ -319,6 +349,20 @@ SelfUtils.moderatorChanged = (oldSelf, changedSelf) => {
|
|
|
319
349
|
return oldSelf.moderator !== changedSelf.moderator;
|
|
320
350
|
};
|
|
321
351
|
|
|
352
|
+
/**
|
|
353
|
+
* determine whether the roles of self is changed or not
|
|
354
|
+
* @param {Object} oldSelf
|
|
355
|
+
* @param {Object} changedSelf
|
|
356
|
+
* @returns {Boolean}
|
|
357
|
+
*/
|
|
358
|
+
SelfUtils.isRolesChanged = (oldSelf, changedSelf) => {
|
|
359
|
+
if (!changedSelf) {
|
|
360
|
+
// no new self means no change
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return !isEqual(oldSelf?.roles, changedSelf?.roles);
|
|
365
|
+
};
|
|
322
366
|
/**
|
|
323
367
|
* @param {Object} oldSelf
|
|
324
368
|
* @param {Object} changedSelf
|
|
@@ -351,6 +395,25 @@ SelfUtils.isUserAdmitted = (oldSelf: object, changedSelf: object) => {
|
|
|
351
395
|
return SelfUtils.isLocusUserUnadmitted(oldSelf) && SelfUtils.isLocusUserAdmitted(changedSelf);
|
|
352
396
|
};
|
|
353
397
|
|
|
398
|
+
SelfUtils.videoMutedByOthersChanged = (oldSelf, changedSelf) => {
|
|
399
|
+
if (!changedSelf) {
|
|
400
|
+
throw new ParameterError(
|
|
401
|
+
'New self must be defined to determine if self was video muted by others.'
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (!oldSelf || oldSelf.remoteVideoMuted === null) {
|
|
406
|
+
if (changedSelf.remoteVideoMuted) {
|
|
407
|
+
return true; // this happens when host disables "Allow start video"
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// we don't want to be sending the 'meeting:self:videoUnmutedByOthers' notification on meeting join
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return oldSelf.remoteVideoMuted !== changedSelf.remoteVideoMuted;
|
|
415
|
+
};
|
|
416
|
+
|
|
354
417
|
SelfUtils.mutedByOthersChanged = (oldSelf, changedSelf) => {
|
|
355
418
|
if (!changedSelf) {
|
|
356
419
|
throw new ParameterError('New self must be defined to determine if self was muted by others.');
|
|
@@ -379,7 +442,10 @@ SelfUtils.localAudioUnmuteRequestedByServer = (oldSelf: any = {}, changedSelf: a
|
|
|
379
442
|
);
|
|
380
443
|
}
|
|
381
444
|
|
|
382
|
-
return
|
|
445
|
+
return (
|
|
446
|
+
changedSelf.localAudioUnmuteRequested &&
|
|
447
|
+
changedSelf.localAudioUnmuteRequestedTimeStamp > oldSelf.localAudioUnmuteRequestedTimeStamp
|
|
448
|
+
);
|
|
383
449
|
};
|
|
384
450
|
|
|
385
451
|
SelfUtils.localAudioUnmuteRequiredByServer = (oldSelf: any = {}, changedSelf: any) => {
|
|
@@ -432,4 +498,14 @@ SelfUtils.getMediaStatus = (mediaSessions = []) => {
|
|
|
432
498
|
return mediaStatus;
|
|
433
499
|
};
|
|
434
500
|
|
|
501
|
+
SelfUtils.getReplacedBreakoutMoveId = (self: any, deviceId: string) => {
|
|
502
|
+
if (self && Array.isArray(self.devices)) {
|
|
503
|
+
const joinedDevice = self.devices.find((device) => deviceId === device.url);
|
|
504
|
+
if (Array.isArray(joinedDevice?.replaces)) {
|
|
505
|
+
return joinedDevice.replaces[0]?.breakoutMoveId;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return null;
|
|
510
|
+
};
|
|
435
511
|
export default SelfUtils;
|