@webex/plugin-meetings 3.0.0-beta.201 → 3.0.0-beta.203

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +10 -4
  4. package/dist/constants.js.map +1 -1
  5. package/dist/interpretation/index.js +1 -1
  6. package/dist/interpretation/siLanguage.js +1 -1
  7. package/dist/locus-info/index.js +5 -8
  8. package/dist/locus-info/index.js.map +1 -1
  9. package/dist/locus-info/infoUtils.js +7 -1
  10. package/dist/locus-info/infoUtils.js.map +1 -1
  11. package/dist/meeting/in-meeting-actions.js +3 -1
  12. package/dist/meeting/in-meeting-actions.js.map +1 -1
  13. package/dist/meeting/index.js +502 -453
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/recording-controller/index.js +0 -1
  16. package/dist/recording-controller/index.js.map +1 -1
  17. package/dist/types/constants.d.ts +3 -0
  18. package/dist/types/locus-info/index.d.ts +1 -1
  19. package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
  20. package/dist/types/meeting/index.d.ts +14 -0
  21. package/dist/types/recording-controller/index.d.ts +0 -1
  22. package/package.json +19 -19
  23. package/src/constants.ts +7 -0
  24. package/src/locus-info/index.ts +9 -10
  25. package/src/locus-info/infoUtils.ts +10 -2
  26. package/src/meeting/in-meeting-actions.ts +4 -0
  27. package/src/meeting/index.ts +268 -231
  28. package/src/recording-controller/index.ts +0 -1
  29. package/test/unit/spec/locus-info/index.js +80 -3
  30. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  31. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
  32. package/test/unit/spec/meeting/index.js +284 -148
  33. package/test/unit/spec/meetings/index.js +2 -2
@@ -1,5 +1,5 @@
1
1
  import uuid from 'uuid';
2
- import {cloneDeep, isEqual, defer, isEmpty} from 'lodash';
2
+ import {cloneDeep, isEqual, isEmpty} from 'lodash';
3
3
  import jwt from 'jsonwebtoken';
4
4
  // @ts-ignore - Fix this
5
5
  import {StatelessWebexPlugin} from '@webex/webex-core';
@@ -483,6 +483,7 @@ export default class Meeting extends StatelessWebexPlugin {
483
483
  userId: string;
484
484
  video: any;
485
485
  callEvents: any[];
486
+ datachannelUrl: string;
486
487
  deferJoin: Promise<any>;
487
488
  dialInDeviceStatus: string;
488
489
  dialInUrl: string;
@@ -525,6 +526,7 @@ export default class Meeting extends StatelessWebexPlugin {
525
526
  statsAnalyzer: StatsAnalyzer;
526
527
  transcription: Transcription;
527
528
  updateMediaConnections: (mediaConnections: any[]) => void;
529
+ userDisplayHints: any;
528
530
  endCallInitJoinReq: any;
529
531
  endJoinReqResp: any;
530
532
  endLocalSDPGenRemoteSDPRecvDelay: any;
@@ -1348,8 +1350,12 @@ export default class Meeting extends StatelessWebexPlugin {
1348
1350
  EVENT_TRIGGERS.MEETING_INFO_AVAILABLE
1349
1351
  );
1350
1352
 
1353
+ this.updateMeetingActions();
1354
+
1351
1355
  return Promise.resolve();
1352
1356
  } catch (err) {
1357
+ this.updateMeetingActions();
1358
+
1353
1359
  if (err instanceof MeetingInfoV2PolicyError) {
1354
1360
  this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.POLICY;
1355
1361
  this.meetingInfoFailureCode = err.wbxAppApiCode;
@@ -2393,6 +2399,16 @@ export default class Meeting extends StatelessWebexPlugin {
2393
2399
  this.locusId = this.locusUrl?.split('/').pop();
2394
2400
  this.recordingController.setLocusUrl(this.locusUrl);
2395
2401
  this.controlsOptionsManager.setLocusUrl(this.locusUrl);
2402
+
2403
+ Trigger.trigger(
2404
+ this,
2405
+ {
2406
+ file: 'meeting/index',
2407
+ function: 'setUpLocusSelfListener',
2408
+ },
2409
+ EVENT_TRIGGERS.MEETING_LOCUS_URL_UPDATE,
2410
+ {locusUrl: payload}
2411
+ );
2396
2412
  });
2397
2413
  }
2398
2414
 
@@ -2452,230 +2468,12 @@ export default class Meeting extends StatelessWebexPlugin {
2452
2468
  );
2453
2469
  }
2454
2470
  });
2455
- this.locusInfo.on(LOCUSINFO.EVENTS.MEETING_INFO_UPDATED, (payload) => {
2456
- if (payload && payload.info) {
2457
- const changed = this.inMeetingActions.set({
2458
- canInviteNewParticipants: MeetingUtil.canInviteNewParticipants(
2459
- payload.info.userDisplayHints
2460
- ),
2461
- canAdmitParticipant: MeetingUtil.canAdmitParticipant(payload.info.userDisplayHints),
2462
- canLock: MeetingUtil.canUserLock(payload.info.userDisplayHints),
2463
- canUnlock: MeetingUtil.canUserUnlock(payload.info.userDisplayHints),
2464
- canSetDisallowUnmute: ControlsOptionsUtil.canSetDisallowUnmute(
2465
- payload.info.userDisplayHints
2466
- ),
2467
- canUnsetDisallowUnmute: ControlsOptionsUtil.canUnsetDisallowUnmute(
2468
- payload.info.userDisplayHints
2469
- ),
2470
- canSetMuteOnEntry: ControlsOptionsUtil.canSetMuteOnEntry(payload.info.userDisplayHints),
2471
- canUnsetMuteOnEntry: ControlsOptionsUtil.canUnsetMuteOnEntry(
2472
- payload.info.userDisplayHints
2473
- ),
2474
- canSetMuted: ControlsOptionsUtil.canSetMuted(payload.info.userDisplayHints),
2475
- canUnsetMuted: ControlsOptionsUtil.canUnsetMuted(payload.info.userDisplayHints),
2476
- canStartRecording: RecordingUtil.canUserStart(
2477
- payload.info.userDisplayHints,
2478
- this.selfUserPolicies
2479
- ),
2480
- canStopRecording: RecordingUtil.canUserStop(
2481
- payload.info.userDisplayHints,
2482
- this.selfUserPolicies
2483
- ),
2484
- canPauseRecording: RecordingUtil.canUserPause(
2485
- payload.info.userDisplayHints,
2486
- this.selfUserPolicies
2487
- ),
2488
- canResumeRecording: RecordingUtil.canUserResume(
2489
- payload.info.userDisplayHints,
2490
- this.selfUserPolicies
2491
- ),
2492
- canRaiseHand: MeetingUtil.canUserRaiseHand(payload.info.userDisplayHints),
2493
- canLowerAllHands: MeetingUtil.canUserLowerAllHands(payload.info.userDisplayHints),
2494
- canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(
2495
- payload.info.userDisplayHints
2496
- ),
2497
- bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(
2498
- payload.info.userDisplayHints
2499
- ),
2500
- canEnableClosedCaption: MeetingUtil.canEnableClosedCaption(payload.info.userDisplayHints),
2501
- canStartTranscribing: MeetingUtil.canStartTranscribing(payload.info.userDisplayHints),
2502
- canStopTranscribing: MeetingUtil.canStopTranscribing(payload.info.userDisplayHints),
2503
- isClosedCaptionActive: MeetingUtil.isClosedCaptionActive(payload.info.userDisplayHints),
2504
- isSaveTranscriptsEnabled: MeetingUtil.isSaveTranscriptsEnabled(
2505
- payload.info.userDisplayHints
2506
- ),
2507
- isWebexAssistantActive: MeetingUtil.isWebexAssistantActive(payload.info.userDisplayHints),
2508
- canViewCaptionPanel: MeetingUtil.canViewCaptionPanel(payload.info.userDisplayHints),
2509
- isRealTimeTranslationEnabled: MeetingUtil.isRealTimeTranslationEnabled(
2510
- payload.info.userDisplayHints
2511
- ),
2512
- canSelectSpokenLanguages: MeetingUtil.canSelectSpokenLanguages(
2513
- payload.info.userDisplayHints
2514
- ),
2515
- waitingForOthersToJoin: MeetingUtil.waitingForOthersToJoin(payload.info.userDisplayHints),
2516
- canSendReactions: MeetingUtil.canSendReactions(
2517
- this.inMeetingActions.canSendReactions,
2518
- payload.info.userDisplayHints
2519
- ),
2520
- canManageBreakout: MeetingUtil.canManageBreakout(payload.info.userDisplayHints),
2521
- canBroadcastMessageToBreakout: MeetingUtil.canBroadcastMessageToBreakout(
2522
- payload.info.userDisplayHints,
2523
- this.selfUserPolicies
2524
- ),
2525
- canAdmitLobbyToBreakout: MeetingUtil.canAdmitLobbyToBreakout(
2526
- payload.info.userDisplayHints
2527
- ),
2528
- isBreakoutPreassignmentsEnabled: MeetingUtil.isBreakoutPreassignmentsEnabled(
2529
- payload.info.userDisplayHints
2530
- ),
2531
- canUserAskForHelp: MeetingUtil.canUserAskForHelp(payload.info.userDisplayHints),
2532
- canUserRenameSelfAndObserved: MeetingUtil.canUserRenameSelfAndObserved(
2533
- payload.info.userDisplayHints
2534
- ),
2535
- canUserRenameOthers: MeetingUtil.canUserRenameOthers(payload.info.userDisplayHints),
2536
- canMuteAll: ControlsOptionsUtil.hasHints({
2537
- requiredHints: [DISPLAY_HINTS.MUTE_ALL],
2538
- displayHints: payload.info.userDisplayHints,
2539
- }),
2540
- canUnmuteAll: ControlsOptionsUtil.hasHints({
2541
- requiredHints: [DISPLAY_HINTS.UNMUTE_ALL],
2542
- displayHints: payload.info.userDisplayHints,
2543
- }),
2544
- canEnableHardMute: ControlsOptionsUtil.hasHints({
2545
- requiredHints: [DISPLAY_HINTS.ENABLE_HARD_MUTE],
2546
- displayHints: payload.info.userDisplayHints,
2547
- }),
2548
- canDisableHardMute: ControlsOptionsUtil.hasHints({
2549
- requiredHints: [DISPLAY_HINTS.DISABLE_HARD_MUTE],
2550
- displayHints: payload.info.userDisplayHints,
2551
- }),
2552
- canEnableMuteOnEntry: ControlsOptionsUtil.hasHints({
2553
- requiredHints: [DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY],
2554
- displayHints: payload.info.userDisplayHints,
2555
- }),
2556
- canDisableMuteOnEntry: ControlsOptionsUtil.hasHints({
2557
- requiredHints: [DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY],
2558
- displayHints: payload.info.userDisplayHints,
2559
- }),
2560
- canEnableReactions: ControlsOptionsUtil.hasHints({
2561
- requiredHints: [DISPLAY_HINTS.ENABLE_REACTIONS],
2562
- displayHints: payload.info.userDisplayHints,
2563
- }),
2564
- canDisableReactions: ControlsOptionsUtil.hasHints({
2565
- requiredHints: [DISPLAY_HINTS.DISABLE_REACTIONS],
2566
- displayHints: payload.info.userDisplayHints,
2567
- }),
2568
- canEnableReactionDisplayNames: ControlsOptionsUtil.hasHints({
2569
- requiredHints: [DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME],
2570
- displayHints: payload.info.userDisplayHints,
2571
- }),
2572
- canDisableReactionDisplayNames: ControlsOptionsUtil.hasHints({
2573
- requiredHints: [DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME],
2574
- displayHints: payload.info.userDisplayHints,
2575
- }),
2576
- canUpdateShareControl: ControlsOptionsUtil.hasHints({
2577
- requiredHints: [DISPLAY_HINTS.SHARE_CONTROL],
2578
- displayHints: payload.info.userDisplayHints,
2579
- }),
2580
- canEnableViewTheParticipantsList: ControlsOptionsUtil.hasHints({
2581
- requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST],
2582
- displayHints: payload.info.userDisplayHints,
2583
- }),
2584
- canDisableViewTheParticipantsList: ControlsOptionsUtil.hasHints({
2585
- requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST],
2586
- displayHints: payload.info.userDisplayHints,
2587
- }),
2588
- canEnableRaiseHand: ControlsOptionsUtil.hasHints({
2589
- requiredHints: [DISPLAY_HINTS.ENABLE_RAISE_HAND],
2590
- displayHints: payload.info.userDisplayHints,
2591
- }),
2592
- canDisableRaiseHand: ControlsOptionsUtil.hasHints({
2593
- requiredHints: [DISPLAY_HINTS.DISABLE_RAISE_HAND],
2594
- displayHints: payload.info.userDisplayHints,
2595
- }),
2596
- canEnableVideo: ControlsOptionsUtil.hasHints({
2597
- requiredHints: [DISPLAY_HINTS.ENABLE_VIDEO],
2598
- displayHints: payload.info.userDisplayHints,
2599
- }),
2600
- canDisableVideo: ControlsOptionsUtil.hasHints({
2601
- requiredHints: [DISPLAY_HINTS.DISABLE_VIDEO],
2602
- displayHints: payload.info.userDisplayHints,
2603
- }),
2604
- canShareFile:
2605
- ControlsOptionsUtil.hasHints({
2606
- requiredHints: [DISPLAY_HINTS.SHARE_FILE],
2607
- displayHints: payload.info.userDisplayHints,
2608
- }) &&
2609
- ControlsOptionsUtil.hasPolicies({
2610
- requiredPolicies: [SELF_POLICY.SUPPORT_FILE_SHARE],
2611
- policies: this.selfUserPolicies,
2612
- }),
2613
- canTransferFile: ControlsOptionsUtil.hasPolicies({
2614
- requiredPolicies: [SELF_POLICY.SUPPORT_FILE_TRANSFER],
2615
- policies: this.selfUserPolicies,
2616
- }),
2617
- canShareApplication:
2618
- (ControlsOptionsUtil.hasHints({
2619
- requiredHints: [DISPLAY_HINTS.SHARE_APPLICATION],
2620
- displayHints: payload.info.userDisplayHints,
2621
- }) &&
2622
- (ControlsOptionsUtil.hasPolicies({
2623
- requiredPolicies: [SELF_POLICY.SUPPORT_APP_SHARE],
2624
- policies: this.selfUserPolicies,
2625
- }) ||
2626
- // @ts-ignore
2627
- !this.config.experimental.enableUnifiedMeetings)) ||
2628
- this.isLocusCall(),
2629
- canShareCamera:
2630
- ControlsOptionsUtil.hasHints({
2631
- requiredHints: [DISPLAY_HINTS.SHARE_CAMERA],
2632
- displayHints: payload.info.userDisplayHints,
2633
- }) &&
2634
- ControlsOptionsUtil.hasPolicies({
2635
- requiredPolicies: [SELF_POLICY.SUPPORT_CAMERA_SHARE],
2636
- policies: this.selfUserPolicies,
2637
- }),
2638
- canShareDesktop:
2639
- (ControlsOptionsUtil.hasHints({
2640
- requiredHints: [DISPLAY_HINTS.SHARE_DESKTOP],
2641
- displayHints: payload.info.userDisplayHints,
2642
- }) &&
2643
- (ControlsOptionsUtil.hasPolicies({
2644
- requiredPolicies: [SELF_POLICY.SUPPORT_DESKTOP_SHARE],
2645
- policies: this.selfUserPolicies,
2646
- }) ||
2647
- // @ts-ignore
2648
- !this.config.experimental.enableUnifiedMeetings)) ||
2649
- this.isLocusCall(),
2650
- canShareContent:
2651
- ControlsOptionsUtil.hasHints({
2652
- requiredHints: [DISPLAY_HINTS.SHARE_CONTENT],
2653
- displayHints: payload.info.userDisplayHints,
2654
- }) || this.isLocusCall(),
2655
- canAnnotate: ControlsOptionsUtil.hasPolicies({
2656
- requiredPolicies: [SELF_POLICY.SUPPORT_ANNOTATION],
2657
- policies: this.selfUserPolicies,
2658
- }),
2659
- });
2660
-
2661
- this.recordingController.setDisplayHints(payload.info.userDisplayHints);
2662
- this.recordingController.setUserPolicy(this.selfUserPolicies);
2663
- this.controlsOptionsManager.setDisplayHints(payload.info.userDisplayHints);
2664
-
2665
- if (changed) {
2666
- Trigger.trigger(
2667
- this,
2668
- {
2669
- file: 'meeting/index',
2670
- function: 'setUpLocusInfoMeetingInfoListener',
2671
- },
2672
- EVENT_TRIGGERS.MEETING_ACTIONS_UPDATE,
2673
- this.inMeetingActions.get()
2674
- );
2675
- }
2676
-
2677
- this.handleDataChannelUrlChange(payload.info.datachannelUrl);
2678
- }
2471
+ this.locusInfo.on(LOCUSINFO.EVENTS.MEETING_INFO_UPDATED, () => {
2472
+ this.updateMeetingActions();
2473
+ this.recordingController.setDisplayHints(this.userDisplayHints);
2474
+ this.recordingController.setUserPolicy(this.selfUserPolicies);
2475
+ this.controlsOptionsManager.setDisplayHints(this.userDisplayHints);
2476
+ this.handleDataChannelUrlChange(this.datachannelUrl);
2679
2477
  });
2680
2478
  }
2681
2479
 
@@ -2684,15 +2482,10 @@ export default class Meeting extends StatelessWebexPlugin {
2684
2482
  * @param {String} datachannelUrl
2685
2483
  * @returns {void}
2686
2484
  */
2687
-
2688
2485
  handleDataChannelUrlChange(datachannelUrl) {
2689
2486
  // @ts-ignore - config coming from registerPlugin
2690
2487
  if (datachannelUrl && this.config.enableAutomaticLLM) {
2691
- // Defer this as updateLLMConnection relies upon this.locusInfo.url which is only set
2692
- // after the MEETING_INFO_UPDATED callback finishes
2693
- defer(() => {
2694
- this.updateLLMConnection();
2695
- });
2488
+ this.updateLLMConnection();
2696
2489
  }
2697
2490
  }
2698
2491
 
@@ -3234,6 +3027,250 @@ export default class Meeting extends StatelessWebexPlugin {
3234
3027
  MeetingUtil.parseInterpretationInfo(this, webexMeetingInfo);
3235
3028
  }
3236
3029
 
3030
+ /**
3031
+ * Indicates whether policy can be applied
3032
+ * @returns {boolean}
3033
+ */
3034
+ private arePolicyRestrictionsSupported() {
3035
+ // Locus calls do not return the correct display hints
3036
+ if (this.isLocusCall()) {
3037
+ return false;
3038
+ }
3039
+
3040
+ // 1-2-1 calls and SIP dialling will have no meeting info
3041
+ // so cannot support policy information
3042
+ if (isEmpty(this.meetingInfo)) {
3043
+ return false;
3044
+ }
3045
+
3046
+ // Old locus info api does not return policy information
3047
+ // @ts-ignore
3048
+ if (!this.config.experimental.enableUnifiedMeetings) {
3049
+ return false;
3050
+ }
3051
+
3052
+ return true;
3053
+ }
3054
+
3055
+ /**
3056
+ * Updates the meeting actions (display hints), depends on locus display hints, user policy and app api info
3057
+ * @returns {undefined}
3058
+ * @private
3059
+ * @memberof Meeting
3060
+ */
3061
+ private updateMeetingActions() {
3062
+ let changed = false;
3063
+ changed = this.inMeetingActions.set({
3064
+ canUseVoip:
3065
+ ((this.userDisplayHints !== undefined
3066
+ ? ControlsOptionsUtil.hasHints({
3067
+ requiredHints: [DISPLAY_HINTS.VOIP_IS_ENABLED],
3068
+ displayHints: this.userDisplayHints,
3069
+ })
3070
+ : this.meetingInfo?.supportVoIP === true) &&
3071
+ ControlsOptionsUtil.hasPolicies({
3072
+ requiredPolicies: [SELF_POLICY.SUPPORT_VOIP],
3073
+ policies: this.selfUserPolicies,
3074
+ })) ||
3075
+ !this.arePolicyRestrictionsSupported(),
3076
+ });
3077
+ if (this.userDisplayHints !== undefined) {
3078
+ changed =
3079
+ this.inMeetingActions.set({
3080
+ canInviteNewParticipants: MeetingUtil.canInviteNewParticipants(this.userDisplayHints),
3081
+ canAdmitParticipant: MeetingUtil.canAdmitParticipant(this.userDisplayHints),
3082
+ canLock: MeetingUtil.canUserLock(this.userDisplayHints),
3083
+ canUnlock: MeetingUtil.canUserUnlock(this.userDisplayHints),
3084
+ canSetDisallowUnmute: ControlsOptionsUtil.canSetDisallowUnmute(this.userDisplayHints),
3085
+ canUnsetDisallowUnmute: ControlsOptionsUtil.canUnsetDisallowUnmute(this.userDisplayHints),
3086
+ canSetMuteOnEntry: ControlsOptionsUtil.canSetMuteOnEntry(this.userDisplayHints),
3087
+ canUnsetMuteOnEntry: ControlsOptionsUtil.canUnsetMuteOnEntry(this.userDisplayHints),
3088
+ canSetMuted: ControlsOptionsUtil.canSetMuted(this.userDisplayHints),
3089
+ canUnsetMuted: ControlsOptionsUtil.canUnsetMuted(this.userDisplayHints),
3090
+ canStartRecording: RecordingUtil.canUserStart(
3091
+ this.userDisplayHints,
3092
+ this.selfUserPolicies
3093
+ ),
3094
+ canStopRecording: RecordingUtil.canUserStop(this.userDisplayHints, this.selfUserPolicies),
3095
+ canPauseRecording: RecordingUtil.canUserPause(
3096
+ this.userDisplayHints,
3097
+ this.selfUserPolicies
3098
+ ),
3099
+ canResumeRecording: RecordingUtil.canUserResume(
3100
+ this.userDisplayHints,
3101
+ this.selfUserPolicies
3102
+ ),
3103
+ canRaiseHand: MeetingUtil.canUserRaiseHand(this.userDisplayHints),
3104
+ canLowerAllHands: MeetingUtil.canUserLowerAllHands(this.userDisplayHints),
3105
+ canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(this.userDisplayHints),
3106
+ bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(
3107
+ this.userDisplayHints
3108
+ ),
3109
+ canEnableClosedCaption: MeetingUtil.canEnableClosedCaption(this.userDisplayHints),
3110
+ canStartTranscribing: MeetingUtil.canStartTranscribing(this.userDisplayHints),
3111
+ canStopTranscribing: MeetingUtil.canStopTranscribing(this.userDisplayHints),
3112
+ isClosedCaptionActive: MeetingUtil.isClosedCaptionActive(this.userDisplayHints),
3113
+ isSaveTranscriptsEnabled: MeetingUtil.isSaveTranscriptsEnabled(this.userDisplayHints),
3114
+ isWebexAssistantActive: MeetingUtil.isWebexAssistantActive(this.userDisplayHints),
3115
+ canViewCaptionPanel: MeetingUtil.canViewCaptionPanel(this.userDisplayHints),
3116
+ isRealTimeTranslationEnabled: MeetingUtil.isRealTimeTranslationEnabled(
3117
+ this.userDisplayHints
3118
+ ),
3119
+ canSelectSpokenLanguages: MeetingUtil.canSelectSpokenLanguages(this.userDisplayHints),
3120
+ waitingForOthersToJoin: MeetingUtil.waitingForOthersToJoin(this.userDisplayHints),
3121
+ canSendReactions: MeetingUtil.canSendReactions(
3122
+ this.inMeetingActions.canSendReactions,
3123
+ this.userDisplayHints
3124
+ ),
3125
+ canManageBreakout: MeetingUtil.canManageBreakout(this.userDisplayHints),
3126
+ canBroadcastMessageToBreakout: MeetingUtil.canBroadcastMessageToBreakout(
3127
+ this.userDisplayHints,
3128
+ this.selfUserPolicies
3129
+ ),
3130
+ canAdmitLobbyToBreakout: MeetingUtil.canAdmitLobbyToBreakout(this.userDisplayHints),
3131
+ isBreakoutPreassignmentsEnabled: MeetingUtil.isBreakoutPreassignmentsEnabled(
3132
+ this.userDisplayHints
3133
+ ),
3134
+ canUserAskForHelp: MeetingUtil.canUserAskForHelp(this.userDisplayHints),
3135
+ canUserRenameSelfAndObserved: MeetingUtil.canUserRenameSelfAndObserved(
3136
+ this.userDisplayHints
3137
+ ),
3138
+ canUserRenameOthers: MeetingUtil.canUserRenameOthers(this.userDisplayHints),
3139
+ canMuteAll: ControlsOptionsUtil.hasHints({
3140
+ requiredHints: [DISPLAY_HINTS.MUTE_ALL],
3141
+ displayHints: this.userDisplayHints,
3142
+ }),
3143
+ canUnmuteAll: ControlsOptionsUtil.hasHints({
3144
+ requiredHints: [DISPLAY_HINTS.UNMUTE_ALL],
3145
+ displayHints: this.userDisplayHints,
3146
+ }),
3147
+ canEnableHardMute: ControlsOptionsUtil.hasHints({
3148
+ requiredHints: [DISPLAY_HINTS.ENABLE_HARD_MUTE],
3149
+ displayHints: this.userDisplayHints,
3150
+ }),
3151
+ canDisableHardMute: ControlsOptionsUtil.hasHints({
3152
+ requiredHints: [DISPLAY_HINTS.DISABLE_HARD_MUTE],
3153
+ displayHints: this.userDisplayHints,
3154
+ }),
3155
+ canEnableMuteOnEntry: ControlsOptionsUtil.hasHints({
3156
+ requiredHints: [DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY],
3157
+ displayHints: this.userDisplayHints,
3158
+ }),
3159
+ canDisableMuteOnEntry: ControlsOptionsUtil.hasHints({
3160
+ requiredHints: [DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY],
3161
+ displayHints: this.userDisplayHints,
3162
+ }),
3163
+ canEnableReactions: ControlsOptionsUtil.hasHints({
3164
+ requiredHints: [DISPLAY_HINTS.ENABLE_REACTIONS],
3165
+ displayHints: this.userDisplayHints,
3166
+ }),
3167
+ canDisableReactions: ControlsOptionsUtil.hasHints({
3168
+ requiredHints: [DISPLAY_HINTS.DISABLE_REACTIONS],
3169
+ displayHints: this.userDisplayHints,
3170
+ }),
3171
+ canEnableReactionDisplayNames: ControlsOptionsUtil.hasHints({
3172
+ requiredHints: [DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME],
3173
+ displayHints: this.userDisplayHints,
3174
+ }),
3175
+ canDisableReactionDisplayNames: ControlsOptionsUtil.hasHints({
3176
+ requiredHints: [DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME],
3177
+ displayHints: this.userDisplayHints,
3178
+ }),
3179
+ canUpdateShareControl: ControlsOptionsUtil.hasHints({
3180
+ requiredHints: [DISPLAY_HINTS.SHARE_CONTROL],
3181
+ displayHints: this.userDisplayHints,
3182
+ }),
3183
+ canEnableViewTheParticipantsList: ControlsOptionsUtil.hasHints({
3184
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST],
3185
+ displayHints: this.userDisplayHints,
3186
+ }),
3187
+ canDisableViewTheParticipantsList: ControlsOptionsUtil.hasHints({
3188
+ requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST],
3189
+ displayHints: this.userDisplayHints,
3190
+ }),
3191
+ canEnableRaiseHand: ControlsOptionsUtil.hasHints({
3192
+ requiredHints: [DISPLAY_HINTS.ENABLE_RAISE_HAND],
3193
+ displayHints: this.userDisplayHints,
3194
+ }),
3195
+ canDisableRaiseHand: ControlsOptionsUtil.hasHints({
3196
+ requiredHints: [DISPLAY_HINTS.DISABLE_RAISE_HAND],
3197
+ displayHints: this.userDisplayHints,
3198
+ }),
3199
+ canEnableVideo: ControlsOptionsUtil.hasHints({
3200
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIDEO],
3201
+ displayHints: this.userDisplayHints,
3202
+ }),
3203
+ canDisableVideo: ControlsOptionsUtil.hasHints({
3204
+ requiredHints: [DISPLAY_HINTS.DISABLE_VIDEO],
3205
+ displayHints: this.userDisplayHints,
3206
+ }),
3207
+ canShareFile:
3208
+ (ControlsOptionsUtil.hasHints({
3209
+ requiredHints: [DISPLAY_HINTS.SHARE_FILE],
3210
+ displayHints: this.userDisplayHints,
3211
+ }) &&
3212
+ ControlsOptionsUtil.hasPolicies({
3213
+ requiredPolicies: [SELF_POLICY.SUPPORT_FILE_SHARE],
3214
+ policies: this.selfUserPolicies,
3215
+ })) ||
3216
+ !this.arePolicyRestrictionsSupported,
3217
+ canTransferFile: ControlsOptionsUtil.hasPolicies({
3218
+ requiredPolicies: [SELF_POLICY.SUPPORT_FILE_TRANSFER],
3219
+ policies: this.selfUserPolicies,
3220
+ }),
3221
+ canShareApplication:
3222
+ (ControlsOptionsUtil.hasHints({
3223
+ requiredHints: [DISPLAY_HINTS.SHARE_APPLICATION],
3224
+ displayHints: this.userDisplayHints,
3225
+ }) &&
3226
+ ControlsOptionsUtil.hasPolicies({
3227
+ requiredPolicies: [SELF_POLICY.SUPPORT_APP_SHARE],
3228
+ policies: this.selfUserPolicies,
3229
+ })) ||
3230
+ !this.arePolicyRestrictionsSupported(),
3231
+ canShareCamera:
3232
+ ControlsOptionsUtil.hasHints({
3233
+ requiredHints: [DISPLAY_HINTS.SHARE_CAMERA],
3234
+ displayHints: this.userDisplayHints,
3235
+ }) &&
3236
+ ControlsOptionsUtil.hasPolicies({
3237
+ requiredPolicies: [SELF_POLICY.SUPPORT_CAMERA_SHARE],
3238
+ policies: this.selfUserPolicies,
3239
+ }),
3240
+ canShareDesktop:
3241
+ (ControlsOptionsUtil.hasHints({
3242
+ requiredHints: [DISPLAY_HINTS.SHARE_DESKTOP],
3243
+ displayHints: this.userDisplayHints,
3244
+ }) &&
3245
+ ControlsOptionsUtil.hasPolicies({
3246
+ requiredPolicies: [SELF_POLICY.SUPPORT_DESKTOP_SHARE],
3247
+ policies: this.selfUserPolicies,
3248
+ })) ||
3249
+ !this.arePolicyRestrictionsSupported(),
3250
+ canShareContent:
3251
+ ControlsOptionsUtil.hasHints({
3252
+ requiredHints: [DISPLAY_HINTS.SHARE_CONTENT],
3253
+ displayHints: this.userDisplayHints,
3254
+ }) || !this.arePolicyRestrictionsSupported(),
3255
+ canAnnotate: ControlsOptionsUtil.hasPolicies({
3256
+ requiredPolicies: [SELF_POLICY.SUPPORT_ANNOTATION],
3257
+ policies: this.selfUserPolicies,
3258
+ }),
3259
+ }) || changed;
3260
+ }
3261
+ if (changed) {
3262
+ Trigger.trigger(
3263
+ this,
3264
+ {
3265
+ file: 'meeting/index',
3266
+ function: 'updateMeetingActions',
3267
+ },
3268
+ EVENT_TRIGGERS.MEETING_ACTIONS_UPDATE,
3269
+ this.inMeetingActions.get()
3270
+ );
3271
+ }
3272
+ }
3273
+
3237
3274
  /**
3238
3275
  * Sets the self user policies based on the contents of the permission token
3239
3276
  * @param {String} permissionToken
@@ -89,7 +89,6 @@ export default class RecordingController {
89
89
 
90
90
  /**
91
91
  * @param {MeetingRequest} request
92
- * @param {LocusInfo} info
93
92
  * @returns {void}
94
93
  * @private
95
94
  * @memberof RecordingController
@@ -1378,7 +1378,6 @@ describe('plugin-meetings', () => {
1378
1378
  function: 'updateMeetingInfo',
1379
1379
  },
1380
1380
  LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
1381
- {info: locusInfo.parsedLocus.info, self},
1382
1381
  ];
1383
1382
 
1384
1383
  if (expected) {
@@ -1407,15 +1406,40 @@ describe('plugin-meetings', () => {
1407
1406
  locusInfo.emitScoped.resetHistory();
1408
1407
  };
1409
1408
 
1410
- it('emits MEETING_INFO_UPDATED if the info changes', () => {
1409
+ it('emits MEETING_INFO_UPDATED and updates the meeting if the info changes', () => {
1411
1410
  const initialInfo = cloneDeep(meetingInfo);
1412
1411
 
1413
- locusInfo.emitScoped = sinon.stub();
1412
+ let expectedMeeting;
1413
+
1414
+ /*
1415
+ When the event is triggered, it is required that the meeting has already
1416
+ been updated. This is why the meeting is being checked within the stubbed event emitter
1417
+ */
1418
+ sinon.stub(locusInfo, 'emitScoped').callsFake(() => {
1419
+ assert.deepEqual(mockMeeting, expectedMeeting);
1420
+ })
1421
+
1414
1422
 
1415
1423
  // set the info initially as locusInfo.info starts as undefined
1424
+ expectedMeeting = {
1425
+ coHost: {
1426
+ LOWER_SOMEONE_ELSES_HAND: true,
1427
+ },
1428
+ isLocked: false,
1429
+ isUnlocked: true,
1430
+ moderator: {
1431
+ LOWER_SOMEONE_ELSES_HAND: true,
1432
+ },
1433
+ policy: {
1434
+ LOCK_STATUS_UNLOCKED: true,
1435
+ ROSTER_IN_MEETING: true,
1436
+ },
1437
+ userDisplayHints: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
1438
+ };
1416
1439
  locusInfo.updateMeetingInfo(initialInfo, self);
1417
1440
 
1418
1441
  // since it was initially undefined, this should trigger the event
1442
+
1419
1443
  checkMeetingInfoUpdatedCalled(true);
1420
1444
 
1421
1445
  const newInfo = cloneDeep(meetingInfo);
@@ -1423,11 +1447,43 @@ describe('plugin-meetings', () => {
1423
1447
  newInfo.displayHints.coHost = [DISPLAY_HINTS.LOCK_CONTROL_LOCK];
1424
1448
 
1425
1449
  // Updating with different info should trigger the event
1450
+ expectedMeeting = {
1451
+ coHost: {
1452
+ LOWER_SOMEONE_ELSES_HAND: true,
1453
+ LOCK_CONTROL_LOCK: true,
1454
+ },
1455
+ isLocked: false,
1456
+ isUnlocked: true,
1457
+ moderator: {
1458
+ LOWER_SOMEONE_ELSES_HAND: true,
1459
+ },
1460
+ policy: {
1461
+ LOCK_STATUS_UNLOCKED: true,
1462
+ ROSTER_IN_MEETING: true,
1463
+ },
1464
+ userDisplayHints: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
1465
+ };
1426
1466
  locusInfo.updateMeetingInfo(newInfo, self);
1427
1467
 
1428
1468
  checkMeetingInfoUpdatedCalled(true);
1429
1469
 
1430
1470
  // update it with the same info
1471
+ expectedMeeting = {
1472
+ coHost: {
1473
+ LOWER_SOMEONE_ELSES_HAND: true,
1474
+ LOCK_CONTROL_LOCK: true,
1475
+ },
1476
+ isLocked: false,
1477
+ isUnlocked: true,
1478
+ moderator: {
1479
+ LOWER_SOMEONE_ELSES_HAND: true,
1480
+ },
1481
+ policy: {
1482
+ LOCK_STATUS_UNLOCKED: true,
1483
+ ROSTER_IN_MEETING: true,
1484
+ },
1485
+ userDisplayHints: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
1486
+ };
1431
1487
  locusInfo.updateMeetingInfo(newInfo, self);
1432
1488
 
1433
1489
  // since the info is the same it should not call trigger the event
@@ -1439,6 +1495,27 @@ describe('plugin-meetings', () => {
1439
1495
  type: 'COHOST',
1440
1496
  hasRole: true,
1441
1497
  });
1498
+ expectedMeeting = {
1499
+ coHost: {
1500
+ LOWER_SOMEONE_ELSES_HAND: true,
1501
+ LOCK_CONTROL_LOCK: true,
1502
+ },
1503
+ isLocked: false,
1504
+ isUnlocked: true,
1505
+ moderator: {
1506
+ LOWER_SOMEONE_ELSES_HAND: true,
1507
+ },
1508
+ policy: {
1509
+ LOCK_STATUS_UNLOCKED: true,
1510
+ ROSTER_IN_MEETING: true,
1511
+ },
1512
+ userDisplayHints: [
1513
+ 'ROSTER_IN_MEETING',
1514
+ 'LOCK_STATUS_UNLOCKED',
1515
+ 'LOCK_CONTROL_LOCK',
1516
+ 'LOWER_SOMEONE_ELSES_HAND',
1517
+ ],
1518
+ };
1442
1519
  locusInfo.updateMeetingInfo(newInfo, updateSelf);
1443
1520
  // since the info is the same but roles changed, it should call trigger the event
1444
1521
  checkMeetingInfoUpdatedCalledForRoles(true);