@webex/plugin-meetings 1.149.0 → 1.150.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.
- package/dist/constants.js +12 -4
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +88 -11
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/meeting/index.js +198 -38
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +17 -41
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting-info/index.js +1 -1
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/util.js +14 -0
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meetings/index.js +12 -13
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +0 -16
- package/dist/meetings/util.js.map +1 -1
- package/dist/members/index.js +72 -11
- package/dist/members/index.js.map +1 -1
- package/dist/metrics/config.js +6 -0
- package/dist/metrics/config.js.map +1 -1
- package/package.json +5 -5
- package/src/constants.js +9 -2
- package/src/locus-info/mediaSharesUtils.js +84 -12
- package/src/meeting/index.js +179 -19
- package/src/meeting/request.js +50 -29
- package/src/meeting-info/index.js +4 -1
- package/src/meeting-info/util.js +13 -0
- package/src/meetings/index.js +10 -11
- package/src/meetings/util.js +0 -14
- package/src/members/index.js +80 -11
- package/src/metrics/config.js +6 -0
- package/test/integration/spec/journey.js +176 -5
- package/test/integration/spec/space-meeting.js +33 -5
- package/test/unit/spec/meeting/index.js +547 -2
- package/test/utils/webex-test-users.js +2 -0
package/src/meeting/index.js
CHANGED
|
@@ -1310,7 +1310,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1310
1310
|
|
|
1311
1311
|
/**
|
|
1312
1312
|
* Set up the locus info media shares listener
|
|
1313
|
-
* update content sharing id value for members, and updates the member
|
|
1313
|
+
* update content and whiteboard sharing id value for members, and updates the member
|
|
1314
1314
|
* notifies consumer with members:content:update {activeContentSharingId, endedContentSharingId}
|
|
1315
1315
|
* @returns {undefined}
|
|
1316
1316
|
* @private
|
|
@@ -1319,11 +1319,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1319
1319
|
setUpLocusMediaSharesListener() {
|
|
1320
1320
|
// Will get triggered on local and remote share
|
|
1321
1321
|
this.locusInfo.on(EVENTS.LOCUS_INFO_UPDATE_MEDIA_SHARES, (payload) => {
|
|
1322
|
-
const {
|
|
1322
|
+
const {content: contentShare, whiteboard: whiteboardShare} = payload.current;
|
|
1323
|
+
const previousContentShare = payload.previous?.content;
|
|
1324
|
+
const previousWhiteboardShare = payload.previous?.whiteboard;
|
|
1323
1325
|
|
|
1324
1326
|
if (
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
+
(contentShare.beneficiaryId === previousContentShare?.beneficiaryId &&
|
|
1328
|
+
contentShare.disposition === previousContentShare?.disposition) &&
|
|
1329
|
+
(whiteboardShare.beneficiaryId === previousWhiteboardShare?.beneficiaryId &&
|
|
1330
|
+
whiteboardShare.disposition === previousWhiteboardShare?.disposition &&
|
|
1331
|
+
whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl)
|
|
1327
1332
|
) {
|
|
1328
1333
|
// nothing changed, so ignore
|
|
1329
1334
|
// (this happens when we steal presentation from remote)
|
|
@@ -1334,15 +1339,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1334
1339
|
|
|
1335
1340
|
// REMOTE - check if remote started sharing
|
|
1336
1341
|
if (
|
|
1337
|
-
this.selfId !==
|
|
1338
|
-
disposition === FLOOR_ACTION.GRANTED
|
|
1342
|
+
this.selfId !== contentShare.beneficiaryId &&
|
|
1343
|
+
contentShare.disposition === FLOOR_ACTION.GRANTED
|
|
1339
1344
|
) {
|
|
1345
|
+
// CONTENT - sharing content remote
|
|
1340
1346
|
newShareStatus = SHARE_STATUS.REMOTE_SHARE_ACTIVE;
|
|
1341
1347
|
}
|
|
1342
|
-
// LOCAL - check if we started sharing
|
|
1348
|
+
// LOCAL - check if we started sharing content
|
|
1343
1349
|
else if (
|
|
1344
|
-
this.selfId ===
|
|
1345
|
-
disposition === FLOOR_ACTION.GRANTED
|
|
1350
|
+
this.selfId === contentShare.beneficiaryId &&
|
|
1351
|
+
contentShare.disposition === FLOOR_ACTION.GRANTED
|
|
1346
1352
|
) {
|
|
1347
1353
|
if (this.mediaProperties.shareTrack?.readyState === 'ended') {
|
|
1348
1354
|
this.stopShare({
|
|
@@ -1353,13 +1359,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1353
1359
|
});
|
|
1354
1360
|
}
|
|
1355
1361
|
else {
|
|
1362
|
+
// CONTENT - sharing content local
|
|
1356
1363
|
newShareStatus = SHARE_STATUS.LOCAL_SHARE_ACTIVE;
|
|
1357
1364
|
}
|
|
1358
1365
|
}
|
|
1359
|
-
//
|
|
1366
|
+
// If we did not hit the cases above, no one is sharng content, so we check if we are sharing whiteboard
|
|
1367
|
+
// There is no concept of local/remote share for whiteboard
|
|
1368
|
+
// It does not matter who requested to share the whiteboard, everyone gets the same view
|
|
1369
|
+
else if (whiteboardShare.disposition === FLOOR_ACTION.GRANTED) {
|
|
1370
|
+
// WHITEBOARD - sharing whiteboard
|
|
1371
|
+
newShareStatus = SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE;
|
|
1372
|
+
}
|
|
1373
|
+
// or if content share is either released or null and whiteboard share is either released or null, no one is sharing
|
|
1360
1374
|
else if (
|
|
1361
|
-
|
|
1362
|
-
|
|
1375
|
+
(previousContentShare &&
|
|
1376
|
+
(contentShare.disposition === FLOOR_ACTION.RELEASED) || (contentShare.disposition === null)) &&
|
|
1377
|
+
(previousWhiteboardShare &&
|
|
1378
|
+
(whiteboardShare.disposition === FLOOR_ACTION.RELEASED) || (whiteboardShare.disposition === null))
|
|
1363
1379
|
) {
|
|
1364
1380
|
newShareStatus = SHARE_STATUS.NO_SHARE;
|
|
1365
1381
|
}
|
|
@@ -1397,6 +1413,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1397
1413
|
);
|
|
1398
1414
|
break;
|
|
1399
1415
|
|
|
1416
|
+
case SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE:
|
|
1417
|
+
Trigger.trigger(
|
|
1418
|
+
this,
|
|
1419
|
+
{
|
|
1420
|
+
file: 'meeting/index',
|
|
1421
|
+
function: 'stopWhiteboardShare'
|
|
1422
|
+
},
|
|
1423
|
+
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_WHITEBOARD
|
|
1424
|
+
);
|
|
1425
|
+
break;
|
|
1426
|
+
|
|
1400
1427
|
case SHARE_STATUS.NO_SHARE:
|
|
1401
1428
|
// nothing to do
|
|
1402
1429
|
break;
|
|
@@ -1417,13 +1444,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1417
1444
|
},
|
|
1418
1445
|
EVENT_TRIGGERS.MEETING_STARTED_SHARING_REMOTE,
|
|
1419
1446
|
{
|
|
1420
|
-
memberId:
|
|
1447
|
+
memberId: contentShare.beneficiaryId
|
|
1421
1448
|
}
|
|
1422
1449
|
);
|
|
1423
1450
|
};
|
|
1424
1451
|
|
|
1425
1452
|
// if a remote participant is stealing the presentation from us
|
|
1426
|
-
if (this.mediaProperties.mediaDirection?.sendShare) {
|
|
1453
|
+
if (!this.mediaProperties.mediaDirection?.sendShare || oldShareStatus === SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE) {
|
|
1454
|
+
sendStartedSharingRemote();
|
|
1455
|
+
}
|
|
1456
|
+
else {
|
|
1427
1457
|
this.updateShare({
|
|
1428
1458
|
sendShare: false,
|
|
1429
1459
|
receiveShare: this.mediaProperties.mediaDirection.receiveShare
|
|
@@ -1432,9 +1462,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1432
1462
|
sendStartedSharingRemote();
|
|
1433
1463
|
});
|
|
1434
1464
|
}
|
|
1435
|
-
else {
|
|
1436
|
-
sendStartedSharingRemote();
|
|
1437
|
-
}
|
|
1438
1465
|
break;
|
|
1439
1466
|
}
|
|
1440
1467
|
|
|
@@ -1450,6 +1477,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1450
1477
|
Metrics.postEvent({event: eventType.LOCAL_SHARE_FLOOR_GRANTED, meeting: this});
|
|
1451
1478
|
break;
|
|
1452
1479
|
|
|
1480
|
+
case SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE:
|
|
1481
|
+
Trigger.trigger(
|
|
1482
|
+
this,
|
|
1483
|
+
{
|
|
1484
|
+
file: 'meeting/index',
|
|
1485
|
+
function: 'startWhiteboardShare'
|
|
1486
|
+
},
|
|
1487
|
+
EVENT_TRIGGERS.MEETING_STARTED_SHARING_WHITEBOARD,
|
|
1488
|
+
{
|
|
1489
|
+
resourceUrl: whiteboardShare.resourceUrl,
|
|
1490
|
+
memberId: whiteboardShare.beneficiaryId
|
|
1491
|
+
}
|
|
1492
|
+
);
|
|
1493
|
+
Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_FLOOR_GRANTED, meeting: this});
|
|
1494
|
+
break;
|
|
1495
|
+
|
|
1453
1496
|
case SHARE_STATUS.NO_SHARE:
|
|
1454
1497
|
// nothing to do
|
|
1455
1498
|
break;
|
|
@@ -1471,9 +1514,27 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1471
1514
|
},
|
|
1472
1515
|
EVENT_TRIGGERS.MEETING_STARTED_SHARING_REMOTE,
|
|
1473
1516
|
{
|
|
1474
|
-
memberId:
|
|
1517
|
+
memberId: contentShare.beneficiaryId
|
|
1518
|
+
}
|
|
1519
|
+
);
|
|
1520
|
+
this.members.locusMediaSharesUpdate(payload);
|
|
1521
|
+
}
|
|
1522
|
+
else if (newShareStatus === SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE) {
|
|
1523
|
+
// if we got here, then some remote participant has stolen
|
|
1524
|
+
// the presentation from another remote participant
|
|
1525
|
+
Trigger.trigger(
|
|
1526
|
+
this,
|
|
1527
|
+
{
|
|
1528
|
+
file: 'meeting/index',
|
|
1529
|
+
function: 'startWhiteboardShare'
|
|
1530
|
+
},
|
|
1531
|
+
EVENT_TRIGGERS.MEETING_STARTED_SHARING_WHITEBOARD,
|
|
1532
|
+
{
|
|
1533
|
+
resourceUrl: whiteboardShare.resourceUrl,
|
|
1534
|
+
memberId: whiteboardShare.beneficiaryId
|
|
1475
1535
|
}
|
|
1476
1536
|
);
|
|
1537
|
+
Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_FLOOR_GRANTED, meeting: this});
|
|
1477
1538
|
this.members.locusMediaSharesUpdate(payload);
|
|
1478
1539
|
}
|
|
1479
1540
|
});
|
|
@@ -4491,6 +4552,105 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4491
4552
|
});
|
|
4492
4553
|
}
|
|
4493
4554
|
|
|
4555
|
+
/**
|
|
4556
|
+
* Start sharing whiteboard given channelUrl
|
|
4557
|
+
* @param {string} channelUrl whiteboard url
|
|
4558
|
+
* @param {String} resourceToken token created by authorize media injector
|
|
4559
|
+
* @returns {Promise}
|
|
4560
|
+
* @public
|
|
4561
|
+
* @memberof Meeting
|
|
4562
|
+
*/
|
|
4563
|
+
startWhiteboardShare(channelUrl, resourceToken) {
|
|
4564
|
+
const whiteboard = this.locusInfo.mediaShares.find((element) => element.name === 'whiteboard');
|
|
4565
|
+
|
|
4566
|
+
if (!channelUrl) {
|
|
4567
|
+
return Promise.reject(new ParameterError('Cannot share without channelUrl.'));
|
|
4568
|
+
}
|
|
4569
|
+
|
|
4570
|
+
if (whiteboard) {
|
|
4571
|
+
Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_INITIATED, meeting: this});
|
|
4572
|
+
|
|
4573
|
+
const body = {
|
|
4574
|
+
disposition: FLOOR_ACTION.GRANTED,
|
|
4575
|
+
personUrl: this.locusInfo.self.url,
|
|
4576
|
+
deviceUrl: this.deviceUrl,
|
|
4577
|
+
uri: whiteboard.url,
|
|
4578
|
+
resourceUrl: channelUrl
|
|
4579
|
+
};
|
|
4580
|
+
|
|
4581
|
+
if (resourceToken) {
|
|
4582
|
+
body.resourceToken = resourceToken;
|
|
4583
|
+
}
|
|
4584
|
+
|
|
4585
|
+
return this.meetingRequest.changeMeetingFloor(body)
|
|
4586
|
+
.then(() => {
|
|
4587
|
+
this.isSharing = false;
|
|
4588
|
+
|
|
4589
|
+
return Promise.resolve();
|
|
4590
|
+
})
|
|
4591
|
+
.catch((error) => {
|
|
4592
|
+
LoggerProxy.logger.error('Meeting:index#startWhiteboardShare --> Error ', error);
|
|
4593
|
+
|
|
4594
|
+
Metrics.sendOperationalMetric(
|
|
4595
|
+
METRICS_OPERATIONAL_MEASURES.MEETING_START_WHITEBOARD_SHARE_FAILURE,
|
|
4596
|
+
{
|
|
4597
|
+
correlation_id: this.correlationId,
|
|
4598
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
4599
|
+
reason: error.message,
|
|
4600
|
+
stack: error.stack,
|
|
4601
|
+
board: {channelUrl}
|
|
4602
|
+
}
|
|
4603
|
+
);
|
|
4604
|
+
|
|
4605
|
+
return Promise.reject(error);
|
|
4606
|
+
});
|
|
4607
|
+
}
|
|
4608
|
+
|
|
4609
|
+
return Promise.reject(new ParameterError('Cannot share without whiteboard.'));
|
|
4610
|
+
}
|
|
4611
|
+
|
|
4612
|
+
/**
|
|
4613
|
+
* Stop sharing whiteboard given channelUrl
|
|
4614
|
+
* @param {string} channelUrl whiteboard url
|
|
4615
|
+
* @returns {Promise}
|
|
4616
|
+
* @public
|
|
4617
|
+
* @memberof Meeting
|
|
4618
|
+
*/
|
|
4619
|
+
stopWhiteboardShare(channelUrl) {
|
|
4620
|
+
const whiteboard = this.locusInfo.mediaShares.find((element) => element.name === 'whiteboard');
|
|
4621
|
+
|
|
4622
|
+
if (whiteboard) {
|
|
4623
|
+
Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_STOPPED, meeting: this});
|
|
4624
|
+
|
|
4625
|
+
return this.meetingRequest.changeMeetingFloor({
|
|
4626
|
+
disposition: FLOOR_ACTION.RELEASED,
|
|
4627
|
+
personUrl: this.locusInfo.self.url,
|
|
4628
|
+
deviceUrl: this.deviceUrl,
|
|
4629
|
+
uri: whiteboard.url
|
|
4630
|
+
})
|
|
4631
|
+
.catch((error) => {
|
|
4632
|
+
LoggerProxy.logger.error('Meeting:index#stopWhiteboardShare --> Error ', error);
|
|
4633
|
+
|
|
4634
|
+
Metrics.sendOperationalMetric(
|
|
4635
|
+
METRICS_OPERATIONAL_MEASURES.STOP_WHITEBOARD_SHARE_FAILURE,
|
|
4636
|
+
{
|
|
4637
|
+
correlation_id: this.correlationId,
|
|
4638
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
4639
|
+
reason: error.message,
|
|
4640
|
+
stack: error.stack,
|
|
4641
|
+
board: {channelUrl}
|
|
4642
|
+
}
|
|
4643
|
+
);
|
|
4644
|
+
|
|
4645
|
+
return Promise.reject(error);
|
|
4646
|
+
})
|
|
4647
|
+
.finally(() => {
|
|
4648
|
+
});
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
return Promise.reject(new ParameterError('Cannot stop share without whiteboard.'));
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4494
4654
|
/**
|
|
4495
4655
|
* Start sharing content with server
|
|
4496
4656
|
* @returns {Promise} see #meetingRequest.changeMeetingFloor
|
|
@@ -4564,7 +4724,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4564
4724
|
Metrics.postEvent({event: eventType.SHARE_STOPPED, meeting: this});
|
|
4565
4725
|
Media.stopTracks(this.mediaProperties.shareTrack);
|
|
4566
4726
|
|
|
4567
|
-
if (
|
|
4727
|
+
if (content.floor.beneficiary.id !== this.selfId) {
|
|
4568
4728
|
// remote participant started sharing and caused our sharing to stop, we don't want to send any floor action request in that case
|
|
4569
4729
|
this.isSharing = false;
|
|
4570
4730
|
|
package/src/meeting/request.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import uuid from 'uuid';
|
|
2
2
|
import {debounce} from 'lodash';
|
|
3
3
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
4
|
-
import {
|
|
5
|
-
deviceType
|
|
6
|
-
} from '@webex/common';
|
|
4
|
+
import {deviceType} from '@webex/common';
|
|
7
5
|
|
|
8
6
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
9
7
|
import {
|
|
@@ -51,7 +49,19 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
51
49
|
*/
|
|
52
50
|
async joinMeeting(options) {
|
|
53
51
|
const {
|
|
54
|
-
asResourceOccupant,
|
|
52
|
+
asResourceOccupant,
|
|
53
|
+
sipUri,
|
|
54
|
+
meetingNumber,
|
|
55
|
+
deviceUrl,
|
|
56
|
+
locusUrl,
|
|
57
|
+
resourceId,
|
|
58
|
+
correlationId,
|
|
59
|
+
ensureConversation,
|
|
60
|
+
moderator,
|
|
61
|
+
pin,
|
|
62
|
+
moveToResource,
|
|
63
|
+
roapMessage,
|
|
64
|
+
preferTranscoding
|
|
55
65
|
} = options;
|
|
56
66
|
|
|
57
67
|
LoggerProxy.logger.info(
|
|
@@ -95,29 +105,16 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
95
105
|
if (locusUrl) {
|
|
96
106
|
url = `${locusUrl}/${PARTICIPANT}`;
|
|
97
107
|
}
|
|
98
|
-
else if (meetingNumber) {
|
|
108
|
+
else if (sipUri || meetingNumber) {
|
|
99
109
|
try {
|
|
100
110
|
await this.webex.internal.services.waitForCatalog('postauth');
|
|
101
111
|
url = `${this.webex.internal.services.get('locus')}/${LOCI}/${CALL}`;
|
|
102
112
|
body.invitee = {
|
|
103
|
-
address: `wbxmn:${meetingNumber}`
|
|
113
|
+
address: sipUri || `wbxmn:${meetingNumber}`
|
|
104
114
|
};
|
|
105
115
|
}
|
|
106
116
|
catch (e) {
|
|
107
|
-
LoggerProxy.logger.error(`Meeting:request#joinMeeting
|
|
108
|
-
throw (e);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else if (sipUri) {
|
|
112
|
-
try {
|
|
113
|
-
await this.webex.internal.services.waitForCatalog('postauth');
|
|
114
|
-
url = `${this.webex.internal.services.get('locus')}/${LOCI}/${CALL}`;
|
|
115
|
-
body.invitee = {
|
|
116
|
-
address: sipUri
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
catch (e) {
|
|
120
|
-
LoggerProxy.logger.error(`Meeting:request#joinMeeting sipUrl --> ${e}`);
|
|
117
|
+
LoggerProxy.logger.error(`Meeting:request#joinMeeting ${sipUri ? 'sipUri' : 'meetingNumber'} --> ${e}`);
|
|
121
118
|
throw (e);
|
|
122
119
|
}
|
|
123
120
|
}
|
|
@@ -154,7 +151,10 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
154
151
|
* @private
|
|
155
152
|
*/
|
|
156
153
|
dialIn({
|
|
157
|
-
locusUrl,
|
|
154
|
+
locusUrl,
|
|
155
|
+
dialInUrl,
|
|
156
|
+
clientUrl,
|
|
157
|
+
correlationId
|
|
158
158
|
}) {
|
|
159
159
|
LoggerProxy.logger.info(
|
|
160
160
|
'Meeting:request#dialIn --> Provisioning a dial in device',
|
|
@@ -195,7 +195,11 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
195
195
|
* @private
|
|
196
196
|
*/
|
|
197
197
|
dialOut({
|
|
198
|
-
locusUrl,
|
|
198
|
+
locusUrl,
|
|
199
|
+
dialOutUrl,
|
|
200
|
+
phoneNumber,
|
|
201
|
+
clientUrl,
|
|
202
|
+
correlationId
|
|
199
203
|
}) {
|
|
200
204
|
LoggerProxy.logger.info(
|
|
201
205
|
'Meeting:request#dialOut --> Provisioning a dial out device',
|
|
@@ -294,7 +298,10 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
294
298
|
* @private
|
|
295
299
|
*/
|
|
296
300
|
disconnectPhoneAudio({
|
|
297
|
-
locusUrl,
|
|
301
|
+
locusUrl,
|
|
302
|
+
phoneUrl,
|
|
303
|
+
correlationId,
|
|
304
|
+
selfId
|
|
298
305
|
}) {
|
|
299
306
|
LoggerProxy.logger.info(
|
|
300
307
|
`Meeting:request#disconnectPhoneAudio --> request phone ${phoneUrl} to leave`,
|
|
@@ -334,7 +341,11 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
334
341
|
* @returns {Promise}
|
|
335
342
|
*/
|
|
336
343
|
leaveMeeting({
|
|
337
|
-
locusUrl,
|
|
344
|
+
locusUrl,
|
|
345
|
+
selfId,
|
|
346
|
+
deviceUrl: url,
|
|
347
|
+
resourceId,
|
|
348
|
+
correlationId
|
|
338
349
|
}) {
|
|
339
350
|
LoggerProxy.logger.info(
|
|
340
351
|
'Meeting:request#leaveMeeting --> Leaving a meeting',
|
|
@@ -512,13 +523,19 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
512
523
|
};
|
|
513
524
|
}
|
|
514
525
|
|
|
526
|
+
const body = {
|
|
527
|
+
floor: floorReq,
|
|
528
|
+
resourceUrl: options.resourceUrl
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
if (options?.resourceToken) {
|
|
532
|
+
body.resourceToken = options?.resourceToken;
|
|
533
|
+
}
|
|
534
|
+
|
|
515
535
|
return this.request({
|
|
516
536
|
uri: options.uri,
|
|
517
537
|
method: HTTP_VERBS.PUT,
|
|
518
|
-
body
|
|
519
|
-
floor: floorReq,
|
|
520
|
-
resourceUrl: options.resourceUrl
|
|
521
|
-
}
|
|
538
|
+
body
|
|
522
539
|
});
|
|
523
540
|
}
|
|
524
541
|
|
|
@@ -559,7 +576,11 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
559
576
|
* @returns {Promise}
|
|
560
577
|
*/
|
|
561
578
|
changeVideoLayout({
|
|
562
|
-
locusUrl,
|
|
579
|
+
locusUrl,
|
|
580
|
+
deviceUrl,
|
|
581
|
+
layoutType,
|
|
582
|
+
main,
|
|
583
|
+
content
|
|
563
584
|
}) {
|
|
564
585
|
// send main/content renderInfo only if both width and height are specified
|
|
565
586
|
if (main && (!main.width || !main.height)) {
|
|
@@ -108,7 +108,10 @@ export default class MeetingInfo {
|
|
|
108
108
|
* @memberof MeetingInfo
|
|
109
109
|
*/
|
|
110
110
|
fetchMeetingInfo(destination, type = null) {
|
|
111
|
-
return this.fetchInfoOptions(
|
|
111
|
+
return this.fetchInfoOptions(
|
|
112
|
+
MeetingInfoUtil.extractDestination(destination, type),
|
|
113
|
+
type
|
|
114
|
+
).then((options) =>
|
|
112
115
|
// fetch meeting info
|
|
113
116
|
this.requestFetchInfo(options).catch((error) => {
|
|
114
117
|
// if it failed the first time as meeting link
|
package/src/meeting-info/util.js
CHANGED
|
@@ -35,6 +35,19 @@ import {
|
|
|
35
35
|
|
|
36
36
|
const MeetingInfoUtil = {};
|
|
37
37
|
|
|
38
|
+
MeetingInfoUtil.extractDestination = (destination, type) => {
|
|
39
|
+
let dest = destination;
|
|
40
|
+
|
|
41
|
+
if (type === _LOCUS_ID_) {
|
|
42
|
+
if (!(destination && destination.url)) {
|
|
43
|
+
throw new ParameterError('You cannot create a meeting by locus without a locus.url defined');
|
|
44
|
+
}
|
|
45
|
+
dest = destination.url;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return dest;
|
|
49
|
+
};
|
|
50
|
+
|
|
38
51
|
MeetingInfoUtil.getParsedUrl = (link) => {
|
|
39
52
|
try {
|
|
40
53
|
let parsedUrl = url.parse(link);
|
package/src/meetings/index.js
CHANGED
|
@@ -116,15 +116,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
116
116
|
*/
|
|
117
117
|
constructor(...args) {
|
|
118
118
|
super(...args);
|
|
119
|
-
/**
|
|
120
|
-
* The MeetingInfo object to interact with server
|
|
121
|
-
* @instance
|
|
122
|
-
* @type {Object}
|
|
123
|
-
* @private
|
|
124
|
-
* @memberof Meetings
|
|
125
|
-
*/
|
|
126
119
|
|
|
127
|
-
this.meetingInfo = null;
|
|
128
120
|
/**
|
|
129
121
|
* The Meetings request to interact with server
|
|
130
122
|
* @instance
|
|
@@ -381,6 +373,15 @@ export default class Meetings extends WebexPlugin {
|
|
|
381
373
|
LoggerConfig.set(this.config.logging);
|
|
382
374
|
LoggerProxy.set(this.webex.logger);
|
|
383
375
|
|
|
376
|
+
/**
|
|
377
|
+
* The MeetingInfo object to interact with server
|
|
378
|
+
* @instance
|
|
379
|
+
* @type {Object}
|
|
380
|
+
* @private
|
|
381
|
+
* @memberof Meetings
|
|
382
|
+
*/
|
|
383
|
+
this.meetingInfo = this.config.experimental.enableUnifiedMeetings ? new MeetingInfoV2(this.webex) : new MeetingInfo(this.webex);
|
|
384
|
+
|
|
384
385
|
Trigger.trigger(
|
|
385
386
|
this,
|
|
386
387
|
{
|
|
@@ -407,8 +408,6 @@ export default class Meetings extends WebexPlugin {
|
|
|
407
408
|
return Promise.reject(new Error('SDK cannot authorize'));
|
|
408
409
|
}
|
|
409
410
|
|
|
410
|
-
this.meetingInfo = this.config.experimental.enableUnifiedMeetings ? new MeetingInfoV2(this.webex) : new MeetingInfo(this.webex);
|
|
411
|
-
|
|
412
411
|
|
|
413
412
|
if (this.registered) {
|
|
414
413
|
LoggerProxy.logger.info('Meetings:index#register --> INFO, Meetings plugin already registered');
|
|
@@ -725,7 +724,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
725
724
|
this.meetingCollection.set(meeting);
|
|
726
725
|
|
|
727
726
|
try {
|
|
728
|
-
const info = await this.meetingInfo.fetchMeetingInfo(
|
|
727
|
+
const info = await this.meetingInfo.fetchMeetingInfo(destination, type);
|
|
729
728
|
|
|
730
729
|
meeting.parseMeetingInfo(info);
|
|
731
730
|
meeting.meetingInfo = info ? info.body : null;
|
package/src/meetings/util.js
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
CORRELATION_ID,
|
|
9
9
|
EVENT_TRIGGERS
|
|
10
10
|
} from '../constants';
|
|
11
|
-
import ParameterError from '../common/errors/parameter';
|
|
12
11
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
13
12
|
import Trigger from '../common/events/trigger-proxy';
|
|
14
13
|
|
|
@@ -32,19 +31,6 @@ import Trigger from '../common/events/trigger-proxy';
|
|
|
32
31
|
|
|
33
32
|
const MeetingsUtil = {};
|
|
34
33
|
|
|
35
|
-
MeetingsUtil.extractDestination = (destination, type) => {
|
|
36
|
-
let dest = destination;
|
|
37
|
-
|
|
38
|
-
if (type === _LOCUS_ID_) {
|
|
39
|
-
if (!(destination && destination.url)) {
|
|
40
|
-
throw new ParameterError('You cannot create a meeting by locus without a locus.url defined');
|
|
41
|
-
}
|
|
42
|
-
dest = destination.url;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return dest;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
34
|
MeetingsUtil.getMeetingAddedType = (type) => (type === _LOCUS_ID_ ? _INCOMING_ : _CREATED_);
|
|
49
35
|
|
|
50
36
|
MeetingsUtil.handleRoapMercury = (envelope, meetingCollection) => {
|