@wazo/sdk 0.37.2 → 0.37.6

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 (99) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +84 -22
  3. package/esm/__tests__/web-rtc-client.test.js +156 -55
  4. package/esm/api/call-logd.js +10 -22
  5. package/esm/api/calld.js +3 -0
  6. package/esm/api/confd.js +71 -0
  7. package/esm/api-client.js +84 -22
  8. package/esm/checker/Checker.js +160 -55
  9. package/esm/checker/checks/aor.js +84 -22
  10. package/esm/checker/checks/api.js +84 -22
  11. package/esm/checker/checks/index.js +160 -55
  12. package/esm/checker/checks/wazo-websocket.js +4 -0
  13. package/esm/checker/checks/webrtc-transport.js +156 -55
  14. package/esm/checker/checks/webrtc.js +156 -55
  15. package/esm/domain/AdHocAPIConference.js +84 -22
  16. package/esm/domain/CallLog.js +10 -22
  17. package/esm/domain/Features.js +84 -22
  18. package/esm/domain/Meeting.js +71 -0
  19. package/esm/domain/Phone/CTIPhone.js +84 -22
  20. package/esm/domain/Phone/WebRTCPhone.js +22 -8
  21. package/esm/domain/__tests__/CallLog.test.js +10 -22
  22. package/esm/index.js +726 -371
  23. package/esm/lib/WazoSessionDescriptionHandler.js +17 -9
  24. package/esm/service/CallApi.js +84 -22
  25. package/esm/service/getApiClient.js +84 -22
  26. package/esm/simple/Auth.js +717 -363
  27. package/esm/simple/Configuration.js +717 -363
  28. package/esm/simple/Directory.js +84 -22
  29. package/esm/simple/Phone.js +709 -355
  30. package/esm/simple/Websocket.js +6 -0
  31. package/esm/simple/index.js +719 -365
  32. package/esm/simple/room/LocalParticipant.js +689 -335
  33. package/esm/simple/room/Participant.js +689 -335
  34. package/esm/simple/room/RemoteParticipant.js +689 -335
  35. package/esm/simple/room/Room.js +689 -335
  36. package/esm/simple/room/SipRoom.js +13001 -0
  37. package/esm/simple/room/Stream.js +719 -365
  38. package/esm/simple/room/__tests__/RemoteParticipant.test.js +4130 -3774
  39. package/esm/simple/utils.js +719 -365
  40. package/esm/web-rtc-client.js +156 -55
  41. package/esm/websocket-client.js +5 -1
  42. package/lib/__tests__/api-client.test.js +84 -22
  43. package/lib/__tests__/web-rtc-client.test.js +156 -55
  44. package/lib/api/call-logd.js +10 -22
  45. package/lib/api/calld.js +3 -0
  46. package/lib/api/confd.js +71 -0
  47. package/lib/api-client.js +84 -22
  48. package/lib/checker/Checker.js +160 -55
  49. package/lib/checker/checks/aor.js +84 -22
  50. package/lib/checker/checks/api.js +84 -22
  51. package/lib/checker/checks/index.js +160 -55
  52. package/lib/checker/checks/wazo-websocket.js +4 -0
  53. package/lib/checker/checks/webrtc-transport.js +156 -55
  54. package/lib/checker/checks/webrtc.js +156 -55
  55. package/lib/domain/AdHocAPIConference.js +84 -22
  56. package/lib/domain/CallLog.js +10 -22
  57. package/lib/domain/Features.js +84 -22
  58. package/lib/domain/Meeting.js +73 -0
  59. package/lib/domain/Phone/CTIPhone.js +84 -22
  60. package/lib/domain/Phone/WebRTCPhone.js +22 -8
  61. package/lib/domain/__tests__/CallLog.test.js +10 -22
  62. package/lib/index.js +726 -371
  63. package/lib/lib/WazoSessionDescriptionHandler.js +17 -9
  64. package/lib/service/CallApi.js +84 -22
  65. package/lib/service/getApiClient.js +84 -22
  66. package/lib/simple/Auth.js +717 -363
  67. package/lib/simple/Configuration.js +717 -363
  68. package/lib/simple/Directory.js +84 -22
  69. package/lib/simple/Phone.js +709 -355
  70. package/lib/simple/Websocket.js +6 -0
  71. package/lib/simple/index.js +719 -365
  72. package/lib/simple/room/LocalParticipant.js +689 -335
  73. package/lib/simple/room/Participant.js +689 -335
  74. package/lib/simple/room/RemoteParticipant.js +689 -335
  75. package/lib/simple/room/Room.js +689 -335
  76. package/lib/simple/room/SipRoom.js +13011 -0
  77. package/lib/simple/room/Stream.js +719 -365
  78. package/lib/simple/room/__tests__/RemoteParticipant.test.js +4131 -3775
  79. package/lib/simple/utils.js +719 -365
  80. package/lib/web-rtc-client.js +156 -55
  81. package/lib/websocket-client.js +6 -0
  82. package/package.json +1 -1
  83. package/src/api/calld.js +3 -0
  84. package/src/api/confd.js +13 -0
  85. package/src/domain/CallLog.js +10 -22
  86. package/src/domain/Meeting.js +59 -0
  87. package/src/domain/Phone/WebRTCPhone.js +22 -8
  88. package/src/index.js +2 -0
  89. package/src/lib/WazoSessionDescriptionHandler.js +17 -9
  90. package/src/simple/Phone.js +13 -4
  91. package/src/simple/index.js +4 -0
  92. package/src/simple/room/Participant.js +7 -0
  93. package/src/simple/room/Room.js +158 -79
  94. package/src/simple/room/SipRoom.js +147 -0
  95. package/src/simple/room/Stream.js +1 -3
  96. package/src/simple/room/__tests__/RemoteParticipant.test.js +3 -2
  97. package/src/types/WebSocketMessage.js +21 -0
  98. package/src/web-rtc-client.js +55 -24
  99. package/src/websocket-client.js +4 -0
package/esm/index.js CHANGED
@@ -358,7 +358,7 @@ var IssueReporter$1 = new IssueReporter();
358
358
 
359
359
  const methods = ['head', 'get', 'post', 'put', 'delete'];
360
360
 
361
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
361
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
362
362
 
363
363
  // Use a function here to be able to mock it in tests
364
364
  const realFetch = () => {
@@ -497,7 +497,7 @@ class ApiRequester {
497
497
  };
498
498
 
499
499
  if (this.refreshTokenPromise) {
500
- logger$b.info('A token is already refreshing, waiting ...', { url });
500
+ logger$c.info('A token is already refreshing, waiting ...', { url });
501
501
  await this.refreshTokenPromise;
502
502
  }
503
503
 
@@ -517,7 +517,7 @@ class ApiRequester {
517
517
  return promise.then(async (err ) => {
518
518
  // Check if the token is still valid
519
519
  if (firstCall && this._checkTokenExpired(response, err)) {
520
- logger$b.warn('token expired', { error: err.reason });
520
+ logger$c.warn('token expired', { error: err.reason });
521
521
  // Replay the call after refreshing the token
522
522
  return this._replayWithNewToken(err, path, method, body, headers, parse);
523
523
  }
@@ -527,7 +527,7 @@ class ApiRequester {
527
527
  : exceptionClass.fromResponse(err, response.status);
528
528
 
529
529
  if (this.shouldLogErrors) {
530
- logger$b.error('API error', error);
530
+ logger$c.error('API error', error);
531
531
  }
532
532
 
533
533
  throw error;
@@ -537,7 +537,7 @@ class ApiRequester {
537
537
  return newParse(response, isJson);
538
538
  }).catch(error => {
539
539
  if (this.shouldLogErrors) {
540
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
540
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
541
541
  }
542
542
 
543
543
  throw error;
@@ -565,13 +565,13 @@ class ApiRequester {
565
565
  ) {
566
566
  const isTokenNotFound = this._isTokenNotFound(err);
567
567
  let newPath = path;
568
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
568
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
569
569
 
570
570
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
571
571
 
572
572
  return this.refreshTokenPromise.then(() => {
573
573
  this.refreshTokenPromise = null;
574
- logger$b.info('token refreshed', { isTokenNotFound });
574
+ logger$c.info('token refreshed', { isTokenNotFound });
575
575
  if (isTokenNotFound) {
576
576
  const pathParts = path.split('/');
577
577
  pathParts.pop();
@@ -2513,6 +2513,65 @@ class ExternalApp {
2513
2513
  }
2514
2514
  }
2515
2515
 
2516
+ //
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+ class Meeting {
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+ static parse(plain ) {
2540
+ return new Meeting({
2541
+ guestSipAuthorization: plain.guest_sip_authorization,
2542
+ hostname: plain.hostname,
2543
+ name: plain.name,
2544
+ ownerUuids: plain.owner_uuids,
2545
+ port: plain.port,
2546
+ uuid: plain.uuid,
2547
+ number: plain.number,
2548
+ });
2549
+ }
2550
+
2551
+ static newFrom(meeting ) {
2552
+ return newFrom(meeting, Meeting);
2553
+ }
2554
+
2555
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2556
+ this.guestSipAuthorization = guestSipAuthorization;
2557
+ this.hostname = hostname;
2558
+ this.name = name;
2559
+ this.ownerUuids = ownerUuids;
2560
+ this.port = port;
2561
+ this.uuid = uuid;
2562
+ this.number = number;
2563
+
2564
+ // Useful to compare instead of instanceof with minified code
2565
+ this.type = 'Meeting';
2566
+ }
2567
+
2568
+ getGuestSipCredentials() {
2569
+ // eslint-disable-next-line no-undef
2570
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2571
+ return { username, secret };
2572
+ }
2573
+ }
2574
+
2516
2575
  /* */
2517
2576
 
2518
2577
  var confdMethods = (client , baseUrl ) => ({
@@ -2577,6 +2636,18 @@ var confdMethods = (client , baseUrl ) => ({
2577
2636
  return null;
2578
2637
  }
2579
2638
  },
2639
+
2640
+ createMyMeeting: (name ) =>
2641
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2642
+
2643
+ deleteMyMeeting: (meetingUuid ) =>
2644
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2645
+
2646
+ getMeeting: (meetingUuid ) =>
2647
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2648
+
2649
+ guestGetMeeting: (meetingUuid ) =>
2650
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2580
2651
  });
2581
2652
 
2582
2653
  //
@@ -3519,7 +3590,11 @@ class CallLog {
3519
3590
  answered: plain.answered,
3520
3591
  callDirection: plain.call_direction,
3521
3592
  destination: {
3522
- extension: plain.requested_extension || plain.destination_extension,
3593
+ // @TEMP: Temporarily assuming empty numbers are meetings
3594
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3595
+ extension: plain.requested_extension
3596
+ || plain.destination_extension
3597
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3523
3598
  name: plain.requested_name || plain.destination_name || '',
3524
3599
  },
3525
3600
  source: {
@@ -3535,27 +3610,11 @@ class CallLog {
3535
3610
  }
3536
3611
 
3537
3612
  static parseNew(plain , session ) {
3538
- return new CallLog({
3539
- answer: plain.answer ? moment(plain.answer).toDate() : null,
3540
- answered: plain.answered,
3541
- callDirection: plain.call_direction,
3542
- destination: {
3543
- extension: plain.requested_extension || plain.destination_extension,
3544
- name: plain.requested_name || plain.destination_name || '',
3545
- },
3546
- source: {
3547
- extension: plain.source_extension,
3548
- name: plain.source_name,
3549
- },
3550
- id: plain.id,
3551
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3552
- start: moment(plain.start).toDate(),
3553
- end: plain.end ? moment(plain.end).toDate() : null,
3554
- recordings: Recording.parseMany(plain.recordings),
3555
- // @TODO: FIXME add verification declined vs missed call
3556
- newMissedCall: session
3557
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3558
- });
3613
+ const callLog = CallLog.parse(plain);
3614
+ // @TODO: FIXME add verification declined vs missed call
3615
+ callLog.newMissedCall = session
3616
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3617
+ return callLog;
3559
3618
  }
3560
3619
 
3561
3620
  static newFrom(profile ) {
@@ -3903,7 +3962,7 @@ const TRANSFER_FLOW_BLIND = 'blind';
3903
3962
 
3904
3963
  // const MINIMUM_WAZO_ENGINE_VERSION_FOR_CTI_HOLD = '20.11';
3905
3964
 
3906
- const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3965
+ const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3907
3966
 
3908
3967
  class CTIPhone extends Emitter {
3909
3968
 
@@ -3916,7 +3975,7 @@ class CTIPhone extends Emitter {
3916
3975
 
3917
3976
  constructor(session , isMobile = false, callbackAllLines = false) {
3918
3977
  super();
3919
- logger$a.info('CTI Phone created');
3978
+ logger$b.info('CTI Phone created');
3920
3979
  this.session = session;
3921
3980
  this.isMobile = isMobile;
3922
3981
  this.callbackAllLines = callbackAllLines;
@@ -3977,7 +4036,7 @@ class CTIPhone extends Emitter {
3977
4036
  }
3978
4037
 
3979
4038
  async makeCall(number , line ) {
3980
- logger$a.info('make CTI call', { number });
4039
+ logger$b.info('make CTI call', { number });
3981
4040
 
3982
4041
  if (!number) {
3983
4042
  return null;
@@ -4000,7 +4059,7 @@ class CTIPhone extends Emitter {
4000
4059
  if (!callSession) {
4001
4060
  return Promise.resolve(null);
4002
4061
  }
4003
- logger$a.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
4062
+ logger$b.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
4004
4063
 
4005
4064
  if (!this.currentCall) {
4006
4065
  this.currentCall = callSession.call;
@@ -4013,7 +4072,7 @@ class CTIPhone extends Emitter {
4013
4072
  if (!callSession) {
4014
4073
  return;
4015
4074
  }
4016
- logger$a.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
4075
+ logger$b.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
4017
4076
 
4018
4077
  this.currentCall = undefined;
4019
4078
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -4023,7 +4082,7 @@ class CTIPhone extends Emitter {
4023
4082
  if (!callSession) {
4024
4083
  return Promise.resolve(false);
4025
4084
  }
4026
- logger$a.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4085
+ logger$b.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4027
4086
 
4028
4087
  try {
4029
4088
  await CallApi.cancelCall(callSession);
@@ -4034,7 +4093,7 @@ class CTIPhone extends Emitter {
4034
4093
  this.eventEmitter.emit('onCallEnded', callSession);
4035
4094
  return true;
4036
4095
  } catch (e) {
4037
- logger$a.error('hangup CTI call, error', e);
4096
+ logger$b.error('hangup CTI call, error', e);
4038
4097
 
4039
4098
  this.eventEmitter.emit('onCallFailed', callSession);
4040
4099
  return false;
@@ -4047,7 +4106,7 @@ class CTIPhone extends Emitter {
4047
4106
  if (!callSession) {
4048
4107
  return;
4049
4108
  }
4050
- logger$a.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4109
+ logger$b.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4051
4110
 
4052
4111
  await CallApi.cancelCall(callSession);
4053
4112
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -4057,7 +4116,7 @@ class CTIPhone extends Emitter {
4057
4116
  if (!callSession) {
4058
4117
  return;
4059
4118
  }
4060
- logger$a.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4119
+ logger$b.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4061
4120
 
4062
4121
  await CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_BLIND);
4063
4122
  }
@@ -4068,19 +4127,19 @@ class CTIPhone extends Emitter {
4068
4127
  if (!callSession) {
4069
4128
  return;
4070
4129
  }
4071
- logger$a.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4130
+ logger$b.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4072
4131
 
4073
4132
  return CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_ATTENDED);
4074
4133
  }
4075
4134
 
4076
4135
  async cancelCTIIndirectTransfer(transferId ) {
4077
- logger$a.info('cancel CTI transfer', { transferId });
4136
+ logger$b.info('cancel CTI transfer', { transferId });
4078
4137
 
4079
4138
  return CallApi.cancelCallTransfer(transferId);
4080
4139
  }
4081
4140
 
4082
4141
  async confirmCTIIndirectTransfer(transferId ) {
4083
- logger$a.info('confirm CTI transfer', { transferId });
4142
+ logger$b.info('confirm CTI transfer', { transferId });
4084
4143
 
4085
4144
  return CallApi.confirmCallTransfer(transferId);
4086
4145
  }
@@ -4089,19 +4148,19 @@ class CTIPhone extends Emitter {
4089
4148
  if (!callSession) {
4090
4149
  return;
4091
4150
  }
4092
- logger$a.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4151
+ logger$b.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4093
4152
 
4094
4153
  return CallApi.sendDTMF(callSession.callId, digits);
4095
4154
  }
4096
4155
 
4097
4156
  onConnectionMade() {
4098
- logger$a.info('on CTI connection made');
4157
+ logger$b.info('on CTI connection made');
4099
4158
 
4100
4159
  this.eventEmitter.emit('onCallAccepted');
4101
4160
  }
4102
4161
 
4103
4162
  async close() {
4104
- logger$a.info('CTI close');
4163
+ logger$b.info('CTI close');
4105
4164
 
4106
4165
  return Promise.resolve();
4107
4166
  }
@@ -4110,7 +4169,7 @@ class CTIPhone extends Emitter {
4110
4169
  if (!callSession) {
4111
4170
  return;
4112
4171
  }
4113
- logger$a.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4172
+ logger$b.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4114
4173
 
4115
4174
  return CallApi.hold(callSession.callId);
4116
4175
  }
@@ -4119,7 +4178,7 @@ class CTIPhone extends Emitter {
4119
4178
  if (!callSession) {
4120
4179
  return;
4121
4180
  }
4122
- logger$a.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4181
+ logger$b.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4123
4182
 
4124
4183
  return CallApi.resume(callSession.callId);
4125
4184
  }
@@ -4128,7 +4187,7 @@ class CTIPhone extends Emitter {
4128
4187
  if (!callSession) {
4129
4188
  return;
4130
4189
  }
4131
- logger$a.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4190
+ logger$b.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4132
4191
 
4133
4192
  return CallApi.mute(callSession.callId);
4134
4193
  }
@@ -4137,7 +4196,7 @@ class CTIPhone extends Emitter {
4137
4196
  if (!callSession) {
4138
4197
  return;
4139
4198
  }
4140
- logger$a.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4199
+ logger$b.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4141
4200
 
4142
4201
  return CallApi.unmute(callSession.callId);
4143
4202
  }
@@ -4783,6 +4842,9 @@ var calldMethods = (client , baseUrl ) => ({
4783
4842
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4784
4843
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4785
4844
 
4845
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4846
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4847
+
4786
4848
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4787
4849
 
4788
4850
  mute: (callId ) =>
@@ -5136,7 +5198,7 @@ const AGENTD_VERSION = '1.0';
5136
5198
  const WEBHOOKD_VERSION = '1.0';
5137
5199
  const AMID_VERSION = '1.0';
5138
5200
 
5139
- const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5201
+ const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5140
5202
 
5141
5203
  class ApiClient {
5142
5204
 
@@ -5188,12 +5250,12 @@ class ApiClient {
5188
5250
  }
5189
5251
 
5190
5252
  async forceRefreshToken() {
5191
- logger$9.info('forcing refresh token, calling callback');
5253
+ logger$a.info('forcing refresh token, calling callback');
5192
5254
  return this.refreshTokenCallback();
5193
5255
  }
5194
5256
 
5195
5257
  async refreshTokenCallback() {
5196
- logger$9.info('refresh token callback called', {
5258
+ logger$a.info('refresh token callback called', {
5197
5259
  refreshToken: this.refreshToken,
5198
5260
  refreshBackend: this.refreshBackend,
5199
5261
  refreshExpiration: this.refreshExpiration,
@@ -5211,7 +5273,7 @@ class ApiClient {
5211
5273
  this.isMobile,
5212
5274
  );
5213
5275
 
5214
- logger$9.info('token refreshed', { token: session.token });
5276
+ logger$a.info('token refreshed', { token: session.token });
5215
5277
 
5216
5278
  if (this.onRefreshToken) {
5217
5279
  this.onRefreshToken(session.token, session);
@@ -5426,7 +5488,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5426
5488
  .then(() => {
5427
5489
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5428
5490
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5429
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5491
+ if (this.peerConnection.addTransceiver) {
5492
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5493
+ }
5430
5494
  }
5431
5495
  })
5432
5496
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5453,12 +5517,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5453
5517
  };
5454
5518
  })
5455
5519
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5456
- .then((sessionDescription) => {
5457
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5458
- this.localMediaStreamConstraints = options.constraints;
5459
-
5460
- return sessionDescription;
5461
- })
5462
5520
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5463
5521
  .catch((error) => {
5464
5522
  wazoLogger.error('error when creating media', error);
@@ -5653,6 +5711,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5653
5711
 
5654
5712
  // set the transceiver direction to the answer direction
5655
5713
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5714
+ if (transceiver.stopped) {
5715
+ return;
5716
+ }
5656
5717
  if (transceiver.direction /* guarding, but should always be true */) {
5657
5718
  const { receiver } = transceiver;
5658
5719
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -5697,10 +5758,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5697
5758
  if (kind !== 'audio' && kind !== 'video') {
5698
5759
  throw new Error(`Unknown new track kind ${kind}.`);
5699
5760
  }
5700
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5761
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
5762
+ otherSender.track && otherSender.track.kind === kind);
5701
5763
 
5702
5764
  // Do not reuse sender video tracks in SFU
5703
5765
  if (sender && (!sfu || newTrack.kind === 'audio')) {
5766
+ if (sender.track) {
5767
+ // eslint-disable-next-line no-param-reassign
5768
+ newTrack.enabled = sender.track.enabled;
5769
+ }
5704
5770
  trackUpdates.push(
5705
5771
  new Promise((resolve) => {
5706
5772
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5734,7 +5800,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5734
5800
  // Review: could make streamless tracks a configurable option?
5735
5801
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
5736
5802
  try {
5737
- pc.addTrack(newTrack, localStream);
5803
+ if (pc.addTrack) {
5804
+ pc.addTrack(newTrack, localStream);
5805
+ } else {
5806
+ pc.addStream(localStream);
5807
+ }
5738
5808
  } catch (error) {
5739
5809
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
5740
5810
  throw error;
@@ -5870,7 +5940,7 @@ const DEFAULT_ICE_TIMEOUT = 3000;
5870
5940
  const SEND_STATS_DELAY = 5000;
5871
5941
 
5872
5942
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
5873
- const logger$8 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
5943
+ const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
5874
5944
  const statsLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-stats') : console;
5875
5945
 
5876
5946
  // events
@@ -5916,6 +5986,7 @@ const MAX_REGISTER_TRIES = 10;
5916
5986
 
5917
5987
 
5918
5988
 
5989
+
5919
5990
 
5920
5991
 
5921
5992
 
@@ -5942,6 +6013,7 @@ class WebRTCClient extends Emitter {
5942
6013
 
5943
6014
 
5944
6015
 
6016
+
5945
6017
 
5946
6018
  // sugar
5947
6019
 
@@ -5980,6 +6052,8 @@ class WebRTCClient extends Emitter {
5980
6052
  super();
5981
6053
  this.uaConfigOverrides = uaConfigOverrides;
5982
6054
  this.config = config;
6055
+ this.skipRegister = config.skipRegister;
6056
+
5983
6057
  this._buildConfig(config, session).then((newConfig ) => {
5984
6058
  this.config = newConfig;
5985
6059
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -6035,13 +6109,13 @@ class WebRTCClient extends Emitter {
6035
6109
 
6036
6110
  createUserAgent(configOverrides ) {
6037
6111
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
6038
- logger$8.info('sdk webrtc, creating UA', { webRTCConfiguration });
6112
+ logger$9.info('sdk webrtc, creating UA', { webRTCConfiguration });
6039
6113
 
6040
6114
  webRTCConfiguration.delegate = {
6041
6115
  onConnect: this.onConnect.bind(this),
6042
6116
  onDisconnect: this.onDisconnect.bind(this),
6043
6117
  onInvite: (invitation ) => {
6044
- logger$8.info('sdk webrtc on invite', {
6118
+ logger$9.info('sdk webrtc on invite', {
6045
6119
  method: 'delegate.onInvite',
6046
6120
  id: invitation.id,
6047
6121
  remoteURI: invitation.remoteURI,
@@ -6084,7 +6158,7 @@ class WebRTCClient extends Emitter {
6084
6158
  }
6085
6159
 
6086
6160
  onConnect() {
6087
- logger$8.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6161
+ logger$9.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6088
6162
  this.eventEmitter.emit(CONNECTED);
6089
6163
  if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
6090
6164
  this.registerer.waitingToggle(false);
@@ -6093,7 +6167,7 @@ class WebRTCClient extends Emitter {
6093
6167
  }
6094
6168
 
6095
6169
  async onDisconnect(error ) {
6096
- logger$8.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6170
+ logger$9.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6097
6171
  this.connectionPromise = null;
6098
6172
  // The UA will attempt to reconnect automatically when an error occurred
6099
6173
  this.eventEmitter.emit(DISCONNECTED, error);
@@ -6107,40 +6181,48 @@ class WebRTCClient extends Emitter {
6107
6181
  }
6108
6182
 
6109
6183
  register(tries = 0) {
6110
- logger$8.info('sdk webrtc registering...', {
6184
+ const logInfo = {
6111
6185
  userAgent: !!this.userAgent,
6112
6186
  registered: this.isRegistered(),
6113
6187
  connectionPromise: !!this.connectionPromise,
6114
6188
  registerer: !!this.registerer,
6115
6189
  waiting: this.registerer && this.registerer.waiting,
6116
6190
  tries,
6117
- });
6191
+ skipRegister: this.skipRegister,
6192
+ };
6193
+
6194
+ if (this.skipRegister) {
6195
+ logger$9.info('sdk webrtc skip register...', logInfo);
6196
+ return Promise.resolve();
6197
+ }
6198
+
6199
+ logger$9.info('sdk webrtc registering...', logInfo);
6118
6200
 
6119
6201
  if (!this.userAgent) {
6120
- logger$8.info('sdk webrtc recreating User Agent');
6202
+ logger$9.info('sdk webrtc recreating User Agent');
6121
6203
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6122
6204
  }
6123
6205
  if (!this.userAgent || this.isRegistered()) {
6124
- logger$8.info('sdk webrtc registering aborted, already registered or no UA can be created');
6206
+ logger$9.info('sdk webrtc registering aborted, already registered or no UA can be created');
6125
6207
  return Promise.resolve();
6126
6208
  }
6127
6209
 
6128
6210
  if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
6129
- logger$8.info('sdk webrtc registering aborted due to a registration in progress.');
6211
+ logger$9.info('sdk webrtc registering aborted due to a registration in progress.');
6130
6212
  return Promise.resolve();
6131
6213
  }
6132
6214
 
6133
6215
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6134
6216
 
6135
6217
  const onRegisterFailed = () => {
6136
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6218
+ logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6137
6219
  this.connectionPromise = null;
6138
6220
  if (this.registerer && this.registerer.waiting) {
6139
6221
  this.registerer.waitingToggle(false);
6140
6222
  }
6141
6223
 
6142
6224
  if (tries <= MAX_REGISTER_TRIES) {
6143
- logger$8.info('sdk webrtc registering, retrying...', { tries });
6225
+ logger$9.info('sdk webrtc registering, retrying...', { tries });
6144
6226
  setTimeout(() => this.register(tries + 1), 300);
6145
6227
  }
6146
6228
  };
@@ -6149,18 +6231,18 @@ class WebRTCClient extends Emitter {
6149
6231
  // Avoid race condition with the close method called just before register and setting userAgent to null
6150
6232
  // during the resolution of the primise.
6151
6233
  if (!this.userAgent) {
6152
- logger$8.info('sdk webrtc recreating User Agent after connection');
6234
+ logger$9.info('sdk webrtc recreating User Agent after connection');
6153
6235
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6154
6236
  }
6155
6237
 
6156
- logger$8.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6238
+ logger$9.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6157
6239
  this.registerer = new Registerer(this.userAgent, registerOptions);
6158
6240
  this.connectionPromise = null;
6159
6241
  this._monkeyPatchRegisterer(this.registerer);
6160
6242
 
6161
6243
  // Bind registerer events
6162
6244
  this.registerer.stateChange.addListener(newState => {
6163
- logger$8.info('sdk webrtc registering, state changed', { newState });
6245
+ logger$9.info('sdk webrtc registering, state changed', { newState });
6164
6246
 
6165
6247
  if (newState === RegistererState.Registered && this.registerer
6166
6248
  && this.registerer.state === RegistererState.Registered) {
@@ -6173,7 +6255,7 @@ class WebRTCClient extends Emitter {
6173
6255
  const options = {
6174
6256
  requestDelegate: {
6175
6257
  onReject: response => {
6176
- logger$8.error('sdk webrtc registering, rejected', { response });
6258
+ logger$9.error('sdk webrtc registering, rejected', { response });
6177
6259
 
6178
6260
  onRegisterFailed();
6179
6261
  },
@@ -6181,13 +6263,13 @@ class WebRTCClient extends Emitter {
6181
6263
  };
6182
6264
 
6183
6265
  return this.registerer.register(options).catch((e) => {
6184
- logger$8.error('sdk webrtc registering, error', e);
6266
+ logger$9.error('sdk webrtc registering, error', e);
6185
6267
 
6186
6268
  this.eventEmitter.emit(REGISTRATION_FAILED);
6187
6269
  return e;
6188
6270
  });
6189
6271
  }).catch(error => {
6190
- logger$8.error('sdk webrtc registering, transport error', error);
6272
+ logger$9.error('sdk webrtc registering, transport error', error);
6191
6273
  onRegisterFailed();
6192
6274
  });
6193
6275
  }
@@ -6216,21 +6298,21 @@ class WebRTCClient extends Emitter {
6216
6298
  }
6217
6299
 
6218
6300
  unregister() {
6219
- logger$8.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6301
+ logger$9.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6220
6302
  if (!this.registerer) {
6221
6303
  return Promise.resolve();
6222
6304
  }
6223
6305
 
6224
6306
  try {
6225
6307
  return this.registerer.unregister().then(() => {
6226
- logger$8.info('sdk webrtc unregistered');
6308
+ logger$9.info('sdk webrtc unregistered');
6227
6309
  this._cleanupRegister();
6228
6310
  }).catch(e => {
6229
- logger$8.error('sdk webrtc unregistering, promise error', e);
6311
+ logger$9.error('sdk webrtc unregistering, promise error', e);
6230
6312
  this._cleanupRegister();
6231
6313
  });
6232
6314
  } catch (e) {
6233
- logger$8.error('sdk webrtc unregistering, error', e);
6315
+ logger$9.error('sdk webrtc unregistering, error', e);
6234
6316
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
6235
6317
  // error when the registerer is in a bad state
6236
6318
  this._cleanupRegister();
@@ -6238,7 +6320,7 @@ class WebRTCClient extends Emitter {
6238
6320
  }
6239
6321
 
6240
6322
  stop() {
6241
- logger$8.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6323
+ logger$9.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6242
6324
  if (!this.userAgent) {
6243
6325
  return Promise.resolve();
6244
6326
  }
@@ -6246,12 +6328,12 @@ class WebRTCClient extends Emitter {
6246
6328
  return this.userAgent.stop().then(() => {
6247
6329
  return this._cleanupRegister();
6248
6330
  }).catch(e => {
6249
- logger$8.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6331
+ logger$9.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6250
6332
  });
6251
6333
  }
6252
6334
 
6253
6335
  call(number , enableVideo , audioOnly = false, conference = false) {
6254
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6336
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6255
6337
  const inviterOptions = {
6256
6338
  sessionDescriptionHandlerOptionsReInvite: {
6257
6339
  conference,
@@ -6280,7 +6362,7 @@ class WebRTCClient extends Emitter {
6280
6362
  this._onAccepted(session, response.session, true);
6281
6363
  },
6282
6364
  onReject: (response ) => {
6283
- logger$8.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6365
+ logger$9.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6284
6366
  this._stopSendingStats(session);
6285
6367
 
6286
6368
  this.eventEmitter.emit(REJECTED, session, response);
@@ -6302,11 +6384,11 @@ class WebRTCClient extends Emitter {
6302
6384
  }
6303
6385
 
6304
6386
  answer(session , enableVideo ) {
6305
- logger$8.info('sdk webrtc answer call', { id: session.id, enableVideo });
6387
+ logger$9.info('sdk webrtc answer call', { id: session.id, enableVideo });
6306
6388
 
6307
6389
  if (!session || !session.accept) {
6308
6390
  const error = 'No session to answer, or not an invitation';
6309
- logger$8.warn(error);
6391
+ logger$9.warn(error);
6310
6392
  return Promise.reject(new Error(error));
6311
6393
  }
6312
6394
  const options = {
@@ -6316,15 +6398,15 @@ class WebRTCClient extends Emitter {
6316
6398
  return session.accept(options).then(() => {
6317
6399
  if (session.isCanceled) {
6318
6400
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
6319
- logger$8.error(message, { id: session.id });
6401
+ logger$9.error(message, { id: session.id });
6320
6402
  this.onCallEnded(session);
6321
6403
 
6322
6404
  throw new CanceledCallError(message);
6323
6405
  }
6324
- logger$8.info('sdk webrtc answer, accepted.');
6406
+ logger$9.info('sdk webrtc answer, accepted.');
6325
6407
  this._onAccepted(session);
6326
6408
  }).catch(e => {
6327
- logger$8.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6409
+ logger$9.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6328
6410
 
6329
6411
  throw e;
6330
6412
  });
@@ -6332,7 +6414,7 @@ class WebRTCClient extends Emitter {
6332
6414
 
6333
6415
  hangup(session ) {
6334
6416
  const { state, id } = session;
6335
- logger$8.info('sdk webrtc hangup call', { id, state });
6417
+ logger$9.info('sdk webrtc hangup call', { id, state });
6336
6418
 
6337
6419
  try {
6338
6420
  this._stopSendingStats(session);
@@ -6361,24 +6443,24 @@ class WebRTCClient extends Emitter {
6361
6443
 
6362
6444
  return bye();
6363
6445
  } catch (error) {
6364
- logger$8.warn('sdk webrtc hangup, error', error);
6446
+ logger$9.warn('sdk webrtc hangup, error', error);
6365
6447
  }
6366
6448
 
6367
6449
  return null;
6368
6450
  }
6369
6451
 
6370
6452
  reject(session ) {
6371
- logger$8.info('sdk webrtc reject call', { id: session.id });
6453
+ logger$9.info('sdk webrtc reject call', { id: session.id });
6372
6454
 
6373
6455
  try {
6374
6456
  return session.reject ? session.reject() : session.cancel();
6375
6457
  } catch (e) {
6376
- logger$8.warn('Error when rejecting call', e.message, e.stack);
6458
+ logger$9.warn('Error when rejecting call', e.message, e.stack);
6377
6459
  }
6378
6460
  }
6379
6461
 
6380
6462
  async close() {
6381
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6463
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6382
6464
  this._cleanupMedia();
6383
6465
  this.connectionPromise = null;
6384
6466
 
@@ -6409,7 +6491,7 @@ class WebRTCClient extends Emitter {
6409
6491
  // eg: "INVITE not rejectable in state Completed"
6410
6492
  }
6411
6493
  this.userAgent = null;
6412
- logger$8.info('sdk webrtc client closed');
6494
+ logger$9.info('sdk webrtc client closed');
6413
6495
  }
6414
6496
 
6415
6497
  getNumber(session ) {
@@ -6422,13 +6504,13 @@ class WebRTCClient extends Emitter {
6422
6504
  }
6423
6505
 
6424
6506
  mute(session ) {
6425
- logger$8.info('sdk webrtc mute', { id: session.id });
6507
+ logger$9.info('sdk webrtc mute', { id: session.id });
6426
6508
 
6427
6509
  this._toggleAudio(session, true);
6428
6510
  }
6429
6511
 
6430
6512
  unmute(session ) {
6431
- logger$8.info('sdk webrtc unmute', { id: session.id });
6513
+ logger$9.info('sdk webrtc unmute', { id: session.id });
6432
6514
 
6433
6515
  this._toggleAudio(session, false);
6434
6516
  }
@@ -6445,12 +6527,18 @@ class WebRTCClient extends Emitter {
6445
6527
  }
6446
6528
 
6447
6529
  if (pc.getSenders) {
6530
+ if (!pc.getSenders().length) {
6531
+ return false;
6532
+ }
6448
6533
  pc.getSenders().forEach(sender => {
6449
6534
  if (sender && sender.track && sender.track.kind === 'audio') {
6450
6535
  muted = muted && !sender.track.enabled;
6451
6536
  }
6452
6537
  });
6453
6538
  } else {
6539
+ if (!pc.getLocalStreams().length) {
6540
+ return false;
6541
+ }
6454
6542
  pc.getLocalStreams().forEach(stream => {
6455
6543
  stream.getAudioTracks().forEach(track => {
6456
6544
  muted = muted && !track.enabled;
@@ -6462,20 +6550,20 @@ class WebRTCClient extends Emitter {
6462
6550
  }
6463
6551
 
6464
6552
  toggleCameraOn(session ) {
6465
- logger$8.info('sdk webrtc toggle camera on', { id: session.id });
6553
+ logger$9.info('sdk webrtc toggle camera on', { id: session.id });
6466
6554
 
6467
6555
  this._toggleVideo(session, false);
6468
6556
  }
6469
6557
 
6470
6558
  toggleCameraOff(session ) {
6471
- logger$8.info('sdk webrtc toggle camera off', { id: session.id });
6559
+ logger$9.info('sdk webrtc toggle camera off', { id: session.id });
6472
6560
 
6473
6561
  this._toggleVideo(session, true);
6474
6562
  }
6475
6563
 
6476
6564
  hold(session , isConference = false) {
6477
6565
  const sessionId = this.getSipSessionId(session);
6478
- logger$8.info('sdk webrtc hold', {
6566
+ logger$9.info('sdk webrtc hold', {
6479
6567
  sessionId,
6480
6568
  keys: Object.keys(this.heldSessions),
6481
6569
  pendingReinvite: !!session.pendingReinvite,
@@ -6509,6 +6597,8 @@ class WebRTCClient extends Emitter {
6509
6597
  }
6510
6598
  options.sessionDescriptionHandlerOptions = {
6511
6599
  constraints: options.constraints,
6600
+ hold: true,
6601
+ conference: isConference,
6512
6602
  };
6513
6603
 
6514
6604
  // Send re-INVITE
@@ -6518,7 +6608,7 @@ class WebRTCClient extends Emitter {
6518
6608
  unhold(session , isConference = false) {
6519
6609
  const sessionId = this.getSipSessionId(session);
6520
6610
 
6521
- logger$8.info('sdk webrtc unhold', {
6611
+ logger$9.info('sdk webrtc unhold', {
6522
6612
  sessionId,
6523
6613
  keys: Object.keys(this.heldSessions),
6524
6614
  pendingReinvite: !!session.pendingReinvite,
@@ -6551,6 +6641,8 @@ class WebRTCClient extends Emitter {
6551
6641
  }
6552
6642
  options.sessionDescriptionHandlerOptions = {
6553
6643
  constraints: options.constraints,
6644
+ hold: false,
6645
+ conference: isConference,
6554
6646
  };
6555
6647
 
6556
6648
  // Send re-INVITE
@@ -6609,7 +6701,7 @@ class WebRTCClient extends Emitter {
6609
6701
  return;
6610
6702
  }
6611
6703
 
6612
- logger$8.info('send WebRTC message', { sipId: sipSession.id, contentType });
6704
+ logger$9.info('send WebRTC message', { sipId: sipSession.id, contentType });
6613
6705
 
6614
6706
  try {
6615
6707
  sipSession.message({
@@ -6734,7 +6826,8 @@ class WebRTCClient extends Emitter {
6734
6826
  }
6735
6827
  const sdh = session.sessionDescriptionHandler;
6736
6828
  const pc = sdh.peerConnection;
6737
- const localStream = this.getLocalStream(this.getSipSessionId(session));
6829
+ const sessionId = this.getSipSessionId(session);
6830
+ const localStream = this.getLocalStream(sessionId);
6738
6831
 
6739
6832
  // Release old video stream
6740
6833
  if (localStream) {
@@ -6760,11 +6853,8 @@ class WebRTCClient extends Emitter {
6760
6853
 
6761
6854
  // let's update the local stream
6762
6855
  this.eventEmitter.emit('onVideoInputChange', stream);
6763
- try {
6764
- await sdh.setLocalMediaStream(stream);
6765
- } catch (_) {
6766
- // Nothing to do
6767
- }
6856
+ this.setLocalMediaStream(sessionId, stream);
6857
+
6768
6858
  return stream;
6769
6859
  });
6770
6860
  }
@@ -6976,7 +7066,7 @@ class WebRTCClient extends Emitter {
6976
7066
  }
6977
7067
 
6978
7068
  startHeartbeat() {
6979
- logger$8.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7069
+ logger$9.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
6980
7070
  if (!this.userAgent) {
6981
7071
  this.heartbeat.stop();
6982
7072
  return;
@@ -6989,7 +7079,7 @@ class WebRTCClient extends Emitter {
6989
7079
  }
6990
7080
 
6991
7081
  stopHeartbeat() {
6992
- logger$8.info('sdk webrtc stop heartbeat');
7082
+ logger$9.info('sdk webrtc stop heartbeat');
6993
7083
  this.heartbeat.stop();
6994
7084
  }
6995
7085
 
@@ -7009,7 +7099,7 @@ class WebRTCClient extends Emitter {
7009
7099
  }
7010
7100
 
7011
7101
  attemptReconnection() {
7012
- logger$8.info('attempt reconnection', { userAgent: !!this.userAgent });
7102
+ logger$9.info('attempt reconnection', { userAgent: !!this.userAgent });
7013
7103
  if (!this.userAgent) {
7014
7104
  return;
7015
7105
  }
@@ -7066,9 +7156,11 @@ class WebRTCClient extends Emitter {
7066
7156
  remoteStream.removeTrack(track);
7067
7157
  });
7068
7158
 
7069
- pc.getReceivers().forEach(receiver => {
7070
- remoteStream.addTrack(receiver.track);
7071
- });
7159
+ if (pc.getReceivers) {
7160
+ pc.getReceivers().forEach(receiver => {
7161
+ remoteStream.addTrack(receiver.track);
7162
+ });
7163
+ }
7072
7164
  }
7073
7165
 
7074
7166
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -7103,6 +7195,25 @@ class WebRTCClient extends Emitter {
7103
7195
  return sessionId in this.conferences;
7104
7196
  }
7105
7197
 
7198
+ createAudioElementFor(sessionId ) {
7199
+ const audio = document.createElement('audio');
7200
+ audio.setAttribute('id', `audio-${sessionId}`);
7201
+
7202
+ if (audio.setSinkId && this.audioOutputDeviceId) {
7203
+ audio.setSinkId(this.audioOutputDeviceId);
7204
+ }
7205
+
7206
+ if (document.body) {
7207
+ document.body.appendChild(audio);
7208
+ }
7209
+ this.audioElements[sessionId] = audio;
7210
+
7211
+ audio.volume = this.audioOutputVolume;
7212
+ audio.autoplay = true;
7213
+
7214
+ return audio;
7215
+ }
7216
+
7106
7217
  _onTransportError() {
7107
7218
  this.eventEmitter.emit(TRANSPORT_ERROR);
7108
7219
  this.attemptReconnection();
@@ -7112,7 +7223,7 @@ class WebRTCClient extends Emitter {
7112
7223
  const body = message && typeof message === 'object' ? message.data : message;
7113
7224
  if (body && body.indexOf('200 OK') !== -1) {
7114
7225
  if (this.hasHeartbeat()) {
7115
- logger$8.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7226
+ logger$9.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7116
7227
 
7117
7228
  this.heartbeat.onHeartbeat();
7118
7229
  if (this.heartbeatCb) {
@@ -7123,7 +7234,7 @@ class WebRTCClient extends Emitter {
7123
7234
  }
7124
7235
 
7125
7236
  async _onHeartbeatTimeout() {
7126
- logger$8.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7237
+ logger$9.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7127
7238
 
7128
7239
  if (this.heartbeatTimeoutCb) {
7129
7240
  this.heartbeatTimeoutCb();
@@ -7135,7 +7246,7 @@ class WebRTCClient extends Emitter {
7135
7246
  try {
7136
7247
  await this.userAgent.transport.disconnect();
7137
7248
  } catch (e) {
7138
- logger$8.error('Transport disconnection after heartbeat timeout, error', e);
7249
+ logger$9.error('Transport disconnection after heartbeat timeout, error', e);
7139
7250
  }
7140
7251
  }
7141
7252
 
@@ -7168,31 +7279,31 @@ class WebRTCClient extends Emitter {
7168
7279
  }
7169
7280
 
7170
7281
  _connectIfNeeded() {
7171
- logger$8.info('connect if needed, checking', { connected: this.isConnected() });
7282
+ logger$9.info('connect if needed, checking', { connected: this.isConnected() });
7172
7283
  if (!this.userAgent) {
7173
- logger$8.info('need to recreate User Agent');
7284
+ logger$9.info('need to recreate User Agent');
7174
7285
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
7175
7286
  }
7176
7287
 
7177
7288
  if (this.isConnected()) {
7178
- logger$8.info('webrtc sdk, already connected');
7289
+ logger$9.info('webrtc sdk, already connected');
7179
7290
  return Promise.resolve();
7180
7291
  }
7181
7292
 
7182
7293
  if (this.isConnecting()) {
7183
- logger$8.info('webrtc sdk, already connecting...');
7294
+ logger$9.info('webrtc sdk, already connecting...');
7184
7295
 
7185
7296
  this.connectionPromise = this.userAgent.transport.connectPromise;
7186
7297
  return this.connectionPromise;
7187
7298
  }
7188
7299
 
7189
7300
  if (this.connectionPromise) {
7190
- logger$8.info('webrtc sdk, connection promise connecting...');
7301
+ logger$9.info('webrtc sdk, connection promise connecting...');
7191
7302
  // $FlowFixMe
7192
7303
  return this.connectionPromise;
7193
7304
  }
7194
7305
 
7195
- logger$8.info('WebRTC UA needs to connect');
7306
+ logger$9.info('WebRTC UA needs to connect');
7196
7307
 
7197
7308
  // Force UA to reconnect
7198
7309
  if (this.userAgent && this.userAgent.state !== UserAgentState.Stopped) {
@@ -7317,7 +7428,7 @@ class WebRTCClient extends Emitter {
7317
7428
 
7318
7429
  sdh.peerConnectionDelegate = {
7319
7430
  onicecandidateerror: (error ) => {
7320
- logger$8.error('on icecandidate error', {
7431
+ logger$9.error('on icecandidate error', {
7321
7432
  address: error.address,
7322
7433
  port: error.port,
7323
7434
  errorCode: error.errorCode,
@@ -7332,7 +7443,7 @@ class WebRTCClient extends Emitter {
7332
7443
  let hadRemoteVideo = false;
7333
7444
 
7334
7445
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7335
- // Becase when `onInvite` is called we already got the video track
7446
+ // Because when `onInvite` is called we already got the video track
7336
7447
  session.onInviteRequest = (request) => {
7337
7448
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7338
7449
 
@@ -7346,7 +7457,7 @@ class WebRTCClient extends Emitter {
7346
7457
  updatedNumber = session.assertedIdentity.uri.normal.user;
7347
7458
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
7348
7459
  }
7349
- logger$8.info('re-invite received', { updatedCalleeName, updatedNumber });
7460
+ logger$9.info('re-invite received', { updatedCalleeName, updatedNumber });
7350
7461
 
7351
7462
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7352
7463
 
@@ -7367,7 +7478,7 @@ class WebRTCClient extends Emitter {
7367
7478
  }
7368
7479
 
7369
7480
  _onAccepted(session , sessionDialog , withEvent = true) {
7370
- logger$8.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7481
+ logger$9.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7371
7482
 
7372
7483
  this.storeSipSession(session);
7373
7484
 
@@ -7407,20 +7518,10 @@ class WebRTCClient extends Emitter {
7407
7518
  const isConference = this.isConference(sessionId);
7408
7519
 
7409
7520
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7410
- const audio = document.createElement('audio');
7411
- audio.setAttribute('id', `audio-${sessionId}`);
7412
-
7413
- if (audio.setSinkId && this.audioOutputDeviceId) {
7414
- audio.setSinkId(this.audioOutputDeviceId);
7415
- }
7416
-
7417
- if (document.body) {
7418
- document.body.appendChild(audio);
7419
- }
7420
- this.audioElements[sessionId] = audio;
7521
+ this.createAudioElementFor(sessionId);
7421
7522
  }
7422
7523
 
7423
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7524
+ const audioElement = this.audioElements[sessionId];
7424
7525
  const stream = newStream || this.getRemoteStream(sessionId);
7425
7526
 
7426
7527
  if (!this._isWeb() || !stream) {
@@ -7567,10 +7668,10 @@ class WebRTCClient extends Emitter {
7567
7668
 
7568
7669
  _stopSendingStats(session ) {
7569
7670
  const sessionId = this.getSipSessionId(session);
7570
- logger$8.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7671
+ logger$9.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7571
7672
 
7572
7673
  if (sessionId in this.statsIntervals) {
7573
- logger$8.trace('Stop sending stats for call', { sessionId });
7674
+ logger$9.trace('Stop sending stats for call', { sessionId });
7574
7675
  this.statsIntervals[sessionId]();
7575
7676
  delete this.statsIntervals[sessionId];
7576
7677
  }
@@ -7586,7 +7687,7 @@ class WebRTCClient extends Emitter {
7586
7687
  try {
7587
7688
  await this.userAgent.transport.disconnect();
7588
7689
  } catch (e) {
7589
- logger$8.error('WebRTC transport disconnect, error', e);
7690
+ logger$9.error('WebRTC transport disconnect, error', e);
7590
7691
  }
7591
7692
  }
7592
7693
  }
@@ -7647,6 +7748,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
7647
7748
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
7648
7749
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
7649
7750
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
7751
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
7752
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
7650
7753
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
7651
7754
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
7652
7755
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -7688,7 +7791,7 @@ const BLACKLIST_EVENTS = [
7688
7791
  ];
7689
7792
 
7690
7793
  const HEARTBEAT_ENGINE_VERSION = '20.09';
7691
- const logger$7 = IssueReporter$1.loggerFor('wazo-ws');
7794
+ const logger$8 = IssueReporter$1.loggerFor('wazo-ws');
7692
7795
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
7693
7796
 
7694
7797
  class WebSocketClient extends Emitter {
@@ -7737,19 +7840,19 @@ class WebSocketClient extends Emitter {
7737
7840
  }
7738
7841
 
7739
7842
  connect() {
7740
- logger$7.info('connect method started', { host: this.host, token: this.token });
7843
+ logger$8.info('connect method started', { host: this.host, token: this.token });
7741
7844
  this.socket = new ReconnectingWebSocket(this._getUrl.bind(this), [], this.options);
7742
7845
  if (this.options.binaryType) {
7743
7846
  this.socket.binaryType = this.options.binaryType;
7744
7847
  }
7745
7848
 
7746
7849
  this.socket.onopen = () => {
7747
- logger$7.info('on Wazo WS open', { method: 'connect', host: this.host });
7850
+ logger$8.info('on Wazo WS open', { method: 'connect', host: this.host });
7748
7851
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
7749
7852
  };
7750
7853
 
7751
7854
  this.socket.onerror = event => {
7752
- logger$7.error('on Wazo WS error', event.target);
7855
+ logger$8.error('on Wazo WS error', event.target);
7753
7856
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
7754
7857
  };
7755
7858
 
@@ -7779,7 +7882,7 @@ class WebSocketClient extends Emitter {
7779
7882
 
7780
7883
  this.socket.onclose = event => {
7781
7884
  // Can't be converted to JSON (circular structure)
7782
- logger$7.info('on Wazo WS close', {
7885
+ logger$8.info('on Wazo WS close', {
7783
7886
  reason: event.reason,
7784
7887
  code: event.code,
7785
7888
  readyState: event.target.readyState,
@@ -7797,12 +7900,12 @@ class WebSocketClient extends Emitter {
7797
7900
  };
7798
7901
 
7799
7902
  this.socket.onerror = event => {
7800
- logger$7.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
7903
+ logger$8.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
7801
7904
  };
7802
7905
  }
7803
7906
 
7804
7907
  close(force = false) {
7805
- logger$7.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
7908
+ logger$8.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
7806
7909
 
7807
7910
  if (!this.socket) {
7808
7911
  return;
@@ -7820,7 +7923,7 @@ class WebSocketClient extends Emitter {
7820
7923
 
7821
7924
  updateToken(token ) {
7822
7925
  this.token = token;
7823
- logger$7.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
7926
+ logger$8.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
7824
7927
 
7825
7928
  if (this.socket) {
7826
7929
  // If still connected, send the token to the WS
@@ -7838,7 +7941,7 @@ class WebSocketClient extends Emitter {
7838
7941
  }
7839
7942
 
7840
7943
  startHeartbeat() {
7841
- logger$7.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
7944
+ logger$8.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
7842
7945
 
7843
7946
  if (!this.socket) {
7844
7947
  this.heartbeat.stop();
@@ -7852,7 +7955,7 @@ class WebSocketClient extends Emitter {
7852
7955
  }
7853
7956
 
7854
7957
  stopHeartbeat() {
7855
- logger$7.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
7958
+ logger$8.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
7856
7959
 
7857
7960
  this.heartbeat.stop();
7858
7961
  }
@@ -7882,7 +7985,7 @@ class WebSocketClient extends Emitter {
7882
7985
  }
7883
7986
 
7884
7987
  reconnect(reason ) {
7885
- logger$7.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
7988
+ logger$8.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
7886
7989
  if (!this.socket) {
7887
7990
  return;
7888
7991
  }
@@ -7938,7 +8041,7 @@ class WebSocketClient extends Emitter {
7938
8041
  this.close();
7939
8042
  }
7940
8043
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
7941
- logger$7.log('Wazo WS url computed to reconnect', { url });
8044
+ logger$8.log('Wazo WS url computed to reconnect', { url });
7942
8045
 
7943
8046
  return url;
7944
8047
  }
@@ -7946,12 +8049,12 @@ class WebSocketClient extends Emitter {
7946
8049
  _onHeartbeat(message ) {
7947
8050
  if (message.payload === 'pong') {
7948
8051
  this.heartbeat.onHeartbeat();
7949
- logger$7.log('on heartbeat received from Wazo WS');
8052
+ logger$8.log('on heartbeat received from Wazo WS');
7950
8053
  }
7951
8054
  }
7952
8055
 
7953
8056
  async _onHeartbeatTimeout() {
7954
- logger$7.log('heartbeat timed out', { host: this.host, token: this.token });
8057
+ logger$8.log('heartbeat timed out', { host: this.host, token: this.token });
7955
8058
 
7956
8059
  this.close();
7957
8060
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -7993,6 +8096,8 @@ WebSocketClient.eventLists = [
7993
8096
  CHATD_USER_ROOM_CREATED,
7994
8097
  CONFERENCE_USER_PARTICIPANT_JOINED,
7995
8098
  CONFERENCE_USER_PARTICIPANT_LEFT,
8099
+ MEETING_USER_PARTICIPANT_JOINED,
8100
+ MEETING_USER_PARTICIPANT_LEFT,
7996
8101
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
7997
8102
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
7998
8103
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -8063,6 +8168,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
8063
8168
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
8064
8169
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
8065
8170
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
8171
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
8172
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
8066
8173
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
8067
8174
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
8068
8175
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -8557,7 +8664,7 @@ const events = [
8557
8664
  ON_SIGNAL,
8558
8665
  ];
8559
8666
 
8560
- const logger$6 = IssueReporter$1.loggerFor('webrtc-phone');
8667
+ const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
8561
8668
 
8562
8669
  class WebRTCPhone extends Emitter {
8563
8670
 
@@ -8628,7 +8735,7 @@ class WebRTCPhone extends Emitter {
8628
8735
  }).catch(error => {
8629
8736
  // Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
8630
8737
  console.error('register error', error, error.message, error.stack);
8631
- logger$6.error('WebRTC register error', { message: error.message, stack: error.stack });
8738
+ logger$7.error('WebRTC register error', { message: error.message, stack: error.stack });
8632
8739
  });
8633
8740
  }
8634
8741
 
@@ -8643,7 +8750,7 @@ class WebRTCPhone extends Emitter {
8643
8750
  if (!this.client) {
8644
8751
  return;
8645
8752
  }
8646
- logger$6.info('WebRTC phone stop');
8753
+ logger$7.info('WebRTC phone stop');
8647
8754
  this.client.stop();
8648
8755
  }
8649
8756
 
@@ -8658,14 +8765,14 @@ class WebRTCPhone extends Emitter {
8658
8765
  async sendReinvite(callSession , constraints = null, conference = false,
8659
8766
  audioOnly = false) {
8660
8767
  const sipSession = this.findSipSession(callSession);
8661
- logger$6.info('WebRTC phone - send reinvite', {
8768
+ logger$7.info('WebRTC phone - send reinvite', {
8662
8769
  sessionId: sipSession ? sipSession.id : null,
8663
8770
  constraints,
8664
8771
  audioOnly,
8665
8772
  });
8666
8773
 
8667
8774
  if (!sipSession) {
8668
- return null;
8775
+ return false;
8669
8776
  }
8670
8777
 
8671
8778
  // $FlowFixMe
@@ -8675,19 +8782,17 @@ class WebRTCPhone extends Emitter {
8675
8782
  // Downgrade
8676
8783
  if (constraints && !isUpgrade) {
8677
8784
  // No reinvite needed
8678
- return this._downgradeToAudio(callSession);
8785
+ this._downgradeToAudio(callSession);
8786
+ return false;
8679
8787
  }
8680
8788
 
8681
8789
  if (isUpgrade) {
8682
8790
  const shouldReinvite = await this._upgradeToVideo(callSession, constraints, conference);
8683
8791
  if (!shouldReinvite) {
8684
- return;
8792
+ return false;
8685
8793
  }
8686
8794
  }
8687
8795
 
8688
- // Force reinvite in SDH
8689
- sipSession.sessionDescriptionHandler.localMediaStreamConstraints = null;
8690
-
8691
8796
  return this.client.reinvite(sipSession, constraints, conference, audioOnly);
8692
8797
  }
8693
8798
 
@@ -8696,7 +8801,7 @@ class WebRTCPhone extends Emitter {
8696
8801
  }
8697
8802
 
8698
8803
  startHeartbeat() {
8699
- logger$6.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8804
+ logger$7.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8700
8805
  if (!this.client || this.client.hasHeartbeat()) {
8701
8806
  return;
8702
8807
  }
@@ -8705,7 +8810,7 @@ class WebRTCPhone extends Emitter {
8705
8810
  }
8706
8811
 
8707
8812
  stopHeartbeat() {
8708
- logger$6.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8813
+ logger$7.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8709
8814
  if (!this.client) {
8710
8815
  return;
8711
8816
  }
@@ -8722,7 +8827,7 @@ class WebRTCPhone extends Emitter {
8722
8827
  }
8723
8828
 
8724
8829
  reconnect() {
8725
- logger$6.info('WebRTC phone - reconnect', { client: !!this.client });
8830
+ logger$7.info('WebRTC phone - reconnect', { client: !!this.client });
8726
8831
  if (!this.client) {
8727
8832
  return;
8728
8833
  }
@@ -8760,7 +8865,7 @@ class WebRTCPhone extends Emitter {
8760
8865
  _downgradeToAudio(callSession ) {
8761
8866
  const sipSession = this.findSipSession(callSession);
8762
8867
  if (!sipSession) {
8763
- return;
8868
+ return false;
8764
8869
  }
8765
8870
 
8766
8871
  // Release local video stream when downgrading to audio
@@ -8873,7 +8978,7 @@ class WebRTCPhone extends Emitter {
8873
8978
  // Monkey patch to know when canceled with the CANCEL message
8874
8979
  const onCancel = sipSession._onCancel.bind(sipSession);
8875
8980
  sipSession._onCancel = (message ) => {
8876
- logger$6.trace('on sip session canceled', { callId: message.callId });
8981
+ logger$7.trace('on sip session canceled', { callId: message.callId });
8877
8982
 
8878
8983
  onCancel(message);
8879
8984
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
@@ -8898,13 +9003,13 @@ class WebRTCPhone extends Emitter {
8898
9003
  this.audioOutputVolume,
8899
9004
  );
8900
9005
  case SessionState.Terminating:
8901
- logger$6.info('WebRTC phone - call terminating', { sipId: sipSession.id });
9006
+ logger$7.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8902
9007
 
8903
9008
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
8904
9009
 
8905
9010
  break;
8906
9011
  case SessionState.Terminated:
8907
- logger$6.info('WebRTC phone - call terminated', { sipId: sipSession.id });
9012
+ logger$7.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8908
9013
 
8909
9014
  this._onCallTerminated(sipSession);
8910
9015
 
@@ -8940,7 +9045,7 @@ class WebRTCPhone extends Emitter {
8940
9045
  }
8941
9046
 
8942
9047
  async startScreenSharing(constraints , callSession ) {
8943
- logger$6.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
9048
+ logger$7.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8944
9049
 
8945
9050
  const screenShareStream = await this._getStreamFromConstraints(constraints);
8946
9051
  if (!screenShareStream) {
@@ -8962,6 +9067,10 @@ class WebRTCPhone extends Emitter {
8962
9067
  localStream.removeTrack(videoTrack);
8963
9068
  }
8964
9069
 
9070
+ if (localStream) {
9071
+ localStream.addTrack(screenTrack);
9072
+ }
9073
+
8965
9074
  if (sender) {
8966
9075
  sender.replaceTrack(screenTrack);
8967
9076
  }
@@ -8976,7 +9085,8 @@ class WebRTCPhone extends Emitter {
8976
9085
  return;
8977
9086
  }
8978
9087
 
8979
- logger$6.info('WebRTC phone - stop screen sharing');
9088
+ logger$7.info('WebRTC phone - stop screen sharing');
9089
+ let reinvited = false;
8980
9090
 
8981
9091
  try {
8982
9092
  if (this.currentScreenShare.stream) {
@@ -8991,7 +9101,8 @@ class WebRTCPhone extends Emitter {
8991
9101
  // When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
8992
9102
  // We have to downgrade to audio.
8993
9103
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8994
- await this.sendReinvite(targetCallSession, { audio: false, video: screenshareStopped }, conference);
9104
+ const constraints = { audio: false, video: screenshareStopped };
9105
+ reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8995
9106
  }
8996
9107
  } catch (e) {
8997
9108
  console.warn(e);
@@ -9005,6 +9116,8 @@ class WebRTCPhone extends Emitter {
9005
9116
  );
9006
9117
 
9007
9118
  this.currentScreenShare = null;
9119
+
9120
+ return reinvited;
9008
9121
  }
9009
9122
 
9010
9123
  async _getStreamFromConstraints(constraints , conference = false) {
@@ -9042,7 +9155,7 @@ class WebRTCPhone extends Emitter {
9042
9155
  }
9043
9156
 
9044
9157
  _onCallAccepted(sipSession , cameraEnabled ) {
9045
- logger$6.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9158
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9046
9159
 
9047
9160
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9048
9161
  this.currentSipSession = sipSession;
@@ -9060,11 +9173,15 @@ class WebRTCPhone extends Emitter {
9060
9173
  }
9061
9174
 
9062
9175
  changeAudioDevice(id ) {
9063
- logger$6.info('WebRTC phone - change audio device', { deviceId: id });
9176
+ logger$7.info('WebRTC phone - change audio device', { deviceId: id });
9064
9177
  this.audioOutputDeviceId = id;
9065
9178
  this.client.changeAudioOutputDevice(id);
9066
9179
  }
9067
9180
 
9181
+ createAudioElementFor(sessionId ) {
9182
+ return this.client.createAudioElementFor(sessionId);
9183
+ }
9184
+
9068
9185
  changeRingDevice(id ) {
9069
9186
  this.audioRingDeviceId = id;
9070
9187
  }
@@ -9081,25 +9198,25 @@ class WebRTCPhone extends Emitter {
9081
9198
  }
9082
9199
 
9083
9200
  changeAudioInputDevice(id ) {
9084
- logger$6.info('WebRTC phone - changeAudio input device', { deviceId: id });
9201
+ logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
9085
9202
 
9086
9203
  return this.client.changeAudioInputDevice(id, this.currentSipSession);
9087
9204
  }
9088
9205
 
9089
9206
  changeVideoInputDevice(id ) {
9090
- logger$6.info('WebRTC phone - change video input device', { deviceId: id });
9207
+ logger$7.info('WebRTC phone - change video input device', { deviceId: id });
9091
9208
 
9092
9209
  return this.client.changeVideoInputDevice(id, this.currentSipSession);
9093
9210
  }
9094
9211
 
9095
9212
  changeSessionVideoInputDevice(id ) {
9096
- logger$6.info('WebRTC phone - change session video input device', { deviceId: id });
9213
+ logger$7.info('WebRTC phone - change session video input device', { deviceId: id });
9097
9214
 
9098
9215
  return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
9099
9216
  }
9100
9217
 
9101
9218
  _onCallTerminated(sipSession ) {
9102
- logger$6.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9219
+ logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9103
9220
 
9104
9221
  const callSession = this._createCallSession(sipSession);
9105
9222
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
@@ -9133,7 +9250,7 @@ class WebRTCPhone extends Emitter {
9133
9250
  const hasIncomingCallSession = this.hasIncomingCallSession();
9134
9251
 
9135
9252
  // Re-trigger incoming call event for remaining incoming calls
9136
- logger$6.info('WebRTC phone - check to re-trigger incoming call', {
9253
+ logger$7.info('WebRTC phone - check to re-trigger incoming call', {
9137
9254
  sipId: sipSession.id,
9138
9255
  shouldRetrigger,
9139
9256
  hasIncomingCallSession,
@@ -9222,37 +9339,37 @@ class WebRTCPhone extends Emitter {
9222
9339
 
9223
9340
  // Deprecated
9224
9341
  getLocalStreamForCall(callSession ) {
9225
- logger$6.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
9342
+ logger$7.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
9226
9343
 
9227
9344
  return this.getLocalStream(callSession);
9228
9345
  }
9229
9346
 
9230
9347
  // Deprecated
9231
9348
  getRemoteStreamForCall(callSession ) {
9232
- logger$6.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
9349
+ logger$7.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
9233
9350
 
9234
9351
  return this.getRemoteVideoStream(callSession);
9235
9352
  }
9236
9353
 
9237
9354
  getRemoteStreamsForCall(callSession ) {
9238
- logger$6.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
9355
+ logger$7.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
9239
9356
 
9240
9357
  return this.getRemoteStream(callSession);
9241
9358
  }
9242
9359
 
9243
9360
  accept(callSession , cameraEnabled ) {
9244
- logger$6.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
9361
+ logger$7.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
9245
9362
  if (this.currentSipSession) {
9246
9363
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
9247
9364
  }
9248
9365
 
9249
9366
  if (!callSession) {
9250
- logger$6.warn('no CallSession to accept.');
9367
+ logger$7.warn('no CallSession to accept.');
9251
9368
  return Promise.resolve(null);
9252
9369
  }
9253
9370
 
9254
9371
  if (callSession.getId() in this.acceptedSessions) {
9255
- logger$6.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
9372
+ logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
9256
9373
  return Promise.resolve(callSession.sipCallId);
9257
9374
  }
9258
9375
 
@@ -9264,24 +9381,24 @@ class WebRTCPhone extends Emitter {
9264
9381
  const sipSession = this.client.getSipSession(callSession.getId());
9265
9382
  if (sipSession) {
9266
9383
  if (sipSession.state === SessionState.Terminated || sipSession.state === SessionState.Terminating) {
9267
- logger$6.warn('Trying to answer a terminated sipSession.');
9384
+ logger$7.warn('Trying to answer a terminated sipSession.');
9268
9385
 
9269
9386
  return Promise.resolve(null);
9270
9387
  }
9271
9388
 
9272
- logger$6.info('accept call, session found', { sipId: sipSession.id });
9389
+ logger$7.info('accept call, session found', { sipId: sipSession.id });
9273
9390
 
9274
9391
  // $FlowFixMe
9275
9392
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
9276
9393
  return callSession.sipCallId;
9277
9394
  }).catch(e => {
9278
- logger$6.error(e);
9395
+ logger$7.error(e);
9279
9396
  this.endCurrentCall(callSession);
9280
9397
  throw e;
9281
9398
  });
9282
9399
  }
9283
9400
 
9284
- logger$6.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
9401
+ logger$7.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
9285
9402
 
9286
9403
  return Promise.resolve(null);
9287
9404
  }
@@ -9291,7 +9408,7 @@ class WebRTCPhone extends Emitter {
9291
9408
  }
9292
9409
 
9293
9410
  async reject(callSession ) {
9294
- logger$6.info('reject WebRTC called', { id: callSession.getId() });
9411
+ logger$7.info('reject WebRTC called', { id: callSession.getId() });
9295
9412
 
9296
9413
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call rejected locally');
9297
9414
  if (!callSession || callSession.getId() in this.rejectedSessions) {
@@ -9303,14 +9420,14 @@ class WebRTCPhone extends Emitter {
9303
9420
 
9304
9421
  const sipSession = this.findSipSession(callSession);
9305
9422
  if (sipSession) {
9306
- logger$6.info('WebRTC rejecting', { sipId: sipSession.id });
9423
+ logger$7.info('WebRTC rejecting', { sipId: sipSession.id });
9307
9424
 
9308
9425
  this.client.hangup(sipSession);
9309
9426
  }
9310
9427
  }
9311
9428
 
9312
9429
  async ignore(callSession ) {
9313
- logger$6.info('WebRTC ignore', { id: callSession.getId() });
9430
+ logger$7.info('WebRTC ignore', { id: callSession.getId() });
9314
9431
 
9315
9432
  // kill the ring
9316
9433
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'ignoring call');
@@ -9319,7 +9436,7 @@ class WebRTCPhone extends Emitter {
9319
9436
  }
9320
9437
 
9321
9438
  hold(callSession , withEvent = true, isConference = false) {
9322
- logger$6.info('WebRTC hold', { id: callSession.getId() });
9439
+ logger$7.info('WebRTC hold', { id: callSession.getId() });
9323
9440
 
9324
9441
  const sipSession = this.findSipSession(callSession);
9325
9442
 
@@ -9330,7 +9447,7 @@ class WebRTCPhone extends Emitter {
9330
9447
 
9331
9448
  // @Deprecated
9332
9449
  unhold(callSession , withEvent = true, isConference = false) {
9333
- logger$6.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
9450
+ logger$7.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
9334
9451
 
9335
9452
  console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
9336
9453
 
@@ -9345,7 +9462,7 @@ class WebRTCPhone extends Emitter {
9345
9462
  const sipSession = this.findSipSession(callSession);
9346
9463
 
9347
9464
  if (sipSession) {
9348
- logger$6.info('WebRTC atxfer', { sipId: sipSession.id });
9465
+ logger$7.info('WebRTC atxfer', { sipId: sipSession.id });
9349
9466
 
9350
9467
  return this.client.atxfer(sipSession);
9351
9468
  }
@@ -9360,7 +9477,7 @@ class WebRTCPhone extends Emitter {
9360
9477
  if (!sipSession) {
9361
9478
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
9362
9479
  }
9363
- logger$6.info('WebRTC hold sip session', { sipId: sipSession.id });
9480
+ logger$7.info('WebRTC hold sip session', { sipId: sipSession.id });
9364
9481
 
9365
9482
  const promise = this.client.hold(sipSession, isConference);
9366
9483
  if (withEvent) {
@@ -9379,7 +9496,7 @@ class WebRTCPhone extends Emitter {
9379
9496
  if (!sipSession) {
9380
9497
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
9381
9498
  }
9382
- logger$6.info('WebRTC unhold', { sipId: sipSession.id });
9499
+ logger$7.info('WebRTC unhold', { sipId: sipSession.id });
9383
9500
 
9384
9501
  const promise = this.client.unhold(sipSession, isConference);
9385
9502
  if (withEvent) {
@@ -9390,18 +9507,18 @@ class WebRTCPhone extends Emitter {
9390
9507
  }
9391
9508
 
9392
9509
  resume(callSession , isConference = false) {
9393
- logger$6.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
9510
+ logger$7.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
9394
9511
 
9395
9512
  const sipSession = this.findSipSession(callSession);
9396
9513
  if (!sipSession) {
9397
9514
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
9398
9515
  }
9399
9516
 
9400
- logger$6.info('WebRTC resuming', { sipId: sipSession.id });
9517
+ logger$7.info('WebRTC resuming', { sipId: sipSession.id });
9401
9518
 
9402
9519
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9403
9520
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9404
- logger$6.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9521
+ logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9405
9522
  this.holdSipSession(this.currentSipSession, callSession);
9406
9523
  }
9407
9524
 
@@ -9416,14 +9533,14 @@ class WebRTCPhone extends Emitter {
9416
9533
  }
9417
9534
 
9418
9535
  mute(callSession , withEvent = true) {
9419
- logger$6.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
9536
+ logger$7.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
9420
9537
 
9421
9538
  const sipSession = this.findSipSession(callSession);
9422
9539
  if (!sipSession) {
9423
9540
  return;
9424
9541
  }
9425
9542
 
9426
- logger$6.info('WebRTC muting', { sipId: sipSession.id });
9543
+ logger$7.info('WebRTC muting', { sipId: sipSession.id });
9427
9544
  this.client.mute(sipSession);
9428
9545
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: true });
9429
9546
 
@@ -9437,14 +9554,14 @@ class WebRTCPhone extends Emitter {
9437
9554
  }
9438
9555
 
9439
9556
  unmute(callSession , withEvent = true) {
9440
- logger$6.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
9557
+ logger$7.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
9441
9558
 
9442
9559
  const sipSession = this.findSipSession(callSession);
9443
9560
  if (!sipSession) {
9444
9561
  return;
9445
9562
  }
9446
9563
 
9447
- logger$6.info('WebRTC unmuting', { sipId: sipSession.id });
9564
+ logger$7.info('WebRTC unmuting', { sipId: sipSession.id });
9448
9565
  this.client.unmute(sipSession);
9449
9566
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: false });
9450
9567
 
@@ -9471,7 +9588,7 @@ class WebRTCPhone extends Emitter {
9471
9588
  if (!sipSession) {
9472
9589
  return;
9473
9590
  }
9474
- logger$6.info('WebRTC turn camera on', { sipId: sipSession.id });
9591
+ logger$7.info('WebRTC turn camera on', { sipId: sipSession.id });
9475
9592
 
9476
9593
  this.client.toggleCameraOn(sipSession);
9477
9594
 
@@ -9483,7 +9600,7 @@ class WebRTCPhone extends Emitter {
9483
9600
  if (!sipSession) {
9484
9601
  return;
9485
9602
  }
9486
- logger$6.info('WebRTC turn camera off', { sipId: sipSession.id });
9603
+ logger$7.info('WebRTC turn camera off', { sipId: sipSession.id });
9487
9604
 
9488
9605
  this.client.toggleCameraOff(sipSession);
9489
9606
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -9495,7 +9612,7 @@ class WebRTCPhone extends Emitter {
9495
9612
  return;
9496
9613
  }
9497
9614
 
9498
- logger$6.info('WebRTC send key', { sipId: sipSession.id, tone });
9615
+ logger$7.info('WebRTC send key', { sipId: sipSession.id, tone });
9499
9616
  this.client.sendDTMF(sipSession, tone);
9500
9617
  }
9501
9618
 
@@ -9503,7 +9620,7 @@ class WebRTCPhone extends Emitter {
9503
9620
  // @TODO: line is not used here
9504
9621
  async makeCall(number , line , cameraEnabled ,
9505
9622
  audioOnly = false, conference = false) {
9506
- logger$6.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9623
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9507
9624
  if (!number) {
9508
9625
  return Promise.resolve(null);
9509
9626
  }
@@ -9513,7 +9630,7 @@ class WebRTCPhone extends Emitter {
9513
9630
  }
9514
9631
  if (this.currentSipSession) {
9515
9632
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
9516
- logger$6.warn('Unable to hold current session when making another call', e);
9633
+ logger$7.warn('Unable to hold current session when making another call', e);
9517
9634
  });
9518
9635
  }
9519
9636
 
@@ -9523,7 +9640,7 @@ class WebRTCPhone extends Emitter {
9523
9640
  this._bindEvents(sipSession);
9524
9641
  } catch (error) {
9525
9642
  console.warn(error);
9526
- logger$6.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
9643
+ logger$7.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
9527
9644
  return Promise.resolve(null);
9528
9645
  }
9529
9646
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
@@ -9551,7 +9668,7 @@ class WebRTCPhone extends Emitter {
9551
9668
  return;
9552
9669
  }
9553
9670
 
9554
- logger$6.info('WebRTC transfer', { sipId: sipSession.id, target });
9671
+ logger$7.info('WebRTC transfer', { sipId: sipSession.id, target });
9555
9672
 
9556
9673
  this.client.transfer(sipSession, target);
9557
9674
  }
@@ -9560,7 +9677,7 @@ class WebRTCPhone extends Emitter {
9560
9677
  const sipSession = this.client.getSipSession(source.sipCallId);
9561
9678
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
9562
9679
 
9563
- logger$6.info('WebRTC indirect transfer', {
9680
+ logger$7.info('WebRTC indirect transfer', {
9564
9681
  sipId: sipSession ? sipSession.id : null,
9565
9682
  target: sipSessionTarget ? sipSessionTarget.id : null,
9566
9683
  });
@@ -9588,7 +9705,7 @@ class WebRTCPhone extends Emitter {
9588
9705
  return false;
9589
9706
  }
9590
9707
 
9591
- logger$6.info('WebRTC hangup', { sipId: sipSession.id });
9708
+ logger$7.info('WebRTC hangup', { sipId: sipSession.id });
9592
9709
 
9593
9710
  const sipSessionId = this.getSipSessionId(sipSession);
9594
9711
 
@@ -9633,7 +9750,7 @@ class WebRTCPhone extends Emitter {
9633
9750
  }
9634
9751
 
9635
9752
  async close() {
9636
- logger$6.info('WebRTC close');
9753
+ logger$7.info('WebRTC close');
9637
9754
 
9638
9755
  try {
9639
9756
  await Promise.race([
@@ -9641,7 +9758,7 @@ class WebRTCPhone extends Emitter {
9641
9758
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000)),
9642
9759
  ]);
9643
9760
  } catch (e) {
9644
- logger$6.error('WebRTC close, unregister error', e);
9761
+ logger$7.error('WebRTC close, unregister error', e);
9645
9762
  }
9646
9763
 
9647
9764
  this.client.close();
@@ -9659,12 +9776,12 @@ class WebRTCPhone extends Emitter {
9659
9776
  }
9660
9777
 
9661
9778
  enableRinging() {
9662
- logger$6.info('WebRTC enable ringing');
9779
+ logger$7.info('WebRTC enable ringing');
9663
9780
  this.ringingEnabled = true;
9664
9781
  }
9665
9782
 
9666
9783
  disableRinging() {
9667
- logger$6.info('WebRTC disable ringing');
9784
+ logger$7.info('WebRTC disable ringing');
9668
9785
  this.ringingEnabled = false;
9669
9786
  }
9670
9787
 
@@ -9704,7 +9821,7 @@ class WebRTCPhone extends Emitter {
9704
9821
 
9705
9822
  // Deprecated
9706
9823
  getLocalMediaStream(callSession ) {
9707
- logger$6.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9824
+ logger$7.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9708
9825
  return this.getLocalStream(callSession);
9709
9826
  }
9710
9827
 
@@ -9712,6 +9829,10 @@ class WebRTCPhone extends Emitter {
9712
9829
  return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
9713
9830
  }
9714
9831
 
9832
+ hasALocalVideoTrack(callSession ) {
9833
+ return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
9834
+ }
9835
+
9715
9836
  getRemoteStream(callSession ) {
9716
9837
  return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
9717
9838
  }
@@ -9734,7 +9855,7 @@ class WebRTCPhone extends Emitter {
9734
9855
  this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
9735
9856
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
9736
9857
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
9737
- logger$6.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9858
+ logger$7.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9738
9859
 
9739
9860
  const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
9740
9861
  this.incomingSessions.push(callSession.getId());
@@ -9757,7 +9878,7 @@ class WebRTCPhone extends Emitter {
9757
9878
  });
9758
9879
 
9759
9880
  this.client.on(this.client.ON_REINVITE, (...args) => {
9760
- logger$6.info('WebRTC on reinvite', {
9881
+ logger$7.info('WebRTC on reinvite', {
9761
9882
  sessionId: args[0].id,
9762
9883
  inviteId: args[1].id,
9763
9884
  updatedCalleeName: args[2],
@@ -9777,7 +9898,7 @@ class WebRTCPhone extends Emitter {
9777
9898
  });
9778
9899
 
9779
9900
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
9780
- logger$6.info('WebRTC call accepted', { sipId: sipSession.id });
9901
+ logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
9781
9902
 
9782
9903
  this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
9783
9904
 
@@ -9788,17 +9909,17 @@ class WebRTCPhone extends Emitter {
9788
9909
  this.client.on('ended', () => {});
9789
9910
 
9790
9911
  this.client.on(this.client.ON_ERROR, e => {
9791
- logger$6.error('WebRTC error', e);
9912
+ logger$7.error('WebRTC error', e);
9792
9913
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9793
9914
  });
9794
9915
 
9795
9916
  this.client.on(this.client.UNREGISTERED, () => {
9796
- logger$6.info('WebRTC unregistered');
9917
+ logger$7.info('WebRTC unregistered');
9797
9918
  this.eventEmitter.emit(ON_UNREGISTERED);
9798
9919
  });
9799
9920
 
9800
9921
  this.client.on(this.client.REGISTERED, () => {
9801
- logger$6.info('WebRTC registered', {
9922
+ logger$7.info('WebRTC registered', {
9802
9923
  shouldSendReinvite: this.shouldSendReinvite,
9803
9924
  state: this.currentSipSession ? this.currentSipSession.state : null,
9804
9925
  currentSipSession: !!this.currentSipSession,
@@ -9814,19 +9935,19 @@ class WebRTCPhone extends Emitter {
9814
9935
  try {
9815
9936
  this.sendReinvite(this.currentCallSession);
9816
9937
  } catch (e) {
9817
- logger$6.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9938
+ logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9818
9939
  }
9819
9940
  }
9820
9941
  });
9821
9942
 
9822
9943
  this.client.on(this.client.CONNECTED, () => {
9823
- logger$6.info('WebRTC client connected');
9944
+ logger$7.info('WebRTC client connected');
9824
9945
 
9825
9946
  this.stopHeartbeat();
9826
9947
  });
9827
9948
 
9828
9949
  this.client.on(this.client.DISCONNECTED, () => {
9829
- logger$6.info('WebRTC client disconnected');
9950
+ logger$7.info('WebRTC client disconnected');
9830
9951
 
9831
9952
  this.eventEmitter.emit(ON_UNREGISTERED);
9832
9953
 
@@ -10524,7 +10645,7 @@ var checks = [
10524
10645
 
10525
10646
  //
10526
10647
 
10527
- const logger$5 = IssueReporter$1.loggerFor('engine-check');
10648
+ const logger$6 = IssueReporter$1.loggerFor('engine-check');
10528
10649
 
10529
10650
  class Checker {
10530
10651
 
@@ -10542,28 +10663,28 @@ class Checker {
10542
10663
  async check(onCheckBegin = () => {}, onCheckResult = () => {}) {
10543
10664
  await this._addEngineVersion();
10544
10665
 
10545
- logger$5.info('Engine check starting');
10666
+ logger$6.info('Engine check starting');
10546
10667
 
10547
10668
  for (let i = 0; i < this.checks.length; i++) {
10548
10669
  const { name, check } = this.checks[i];
10549
10670
 
10550
- logger$5.info(`Checking ${name} ...`);
10671
+ logger$6.info(`Checking ${name} ...`);
10551
10672
 
10552
10673
  onCheckBegin(name);
10553
10674
  try {
10554
10675
  // eslint-disable-next-line no-await-in-loop
10555
10676
  const result = await check(this.server, this.session, this.externalAppConfig);
10556
- logger$5.info(`Checking ${name} success.`, { result });
10677
+ logger$6.info(`Checking ${name} success.`, { result });
10557
10678
 
10558
10679
  onCheckResult(name, result);
10559
10680
  } catch (e) {
10560
- logger$5.info(`Checking ${name} failure`, { message: e.message });
10681
+ logger$6.info(`Checking ${name} failure`, { message: e.message });
10561
10682
 
10562
10683
  onCheckResult(name, e);
10563
10684
  }
10564
10685
  }
10565
10686
 
10566
- logger$5.info('Engine check done.');
10687
+ logger$6.info('Engine check done.');
10567
10688
  }
10568
10689
 
10569
10690
  addCheck(check ) {
@@ -10657,7 +10778,7 @@ const getCallableNumber = (number , country ) => {
10657
10778
  class InvalidSubscription extends Error {}
10658
10779
  class InvalidAuthorization extends Error {}
10659
10780
 
10660
- const logger$4 = IssueReporter$1.loggerFor('simple-auth');
10781
+ const logger$5 = IssueReporter$1.loggerFor('simple-auth');
10661
10782
 
10662
10783
  class Auth {
10663
10784
 
@@ -10692,7 +10813,7 @@ class Auth {
10692
10813
  setApiClientId(this.clientId);
10693
10814
  setRefreshExpiration(this.expiration);
10694
10815
  setOnRefreshToken((token , session ) => {
10695
- logger$4.info('on refresh token done', { token });
10816
+ logger$5.info('on refresh token done', { token });
10696
10817
  setApiToken(token);
10697
10818
  Wazo.Websocket.updateToken(token);
10698
10819
 
@@ -11091,7 +11212,7 @@ class AdHocAPIConference {
11091
11212
 
11092
11213
  //
11093
11214
 
11094
- const logger$3 = IssueReporter$1.loggerFor('simple-phone');
11215
+ const logger$4 = IssueReporter$1.loggerFor('simple-phone');
11095
11216
  const sipLogger = IssueReporter$1.loggerFor('sip.js');
11096
11217
  const protocolLogger = IssueReporter$1.loggerFor('sip');
11097
11218
 
@@ -11198,7 +11319,7 @@ class Phone extends Emitter {
11198
11319
  async disconnect() {
11199
11320
  if (this.phone) {
11200
11321
  if (this.phone.hasAnActiveCall()) {
11201
- logger$3.info('hangup call on disconnect');
11322
+ logger$4.info('hangup call on disconnect');
11202
11323
  // $FlowFixMe
11203
11324
  await this.phone.hangup();
11204
11325
  }
@@ -11221,13 +11342,13 @@ class Phone extends Emitter {
11221
11342
  }
11222
11343
 
11223
11344
  async hangup(callSession ) {
11224
- logger$3.info('hangup via simple phone', { callId: callSession.getId() });
11345
+ logger$4.info('hangup via simple phone', { callId: callSession.getId() });
11225
11346
 
11226
11347
  return this.phone && this.phone.hangup(callSession);
11227
11348
  }
11228
11349
 
11229
11350
  async accept(callSession , cameraEnabled ) {
11230
- logger$3.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
11351
+ logger$4.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
11231
11352
 
11232
11353
  return this.phone && this.phone.accept(callSession, cameraEnabled);
11233
11354
  }
@@ -11247,13 +11368,18 @@ class Phone extends Emitter {
11247
11368
  return adHocConference.start();
11248
11369
  }
11249
11370
 
11250
- mute(callSession ) {
11251
- this.muteViaAPI(callSession);
11371
+ mute(callSession , withApi = true) {
11372
+ if (withApi) {
11373
+ this.muteViaAPI(callSession);
11374
+ }
11375
+
11252
11376
  return this.phone && this.phone.mute(callSession);
11253
11377
  }
11254
11378
 
11255
- unmute(callSession ) {
11256
- this.unmuteViaAPI(callSession);
11379
+ unmute(callSession , withApi = true) {
11380
+ if (withApi) {
11381
+ this.unmuteViaAPI(callSession);
11382
+ }
11257
11383
 
11258
11384
  return this.phone && this.phone.unmute(callSession);
11259
11385
  }
@@ -11261,7 +11387,7 @@ class Phone extends Emitter {
11261
11387
  muteViaAPI(callSession ) {
11262
11388
  if (callSession && callSession.callId) {
11263
11389
  Wazo.getApiClient().calld.mute(callSession.callId).catch(e => {
11264
- logger$3.error('Mute via API, error', e);
11390
+ logger$4.error('Mute via API, error', e);
11265
11391
  });
11266
11392
  }
11267
11393
  }
@@ -11269,7 +11395,7 @@ class Phone extends Emitter {
11269
11395
  unmuteViaAPI(callSession ) {
11270
11396
  if (callSession && callSession.callId) {
11271
11397
  Wazo.getApiClient().calld.unmute(callSession.callId).catch(e => {
11272
- logger$3.error('Unmute via API, error', e);
11398
+ logger$4.error('Unmute via API, error', e);
11273
11399
  });
11274
11400
  }
11275
11401
  }
@@ -11359,9 +11485,13 @@ class Phone extends Emitter {
11359
11485
  return this.phone && this.phone.hasLocalVideo(callSession);
11360
11486
  }
11361
11487
 
11488
+ hasALocalVideoTrack(callSession ) {
11489
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
11490
+ }
11491
+
11362
11492
  // @Deprecated
11363
11493
  getLocalMediaStream(callSession ) {
11364
- logger$3.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
11494
+ logger$4.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
11365
11495
 
11366
11496
  return this.phone && this.phone.getLocalStream(callSession);
11367
11497
  }
@@ -11380,20 +11510,20 @@ class Phone extends Emitter {
11380
11510
 
11381
11511
  // @Deprecated
11382
11512
  getRemoteStreamForCall(callSession ) {
11383
- logger$3.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
11513
+ logger$4.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
11384
11514
  return this.getRemoteStream(callSession);
11385
11515
  }
11386
11516
 
11387
11517
  // Returns remote streams directly from the peerConnection
11388
11518
  // @Deprecated
11389
11519
  getRemoteStreamsForCall(callSession ) {
11390
- logger$3.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
11520
+ logger$4.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
11391
11521
  return this.getLocalStream(callSession);
11392
11522
  }
11393
11523
 
11394
11524
  // @Deprecated
11395
11525
  getRemoteVideoStreamForCall(callSession ) {
11396
- logger$3.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
11526
+ logger$4.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
11397
11527
 
11398
11528
  return this.getRemoteVideoStream(callSession);
11399
11529
  }
@@ -11474,7 +11604,7 @@ var Phone$1 = global.wazoTelephonyInstance;
11474
11604
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
11475
11605
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
11476
11606
 
11477
- const logger$2 = IssueReporter$1.loggerFor('simple-ws-client');
11607
+ const logger$3 = IssueReporter$1.loggerFor('simple-ws-client');
11478
11608
 
11479
11609
  class Websocket extends Emitter {
11480
11610
 
@@ -11498,7 +11628,7 @@ class Websocket extends Emitter {
11498
11628
  }
11499
11629
 
11500
11630
  open(host , session ) {
11501
- logger$2.info('open simple WebSocket', { host, token: session.token });
11631
+ logger$3.info('open simple WebSocket', { host, token: session.token });
11502
11632
  this.ws = new WebSocketClient(
11503
11633
  {
11504
11634
  host,
@@ -11526,7 +11656,7 @@ class Websocket extends Emitter {
11526
11656
  }
11527
11657
 
11528
11658
  updateToken(token ) {
11529
- logger$2.info('update token via simple Websocket', { token, ws: !!this.ws });
11659
+ logger$3.info('update token via simple Websocket', { token, ws: !!this.ws });
11530
11660
 
11531
11661
  if (!this.ws) {
11532
11662
  return;
@@ -11554,7 +11684,7 @@ var Websocket$1 = global.wazoWebsocketInstance;
11554
11684
 
11555
11685
  //
11556
11686
 
11557
- const logger$1 = IssueReporter$1.loggerFor('room');
11687
+ const logger$2 = IssueReporter$1.loggerFor('room');
11558
11688
 
11559
11689
  class Participant extends Emitter {
11560
11690
 
@@ -11588,6 +11718,7 @@ class Participant extends Emitter {
11588
11718
 
11589
11719
 
11590
11720
  /**
11721
+ * @param room Room The room where the participant is
11591
11722
  * @param rawParticipant string Participant sent via the Wazo WS
11592
11723
  * @param extra Object extra status of the participant
11593
11724
  */
@@ -11675,7 +11806,7 @@ class Participant extends Emitter {
11675
11806
  }
11676
11807
 
11677
11808
  onTalking(isTalking ) {
11678
- logger$1.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
11809
+ logger$2.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
11679
11810
  this.isTalking = isTalking;
11680
11811
  // you may notice we're not broadcasting: since all participants are getting this info
11681
11812
  // directly from asterisk, there's no need to do so
@@ -11778,7 +11909,7 @@ class Participant extends Emitter {
11778
11909
  }
11779
11910
 
11780
11911
  updateStatus(status , broadcast = true) {
11781
- logger$1.info('updating participant status', { name: this.name, status });
11912
+ logger$2.info('updating participant status', { name: this.name, status });
11782
11913
 
11783
11914
  if (typeof status.audioMuted !== 'undefined' && status.audioMuted !== this.audioMuted) {
11784
11915
  if (status.audioMuted) {
@@ -11815,13 +11946,18 @@ class Participant extends Emitter {
11815
11946
  // Poor man's object comparison
11816
11947
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
11817
11948
  this.extra = { ...this.extra, ...status.extra };
11949
+
11950
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
11951
+ this.extra.contact = new Contact(this.extra.contact);
11952
+ }
11953
+
11818
11954
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
11819
11955
  }
11820
11956
  }
11821
11957
 
11822
11958
  broadcastStatus(inboundStatus = null) {
11823
11959
  const status = inboundStatus || this.getStatus();
11824
- logger$1.info('broadcasting participant status', { callId: this.callId, status });
11960
+ logger$2.info('broadcasting participant status', { callId: this.callId, status });
11825
11961
 
11826
11962
  this.room.sendSignal({
11827
11963
  type: SIGNAL_TYPE_PARTICIPANT_UPDATE,
@@ -11842,18 +11978,24 @@ class RemoteParticipant extends Participant {
11842
11978
  }
11843
11979
  }
11844
11980
 
11845
- /* global document */
11981
+ //
11982
+
11983
+ class LocalParticipant extends Participant {
11984
+ }
11985
+
11986
+ //
11846
11987
 
11847
11988
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
11848
11989
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
11849
11990
 
11850
- const logger = IssueReporter$1.loggerFor('sdk-room');
11991
+ const logger$1 = IssueReporter$1.loggerFor('sdk-room');
11851
11992
 
11852
11993
  class Room extends Emitter {
11853
11994
 
11854
11995
 
11855
11996
 
11856
11997
 
11998
+
11857
11999
 
11858
12000
 
11859
12001
 
@@ -11875,6 +12017,8 @@ class Room extends Emitter {
11875
12017
 
11876
12018
 
11877
12019
 
12020
+
12021
+
11878
12022
 
11879
12023
 
11880
12024
 
@@ -11892,6 +12036,7 @@ class Room extends Emitter {
11892
12036
  * @param extension string
11893
12037
  * @param sourceId number
11894
12038
  * @param callId string
12039
+ * @param meetingUuid string
11895
12040
  * @param extra Object
11896
12041
  */
11897
12042
  constructor(
@@ -11899,15 +12044,17 @@ class Room extends Emitter {
11899
12044
  extension ,
11900
12045
  sourceId ,
11901
12046
  callId ,
12047
+ meetingUuid ,
11902
12048
  extra = {},
11903
12049
  ) {
11904
12050
  super();
11905
- logger.info('room initialized', { callId, extension, sourceId });
12051
+ logger$1.info('room initialized', { callId, extension, sourceId, meetingUuid });
11906
12052
 
11907
12053
  // Represents the room callSession
11908
12054
  this.callSession = callSession;
11909
12055
  this.extension = extension;
11910
12056
  this.sourceId = sourceId;
12057
+ this.meetingUuid = meetingUuid;
11911
12058
  this.callId = callId;
11912
12059
  this.participants = [];
11913
12060
  this.connected = false;
@@ -11927,6 +12074,8 @@ class Room extends Emitter {
11927
12074
  // Sugar syntax for `room.EVENT_NAME`
11928
12075
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
11929
12076
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
12077
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
12078
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
11930
12079
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
11931
12080
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
11932
12081
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -11961,10 +12110,11 @@ class Room extends Emitter {
11961
12110
  * @param audioOnly boolean
11962
12111
  * @param extra Object
11963
12112
  * @param room ?Room
12113
+ * @param meeting ?Meeting
11964
12114
  * @returns {Promise<Room>}
11965
12115
  */
11966
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
11967
- logger.info('connecting to room', { extension, audioOnly, room: !!room });
12116
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
12117
+ logger$1.info('connecting to room', { extension, audioOnly, room: !!room });
11968
12118
 
11969
12119
  if (!room) {
11970
12120
  await Wazo.Phone.connect();
@@ -11977,7 +12127,7 @@ class Room extends Emitter {
11977
12127
 
11978
12128
  // Call_created is triggered before call_accepted, so we have to listen for it here.
11979
12129
  Wazo.Websocket.once(Wazo.Websocket.CALL_CREATED, ({ data }) => {
11980
- logger.info('room call received via WS', { callId: data.call_id });
12130
+ logger$1.info('room call received via WS', { callId: data.call_id });
11981
12131
  if (room) {
11982
12132
  room.setCallId(data.call_id);
11983
12133
  }
@@ -11998,34 +12148,44 @@ class Room extends Emitter {
11998
12148
  room.setCallId(room.callSession.call.id);
11999
12149
  }
12000
12150
 
12001
- // Fetch conference source
12002
- const sources = await getApiClient().dird.fetchConferenceSource('default');
12003
- // Retrieve conference sources
12004
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
12005
- // Retrieve conference
12006
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
12151
+ if (!meeting) {
12152
+ // Fetch conference source
12153
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
12154
+ // Retrieve conference sources
12155
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
12156
+ // Retrieve conference
12157
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
12007
12158
 
12008
- logger.info('connected to room', {
12009
- sourceId: conference ? conference.sourceId : null,
12010
- name: conference ? conference.name : null,
12011
- });
12159
+ logger$1.info('connected to room', {
12160
+ sourceId: conference ? conference.sourceId : null,
12161
+ name: conference ? conference.name : null,
12162
+ });
12012
12163
 
12013
- if (conference) {
12014
- room.setSourceId(conference.sourceId);
12015
- room.setName(conference.name);
12164
+ if (conference) {
12165
+ room.setSourceId(conference.sourceId);
12166
+ room.setName(conference.name);
12167
+ }
12168
+ } else if (meeting) {
12169
+ logger$1.info('Already connected to meeting', {
12170
+ uuid: meeting.uuid,
12171
+ name: meeting.name,
12172
+ });
12173
+
12174
+ room.setMeetingUuid(meeting.uuid);
12175
+ room.setName(meeting.name);
12016
12176
  }
12017
12177
 
12018
12178
  return room;
12019
12179
  }
12020
12180
 
12021
12181
  static disconnect() {
12022
- logger.info('static disconnection to room');
12182
+ logger$1.info('static disconnection to room');
12023
12183
 
12024
12184
  Wazo.Phone.disconnect();
12025
12185
  }
12026
12186
 
12027
12187
  async disconnect() {
12028
- logger.info('disconnection to room called');
12188
+ logger$1.info('disconnection to room called');
12029
12189
 
12030
12190
  await Wazo.Phone.hangup(this.callSession);
12031
12191
  this.callSession = null;
@@ -12040,20 +12200,24 @@ class Room extends Emitter {
12040
12200
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
12041
12201
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12042
12202
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12043
-
12044
- if (this.roomAudioElement && document.body) {
12045
- document.body.removeChild(this.roomAudioElement);
12046
- }
12203
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12204
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12047
12205
  }
12048
12206
 
12049
12207
  setSourceId(sourceId ) {
12050
- logger.info('set room source id', { sourceId });
12208
+ logger$1.info('set room source id', { sourceId });
12051
12209
 
12052
12210
  this.sourceId = sourceId;
12053
12211
  }
12054
12212
 
12213
+ setMeetingUuid(meetingUuid ) {
12214
+ logger$1.info('set meeting uuid', { meetingUuid });
12215
+
12216
+ this.meetingUuid = meetingUuid;
12217
+ }
12218
+
12055
12219
  setCallId(callId ) {
12056
- logger.info('set room call id', { callId });
12220
+ logger$1.info('set room call id', { callId });
12057
12221
 
12058
12222
  if (callId) {
12059
12223
  this.callId = callId;
@@ -12061,7 +12225,7 @@ class Room extends Emitter {
12061
12225
  }
12062
12226
 
12063
12227
  setName(name ) {
12064
- logger.info('set room name', { name });
12228
+ logger$1.info('set room name', { name });
12065
12229
 
12066
12230
  this.name = name;
12067
12231
  }
@@ -12080,7 +12244,7 @@ class Room extends Emitter {
12080
12244
  }
12081
12245
 
12082
12246
  async startScreenSharing(constraints ) {
12083
- logger.info('start room screen sharing', { constraints });
12247
+ logger$1.info('start room screen sharing', { constraints });
12084
12248
 
12085
12249
  const screensharingStream = await Wazo.Phone.startScreenSharing(constraints, this.callSession);
12086
12250
  if (!screensharingStream) {
@@ -12093,18 +12257,26 @@ class Room extends Emitter {
12093
12257
  return screensharingStream;
12094
12258
  }
12095
12259
 
12096
- stopScreenSharing(restoreLocalStream = true) {
12097
- logger.info('stop room screen sharing');
12260
+ async stopScreenSharing(restoreLocalStream = true) {
12261
+ logger$1.info('stop room screen sharing');
12098
12262
 
12099
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
12263
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
12100
12264
 
12101
12265
  if (this.localParticipant) {
12102
12266
  this.localParticipant.onStopScreensharing();
12103
12267
  }
12268
+
12269
+ if (!reinvited && this.localParticipant) {
12270
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
12271
+ // So not REINVITE even is fired, we have to restore the video stream manually
12272
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
12273
+ // $FlowFixMe
12274
+ this._associateStreamTo(localVideoStream, this.localParticipant);
12275
+ }
12104
12276
  }
12105
12277
 
12106
12278
  turnCameraOff() {
12107
- logger.info('turn room camera off');
12279
+ logger$1.info('turn room camera off');
12108
12280
 
12109
12281
  Wazo.Phone.turnCameraOff(this.callSession);
12110
12282
 
@@ -12114,7 +12286,7 @@ class Room extends Emitter {
12114
12286
  }
12115
12287
 
12116
12288
  turnCameraOn() {
12117
- logger.info('turn room camera on');
12289
+ logger$1.info('turn room camera on');
12118
12290
 
12119
12291
  Wazo.Phone.turnCameraOn(this.callSession);
12120
12292
 
@@ -12124,7 +12296,7 @@ class Room extends Emitter {
12124
12296
  }
12125
12297
 
12126
12298
  mute() {
12127
- logger.info('mute room');
12299
+ logger$1.info('mute room');
12128
12300
 
12129
12301
  Wazo.Phone.mute(this.callSession);
12130
12302
 
@@ -12132,7 +12304,7 @@ class Room extends Emitter {
12132
12304
  }
12133
12305
 
12134
12306
  unmute() {
12135
- logger.info('unmute room');
12307
+ logger$1.info('unmute room');
12136
12308
 
12137
12309
  Wazo.Phone.unmute(this.callSession);
12138
12310
 
@@ -12152,7 +12324,7 @@ class Room extends Emitter {
12152
12324
  }
12153
12325
 
12154
12326
  hold() {
12155
- logger.info('hold room');
12327
+ logger$1.info('hold room');
12156
12328
 
12157
12329
  Wazo.Phone.hold(this.callSession, true);
12158
12330
 
@@ -12162,7 +12334,7 @@ class Room extends Emitter {
12162
12334
  }
12163
12335
 
12164
12336
  resume() {
12165
- logger.info('resume room');
12337
+ logger$1.info('resume room');
12166
12338
 
12167
12339
  Wazo.Phone.resume(this.callSession, true);
12168
12340
 
@@ -12172,13 +12344,13 @@ class Room extends Emitter {
12172
12344
  }
12173
12345
 
12174
12346
  sendDTMF(tone ) {
12175
- logger.info('send room DTMF', { tone });
12347
+ logger$1.info('send room DTMF', { tone });
12176
12348
 
12177
12349
  Wazo.Phone.sendDTMF(tone, this.callSession);
12178
12350
  }
12179
12351
 
12180
12352
  async sendReinvite(newConstraints = null) {
12181
- logger.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
12353
+ logger$1.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
12182
12354
  const wasScreensharing = this.localParticipant && this.localParticipant.screensharing;
12183
12355
 
12184
12356
  Wazo.Phone.on(Wazo.Phone.ON_SHARE_SCREEN_STARTED, () => {
@@ -12203,6 +12375,22 @@ class Room extends Emitter {
12203
12375
  return response;
12204
12376
  }
12205
12377
 
12378
+ hasALocalVideoTrack() {
12379
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
12380
+ }
12381
+
12382
+ getLocalStream() {
12383
+ return Wazo.Phone.getLocalStream(this.callSession);
12384
+ }
12385
+
12386
+ getRemoteStream() {
12387
+ return Wazo.Phone.getRemoteStream(this.callSession);
12388
+ }
12389
+
12390
+ getRemoteVideoStream() {
12391
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
12392
+ }
12393
+
12206
12394
  _bindEvents() {
12207
12395
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
12208
12396
  return;
@@ -12221,35 +12409,18 @@ class Room extends Emitter {
12221
12409
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
12222
12410
 
12223
12411
  this.on(this.ON_AUDIO_STREAM, stream => {
12224
- logger.info('on room audio stream');
12412
+ logger$1.info('on room audio stream');
12225
12413
 
12226
12414
  this.audioStream = stream;
12227
- if (document.createElement) {
12228
- // $FlowFixMe
12229
- let roomAudioElement = document.getElementById('audio-room');
12230
- if (!this.roomAudioElement) {
12231
- roomAudioElement = document.createElement('audio');
12232
- // $FlowFixMe
12233
- document.body.appendChild(roomAudioElement);
12234
- }
12235
- if (!roomAudioElement) {
12236
- return;
12237
- }
12238
- this.roomAudioElement = roomAudioElement;
12415
+ if (!this.roomAudioElement) {
12416
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
12417
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
12239
12418
  this.roomAudioElement.srcObject = stream;
12240
- this.roomAudioElement.autoplay = true;
12241
- this.roomAudioElement.id = 'audio-room';
12242
-
12243
- // $FlowFixMe
12244
- if (this.roomAudioElement.setSinkId) {
12245
- // $FlowFixMe
12246
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
12247
- }
12248
12419
  }
12249
12420
  });
12250
12421
 
12251
12422
  this.on(this.ON_VIDEO_STREAM, (stream, streamId, event, sipSession) => {
12252
- logger.info('on room video stream', { streamId });
12423
+ logger$1.info('on room video stream', { streamId });
12253
12424
 
12254
12425
  this._mapMsid(sipSession.body.body);
12255
12426
 
@@ -12264,7 +12435,7 @@ class Room extends Emitter {
12264
12435
  });
12265
12436
 
12266
12437
  this.on(this.ON_REMOVE_STREAM, stream => {
12267
- logger.info('on room remove stream');
12438
+ logger$1.info('on room remove stream');
12268
12439
 
12269
12440
  const participant = this.participants.find(someParticipant =>
12270
12441
  someParticipant.streams.find(someStream => someStream && someStream.id === stream.id));
@@ -12319,6 +12490,9 @@ class Room extends Emitter {
12319
12490
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12320
12491
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12321
12492
 
12493
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12494
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12495
+
12322
12496
  // Phone events
12323
12497
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
12324
12498
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -12329,15 +12503,15 @@ class Room extends Emitter {
12329
12503
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
12330
12504
  }
12331
12505
 
12332
- _onMessage(message ) {
12506
+ _onMessage(message ) {
12333
12507
  if (message.method !== 'MESSAGE') {
12334
- return;
12508
+ return null;
12335
12509
  }
12336
12510
  let body;
12337
12511
  try {
12338
12512
  body = JSON.parse(message.body);
12339
12513
  } catch (e) {
12340
- return;
12514
+ return null;
12341
12515
  }
12342
12516
 
12343
12517
  switch (body.type) {
@@ -12356,6 +12530,8 @@ class Room extends Emitter {
12356
12530
  }
12357
12531
 
12358
12532
  this.eventEmitter.emit(this.ON_MESSAGE, body);
12533
+
12534
+ return body;
12359
12535
  }
12360
12536
 
12361
12537
  _onChat(content ) {
@@ -12391,7 +12567,7 @@ class Room extends Emitter {
12391
12567
  const requester = this._getParticipantFromCallId(origin.callId);
12392
12568
  if (requester) {
12393
12569
  // @FIXME?: when need to trigger an update on join-in; this is a bit of a hack
12394
- logger.info('trigger room requester status', { origin });
12570
+ logger$1.info('trigger room requester status', { origin });
12395
12571
  requester.triggerUpdate('REQUESTER_UPDATE');
12396
12572
  }
12397
12573
  break;
@@ -12420,25 +12596,26 @@ class Room extends Emitter {
12420
12596
  const session = Wazo.Auth.getSession();
12421
12597
  let participants = [];
12422
12598
 
12423
- // @TODO: we could use a better function name here
12424
- const isJoining = part => {
12425
- this.__associateStreams(part);
12426
- // @VALIDATE: no need to publicize ourselves, no?
12427
- if (part instanceof RemoteParticipant) {
12428
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
12429
- }
12430
- };
12431
-
12432
12599
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
12433
12600
  if (participant.user_uuid === session.uuid) {
12434
- logger.info('room current user joined');
12601
+ logger$1.info('room current user joined');
12435
12602
 
12436
12603
  // Retrieve participants via an API calls
12437
12604
  const conferenceId = this.sourceId || payload.data.conference_id;
12438
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
12439
- logger.info('fetching conference participants', { conferenceId });
12605
+ let response;
12606
+ try {
12607
+ if (this.meetingUuid) {
12608
+ logger$1.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
12609
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
12610
+ } else {
12611
+ logger$1.info('fetching conference participants', { conferenceId });
12612
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
12613
+ }
12614
+ } catch (e) {
12615
+ logger$1.error('room participants fetching, error', e);
12616
+ }
12440
12617
  if (response) {
12441
- logger.info('conference participants fetched', { nb: response.items.length });
12618
+ logger$1.info('conference participants fetched', { nb: response.items.length });
12442
12619
  participants = response.items.map(item => {
12443
12620
  const isMe = item.call_id === this.callId;
12444
12621
 
@@ -12451,25 +12628,10 @@ class Room extends Emitter {
12451
12628
 
12452
12629
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
12453
12630
  if (!this.localParticipant && localParticipant) {
12454
- this.localParticipant = localParticipant;
12455
-
12456
- const localVideoStream = this._getLocalVideoStream();
12457
- if (localVideoStream) {
12458
- this._saveLocalVideoStream(localVideoStream);
12459
- }
12460
-
12461
- this.connected = true;
12462
-
12463
- // we're in the room, now let's request everyone's status
12464
- if (this.localParticipant) {
12465
- this.sendSignal({
12466
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
12467
- origin: this.localParticipant.getStatus(),
12468
- });
12469
- }
12631
+ this._onLocalParticipantJoined(localParticipant);
12470
12632
  }
12471
12633
 
12472
- participants.forEach(someParticipant => isJoining(someParticipant));
12634
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
12473
12635
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
12474
12636
  }
12475
12637
 
@@ -12480,16 +12642,45 @@ class Room extends Emitter {
12480
12642
  ? new Wazo.RemoteParticipant(this, participant)
12481
12643
  : null;
12482
12644
 
12483
- logger.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
12645
+ logger$1.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
12484
12646
 
12485
12647
  if (remoteParticipant) {
12486
12648
  this.participants.push(remoteParticipant);
12487
- isJoining(remoteParticipant);
12649
+ this._isParticipantJoining(remoteParticipant);
12488
12650
  }
12489
12651
 
12490
12652
  return remoteParticipant;
12491
12653
  }
12492
12654
 
12655
+ _onLocalParticipantJoined(localParticipant ) {
12656
+ this.localParticipant = localParticipant;
12657
+
12658
+ const localVideoStream = this._getLocalVideoStream();
12659
+ if (localVideoStream) {
12660
+ this._saveLocalVideoStream(localVideoStream);
12661
+ }
12662
+
12663
+ this.connected = true;
12664
+
12665
+ localParticipant.broadcastStatus();
12666
+
12667
+ // we're in the room, now let's request everyone's status
12668
+ if (this.localParticipant) {
12669
+ this.sendSignal({
12670
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
12671
+ origin: this.localParticipant.getStatus(),
12672
+ });
12673
+ }
12674
+ }
12675
+
12676
+ _isParticipantJoining(participant ) {
12677
+ this.__associateStreams(participant);
12678
+ // @VALIDATE: no need to publicize ourselves, no?
12679
+ if (participant instanceof RemoteParticipant) {
12680
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
12681
+ }
12682
+ }
12683
+
12493
12684
  _saveLocalVideoStream(stream ) {
12494
12685
  const { localParticipant } = this;
12495
12686
 
@@ -12535,9 +12726,11 @@ class Room extends Emitter {
12535
12726
  _onParticipantTrackUpdate(oldParticipant , update ) {
12536
12727
  const newParticipant = oldParticipant;
12537
12728
 
12538
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
12729
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
12539
12730
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
12540
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
12731
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
12732
+ const stream = pc.getRemoteStreams().find(someStream =>
12733
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
12541
12734
 
12542
12735
  if (update === 'downgrade') {
12543
12736
  newParticipant.streams = [];
@@ -12567,15 +12760,42 @@ class Room extends Emitter {
12567
12760
  return;
12568
12761
  }
12569
12762
 
12570
- if (this._unassociatedVideoStreams[trackId]) {
12763
+ const streamId = this._getStreamIdFrTrackId(trackId);
12764
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
12765
+ const stream = this._unassociatedVideoStreams[key];
12766
+
12767
+ if (stream) {
12571
12768
  // Try to associate stream
12572
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
12769
+ this._associateStreamTo(stream, participant);
12573
12770
 
12574
- delete this._unassociatedVideoStreams[trackId];
12771
+ delete this._unassociatedVideoStreams[key];
12575
12772
  delete this._unassociatedParticipants[participant.callId];
12576
12773
  }
12577
12774
  }
12578
12775
 
12776
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
12777
+ // Find by trackId
12778
+ if (trackId in this._unassociatedVideoStreams) {
12779
+ return trackId;
12780
+ }
12781
+
12782
+ // Find by streamId
12783
+ if (streamId && streamId in this._unassociatedVideoStreams) {
12784
+ return streamId;
12785
+ }
12786
+
12787
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
12788
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12789
+ stream && stream.id === streamId);
12790
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12791
+ }
12792
+
12793
+ _getStreamIdFrTrackId(trackId ) {
12794
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
12795
+
12796
+ return mapping ? mapping.streamId : null;
12797
+ }
12798
+
12579
12799
  _associateStreamTo(rawStream , participant ) {
12580
12800
  const stream = new Wazo.Stream(rawStream, participant);
12581
12801
  participant.streams.push(stream);
@@ -12599,7 +12819,141 @@ class Room extends Emitter {
12599
12819
 
12600
12820
  //
12601
12821
 
12602
- class LocalParticipant extends Participant {
12822
+ const logger = IssueReporter$1.loggerFor('sdk-sip-room');
12823
+
12824
+ class SipRoom extends Room {
12825
+
12826
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
12827
+ logger.info('connecting to sip room', { extension, audioOnly, room: !!room });
12828
+
12829
+ if (!room) {
12830
+ await Wazo.Phone.connect();
12831
+
12832
+ const withCamera = constraints && !!constraints.video;
12833
+
12834
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
12835
+ // eslint-disable-next-line no-param-reassign
12836
+ room = new SipRoom(callSession, extension, null, null, extra);
12837
+ }
12838
+
12839
+ if (room && room.callSession && room.callSession.call) {
12840
+ room.setCallId(room.callSession.call.id);
12841
+ }
12842
+
12843
+ logger.info('connected to room', {
12844
+ extension: room.extension,
12845
+ });
12846
+
12847
+ return room;
12848
+ }
12849
+
12850
+ mute() {
12851
+ logger.info('mute sip room');
12852
+
12853
+ Wazo.Phone.mute(this.callSession, false);
12854
+
12855
+ this.sendMuteStatus();
12856
+ }
12857
+
12858
+ unmute() {
12859
+ logger.info('unmute sip room');
12860
+
12861
+ Wazo.Phone.unmute(this.callSession, false);
12862
+
12863
+ this.sendUnMuteStatus();
12864
+ }
12865
+
12866
+ getLocalGuestName() {
12867
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
12868
+ }
12869
+
12870
+ // Overridden to not listen to websocket messages
12871
+ _transferEvents() {
12872
+ // Phone events
12873
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
12874
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
12875
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
12876
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
12877
+
12878
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
12879
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
12880
+ }
12881
+
12882
+ _onMessage(message ) {
12883
+ // eslint-disable-next-line no-underscore-dangle
12884
+ const body = super._onMessage(message);
12885
+ if (!body) {
12886
+ return;
12887
+ }
12888
+
12889
+ const getChannel = () => body.channels[0];
12890
+
12891
+ switch (body.type) {
12892
+ case 'ConfbridgeWelcome':
12893
+ body.channels.forEach(channel => {
12894
+ this._onParticipantJoined(channel);
12895
+ });
12896
+
12897
+ break;
12898
+ case 'ConfbridgeJoin': {
12899
+ const channel = getChannel();
12900
+ this._onParticipantJoined(channel);
12901
+ break;
12902
+ }
12903
+ case 'ConfbridgeLeave': {
12904
+ const channel = getChannel();
12905
+ this._onParticipantLeft({
12906
+ data: {
12907
+ call_id: channel.id,
12908
+ },
12909
+ });
12910
+ break;
12911
+ }
12912
+ }
12913
+ }
12914
+
12915
+ async _onParticipantJoined(channel ) {
12916
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
12917
+ const callId = channel.id;
12918
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
12919
+ const name = channel.caller ? channel.caller.name : null;
12920
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
12921
+ const participant = new ParticipantClass(this, {
12922
+ caller_id_name: name,
12923
+ call_id: callId,
12924
+ }, extra);
12925
+
12926
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
12927
+ if (participantIdx !== -1 && name) {
12928
+ this.participants[participantIdx].name = name;
12929
+ return;
12930
+ }
12931
+
12932
+ if (isLocal) {
12933
+ // Should be updated by the Wazo WS but we don't have it for now
12934
+ if (this.callSession) {
12935
+ this.callSession.ringing = false;
12936
+ }
12937
+
12938
+ this._onLocalParticipantJoined(participant);
12939
+
12940
+ // Give some time for the stream to be updated
12941
+ setTimeout(() => {
12942
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
12943
+ }, 1000);
12944
+ }
12945
+
12946
+ this.participants.push(participant);
12947
+
12948
+ this._isParticipantJoining(participant);
12949
+
12950
+ return participant;
12951
+ }
12952
+
12953
+ _getCurrentSipCallIs() {
12954
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
12955
+ }
12956
+
12603
12957
  }
12604
12958
 
12605
12959
  /* global document */
@@ -12652,9 +13006,7 @@ class Stream {
12652
13006
  return false;
12653
13007
  }
12654
13008
 
12655
- // With canvas track (used to fake upgrade in conference), we don't have a width
12656
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
12657
- && track.readyState !== 'ended' && 'width' in track.getSettings());
13009
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
12658
13010
  }
12659
13011
 
12660
13012
  get id() {
@@ -12718,6 +13070,7 @@ const Wazo = {
12718
13070
  Phone: Phone$1,
12719
13071
  Websocket: Websocket$1,
12720
13072
  Room,
13073
+ SipRoom,
12721
13074
  RemoteParticipant,
12722
13075
  LocalParticipant,
12723
13076
  Stream,
@@ -12754,6 +13107,7 @@ const Wazo = {
12754
13107
  IndirectTransfer,
12755
13108
  SwitchboardCall,
12756
13109
  WebRTCPhone,
13110
+ Meeting,
12757
13111
  },
12758
13112
 
12759
13113
  // Api
@@ -12843,6 +13197,7 @@ var index = {
12843
13197
  SOCKET_EVENTS: SOCKET_EVENTS$1,
12844
13198
  Wazo,
12845
13199
  WebRTCPhone,
13200
+ Meeting,
12846
13201
  };
12847
13202
 
12848
13203
  export default index;