@webex/plugin-meetings 3.8.0-web-workers-keepalive.1 → 3.8.1-next.1

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 (168) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +70 -6
  3. package/dist/breakouts/index.js.map +1 -1
  4. package/dist/common/errors/webex-errors.js +12 -2
  5. package/dist/common/errors/webex-errors.js.map +1 -1
  6. package/dist/config.js +4 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.js +22 -123
  9. package/dist/constants.js.map +1 -1
  10. package/dist/controls-options-manager/enums.js +2 -0
  11. package/dist/controls-options-manager/enums.js.map +1 -1
  12. package/dist/controls-options-manager/types.js.map +1 -1
  13. package/dist/controls-options-manager/util.js +52 -0
  14. package/dist/controls-options-manager/util.js.map +1 -1
  15. package/dist/interpretation/index.js +1 -1
  16. package/dist/interpretation/siLanguage.js +1 -1
  17. package/dist/locus-info/controlsUtils.js +30 -10
  18. package/dist/locus-info/controlsUtils.js.map +1 -1
  19. package/dist/locus-info/index.js +83 -12
  20. package/dist/locus-info/index.js.map +1 -1
  21. package/dist/locus-info/selfUtils.js +432 -418
  22. package/dist/locus-info/selfUtils.js.map +1 -1
  23. package/dist/media/index.js +17 -17
  24. package/dist/media/index.js.map +1 -1
  25. package/dist/media/properties.js +94 -6
  26. package/dist/media/properties.js.map +1 -1
  27. package/dist/meeting/brbState.js +9 -2
  28. package/dist/meeting/brbState.js.map +1 -1
  29. package/dist/meeting/in-meeting-actions.js +17 -1
  30. package/dist/meeting/in-meeting-actions.js.map +1 -1
  31. package/dist/meeting/index.js +568 -328
  32. package/dist/meeting/index.js.map +1 -1
  33. package/dist/meeting/locusMediaRequest.js +0 -17
  34. package/dist/meeting/locusMediaRequest.js.map +1 -1
  35. package/dist/meeting/muteState.js +4 -4
  36. package/dist/meeting/muteState.js.map +1 -1
  37. package/dist/meeting/request.js +30 -0
  38. package/dist/meeting/request.js.map +1 -1
  39. package/dist/meeting/request.type.js.map +1 -1
  40. package/dist/meeting/util.js +9 -1
  41. package/dist/meeting/util.js.map +1 -1
  42. package/dist/meeting-info/meeting-info-v2.js +19 -13
  43. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  44. package/dist/meeting-info/utilv2.js +5 -1
  45. package/dist/meeting-info/utilv2.js.map +1 -1
  46. package/dist/meetings/index.js +76 -0
  47. package/dist/meetings/index.js.map +1 -1
  48. package/dist/meetings/util.js +14 -0
  49. package/dist/meetings/util.js.map +1 -1
  50. package/dist/member/index.js +45 -9
  51. package/dist/member/index.js.map +1 -1
  52. package/dist/member/types.js +3 -0
  53. package/dist/member/types.js.map +1 -1
  54. package/dist/member/util.js +335 -356
  55. package/dist/member/util.js.map +1 -1
  56. package/dist/members/collection.js.map +1 -1
  57. package/dist/members/index.js +137 -29
  58. package/dist/members/index.js.map +1 -1
  59. package/dist/members/request.js +38 -0
  60. package/dist/members/request.js.map +1 -1
  61. package/dist/members/util.js +36 -1
  62. package/dist/members/util.js.map +1 -1
  63. package/dist/metrics/constants.js +1 -0
  64. package/dist/metrics/constants.js.map +1 -1
  65. package/dist/reachability/clusterReachability.js +23 -31
  66. package/dist/reachability/clusterReachability.js.map +1 -1
  67. package/dist/reachability/index.js +42 -2
  68. package/dist/reachability/index.js.map +1 -1
  69. package/dist/reconnection-manager/index.js +2 -2
  70. package/dist/reconnection-manager/index.js.map +1 -1
  71. package/dist/roap/index.js.map +1 -1
  72. package/dist/roap/turnDiscovery.js +45 -27
  73. package/dist/roap/turnDiscovery.js.map +1 -1
  74. package/dist/roap/types.js +17 -0
  75. package/dist/roap/types.js.map +1 -0
  76. package/dist/types/common/errors/webex-errors.d.ts +7 -1
  77. package/dist/types/config.d.ts +2 -0
  78. package/dist/types/constants.d.ts +15 -85
  79. package/dist/types/controls-options-manager/enums.d.ts +3 -1
  80. package/dist/types/controls-options-manager/types.d.ts +7 -1
  81. package/dist/types/locus-info/index.d.ts +3 -3
  82. package/dist/types/locus-info/selfUtils.d.ts +216 -1
  83. package/dist/types/media/properties.d.ts +15 -0
  84. package/dist/types/meeting/in-meeting-actions.d.ts +16 -0
  85. package/dist/types/meeting/index.d.ts +35 -1
  86. package/dist/types/meeting/muteState.d.ts +0 -1
  87. package/dist/types/meeting/request.d.ts +12 -1
  88. package/dist/types/meeting/request.type.d.ts +6 -0
  89. package/dist/types/meeting/util.d.ts +3 -1
  90. package/dist/types/meeting-info/meeting-info-v2.d.ts +2 -1
  91. package/dist/types/meetings/index.d.ts +28 -0
  92. package/dist/types/member/index.d.ts +20 -6
  93. package/dist/types/member/types.d.ts +73 -14
  94. package/dist/types/member/util.d.ts +156 -1
  95. package/dist/types/members/collection.d.ts +6 -5
  96. package/dist/types/members/index.d.ts +32 -43
  97. package/dist/types/members/request.d.ts +26 -0
  98. package/dist/types/members/util.d.ts +27 -0
  99. package/dist/types/metrics/constants.d.ts +1 -0
  100. package/dist/types/reachability/clusterReachability.d.ts +2 -6
  101. package/dist/types/reachability/index.d.ts +8 -0
  102. package/dist/types/roap/index.d.ts +3 -2
  103. package/dist/types/roap/turnDiscovery.d.ts +5 -17
  104. package/dist/types/roap/types.d.ts +16 -0
  105. package/dist/webinar/index.js +1 -1
  106. package/package.json +24 -23
  107. package/src/breakouts/index.ts +69 -0
  108. package/src/common/errors/webex-errors.ts +8 -1
  109. package/src/config.ts +2 -0
  110. package/src/constants.ts +23 -90
  111. package/src/controls-options-manager/enums.ts +2 -0
  112. package/src/controls-options-manager/types.ts +11 -1
  113. package/src/controls-options-manager/util.ts +62 -0
  114. package/src/locus-info/controlsUtils.ts +48 -12
  115. package/src/locus-info/index.ts +88 -13
  116. package/src/locus-info/selfUtils.ts +496 -442
  117. package/src/media/index.ts +23 -21
  118. package/src/media/properties.ts +96 -0
  119. package/src/meeting/brbState.ts +11 -2
  120. package/src/meeting/in-meeting-actions.ts +32 -0
  121. package/src/meeting/index.ts +356 -87
  122. package/src/meeting/locusMediaRequest.ts +0 -18
  123. package/src/meeting/muteState.ts +4 -4
  124. package/src/meeting/request.ts +36 -1
  125. package/src/meeting/request.type.ts +7 -0
  126. package/src/meeting/util.ts +9 -1
  127. package/src/meeting-info/meeting-info-v2.ts +7 -2
  128. package/src/meeting-info/utilv2.ts +5 -0
  129. package/src/meetings/index.ts +76 -0
  130. package/src/meetings/util.ts +18 -0
  131. package/src/member/index.ts +57 -22
  132. package/src/member/types.ts +82 -16
  133. package/src/member/util.ts +357 -353
  134. package/src/members/collection.ts +4 -3
  135. package/src/members/index.ts +137 -18
  136. package/src/members/request.ts +44 -0
  137. package/src/members/util.ts +43 -1
  138. package/src/metrics/constants.ts +1 -0
  139. package/src/reachability/clusterReachability.ts +26 -25
  140. package/src/reachability/index.ts +55 -1
  141. package/src/reconnection-manager/index.ts +2 -2
  142. package/src/roap/index.ts +3 -7
  143. package/src/roap/turnDiscovery.ts +34 -39
  144. package/src/roap/types.ts +23 -0
  145. package/test/unit/spec/breakouts/index.ts +167 -95
  146. package/test/unit/spec/controls-options-manager/util.js +120 -0
  147. package/test/unit/spec/locus-info/controlsUtils.js +131 -9
  148. package/test/unit/spec/locus-info/index.js +195 -73
  149. package/test/unit/spec/locus-info/selfUtils.js +98 -24
  150. package/test/unit/spec/media/index.ts +150 -18
  151. package/test/unit/spec/media/properties.ts +130 -0
  152. package/test/unit/spec/meeting/brbState.ts +40 -2
  153. package/test/unit/spec/meeting/in-meeting-actions.ts +19 -4
  154. package/test/unit/spec/meeting/index.js +553 -36
  155. package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
  156. package/test/unit/spec/meeting/muteState.js +73 -2
  157. package/test/unit/spec/meeting/request.js +32 -1
  158. package/test/unit/spec/meeting/utils.js +79 -33
  159. package/test/unit/spec/meeting-info/meetinginfov2.js +41 -0
  160. package/test/unit/spec/meeting-info/utilv2.js +19 -0
  161. package/test/unit/spec/meetings/index.js +68 -1
  162. package/test/unit/spec/members/index.js +304 -78
  163. package/test/unit/spec/members/request.js +68 -22
  164. package/test/unit/spec/members/utils.js +75 -0
  165. package/test/unit/spec/reachability/clusterReachability.ts +41 -55
  166. package/test/unit/spec/reachability/index.ts +89 -0
  167. package/test/unit/spec/reconnection-manager/index.js +4 -4
  168. package/test/unit/spec/roap/turnDiscovery.ts +110 -28
@@ -17,513 +17,567 @@ import {
17
17
  } from '../constants';
18
18
  import ParameterError from '../common/errors/parameter';
19
19
 
20
- const SelfUtils: any = {};
21
20
  const PSTN_DEVICE_TYPE = 'PROVISIONAL';
22
21
 
23
- /**
24
- * parses the relevant values for self: muted, guest, moderator, mediaStatus, state, joinedWith, pstnDevices, creator, id
25
- * @param {Object} self
26
- * @param {String} deviceId
27
- * @returns {undefined}
28
- */
29
- SelfUtils.parse = (self: any, deviceId: string) => {
30
- if (self) {
31
- const joinedWith = self.devices.find((device) => deviceId === device.url);
32
- const pstnDevices = self.devices.filter((device) => PSTN_DEVICE_TYPE === device.deviceType);
22
+ const SelfUtils = {
23
+ /**
24
+ * parses the relevant values for self: muted, guest, moderator, mediaStatus, state, joinedWith, pstnDevices, creator, id
25
+ * @param {Object} self
26
+ * @param {String} deviceId
27
+ * @param {Array} participants
28
+ * @returns {undefined}
29
+ */
30
+ parse: (self: any, deviceId: string, participants: Array<any>) => {
31
+ if (self) {
32
+ const joinedWith = self.devices.find((device) => deviceId === device.url);
33
+ const pairedWith =
34
+ joinedWith?.intent?.type === _OBSERVE_ &&
35
+ participants?.find((participant) => participant.url === joinedWith?.intent?.associatedWith)
36
+ ?.devices[0];
37
+
38
+ const pstnDevices = self.devices.filter((device) => PSTN_DEVICE_TYPE === device.deviceType);
39
+
40
+ return {
41
+ remoteVideoMuted: SelfUtils.getRemoteVideoMuted(self),
42
+ remoteMuted: SelfUtils.getRemoteMuted(self),
43
+ unmuteAllowed: SelfUtils.getUnmuteAllowed(self),
44
+ localAudioUnmuteRequested: SelfUtils.getLocalAudioUnmuteRequested(self),
45
+ localAudioUnmuteRequestedTimeStamp: SelfUtils.getLocalAudioUnmuteRequestedTimeStamp(self),
46
+ localAudioUnmuteRequired: SelfUtils.getLocalAudioUnmuteRequired(self),
47
+ lastModified: SelfUtils.getLastModified(self),
48
+ modifiedBy: SelfUtils.getModifiedBy(self),
49
+ guest: self.guest,
50
+ moderator: self.moderator,
51
+ // cumulative media stats
52
+ mediaStatus: SelfUtils.getStatus(self.status),
53
+ // TODO: what should be the status if user has refreshed the page,
54
+ // check the joinedWith parameter and communicate to the user
55
+ state: self.state,
56
+ // TODO: give a proper name . With same device as login or different login`
57
+ // Some times we might have joined with both mobile and web
58
+ joinedWith,
59
+ pairedWith,
60
+ pstnDevices,
61
+ // current media stats is for the current device who has joined
62
+ currentMediaStatus: SelfUtils.getMediaStatus(joinedWith?.mediaSessions),
63
+ creator: self.isCreator, // check if its used,
64
+ selfId: self.id,
65
+ selfIdentity: SelfUtils.getSelfIdentity(self),
66
+ selfUrl: self.url,
67
+ removed: self.removed,
68
+ roles: SelfUtils.getRoles(self),
69
+ isUserUnadmitted: SelfUtils.isLocusUserUnadmitted(self?.state, joinedWith, pairedWith),
70
+ layout: SelfUtils.getLayout(self),
71
+ canNotViewTheParticipantList: SelfUtils.canNotViewTheParticipantList(self),
72
+ isSharingBlocked: SelfUtils.isSharingBlocked(self),
73
+ breakoutSessions: SelfUtils.getBreakoutSessions(self),
74
+ breakout: SelfUtils.getBreakout(self),
75
+ interpretation: SelfUtils.getInterpretation(self),
76
+ brb: SelfUtils.getBrb(self),
77
+ };
78
+ }
33
79
 
34
- return {
35
- remoteVideoMuted: SelfUtils.getRemoteVideoMuted(self),
36
- remoteMuted: SelfUtils.getRemoteMuted(self),
37
- unmuteAllowed: SelfUtils.getUnmuteAllowed(self),
38
- localAudioUnmuteRequested: SelfUtils.getLocalAudioUnmuteRequested(self),
39
- localAudioUnmuteRequestedTimeStamp: SelfUtils.getLocalAudioUnmuteRequestedTimeStamp(self),
40
- localAudioUnmuteRequired: SelfUtils.getLocalAudioUnmuteRequired(self),
41
- lastModified: SelfUtils.getLastModified(self),
42
- modifiedBy: SelfUtils.getModifiedBy(self),
43
- guest: self.guest,
44
- moderator: self.moderator,
45
- // cumulative media stats
46
- mediaStatus: SelfUtils.getStatus(self.status),
47
- // TODO: what should be the status if user has refreshed the page,
48
- // check the joinedWith parameter and communicate to the user
49
- state: self.state,
50
- // TODO: give a proper name . With same device as login or different login`
51
- // Some times we might have joined with both mobile and web
52
- joinedWith,
53
- pstnDevices,
54
- // current media stats is for the current device who has joined
55
- currentMediaStatus: SelfUtils.getMediaStatus(joinedWith?.mediaSessions),
56
- creator: self.isCreator, // check if its used,
57
- selfId: self.id,
58
- selfIdentity: SelfUtils.getSelfIdentity(self),
59
- selfUrl: self.url,
60
- removed: self.removed,
61
- roles: SelfUtils.getRoles(self),
62
- isUserUnadmitted: self.state === _IDLE_ && joinedWith?.intent?.type === _WAIT_,
63
- layout: SelfUtils.getLayout(self),
64
- canNotViewTheParticipantList: SelfUtils.canNotViewTheParticipantList(self),
65
- isSharingBlocked: SelfUtils.isSharingBlocked(self),
66
- breakoutSessions: SelfUtils.getBreakoutSessions(self),
67
- breakout: SelfUtils.getBreakout(self),
68
- interpretation: SelfUtils.getInterpretation(self),
69
- brb: SelfUtils.getBrb(self),
70
- };
71
- }
80
+ return null;
81
+ },
72
82
 
73
- return null;
74
- };
83
+ getBreakoutSessions: (self) => self?.controls?.breakout?.sessions,
84
+ getBreakout: (self) => self?.controls?.breakout,
85
+ getInterpretation: (self) => self?.controls?.interpretation,
86
+ getBrb: (self) => self?.controls?.brb,
75
87
 
76
- SelfUtils.getBreakoutSessions = (self) => self?.controls?.breakout?.sessions;
77
- SelfUtils.getBreakout = (self) => self?.controls?.breakout;
78
- SelfUtils.getInterpretation = (self) => self?.controls?.interpretation;
79
- SelfUtils.getBrb = (self) => self?.controls?.brb;
88
+ getLayout: (self) =>
89
+ Array.isArray(self?.controls?.layouts) ? self.controls.layouts[0].type : undefined,
80
90
 
81
- SelfUtils.getLayout = (self) =>
82
- Array.isArray(self?.controls?.layouts) ? self.controls.layouts[0].type : undefined;
91
+ getRoles: (self) =>
92
+ (self?.controls?.role?.roles || []).reduce((roles, role) => {
93
+ if (role.hasRole) {
94
+ roles.push(role.type);
95
+ }
83
96
 
84
- SelfUtils.getRoles = (self) =>
85
- (self?.controls?.role?.roles || []).reduce((roles, role) => {
86
- if (role.hasRole) {
87
- roles.push(role.type);
88
- }
97
+ return roles;
98
+ }, []),
89
99
 
90
- return roles;
91
- }, []);
92
-
93
- SelfUtils.canNotViewTheParticipantList = (self) => !!self?.canNotViewTheParticipantList;
94
-
95
- SelfUtils.isSharingBlocked = (self) => !!self?.isSharingBlocked;
96
-
97
- SelfUtils.getSelves = (oldSelf, newSelf, deviceId) => {
98
- const previous = oldSelf && SelfUtils.parse(oldSelf, deviceId);
99
- const current = newSelf && SelfUtils.parse(newSelf, deviceId);
100
- const updates: any = {};
101
-
102
- updates.isUserUnadmitted = SelfUtils.isUserUnadmitted(previous, current);
103
- updates.isUserAdmitted = SelfUtils.isUserAdmitted(previous, current);
104
- updates.isVideoMutedByOthersChanged = SelfUtils.videoMutedByOthersChanged(previous, current);
105
- updates.isMutedByOthersChanged = SelfUtils.mutedByOthersChanged(previous, current);
106
- updates.localAudioUnmuteRequestedByServer = SelfUtils.localAudioUnmuteRequestedByServer(
107
- previous,
108
- current
109
- );
110
- updates.localAudioUnmuteRequiredByServer = SelfUtils.localAudioUnmuteRequiredByServer(
111
- previous,
112
- current
113
- );
114
- updates.moderatorChanged = SelfUtils.moderatorChanged(previous, current);
115
- updates.isRolesChanged = SelfUtils.isRolesChanged(previous, current);
116
- updates.isMediaInactiveOrReleased = SelfUtils.wasMediaInactiveOrReleased(previous, current);
117
- updates.isUserObserving = SelfUtils.isDeviceObserving(previous, current);
118
- updates.layoutChanged = SelfUtils.layoutChanged(previous, current);
119
-
120
- updates.isMediaInactive = SelfUtils.isMediaInactive(previous, current);
121
- updates.audioStateChange =
122
- previous?.currentMediaStatus.audio !== current.currentMediaStatus.audio;
123
- updates.videoStateChange =
124
- previous?.currentMediaStatus.video !== current.currentMediaStatus.video;
125
- updates.shareStateChange =
126
- previous?.currentMediaStatus.share !== current.currentMediaStatus.share;
127
-
128
- updates.canNotViewTheParticipantListChanged =
129
- previous?.canNotViewTheParticipantList !== current.canNotViewTheParticipantList;
130
- updates.isSharingBlockedChanged = previous?.isSharingBlocked !== current.isSharingBlocked;
131
- updates.breakoutsChanged = SelfUtils.breakoutsChanged(previous, current);
132
- updates.interpretationChanged = SelfUtils.interpretationChanged(previous, current);
133
- updates.brbChanged = SelfUtils.brbChanged(previous, current);
134
-
135
- return {
136
- previous,
137
- current,
138
- updates,
139
- };
140
- };
100
+ canNotViewTheParticipantList: (self) => !!self?.canNotViewTheParticipantList,
101
+
102
+ isSharingBlocked: (self) => !!self?.isSharingBlocked,
103
+
104
+ getSelves: (oldParsedSelf, newSelf, deviceId, participants: Array<any>) => {
105
+ const previous = oldParsedSelf;
106
+ const current = newSelf && SelfUtils.parse(newSelf, deviceId, participants);
107
+ const updates: any = {};
141
108
 
142
- /**
143
- * Checks if user has joined the meeting
144
- * @param {Object} self
145
- * @returns {boolean} isJoined
146
- */
147
- SelfUtils.isJoined = (self: any) => self?.state === _JOINED_;
148
-
149
- /**
150
- * Validate if the Meeting Layout Controls Layout has changed.
151
- *
152
- * @param {Self} previous - Previous self state
153
- * @param {Self} current - Current self state [per event]
154
- * @returns {boolean} - If the Meeting Layout Controls Layout has changed.
155
- */
156
- SelfUtils.layoutChanged = (previous: any, current: any) =>
157
- current?.layout && previous?.layout !== current?.layout;
158
-
159
- SelfUtils.breakoutsChanged = (previous, current) =>
160
- !isEqual(previous?.breakoutSessions, current?.breakoutSessions) && !!current?.breakout;
161
-
162
- SelfUtils.interpretationChanged = (previous, current) =>
163
- !isEqual(previous?.interpretation, current?.interpretation) && !!current?.interpretation;
164
-
165
- SelfUtils.brbChanged = (previous, current) =>
166
- !isEqual(previous?.brb, current?.brb) && current?.brb !== undefined;
167
-
168
- SelfUtils.isMediaInactive = (previous, current) => {
169
- if (
170
- previous &&
171
- previous.joinedWith &&
172
- previous.joinedWith.mediaSessions &&
173
- current &&
174
- current.joinedWith &&
175
- current.joinedWith.mediaSessions
176
- ) {
177
- const previousMediaStatus = SelfUtils.getMediaStatus(previous.joinedWith.mediaSessions);
178
- const currentMediaStatus = SelfUtils.getMediaStatus(current.joinedWith.mediaSessions);
109
+ updates.hasUserEnteredLobby = SelfUtils.hasUserEnteredLobby(previous, current);
110
+ updates.hasUserBeenAdmitted = SelfUtils.hasUserBeenAdmitted(previous, current);
111
+ updates.isVideoMutedByOthersChanged = SelfUtils.videoMutedByOthersChanged(previous, current);
112
+ updates.isMutedByOthersChanged = SelfUtils.mutedByOthersChanged(previous, current);
113
+ updates.localAudioUnmuteRequestedByServer = SelfUtils.localAudioUnmuteRequestedByServer(
114
+ previous,
115
+ current
116
+ );
117
+ updates.localAudioUnmuteRequiredByServer = SelfUtils.localAudioUnmuteRequiredByServer(
118
+ previous,
119
+ current
120
+ );
121
+ updates.moderatorChanged = SelfUtils.moderatorChanged(previous, current);
122
+ updates.isRolesChanged = SelfUtils.isRolesChanged(previous, current);
123
+ updates.isMediaInactiveOrReleased = SelfUtils.wasMediaInactiveOrReleased(previous, current);
124
+ updates.isUserObserving = SelfUtils.isDeviceObserving(previous, current);
125
+ updates.layoutChanged = SelfUtils.layoutChanged(previous, current);
126
+
127
+ updates.isMediaInactive = SelfUtils.isMediaInactive(previous, current);
128
+ updates.audioStateChange =
129
+ previous?.currentMediaStatus.audio !== current.currentMediaStatus.audio;
130
+ updates.videoStateChange =
131
+ previous?.currentMediaStatus.video !== current.currentMediaStatus.video;
132
+ updates.shareStateChange =
133
+ previous?.currentMediaStatus.share !== current.currentMediaStatus.share;
134
+
135
+ updates.canNotViewTheParticipantListChanged =
136
+ previous?.canNotViewTheParticipantList !== current.canNotViewTheParticipantList;
137
+ updates.isSharingBlockedChanged = previous?.isSharingBlocked !== current.isSharingBlocked;
138
+ updates.breakoutsChanged = SelfUtils.breakoutsChanged(previous, current);
139
+ updates.interpretationChanged = SelfUtils.interpretationChanged(previous, current);
140
+ updates.brbChanged = SelfUtils.brbChanged(previous, current);
179
141
 
142
+ return {
143
+ previous,
144
+ current,
145
+ updates,
146
+ };
147
+ },
148
+
149
+ /**
150
+ * Checks if user has joined the meeting
151
+ * @param {Object} self
152
+ * @returns {boolean} isJoined
153
+ */
154
+ isJoined: (self: any) => self?.state === _JOINED_,
155
+
156
+ /**
157
+ * Validate if the Meeting Layout Controls Layout has changed.
158
+ *
159
+ * @param {Self} previous - Previous self state
160
+ * @param {Self} current - Current self state [per event]
161
+ * @returns {boolean} - If the Meeting Layout Controls Layout has changed.
162
+ */
163
+ layoutChanged: (previous: any, current: any) =>
164
+ current?.layout && previous?.layout !== current?.layout,
165
+
166
+ breakoutsChanged: (previous, current) =>
167
+ !isEqual(previous?.breakoutSessions, current?.breakoutSessions) && !!current?.breakout,
168
+
169
+ interpretationChanged: (previous, current) =>
170
+ !isEqual(previous?.interpretation, current?.interpretation) && !!current?.interpretation,
171
+
172
+ brbChanged: (previous, current) =>
173
+ !isEqual(previous?.brb, current?.brb) && current?.brb !== undefined,
174
+
175
+ isMediaInactive: (previous, current) => {
180
176
  if (
181
- previousMediaStatus.audio &&
182
- currentMediaStatus.audio &&
183
- previousMediaStatus.audio.state !== MEDIA_STATE.inactive &&
184
- currentMediaStatus.audio.state === MEDIA_STATE.inactive &&
185
- currentMediaStatus.audio.direction !== MEDIA_STATE.inactive
177
+ previous &&
178
+ previous.joinedWith &&
179
+ previous.joinedWith.mediaSessions &&
180
+ current &&
181
+ current.joinedWith &&
182
+ current.joinedWith.mediaSessions
186
183
  ) {
187
- return true;
184
+ const previousMediaStatus = SelfUtils.getMediaStatus(previous.joinedWith.mediaSessions);
185
+ const currentMediaStatus = SelfUtils.getMediaStatus(current.joinedWith.mediaSessions);
186
+
187
+ if (
188
+ previousMediaStatus.audio &&
189
+ currentMediaStatus.audio &&
190
+ previousMediaStatus.audio.state !== MEDIA_STATE.inactive &&
191
+ currentMediaStatus.audio.state === MEDIA_STATE.inactive &&
192
+ currentMediaStatus.audio.direction !== MEDIA_STATE.inactive
193
+ ) {
194
+ return true;
195
+ }
196
+
197
+ if (
198
+ previousMediaStatus.video &&
199
+ currentMediaStatus.video &&
200
+ previousMediaStatus.video.state !== MEDIA_STATE.inactive &&
201
+ currentMediaStatus.video.state === MEDIA_STATE.inactive &&
202
+ currentMediaStatus.video.direction !== MEDIA_STATE.inactive
203
+ ) {
204
+ return true;
205
+ }
206
+
207
+ if (
208
+ previousMediaStatus.share &&
209
+ currentMediaStatus.share &&
210
+ previousMediaStatus.share.state !== MEDIA_STATE.inactive &&
211
+ currentMediaStatus.share.state === MEDIA_STATE.inactive &&
212
+ currentMediaStatus.share.direction !== MEDIA_STATE.inactive
213
+ ) {
214
+ return true;
215
+ }
216
+
217
+ return false;
188
218
  }
189
219
 
220
+ return false;
221
+ },
222
+
223
+ getLastModified: (self) => {
190
224
  if (
191
- previousMediaStatus.video &&
192
- currentMediaStatus.video &&
193
- previousMediaStatus.video.state !== MEDIA_STATE.inactive &&
194
- currentMediaStatus.video.state === MEDIA_STATE.inactive &&
195
- currentMediaStatus.video.direction !== MEDIA_STATE.inactive
225
+ !self ||
226
+ !self.controls ||
227
+ !self.controls.audio ||
228
+ !self.controls.audio.meta ||
229
+ !self.controls.audio.meta.lastModified
196
230
  ) {
197
- return true;
231
+ return null;
198
232
  }
199
233
 
234
+ return self.controls.audio.meta.lastModified;
235
+ },
236
+
237
+ getModifiedBy: (self) => {
200
238
  if (
201
- previousMediaStatus.share &&
202
- currentMediaStatus.share &&
203
- previousMediaStatus.share.state !== MEDIA_STATE.inactive &&
204
- currentMediaStatus.share.state === MEDIA_STATE.inactive &&
205
- currentMediaStatus.share.direction !== MEDIA_STATE.inactive
239
+ !self ||
240
+ !self.controls ||
241
+ !self.controls.audio ||
242
+ !self.controls.audio.meta ||
243
+ !self.controls.audio.meta.modifiedBy
206
244
  ) {
207
- return true;
245
+ return null;
208
246
  }
209
247
 
210
- return false;
211
- }
212
-
213
- return false;
214
- };
215
-
216
- SelfUtils.getLastModified = (self) => {
217
- if (
218
- !self ||
219
- !self.controls ||
220
- !self.controls.audio ||
221
- !self.controls.audio.meta ||
222
- !self.controls.audio.meta.lastModified
223
- ) {
224
- return null;
225
- }
226
-
227
- return self.controls.audio.meta.lastModified;
228
- };
229
-
230
- SelfUtils.getModifiedBy = (self) => {
231
- if (
232
- !self ||
233
- !self.controls ||
234
- !self.controls.audio ||
235
- !self.controls.audio.meta ||
236
- !self.controls.audio.meta.modifiedBy
237
- ) {
238
- return null;
239
- }
240
-
241
- return self.controls.audio.meta.modifiedBy;
242
- };
248
+ return self.controls.audio.meta.modifiedBy;
249
+ },
250
+
251
+ /**
252
+ * get the id from the self object
253
+ * @param {Object} self
254
+ * @returns {String}
255
+ */
256
+ getSelfIdentity: (self: any) => {
257
+ if (!self || !self.person) {
258
+ return null;
259
+ }
243
260
 
244
- /**
245
- * get the id from the self object
246
- * @param {Object} self
247
- * @returns {String}
248
- */
249
- SelfUtils.getSelfIdentity = (self: any) => {
250
- if (!self && !self.person) {
251
- return null;
252
- }
261
+ return self.person.id;
262
+ },
263
+
264
+ /**
265
+ * get the "remote video mute" property from the self object
266
+ * @param {Object} self
267
+ * @returns {Boolean}
268
+ */
269
+ getRemoteVideoMuted: (self: any) => {
270
+ if (!self || !self.controls || !self.controls.video) {
271
+ return null;
272
+ }
253
273
 
254
- return self.person.id;
255
- };
274
+ return self.controls.video.muted;
275
+ },
276
+
277
+ /**
278
+ * get the "remote mute" property from the self object
279
+ * @param {Object} self
280
+ * @returns {Boolean}
281
+ */
282
+ getRemoteMuted: (self: any) => {
283
+ if (!self || !self.controls || !self.controls.audio) {
284
+ return null;
285
+ }
256
286
 
257
- /**
258
- * get the "remote video mute" property from the self object
259
- * @param {Object} self
260
- * @returns {Boolean}
261
- */
262
- SelfUtils.getRemoteVideoMuted = (self: any) => {
263
- if (!self || !self.controls || !self.controls.video) {
264
- return null;
265
- }
287
+ return self.controls.audio.muted;
288
+ },
266
289
 
267
- return self.controls.video.muted;
268
- };
290
+ getLocalAudioUnmuteRequested: (self) => !!self?.controls?.audio?.requestedToUnmute,
269
291
 
270
- /**
271
- * get the "remote mute" property from the self object
272
- * @param {Object} self
273
- * @returns {Boolean}
274
- */
275
- SelfUtils.getRemoteMuted = (self: any) => {
276
- if (!self || !self.controls || !self.controls.audio) {
277
- return null;
278
- }
292
+ // requestedToUnmute timestamp
293
+ getLocalAudioUnmuteRequestedTimeStamp: (self) =>
294
+ Date.parse(self?.controls?.audio?.lastModifiedRequestedToUnmute) || 0,
279
295
 
280
- return self.controls.audio.muted;
281
- };
296
+ getUnmuteAllowed: (self) => {
297
+ if (!self || !self.controls || !self.controls.audio) {
298
+ return null;
299
+ }
282
300
 
283
- SelfUtils.getLocalAudioUnmuteRequested = (self) => !!self?.controls?.audio?.requestedToUnmute;
301
+ return !self.controls.audio.disallowUnmute;
302
+ },
303
+
304
+ getLocalAudioUnmuteRequired: (self) => !!self?.controls?.audio?.localAudioUnmuteRequired,
305
+
306
+ getStatus: (status) => ({
307
+ audio: status.audioStatus,
308
+ video: status.videoStatus,
309
+ slides: status.videoSlidesStatus,
310
+ }),
311
+
312
+ /**
313
+ * @param {Object} oldSelf
314
+ * @param {Object} changedSelf
315
+ * @returns {Boolean}
316
+ */
317
+ wasMediaInactiveOrReleased: (oldSelf: any = {}, changedSelf: any) =>
318
+ oldSelf.joinedWith &&
319
+ oldSelf.joinedWith.state === _JOINED_ &&
320
+ changedSelf.joinedWith &&
321
+ changedSelf.joinedWith.state === _LEFT_ &&
322
+ (changedSelf.joinedWith.reason === MEETING_END_REASON.INACTIVE ||
323
+ changedSelf.joinedWith.reason === MEETING_END_REASON.MEDIA_RELEASED),
324
+
325
+ /**
326
+ * @param {String | undefined} state meeting state
327
+ * @param {any} joinedWith device that user has joined with
328
+ * @param {any} pairedWith device that user is paired with
329
+ * @returns {Boolean | undefined} true if user is in lobby, false if not, undefined if it cannot be determined
330
+ */
331
+ isLocusUserUnadmitted: (state?: string, joinedWith?: any, pairedWith?: any) => {
332
+ if (state === undefined) {
333
+ return undefined;
334
+ }
335
+ if (joinedWith?.intent?.type === _OBSERVE_ && pairedWith) {
336
+ // we are paired with a device, so need to check the lobby state for that device
337
+ return pairedWith.intent?.type === _WAIT_ && state === _IDLE_;
338
+ }
284
339
 
285
- // requestedToUnmute timestamp
286
- SelfUtils.getLocalAudioUnmuteRequestedTimeStamp = (self) =>
287
- Date.parse(self?.controls?.audio?.lastModifiedRequestedToUnmute) || 0;
340
+ return joinedWith?.intent?.type === _WAIT_ && state === _IDLE_;
341
+ },
342
+
343
+ /**
344
+ * @param {String | undefined} state meeting state
345
+ * @param {any} joinedWith device that user has joined with
346
+ * @param {any} pairedWith device that user is paired with
347
+ * @returns {Boolean}
348
+ */
349
+ isLocusUserAdmitted: (state?: string, joinedWith?: any, pairedWith?: any) => {
350
+ if (state === undefined) {
351
+ return undefined;
352
+ }
288
353
 
289
- SelfUtils.getUnmuteAllowed = (self) => {
290
- if (!self || !self.controls || !self.controls.audio) {
291
- return null;
292
- }
354
+ if (joinedWith?.intent?.type === _OBSERVE_ && pairedWith) {
355
+ // we are paired with a device, so need to check the lobby state for that device
356
+ return pairedWith.intent?.type !== _WAIT_ && state === _JOINED_;
357
+ }
293
358
 
294
- return !self.controls.audio.disallowUnmute;
295
- };
359
+ return joinedWith?.intent?.type !== _WAIT_ && state === _JOINED_;
360
+ },
361
+
362
+ /**
363
+ * @param {Object} oldSelf
364
+ * @param {Object} changedSelf
365
+ * @returns {Boolean} true if user has just been placed in the lobby
366
+ * @throws {Error} when self is undefined
367
+ */
368
+ hasUserEnteredLobby: (oldSelf: any, changedSelf: any) => {
369
+ if (!changedSelf) {
370
+ throw new ParameterError(
371
+ 'changedSelf must be defined to determine if self is unadmitted as guest.'
372
+ );
373
+ }
296
374
 
297
- SelfUtils.getLocalAudioUnmuteRequired = (self) => !!self?.controls?.audio?.localAudioUnmuteRequired;
298
-
299
- SelfUtils.getStatus = (status) => ({
300
- audio: status.audioStatus,
301
- video: status.videoStatus,
302
- slides: status.videoSlidesStatus,
303
- });
304
-
305
- /**
306
- * @param {Object} oldSelf
307
- * @param {Object} changedSelf
308
- * @returns {Boolean}
309
- */
310
- SelfUtils.wasMediaInactiveOrReleased = (oldSelf: any = {}, changedSelf: any) =>
311
- oldSelf.joinedWith &&
312
- oldSelf.joinedWith.state === _JOINED_ &&
313
- changedSelf.joinedWith &&
314
- changedSelf.joinedWith.state === _LEFT_ &&
315
- (changedSelf.joinedWith.reason === MEETING_END_REASON.INACTIVE ||
316
- changedSelf.joinedWith.reason === MEETING_END_REASON.MEDIA_RELEASED);
317
-
318
- /**
319
- * @param {Object} check
320
- * @returns {Boolean}
321
- */
322
- SelfUtils.isLocusUserUnadmitted = (check: any) =>
323
- check && check.joinedWith?.intent?.type === _WAIT_ && check.state === _IDLE_;
324
-
325
- /**
326
- * @param {Object} check
327
- * @returns {Boolean}
328
- */
329
- SelfUtils.isLocusUserAdmitted = (check: any) =>
330
- check && check.joinedWith?.intent?.type !== _WAIT_ && check.state === _JOINED_;
331
-
332
- /**
333
- * @param {Object} oldSelf
334
- * @param {Object} changedSelf
335
- * @returns {Boolean}
336
- * @throws {Error} when self is undefined
337
- */
338
- SelfUtils.isUserUnadmitted = (oldSelf: object, changedSelf: object) => {
339
- if (!changedSelf) {
340
- throw new ParameterError(
341
- 'changedSelf must be defined to determine if self is unadmitted as guest.'
375
+ const wasInLobby = SelfUtils.isLocusUserUnadmitted(
376
+ oldSelf?.state,
377
+ oldSelf?.joinedWith,
378
+ oldSelf?.pairedWith
342
379
  );
343
- }
344
380
 
345
- if (SelfUtils.isLocusUserUnadmitted(oldSelf)) {
346
- return false;
347
- }
381
+ const isInLobby = SelfUtils.isLocusUserUnadmitted(
382
+ changedSelf?.state,
383
+ changedSelf?.joinedWith,
384
+ changedSelf?.pairedWith
385
+ );
348
386
 
349
- return SelfUtils.isLocusUserUnadmitted(changedSelf);
350
- };
387
+ return !wasInLobby && isInLobby;
388
+ },
351
389
 
352
- SelfUtils.moderatorChanged = (oldSelf, changedSelf) => {
353
- if (!oldSelf) {
354
- return true;
355
- }
356
- if (!changedSelf) {
357
- throw new ParameterError(
358
- 'New self must be defined to determine if self transitioned moderator status.'
359
- );
360
- }
390
+ moderatorChanged: (oldSelf, changedSelf) => {
391
+ if (!oldSelf) {
392
+ return true;
393
+ }
394
+ if (!changedSelf) {
395
+ throw new ParameterError(
396
+ 'New self must be defined to determine if self transitioned moderator status.'
397
+ );
398
+ }
361
399
 
362
- return oldSelf.moderator !== changedSelf.moderator;
363
- };
400
+ return oldSelf.moderator !== changedSelf.moderator;
401
+ },
402
+
403
+ /**
404
+ * determine whether the roles of self is changed or not
405
+ * @param {Object} oldSelf
406
+ * @param {Object} changedSelf
407
+ * @returns {Boolean}
408
+ */
409
+ isRolesChanged: (oldSelf, changedSelf) => {
410
+ if (!changedSelf) {
411
+ // no new self means no change
412
+ return false;
413
+ }
364
414
 
365
- /**
366
- * determine whether the roles of self is changed or not
367
- * @param {Object} oldSelf
368
- * @param {Object} changedSelf
369
- * @returns {Boolean}
370
- */
371
- SelfUtils.isRolesChanged = (oldSelf, changedSelf) => {
372
- if (!changedSelf) {
373
- // no new self means no change
374
- return false;
375
- }
415
+ return !isEqual(oldSelf?.roles, changedSelf?.roles);
416
+ },
417
+ /**
418
+ * @param {Object} oldSelf
419
+ * @param {Object} changedSelf
420
+ * @returns {Boolean}
421
+ * @throws {Error} if changed self was undefined
422
+ */
423
+ isDeviceObserving: (oldSelf: any, changedSelf: any) =>
424
+ oldSelf &&
425
+ oldSelf.joinedWith?.intent?.type === _MOVE_MEDIA_ &&
426
+ changedSelf &&
427
+ changedSelf.joinedWith?.intent?.type === _OBSERVE_,
428
+
429
+ /**
430
+ * @param {Object} oldSelf
431
+ * @param {Object} changedSelf
432
+ * @returns {Boolean} true if the user has just been admitted from lobby into the meeting
433
+ * @throws {Error} if changed self was undefined
434
+ */
435
+ hasUserBeenAdmitted: (oldSelf: any, changedSelf: any) => {
436
+ if (!oldSelf) {
437
+ // if there was no previous locus, it couldn't have been admitted yet
438
+ return false;
439
+ }
440
+ if (!changedSelf) {
441
+ throw new ParameterError(
442
+ 'New self must be defined to determine if self transitioned to admitted as guest.'
443
+ );
444
+ }
376
445
 
377
- return !isEqual(oldSelf?.roles, changedSelf?.roles);
378
- };
379
- /**
380
- * @param {Object} oldSelf
381
- * @param {Object} changedSelf
382
- * @returns {Boolean}
383
- * @throws {Error} if changed self was undefined
384
- */
385
- SelfUtils.isDeviceObserving = (oldSelf: any, changedSelf: any) =>
386
- oldSelf &&
387
- oldSelf.joinedWith?.intent?.type === _MOVE_MEDIA_ &&
388
- changedSelf &&
389
- changedSelf.joinedWith?.intent?.type === _OBSERVE_;
390
-
391
- /**
392
- * @param {Object} oldSelf
393
- * @param {Object} changedSelf
394
- * @returns {Boolean}
395
- * @throws {Error} if changed self was undefined
396
- */
397
- SelfUtils.isUserAdmitted = (oldSelf: object, changedSelf: object) => {
398
- if (!oldSelf) {
399
- // if there was no previous locus, it couldn't have been admitted yet
400
- return false;
401
- }
402
- if (!changedSelf) {
403
- throw new ParameterError(
404
- 'New self must be defined to determine if self transitioned to admitted as guest.'
446
+ const wasInLobby = SelfUtils.isLocusUserUnadmitted(
447
+ oldSelf?.state,
448
+ oldSelf?.joinedWith,
449
+ oldSelf?.pairedWith
405
450
  );
406
- }
407
451
 
408
- return SelfUtils.isLocusUserUnadmitted(oldSelf) && SelfUtils.isLocusUserAdmitted(changedSelf);
409
- };
410
-
411
- SelfUtils.videoMutedByOthersChanged = (oldSelf, changedSelf) => {
412
- if (!changedSelf) {
413
- throw new ParameterError(
414
- 'New self must be defined to determine if self was video muted by others.'
452
+ const isAdmitted = SelfUtils.isLocusUserAdmitted(
453
+ changedSelf?.state,
454
+ changedSelf?.joinedWith,
455
+ changedSelf?.pairedWith
415
456
  );
416
- }
417
457
 
418
- if (!oldSelf || oldSelf.remoteVideoMuted === null) {
419
- if (changedSelf.remoteVideoMuted) {
420
- return true; // this happens when host disables "Allow start video"
458
+ return wasInLobby && isAdmitted && isAdmitted !== undefined;
459
+ },
460
+
461
+ videoMutedByOthersChanged: (oldSelf, changedSelf) => {
462
+ if (!changedSelf) {
463
+ throw new ParameterError(
464
+ 'New self must be defined to determine if self was video muted by others.'
465
+ );
421
466
  }
422
467
 
423
- // we don't want to be sending the 'meeting:self:videoUnmutedByOthers' notification on meeting join
424
- return false;
425
- }
468
+ if (!oldSelf || oldSelf.remoteVideoMuted === null) {
469
+ if (changedSelf.remoteVideoMuted) {
470
+ return true; // this happens when host disables "Allow start video"
471
+ }
426
472
 
427
- return oldSelf.remoteVideoMuted !== changedSelf.remoteVideoMuted;
428
- };
473
+ // we don't want to be sending the 'meeting:self:videoUnmutedByOthers' notification on meeting join
474
+ return false;
475
+ }
429
476
 
430
- SelfUtils.mutedByOthersChanged = (oldSelf, changedSelf) => {
431
- if (!changedSelf) {
432
- throw new ParameterError('New self must be defined to determine if self was muted by others.');
433
- }
477
+ return oldSelf.remoteVideoMuted !== changedSelf.remoteVideoMuted;
478
+ },
434
479
 
435
- if (!oldSelf || oldSelf.remoteMuted === null) {
436
- if (changedSelf.remoteMuted) {
437
- return true; // this happens when mute on-entry is enabled
480
+ mutedByOthersChanged: (oldSelf, changedSelf) => {
481
+ if (!changedSelf) {
482
+ throw new ParameterError(
483
+ 'New self must be defined to determine if self was muted by others.'
484
+ );
438
485
  }
439
486
 
440
- // we don't want to be sending the 'meeting:self:unmutedByOthers' notification on meeting join
441
- return false;
442
- }
487
+ if (!oldSelf || oldSelf.remoteMuted === null) {
488
+ if (changedSelf.remoteMuted) {
489
+ return true; // this happens when mute on-entry is enabled
490
+ }
443
491
 
444
- // there is no need to trigger user update if no one muted user
445
- if (changedSelf.selfIdentity === changedSelf.modifiedBy) {
446
- return false;
447
- }
492
+ // we don't want to be sending the 'meeting:self:unmutedByOthers' notification on meeting join
493
+ return false;
494
+ }
448
495
 
449
- return (
450
- changedSelf.remoteMuted !== null &&
451
- (oldSelf.remoteMuted !== changedSelf.remoteMuted ||
452
- (changedSelf.remoteMuted && oldSelf.unmuteAllowed !== changedSelf.unmuteAllowed))
453
- );
454
- };
496
+ // there is no need to trigger user update if no one muted user
497
+ if (changedSelf.selfIdentity === changedSelf.modifiedBy) {
498
+ return false;
499
+ }
455
500
 
456
- SelfUtils.localAudioUnmuteRequestedByServer = (oldSelf: any = {}, changedSelf: any) => {
457
- if (!changedSelf) {
458
- throw new ParameterError(
459
- 'New self must be defined to determine if self received request to unmute.'
501
+ return (
502
+ changedSelf.remoteMuted !== null &&
503
+ (oldSelf.remoteMuted !== changedSelf.remoteMuted ||
504
+ (changedSelf.remoteMuted && oldSelf.unmuteAllowed !== changedSelf.unmuteAllowed))
460
505
  );
461
- }
506
+ },
462
507
 
463
- return (
464
- changedSelf.localAudioUnmuteRequested &&
465
- changedSelf.localAudioUnmuteRequestedTimeStamp > oldSelf.localAudioUnmuteRequestedTimeStamp
466
- );
467
- };
508
+ localAudioUnmuteRequestedByServer: (oldSelf: any = {}, changedSelf: any) => {
509
+ if (!changedSelf) {
510
+ throw new ParameterError(
511
+ 'New self must be defined to determine if self received request to unmute.'
512
+ );
513
+ }
468
514
 
469
- SelfUtils.localAudioUnmuteRequiredByServer = (oldSelf: any = {}, changedSelf: any) => {
470
- if (!changedSelf) {
471
- throw new ParameterError(
472
- 'New self must be defined to determine if localAudioUnmuteRequired changed.'
515
+ return (
516
+ changedSelf.localAudioUnmuteRequested &&
517
+ changedSelf.localAudioUnmuteRequestedTimeStamp > oldSelf.localAudioUnmuteRequestedTimeStamp
473
518
  );
474
- }
519
+ },
475
520
 
476
- return (
477
- !changedSelf.remoteMuted &&
478
- changedSelf.localAudioUnmuteRequired &&
479
- oldSelf.localAudioUnmuteRequired !== changedSelf.localAudioUnmuteRequired
480
- );
481
- };
521
+ localAudioUnmuteRequiredByServer: (oldSelf: any = {}, changedSelf: any) => {
522
+ if (!changedSelf) {
523
+ throw new ParameterError(
524
+ 'New self must be defined to determine if localAudioUnmuteRequired changed.'
525
+ );
526
+ }
482
527
 
483
- /**
484
- * extract the sipUrl from the partner
485
- * @param {Object} partner
486
- * @param {Object} info
487
- * @returns {Object}
488
- */
528
+ return (
529
+ !changedSelf.remoteMuted &&
530
+ changedSelf.localAudioUnmuteRequired &&
531
+ oldSelf.localAudioUnmuteRequired !== changedSelf.localAudioUnmuteRequired
532
+ );
533
+ },
534
+
535
+ /**
536
+ * extract the sipUrl from the partner
537
+ * @param {Object} partner
538
+ * @param {Object} info
539
+ * @returns {Object}
540
+ */
541
+
542
+ getSipUrl: (partner: any, type, sipUri) => {
543
+ // For webex meeting the sipUrl gets updated in info parser
544
+ if (partner && type === _CALL_) {
545
+ return {sipUri: partner.person.sipUrl || partner.person.id};
546
+ }
489
547
 
490
- SelfUtils.getSipUrl = (partner: any, type, sipUri) => {
491
- // For webex meeting the sipUrl gets updated in info parser
492
- if (partner && type === _CALL_) {
493
- return {sipUri: partner.person.sipUrl || partner.person.id};
494
- }
548
+ return {sipUri};
549
+ },
495
550
 
496
- return {sipUri};
497
- };
551
+ getMediaStatus: (mediaSessions = []): {audio: any; video: any; share: any} => {
552
+ const mediaStatus = {
553
+ audio: {},
554
+ video: {},
555
+ share: {},
556
+ };
498
557
 
499
- SelfUtils.getMediaStatus = (mediaSessions = []) => {
500
- const mediaStatus = {
501
- audio: {},
502
- video: {},
503
- share: {},
504
- };
505
-
506
- mediaStatus.audio = mediaSessions.find(
507
- (media) => media.mediaType === AUDIO && media.mediaContent === MediaContent.main
508
- );
509
- mediaStatus.video = mediaSessions.find(
510
- (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.main
511
- );
512
- mediaStatus.share = mediaSessions.find(
513
- (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.slides
514
- );
515
-
516
- return mediaStatus;
517
- };
558
+ mediaStatus.audio = mediaSessions.find(
559
+ (media) => media.mediaType === AUDIO && media.mediaContent === MediaContent.main
560
+ );
561
+ mediaStatus.video = mediaSessions.find(
562
+ (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.main
563
+ );
564
+ mediaStatus.share = mediaSessions.find(
565
+ (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.slides
566
+ );
567
+
568
+ return mediaStatus;
569
+ },
518
570
 
519
- SelfUtils.getReplacedBreakoutMoveId = (self: any, deviceId: string) => {
520
- if (self && Array.isArray(self.devices)) {
521
- const joinedDevice = self.devices.find((device) => deviceId === device.url);
522
- if (Array.isArray(joinedDevice?.replaces)) {
523
- return joinedDevice.replaces[0]?.breakoutMoveId;
571
+ getReplacedBreakoutMoveId: (self: any, deviceId: string) => {
572
+ if (self && Array.isArray(self.devices)) {
573
+ const joinedDevice = self.devices.find((device) => deviceId === device.url);
574
+ if (Array.isArray(joinedDevice?.replaces)) {
575
+ return joinedDevice.replaces[0]?.breakoutMoveId;
576
+ }
524
577
  }
525
- }
526
578
 
527
- return null;
579
+ return null;
580
+ },
528
581
  };
582
+
529
583
  export default SelfUtils;