@webex/plugin-meetings 3.0.0-beta.157 → 3.0.0-beta.159
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/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +2 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/locus-info/index.js +1 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.js +105 -131
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.js +7 -2
- package/dist/meetings/index.js.map +1 -1
- package/dist/types/meeting/index.d.ts +8 -1
- package/package.json +19 -19
- package/src/breakouts/index.ts +1 -1
- package/src/locus-info/index.ts +1 -1
- package/src/meeting/index.ts +28 -29
- package/src/meetings/index.ts +12 -2
- package/test/unit/spec/meeting/index.js +21 -0
- package/test/unit/spec/meetings/index.js +45 -11
package/src/meeting/index.ts
CHANGED
|
@@ -160,7 +160,7 @@ export type AddMediaOptions = {
|
|
|
160
160
|
|
|
161
161
|
export const MEDIA_UPDATE_TYPE = {
|
|
162
162
|
TRANSCODED_MEDIA_CONNECTION: 'TRANSCODED_MEDIA_CONNECTION',
|
|
163
|
-
|
|
163
|
+
SHARE_FLOOR_REQUEST: 'SHARE_FLOOR_REQUEST',
|
|
164
164
|
UPDATE_MEDIA: 'UPDATE_MEDIA',
|
|
165
165
|
};
|
|
166
166
|
|
|
@@ -1213,6 +1213,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1213
1213
|
};
|
|
1214
1214
|
}
|
|
1215
1215
|
|
|
1216
|
+
/**
|
|
1217
|
+
* returns meeting is joined
|
|
1218
|
+
* @private
|
|
1219
|
+
* @memberof Meeting
|
|
1220
|
+
* @returns {Boolean}
|
|
1221
|
+
*/
|
|
1222
|
+
private isJoined() {
|
|
1223
|
+
return this.joinedWith?.state === 'JOINED';
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1216
1226
|
/**
|
|
1217
1227
|
* Fetches meeting information.
|
|
1218
1228
|
* @param {Object} options
|
|
@@ -1502,14 +1512,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1502
1512
|
});
|
|
1503
1513
|
|
|
1504
1514
|
this.breakouts.on(BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN, () => {
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1515
|
+
if (this.isJoined()) {
|
|
1516
|
+
Trigger.trigger(
|
|
1517
|
+
this,
|
|
1518
|
+
{
|
|
1519
|
+
file: 'meeting/index',
|
|
1520
|
+
function: 'setUpBreakoutsListener',
|
|
1521
|
+
},
|
|
1522
|
+
EVENT_TRIGGERS.MEETING_BREAKOUTS_ASK_RETURN_TO_MAIN
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1513
1525
|
});
|
|
1514
1526
|
|
|
1515
1527
|
this.breakouts.on(BREAKOUTS.EVENTS.LEAVE_BREAKOUT, () => {
|
|
@@ -4178,7 +4190,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4178
4190
|
// @ts-ignore - Fix type
|
|
4179
4191
|
const {url, info: {datachannelUrl} = {}} = this.locusInfo;
|
|
4180
4192
|
|
|
4181
|
-
const isJoined = this.
|
|
4193
|
+
const isJoined = this.isJoined();
|
|
4182
4194
|
|
|
4183
4195
|
// @ts-ignore - Fix type
|
|
4184
4196
|
if (this.webex.internal.llm.isConnected()) {
|
|
@@ -5196,11 +5208,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5196
5208
|
)
|
|
5197
5209
|
.then(() => {
|
|
5198
5210
|
if (localTracks?.screenShare?.video) {
|
|
5199
|
-
this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.
|
|
5200
|
-
lambda: async () => {
|
|
5201
|
-
return this.requestScreenShareFloor();
|
|
5202
|
-
},
|
|
5203
|
-
});
|
|
5211
|
+
this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.SHARE_FLOOR_REQUEST);
|
|
5204
5212
|
}
|
|
5205
5213
|
})
|
|
5206
5214
|
.then(() => this.mediaProperties.getCurrentConnectionType())
|
|
@@ -5296,12 +5304,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5296
5304
|
* @private
|
|
5297
5305
|
* @memberof Meeting
|
|
5298
5306
|
*/
|
|
5299
|
-
private enqueueMediaUpdate(mediaUpdateType: string, options: any): Promise<void> {
|
|
5300
|
-
if (mediaUpdateType === MEDIA_UPDATE_TYPE.LAMBDA && typeof options?.lambda !== 'function') {
|
|
5301
|
-
return Promise.reject(
|
|
5302
|
-
new Error('lambda must be specified when enqueuing MEDIA_UPDATE_TYPE.LAMBDA')
|
|
5303
|
-
);
|
|
5304
|
-
}
|
|
5307
|
+
private enqueueMediaUpdate(mediaUpdateType: string, options: any = {}): Promise<void> {
|
|
5305
5308
|
const canUpdateMediaNow = this.canUpdateMedia();
|
|
5306
5309
|
|
|
5307
5310
|
return new Promise((resolve, reject) => {
|
|
@@ -5365,8 +5368,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5365
5368
|
case MEDIA_UPDATE_TYPE.TRANSCODED_MEDIA_CONNECTION:
|
|
5366
5369
|
mediaUpdate = this.updateTranscodedMediaConnection();
|
|
5367
5370
|
break;
|
|
5368
|
-
case MEDIA_UPDATE_TYPE.
|
|
5369
|
-
mediaUpdate =
|
|
5371
|
+
case MEDIA_UPDATE_TYPE.SHARE_FLOOR_REQUEST:
|
|
5372
|
+
mediaUpdate = this.requestScreenShareFloor();
|
|
5370
5373
|
break;
|
|
5371
5374
|
case MEDIA_UPDATE_TYPE.UPDATE_MEDIA:
|
|
5372
5375
|
mediaUpdate = this.updateMedia(options);
|
|
@@ -6641,7 +6644,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6641
6644
|
LoggerProxy.logger.info(`${LOG_HEADER} starting`);
|
|
6642
6645
|
|
|
6643
6646
|
if (!this.canUpdateMedia()) {
|
|
6644
|
-
return this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.TRANSCODED_MEDIA_CONNECTION
|
|
6647
|
+
return this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.TRANSCODED_MEDIA_CONNECTION);
|
|
6645
6648
|
}
|
|
6646
6649
|
|
|
6647
6650
|
return this.mediaProperties.webrtcMediaConnection
|
|
@@ -6770,11 +6773,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6770
6773
|
// we're sending the http request to Locus to request the screen share floor
|
|
6771
6774
|
// only after the SDP update, because that's how it's always been done for transcoded meetings
|
|
6772
6775
|
// and also if sharing from the start, we need confluence to have been created
|
|
6773
|
-
await this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.
|
|
6774
|
-
lambda: async () => {
|
|
6775
|
-
return this.requestScreenShareFloor();
|
|
6776
|
-
},
|
|
6777
|
-
});
|
|
6776
|
+
await this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.SHARE_FLOOR_REQUEST);
|
|
6778
6777
|
}
|
|
6779
6778
|
}
|
|
6780
6779
|
|
package/src/meetings/index.ts
CHANGED
|
@@ -261,6 +261,9 @@ export default class Meetings extends WebexPlugin {
|
|
|
261
261
|
const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
|
|
262
262
|
// @ts-ignore
|
|
263
263
|
const deviceFromNewLocus = MeetingsUtil.getThisDevice(newLocus, this.webex.internal.device.url);
|
|
264
|
+
const isResourceMovedOnThisDevice =
|
|
265
|
+
deviceFromNewLocus?.state === _LEFT_ && deviceFromNewLocus?.reason === _MOVED_;
|
|
266
|
+
|
|
264
267
|
const isNewLocusJoinThisDevice = MeetingsUtil.joinedOnThisDevice(
|
|
265
268
|
meeting,
|
|
266
269
|
newLocus,
|
|
@@ -300,9 +303,16 @@ export default class Meetings extends WebexPlugin {
|
|
|
300
303
|
|
|
301
304
|
return false;
|
|
302
305
|
}
|
|
303
|
-
if (isSelfMoved && newLocus?.self?.removed) {
|
|
306
|
+
if (isSelfMoved && (newLocus?.self?.removed || isResourceMovedOnThisDevice)) {
|
|
307
|
+
LoggerProxy.logger.log(
|
|
308
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
if (isSelfJoined && isResourceMovedOnThisDevice) {
|
|
304
314
|
LoggerProxy.logger.log(
|
|
305
|
-
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self
|
|
315
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
306
316
|
);
|
|
307
317
|
|
|
308
318
|
return false;
|
|
@@ -2710,6 +2710,19 @@ describe('plugin-meetings', () => {
|
|
|
2710
2710
|
});
|
|
2711
2711
|
});
|
|
2712
2712
|
|
|
2713
|
+
describe("#isJoined", () => {
|
|
2714
|
+
it("should returns isJoined correctly", () => {
|
|
2715
|
+
meeting.joinedWith = undefined;
|
|
2716
|
+
assert.equal(meeting.isJoined(), false);
|
|
2717
|
+
|
|
2718
|
+
meeting.joinedWith = {state: "NOT_JOINED"};
|
|
2719
|
+
assert.equal(meeting.isJoined(), false);
|
|
2720
|
+
|
|
2721
|
+
meeting.joinedWith = {state: "JOINED"};
|
|
2722
|
+
assert.equal(meeting.isJoined(), true);
|
|
2723
|
+
});
|
|
2724
|
+
});
|
|
2725
|
+
|
|
2713
2726
|
describe('#fetchMeetingInfo', () => {
|
|
2714
2727
|
const FAKE_DESTINATION = 'something@somecompany.com';
|
|
2715
2728
|
const FAKE_TYPE = _SIP_URI_;
|
|
@@ -4463,8 +4476,16 @@ describe('plugin-meetings', () => {
|
|
|
4463
4476
|
);
|
|
4464
4477
|
});
|
|
4465
4478
|
|
|
4479
|
+
it('should not trigger ASK_RETURN_TO_MAIN before joined', () => {
|
|
4480
|
+
TriggerProxy.trigger.reset();
|
|
4481
|
+
meeting.joinedWith = {state: "NOT_JOINED"};
|
|
4482
|
+
meeting.breakouts.trigger('ASK_RETURN_TO_MAIN');
|
|
4483
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
4484
|
+
});
|
|
4485
|
+
|
|
4466
4486
|
it('listens to the ask return to main event from breakouts and triggers the ask return to main event from meeting', () => {
|
|
4467
4487
|
TriggerProxy.trigger.reset();
|
|
4488
|
+
meeting.joinedWith = {state: "JOINED"};
|
|
4468
4489
|
meeting.breakouts.trigger('ASK_RETURN_TO_MAIN');
|
|
4469
4490
|
assert.calledWith(
|
|
4470
4491
|
TriggerProxy.trigger,
|
|
@@ -1083,7 +1083,7 @@ describe('plugin-meetings', () => {
|
|
|
1083
1083
|
'meeting:meetingInfoAvailable'
|
|
1084
1084
|
);
|
|
1085
1085
|
};
|
|
1086
|
-
|
|
1086
|
+
|
|
1087
1087
|
it('creates the meeting from a successful meeting info fetch promise testing', async () => {
|
|
1088
1088
|
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1089
1089
|
|
|
@@ -1104,7 +1104,7 @@ describe('plugin-meetings', () => {
|
|
|
1104
1104
|
permissionToken: 'PT',
|
|
1105
1105
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
1106
1106
|
};
|
|
1107
|
-
|
|
1107
|
+
|
|
1108
1108
|
assert.instanceOf(
|
|
1109
1109
|
meeting,
|
|
1110
1110
|
Meeting,
|
|
@@ -1112,7 +1112,7 @@ describe('plugin-meetings', () => {
|
|
|
1112
1112
|
);
|
|
1113
1113
|
checkCreateWithoutDelay(meeting, 'test destination', 'test type', infoExtraParamsProvided ? infoExtraParams : {}, expectedMeetingData);
|
|
1114
1114
|
});
|
|
1115
|
-
|
|
1115
|
+
|
|
1116
1116
|
it(`creates the meeting from a successful meeting info fetch with random delay${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
|
|
1117
1117
|
const FAKE_LOCUS_MEETING = {
|
|
1118
1118
|
conversationUrl: 'locusConvURL',
|
|
@@ -1129,14 +1129,14 @@ describe('plugin-meetings', () => {
|
|
|
1129
1129
|
active: false,
|
|
1130
1130
|
},
|
|
1131
1131
|
};
|
|
1132
|
-
|
|
1132
|
+
|
|
1133
1133
|
const meeting = await webex.meetings.createMeeting(
|
|
1134
1134
|
FAKE_LOCUS_MEETING,
|
|
1135
1135
|
'test type',
|
|
1136
1136
|
true,
|
|
1137
1137
|
infoExtraParams
|
|
1138
1138
|
);
|
|
1139
|
-
|
|
1139
|
+
|
|
1140
1140
|
assert.instanceOf(
|
|
1141
1141
|
meeting,
|
|
1142
1142
|
Meeting,
|
|
@@ -1144,7 +1144,7 @@ describe('plugin-meetings', () => {
|
|
|
1144
1144
|
);
|
|
1145
1145
|
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1146
1146
|
assert.calledOnce(setTimeoutSpy);
|
|
1147
|
-
|
|
1147
|
+
|
|
1148
1148
|
// Parse meeting info with locus object
|
|
1149
1149
|
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1150
1150
|
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
@@ -1153,7 +1153,7 @@ describe('plugin-meetings', () => {
|
|
|
1153
1153
|
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1154
1154
|
assert.equal(meeting.owner, 'locusOwner');
|
|
1155
1155
|
assert.isUndefined(meeting.permissionToken);
|
|
1156
|
-
|
|
1156
|
+
|
|
1157
1157
|
// Add meeting and send trigger
|
|
1158
1158
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1159
1159
|
assert.calledTwice(TriggerProxy.trigger);
|
|
@@ -1170,7 +1170,7 @@ describe('plugin-meetings', () => {
|
|
|
1170
1170
|
type: 'test meeting added type',
|
|
1171
1171
|
}
|
|
1172
1172
|
);
|
|
1173
|
-
|
|
1173
|
+
|
|
1174
1174
|
// When timer expires
|
|
1175
1175
|
clock.tick(FAKE_TIME_TO_START);
|
|
1176
1176
|
assert.calledWith(
|
|
@@ -1183,7 +1183,7 @@ describe('plugin-meetings', () => {
|
|
|
1183
1183
|
undefined,
|
|
1184
1184
|
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1185
1185
|
);
|
|
1186
|
-
|
|
1186
|
+
|
|
1187
1187
|
// Parse meeting info is called again with new meeting info
|
|
1188
1188
|
await testUtils.flushPromises();
|
|
1189
1189
|
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
@@ -1193,7 +1193,7 @@ describe('plugin-meetings', () => {
|
|
|
1193
1193
|
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1194
1194
|
assert.equal(meeting.owner, 'locusOwner');
|
|
1195
1195
|
assert.equal(meeting.permissionToken, 'PT');
|
|
1196
|
-
|
|
1196
|
+
|
|
1197
1197
|
assert.calledWith(
|
|
1198
1198
|
TriggerProxy.trigger,
|
|
1199
1199
|
meeting,
|
|
@@ -1744,7 +1744,41 @@ describe('plugin-meetings', () => {
|
|
|
1744
1744
|
assert.equal(result, false);
|
|
1745
1745
|
assert.calledWith(
|
|
1746
1746
|
LoggerProxy.logger.log,
|
|
1747
|
-
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status, not need to handle'
|
|
1747
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1748
|
+
);
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
1752
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1753
|
+
newLocus.self.state = 'LEFT';
|
|
1754
|
+
newLocus.self.reason = 'MOVED';
|
|
1755
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1756
|
+
state: 'LEFT',
|
|
1757
|
+
reason: 'MOVED',
|
|
1758
|
+
});
|
|
1759
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1760
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1761
|
+
assert.equal(result, false);
|
|
1762
|
+
assert.calledWith(
|
|
1763
|
+
LoggerProxy.logger.log,
|
|
1764
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1765
|
+
);
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1768
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
1769
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1770
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
1771
|
+
newLocus.self.state = 'JOINED';
|
|
1772
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1773
|
+
state: 'LEFT',
|
|
1774
|
+
reason: 'MOVED',
|
|
1775
|
+
});
|
|
1776
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1777
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1778
|
+
assert.equal(result, false);
|
|
1779
|
+
assert.calledWith(
|
|
1780
|
+
LoggerProxy.logger.log,
|
|
1781
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
1748
1782
|
);
|
|
1749
1783
|
});
|
|
1750
1784
|
});
|