@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/lib/index.js CHANGED
@@ -369,7 +369,7 @@ var IssueReporter$1 = new IssueReporter();
369
369
 
370
370
  const methods = ['head', 'get', 'post', 'put', 'delete'];
371
371
 
372
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
372
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
373
373
 
374
374
  // Use a function here to be able to mock it in tests
375
375
  const realFetch = () => {
@@ -508,7 +508,7 @@ class ApiRequester {
508
508
  };
509
509
 
510
510
  if (this.refreshTokenPromise) {
511
- logger$b.info('A token is already refreshing, waiting ...', { url });
511
+ logger$c.info('A token is already refreshing, waiting ...', { url });
512
512
  await this.refreshTokenPromise;
513
513
  }
514
514
 
@@ -528,7 +528,7 @@ class ApiRequester {
528
528
  return promise.then(async (err ) => {
529
529
  // Check if the token is still valid
530
530
  if (firstCall && this._checkTokenExpired(response, err)) {
531
- logger$b.warn('token expired', { error: err.reason });
531
+ logger$c.warn('token expired', { error: err.reason });
532
532
  // Replay the call after refreshing the token
533
533
  return this._replayWithNewToken(err, path, method, body, headers, parse);
534
534
  }
@@ -538,7 +538,7 @@ class ApiRequester {
538
538
  : exceptionClass.fromResponse(err, response.status);
539
539
 
540
540
  if (this.shouldLogErrors) {
541
- logger$b.error('API error', error);
541
+ logger$c.error('API error', error);
542
542
  }
543
543
 
544
544
  throw error;
@@ -548,7 +548,7 @@ class ApiRequester {
548
548
  return newParse(response, isJson);
549
549
  }).catch(error => {
550
550
  if (this.shouldLogErrors) {
551
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
551
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
552
552
  }
553
553
 
554
554
  throw error;
@@ -576,13 +576,13 @@ class ApiRequester {
576
576
  ) {
577
577
  const isTokenNotFound = this._isTokenNotFound(err);
578
578
  let newPath = path;
579
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
579
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
580
580
 
581
581
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
582
582
 
583
583
  return this.refreshTokenPromise.then(() => {
584
584
  this.refreshTokenPromise = null;
585
- logger$b.info('token refreshed', { isTokenNotFound });
585
+ logger$c.info('token refreshed', { isTokenNotFound });
586
586
  if (isTokenNotFound) {
587
587
  const pathParts = path.split('/');
588
588
  pathParts.pop();
@@ -2524,6 +2524,65 @@ class ExternalApp {
2524
2524
  }
2525
2525
  }
2526
2526
 
2527
+ //
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+ class Meeting {
2540
+
2541
+
2542
+
2543
+
2544
+
2545
+
2546
+
2547
+
2548
+
2549
+
2550
+ static parse(plain ) {
2551
+ return new Meeting({
2552
+ guestSipAuthorization: plain.guest_sip_authorization,
2553
+ hostname: plain.hostname,
2554
+ name: plain.name,
2555
+ ownerUuids: plain.owner_uuids,
2556
+ port: plain.port,
2557
+ uuid: plain.uuid,
2558
+ number: plain.number,
2559
+ });
2560
+ }
2561
+
2562
+ static newFrom(meeting ) {
2563
+ return newFrom(meeting, Meeting);
2564
+ }
2565
+
2566
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2567
+ this.guestSipAuthorization = guestSipAuthorization;
2568
+ this.hostname = hostname;
2569
+ this.name = name;
2570
+ this.ownerUuids = ownerUuids;
2571
+ this.port = port;
2572
+ this.uuid = uuid;
2573
+ this.number = number;
2574
+
2575
+ // Useful to compare instead of instanceof with minified code
2576
+ this.type = 'Meeting';
2577
+ }
2578
+
2579
+ getGuestSipCredentials() {
2580
+ // eslint-disable-next-line no-undef
2581
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2582
+ return { username, secret };
2583
+ }
2584
+ }
2585
+
2527
2586
  /* */
2528
2587
 
2529
2588
  var confdMethods = (client , baseUrl ) => ({
@@ -2588,6 +2647,18 @@ var confdMethods = (client , baseUrl ) => ({
2588
2647
  return null;
2589
2648
  }
2590
2649
  },
2650
+
2651
+ createMyMeeting: (name ) =>
2652
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2653
+
2654
+ deleteMyMeeting: (meetingUuid ) =>
2655
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2656
+
2657
+ getMeeting: (meetingUuid ) =>
2658
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2659
+
2660
+ guestGetMeeting: (meetingUuid ) =>
2661
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2591
2662
  });
2592
2663
 
2593
2664
  //
@@ -3530,7 +3601,11 @@ class CallLog {
3530
3601
  answered: plain.answered,
3531
3602
  callDirection: plain.call_direction,
3532
3603
  destination: {
3533
- extension: plain.requested_extension || plain.destination_extension,
3604
+ // @TEMP: Temporarily assuming empty numbers are meetings
3605
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3606
+ extension: plain.requested_extension
3607
+ || plain.destination_extension
3608
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3534
3609
  name: plain.requested_name || plain.destination_name || '',
3535
3610
  },
3536
3611
  source: {
@@ -3546,27 +3621,11 @@ class CallLog {
3546
3621
  }
3547
3622
 
3548
3623
  static parseNew(plain , session ) {
3549
- return new CallLog({
3550
- answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3551
- answered: plain.answered,
3552
- callDirection: plain.call_direction,
3553
- destination: {
3554
- extension: plain.requested_extension || plain.destination_extension,
3555
- name: plain.requested_name || plain.destination_name || '',
3556
- },
3557
- source: {
3558
- extension: plain.source_extension,
3559
- name: plain.source_name,
3560
- },
3561
- id: plain.id,
3562
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3563
- start: moment__default['default'](plain.start).toDate(),
3564
- end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3565
- recordings: Recording.parseMany(plain.recordings),
3566
- // @TODO: FIXME add verification declined vs missed call
3567
- newMissedCall: session
3568
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3569
- });
3624
+ const callLog = CallLog.parse(plain);
3625
+ // @TODO: FIXME add verification declined vs missed call
3626
+ callLog.newMissedCall = session
3627
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3628
+ return callLog;
3570
3629
  }
3571
3630
 
3572
3631
  static newFrom(profile ) {
@@ -3914,7 +3973,7 @@ const TRANSFER_FLOW_BLIND = 'blind';
3914
3973
 
3915
3974
  // const MINIMUM_WAZO_ENGINE_VERSION_FOR_CTI_HOLD = '20.11';
3916
3975
 
3917
- const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3976
+ const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3918
3977
 
3919
3978
  class CTIPhone extends Emitter {
3920
3979
 
@@ -3927,7 +3986,7 @@ class CTIPhone extends Emitter {
3927
3986
 
3928
3987
  constructor(session , isMobile = false, callbackAllLines = false) {
3929
3988
  super();
3930
- logger$a.info('CTI Phone created');
3989
+ logger$b.info('CTI Phone created');
3931
3990
  this.session = session;
3932
3991
  this.isMobile = isMobile;
3933
3992
  this.callbackAllLines = callbackAllLines;
@@ -3988,7 +4047,7 @@ class CTIPhone extends Emitter {
3988
4047
  }
3989
4048
 
3990
4049
  async makeCall(number , line ) {
3991
- logger$a.info('make CTI call', { number });
4050
+ logger$b.info('make CTI call', { number });
3992
4051
 
3993
4052
  if (!number) {
3994
4053
  return null;
@@ -4011,7 +4070,7 @@ class CTIPhone extends Emitter {
4011
4070
  if (!callSession) {
4012
4071
  return Promise.resolve(null);
4013
4072
  }
4014
- logger$a.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
4073
+ logger$b.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
4015
4074
 
4016
4075
  if (!this.currentCall) {
4017
4076
  this.currentCall = callSession.call;
@@ -4024,7 +4083,7 @@ class CTIPhone extends Emitter {
4024
4083
  if (!callSession) {
4025
4084
  return;
4026
4085
  }
4027
- logger$a.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
4086
+ logger$b.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
4028
4087
 
4029
4088
  this.currentCall = undefined;
4030
4089
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -4034,7 +4093,7 @@ class CTIPhone extends Emitter {
4034
4093
  if (!callSession) {
4035
4094
  return Promise.resolve(false);
4036
4095
  }
4037
- logger$a.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4096
+ logger$b.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4038
4097
 
4039
4098
  try {
4040
4099
  await CallApi.cancelCall(callSession);
@@ -4045,7 +4104,7 @@ class CTIPhone extends Emitter {
4045
4104
  this.eventEmitter.emit('onCallEnded', callSession);
4046
4105
  return true;
4047
4106
  } catch (e) {
4048
- logger$a.error('hangup CTI call, error', e);
4107
+ logger$b.error('hangup CTI call, error', e);
4049
4108
 
4050
4109
  this.eventEmitter.emit('onCallFailed', callSession);
4051
4110
  return false;
@@ -4058,7 +4117,7 @@ class CTIPhone extends Emitter {
4058
4117
  if (!callSession) {
4059
4118
  return;
4060
4119
  }
4061
- logger$a.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4120
+ logger$b.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4062
4121
 
4063
4122
  await CallApi.cancelCall(callSession);
4064
4123
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -4068,7 +4127,7 @@ class CTIPhone extends Emitter {
4068
4127
  if (!callSession) {
4069
4128
  return;
4070
4129
  }
4071
- logger$a.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4130
+ logger$b.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4072
4131
 
4073
4132
  await CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_BLIND);
4074
4133
  }
@@ -4079,19 +4138,19 @@ class CTIPhone extends Emitter {
4079
4138
  if (!callSession) {
4080
4139
  return;
4081
4140
  }
4082
- logger$a.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4141
+ logger$b.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4083
4142
 
4084
4143
  return CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_ATTENDED);
4085
4144
  }
4086
4145
 
4087
4146
  async cancelCTIIndirectTransfer(transferId ) {
4088
- logger$a.info('cancel CTI transfer', { transferId });
4147
+ logger$b.info('cancel CTI transfer', { transferId });
4089
4148
 
4090
4149
  return CallApi.cancelCallTransfer(transferId);
4091
4150
  }
4092
4151
 
4093
4152
  async confirmCTIIndirectTransfer(transferId ) {
4094
- logger$a.info('confirm CTI transfer', { transferId });
4153
+ logger$b.info('confirm CTI transfer', { transferId });
4095
4154
 
4096
4155
  return CallApi.confirmCallTransfer(transferId);
4097
4156
  }
@@ -4100,19 +4159,19 @@ class CTIPhone extends Emitter {
4100
4159
  if (!callSession) {
4101
4160
  return;
4102
4161
  }
4103
- logger$a.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4162
+ logger$b.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4104
4163
 
4105
4164
  return CallApi.sendDTMF(callSession.callId, digits);
4106
4165
  }
4107
4166
 
4108
4167
  onConnectionMade() {
4109
- logger$a.info('on CTI connection made');
4168
+ logger$b.info('on CTI connection made');
4110
4169
 
4111
4170
  this.eventEmitter.emit('onCallAccepted');
4112
4171
  }
4113
4172
 
4114
4173
  async close() {
4115
- logger$a.info('CTI close');
4174
+ logger$b.info('CTI close');
4116
4175
 
4117
4176
  return Promise.resolve();
4118
4177
  }
@@ -4121,7 +4180,7 @@ class CTIPhone extends Emitter {
4121
4180
  if (!callSession) {
4122
4181
  return;
4123
4182
  }
4124
- logger$a.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4183
+ logger$b.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4125
4184
 
4126
4185
  return CallApi.hold(callSession.callId);
4127
4186
  }
@@ -4130,7 +4189,7 @@ class CTIPhone extends Emitter {
4130
4189
  if (!callSession) {
4131
4190
  return;
4132
4191
  }
4133
- logger$a.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4192
+ logger$b.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4134
4193
 
4135
4194
  return CallApi.resume(callSession.callId);
4136
4195
  }
@@ -4139,7 +4198,7 @@ class CTIPhone extends Emitter {
4139
4198
  if (!callSession) {
4140
4199
  return;
4141
4200
  }
4142
- logger$a.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4201
+ logger$b.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4143
4202
 
4144
4203
  return CallApi.mute(callSession.callId);
4145
4204
  }
@@ -4148,7 +4207,7 @@ class CTIPhone extends Emitter {
4148
4207
  if (!callSession) {
4149
4208
  return;
4150
4209
  }
4151
- logger$a.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4210
+ logger$b.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4152
4211
 
4153
4212
  return CallApi.unmute(callSession.callId);
4154
4213
  }
@@ -4794,6 +4853,9 @@ var calldMethods = (client , baseUrl ) => ({
4794
4853
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4795
4854
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4796
4855
 
4856
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4857
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4858
+
4797
4859
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4798
4860
 
4799
4861
  mute: (callId ) =>
@@ -5147,7 +5209,7 @@ const AGENTD_VERSION = '1.0';
5147
5209
  const WEBHOOKD_VERSION = '1.0';
5148
5210
  const AMID_VERSION = '1.0';
5149
5211
 
5150
- const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5212
+ const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5151
5213
 
5152
5214
  class ApiClient {
5153
5215
 
@@ -5199,12 +5261,12 @@ class ApiClient {
5199
5261
  }
5200
5262
 
5201
5263
  async forceRefreshToken() {
5202
- logger$9.info('forcing refresh token, calling callback');
5264
+ logger$a.info('forcing refresh token, calling callback');
5203
5265
  return this.refreshTokenCallback();
5204
5266
  }
5205
5267
 
5206
5268
  async refreshTokenCallback() {
5207
- logger$9.info('refresh token callback called', {
5269
+ logger$a.info('refresh token callback called', {
5208
5270
  refreshToken: this.refreshToken,
5209
5271
  refreshBackend: this.refreshBackend,
5210
5272
  refreshExpiration: this.refreshExpiration,
@@ -5222,7 +5284,7 @@ class ApiClient {
5222
5284
  this.isMobile,
5223
5285
  );
5224
5286
 
5225
- logger$9.info('token refreshed', { token: session.token });
5287
+ logger$a.info('token refreshed', { token: session.token });
5226
5288
 
5227
5289
  if (this.onRefreshToken) {
5228
5290
  this.onRefreshToken(session.token, session);
@@ -5437,7 +5499,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5437
5499
  .then(() => {
5438
5500
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5439
5501
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5440
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5502
+ if (this.peerConnection.addTransceiver) {
5503
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5504
+ }
5441
5505
  }
5442
5506
  })
5443
5507
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5464,12 +5528,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5464
5528
  };
5465
5529
  })
5466
5530
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5467
- .then((sessionDescription) => {
5468
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5469
- this.localMediaStreamConstraints = options.constraints;
5470
-
5471
- return sessionDescription;
5472
- })
5473
5531
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5474
5532
  .catch((error) => {
5475
5533
  wazoLogger.error('error when creating media', error);
@@ -5664,6 +5722,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5664
5722
 
5665
5723
  // set the transceiver direction to the answer direction
5666
5724
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5725
+ if (transceiver.stopped) {
5726
+ return;
5727
+ }
5667
5728
  if (transceiver.direction /* guarding, but should always be true */) {
5668
5729
  const { receiver } = transceiver;
5669
5730
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -5708,10 +5769,15 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5708
5769
  if (kind !== 'audio' && kind !== 'video') {
5709
5770
  throw new Error(`Unknown new track kind ${kind}.`);
5710
5771
  }
5711
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5772
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
5773
+ otherSender.track && otherSender.track.kind === kind);
5712
5774
 
5713
5775
  // Do not reuse sender video tracks in SFU
5714
5776
  if (sender && (!sfu || newTrack.kind === 'audio')) {
5777
+ if (sender.track) {
5778
+ // eslint-disable-next-line no-param-reassign
5779
+ newTrack.enabled = sender.track.enabled;
5780
+ }
5715
5781
  trackUpdates.push(
5716
5782
  new Promise((resolve) => {
5717
5783
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5745,7 +5811,11 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5745
5811
  // Review: could make streamless tracks a configurable option?
5746
5812
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
5747
5813
  try {
5748
- pc.addTrack(newTrack, localStream);
5814
+ if (pc.addTrack) {
5815
+ pc.addTrack(newTrack, localStream);
5816
+ } else {
5817
+ pc.addStream(localStream);
5818
+ }
5749
5819
  } catch (error) {
5750
5820
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
5751
5821
  throw error;
@@ -5881,7 +5951,7 @@ const DEFAULT_ICE_TIMEOUT = 3000;
5881
5951
  const SEND_STATS_DELAY = 5000;
5882
5952
 
5883
5953
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
5884
- const logger$8 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
5954
+ const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
5885
5955
  const statsLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-stats') : console;
5886
5956
 
5887
5957
  // events
@@ -5927,6 +5997,7 @@ const MAX_REGISTER_TRIES = 10;
5927
5997
 
5928
5998
 
5929
5999
 
6000
+
5930
6001
 
5931
6002
 
5932
6003
 
@@ -5953,6 +6024,7 @@ class WebRTCClient extends Emitter {
5953
6024
 
5954
6025
 
5955
6026
 
6027
+
5956
6028
 
5957
6029
  // sugar
5958
6030
 
@@ -5991,6 +6063,8 @@ class WebRTCClient extends Emitter {
5991
6063
  super();
5992
6064
  this.uaConfigOverrides = uaConfigOverrides;
5993
6065
  this.config = config;
6066
+ this.skipRegister = config.skipRegister;
6067
+
5994
6068
  this._buildConfig(config, session).then((newConfig ) => {
5995
6069
  this.config = newConfig;
5996
6070
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -6046,13 +6120,13 @@ class WebRTCClient extends Emitter {
6046
6120
 
6047
6121
  createUserAgent(configOverrides ) {
6048
6122
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
6049
- logger$8.info('sdk webrtc, creating UA', { webRTCConfiguration });
6123
+ logger$9.info('sdk webrtc, creating UA', { webRTCConfiguration });
6050
6124
 
6051
6125
  webRTCConfiguration.delegate = {
6052
6126
  onConnect: this.onConnect.bind(this),
6053
6127
  onDisconnect: this.onDisconnect.bind(this),
6054
6128
  onInvite: (invitation ) => {
6055
- logger$8.info('sdk webrtc on invite', {
6129
+ logger$9.info('sdk webrtc on invite', {
6056
6130
  method: 'delegate.onInvite',
6057
6131
  id: invitation.id,
6058
6132
  remoteURI: invitation.remoteURI,
@@ -6095,7 +6169,7 @@ class WebRTCClient extends Emitter {
6095
6169
  }
6096
6170
 
6097
6171
  onConnect() {
6098
- logger$8.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6172
+ logger$9.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6099
6173
  this.eventEmitter.emit(CONNECTED);
6100
6174
  if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
6101
6175
  this.registerer.waitingToggle(false);
@@ -6104,7 +6178,7 @@ class WebRTCClient extends Emitter {
6104
6178
  }
6105
6179
 
6106
6180
  async onDisconnect(error ) {
6107
- logger$8.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6181
+ logger$9.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6108
6182
  this.connectionPromise = null;
6109
6183
  // The UA will attempt to reconnect automatically when an error occurred
6110
6184
  this.eventEmitter.emit(DISCONNECTED, error);
@@ -6118,40 +6192,48 @@ class WebRTCClient extends Emitter {
6118
6192
  }
6119
6193
 
6120
6194
  register(tries = 0) {
6121
- logger$8.info('sdk webrtc registering...', {
6195
+ const logInfo = {
6122
6196
  userAgent: !!this.userAgent,
6123
6197
  registered: this.isRegistered(),
6124
6198
  connectionPromise: !!this.connectionPromise,
6125
6199
  registerer: !!this.registerer,
6126
6200
  waiting: this.registerer && this.registerer.waiting,
6127
6201
  tries,
6128
- });
6202
+ skipRegister: this.skipRegister,
6203
+ };
6204
+
6205
+ if (this.skipRegister) {
6206
+ logger$9.info('sdk webrtc skip register...', logInfo);
6207
+ return Promise.resolve();
6208
+ }
6209
+
6210
+ logger$9.info('sdk webrtc registering...', logInfo);
6129
6211
 
6130
6212
  if (!this.userAgent) {
6131
- logger$8.info('sdk webrtc recreating User Agent');
6213
+ logger$9.info('sdk webrtc recreating User Agent');
6132
6214
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6133
6215
  }
6134
6216
  if (!this.userAgent || this.isRegistered()) {
6135
- logger$8.info('sdk webrtc registering aborted, already registered or no UA can be created');
6217
+ logger$9.info('sdk webrtc registering aborted, already registered or no UA can be created');
6136
6218
  return Promise.resolve();
6137
6219
  }
6138
6220
 
6139
6221
  if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
6140
- logger$8.info('sdk webrtc registering aborted due to a registration in progress.');
6222
+ logger$9.info('sdk webrtc registering aborted due to a registration in progress.');
6141
6223
  return Promise.resolve();
6142
6224
  }
6143
6225
 
6144
6226
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6145
6227
 
6146
6228
  const onRegisterFailed = () => {
6147
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6229
+ logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6148
6230
  this.connectionPromise = null;
6149
6231
  if (this.registerer && this.registerer.waiting) {
6150
6232
  this.registerer.waitingToggle(false);
6151
6233
  }
6152
6234
 
6153
6235
  if (tries <= MAX_REGISTER_TRIES) {
6154
- logger$8.info('sdk webrtc registering, retrying...', { tries });
6236
+ logger$9.info('sdk webrtc registering, retrying...', { tries });
6155
6237
  setTimeout(() => this.register(tries + 1), 300);
6156
6238
  }
6157
6239
  };
@@ -6160,18 +6242,18 @@ class WebRTCClient extends Emitter {
6160
6242
  // Avoid race condition with the close method called just before register and setting userAgent to null
6161
6243
  // during the resolution of the primise.
6162
6244
  if (!this.userAgent) {
6163
- logger$8.info('sdk webrtc recreating User Agent after connection');
6245
+ logger$9.info('sdk webrtc recreating User Agent after connection');
6164
6246
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6165
6247
  }
6166
6248
 
6167
- logger$8.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6249
+ logger$9.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6168
6250
  this.registerer = new registerer.Registerer(this.userAgent, registerOptions);
6169
6251
  this.connectionPromise = null;
6170
6252
  this._monkeyPatchRegisterer(this.registerer);
6171
6253
 
6172
6254
  // Bind registerer events
6173
6255
  this.registerer.stateChange.addListener(newState => {
6174
- logger$8.info('sdk webrtc registering, state changed', { newState });
6256
+ logger$9.info('sdk webrtc registering, state changed', { newState });
6175
6257
 
6176
6258
  if (newState === registererState.RegistererState.Registered && this.registerer
6177
6259
  && this.registerer.state === registererState.RegistererState.Registered) {
@@ -6184,7 +6266,7 @@ class WebRTCClient extends Emitter {
6184
6266
  const options = {
6185
6267
  requestDelegate: {
6186
6268
  onReject: response => {
6187
- logger$8.error('sdk webrtc registering, rejected', { response });
6269
+ logger$9.error('sdk webrtc registering, rejected', { response });
6188
6270
 
6189
6271
  onRegisterFailed();
6190
6272
  },
@@ -6192,13 +6274,13 @@ class WebRTCClient extends Emitter {
6192
6274
  };
6193
6275
 
6194
6276
  return this.registerer.register(options).catch((e) => {
6195
- logger$8.error('sdk webrtc registering, error', e);
6277
+ logger$9.error('sdk webrtc registering, error', e);
6196
6278
 
6197
6279
  this.eventEmitter.emit(REGISTRATION_FAILED);
6198
6280
  return e;
6199
6281
  });
6200
6282
  }).catch(error => {
6201
- logger$8.error('sdk webrtc registering, transport error', error);
6283
+ logger$9.error('sdk webrtc registering, transport error', error);
6202
6284
  onRegisterFailed();
6203
6285
  });
6204
6286
  }
@@ -6227,21 +6309,21 @@ class WebRTCClient extends Emitter {
6227
6309
  }
6228
6310
 
6229
6311
  unregister() {
6230
- logger$8.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6312
+ logger$9.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6231
6313
  if (!this.registerer) {
6232
6314
  return Promise.resolve();
6233
6315
  }
6234
6316
 
6235
6317
  try {
6236
6318
  return this.registerer.unregister().then(() => {
6237
- logger$8.info('sdk webrtc unregistered');
6319
+ logger$9.info('sdk webrtc unregistered');
6238
6320
  this._cleanupRegister();
6239
6321
  }).catch(e => {
6240
- logger$8.error('sdk webrtc unregistering, promise error', e);
6322
+ logger$9.error('sdk webrtc unregistering, promise error', e);
6241
6323
  this._cleanupRegister();
6242
6324
  });
6243
6325
  } catch (e) {
6244
- logger$8.error('sdk webrtc unregistering, error', e);
6326
+ logger$9.error('sdk webrtc unregistering, error', e);
6245
6327
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
6246
6328
  // error when the registerer is in a bad state
6247
6329
  this._cleanupRegister();
@@ -6249,7 +6331,7 @@ class WebRTCClient extends Emitter {
6249
6331
  }
6250
6332
 
6251
6333
  stop() {
6252
- logger$8.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6334
+ logger$9.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6253
6335
  if (!this.userAgent) {
6254
6336
  return Promise.resolve();
6255
6337
  }
@@ -6257,12 +6339,12 @@ class WebRTCClient extends Emitter {
6257
6339
  return this.userAgent.stop().then(() => {
6258
6340
  return this._cleanupRegister();
6259
6341
  }).catch(e => {
6260
- logger$8.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6342
+ logger$9.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6261
6343
  });
6262
6344
  }
6263
6345
 
6264
6346
  call(number , enableVideo , audioOnly = false, conference = false) {
6265
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6347
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6266
6348
  const inviterOptions = {
6267
6349
  sessionDescriptionHandlerOptionsReInvite: {
6268
6350
  conference,
@@ -6291,7 +6373,7 @@ class WebRTCClient extends Emitter {
6291
6373
  this._onAccepted(session, response.session, true);
6292
6374
  },
6293
6375
  onReject: (response ) => {
6294
- logger$8.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6376
+ logger$9.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6295
6377
  this._stopSendingStats(session);
6296
6378
 
6297
6379
  this.eventEmitter.emit(REJECTED, session, response);
@@ -6313,11 +6395,11 @@ class WebRTCClient extends Emitter {
6313
6395
  }
6314
6396
 
6315
6397
  answer(session , enableVideo ) {
6316
- logger$8.info('sdk webrtc answer call', { id: session.id, enableVideo });
6398
+ logger$9.info('sdk webrtc answer call', { id: session.id, enableVideo });
6317
6399
 
6318
6400
  if (!session || !session.accept) {
6319
6401
  const error = 'No session to answer, or not an invitation';
6320
- logger$8.warn(error);
6402
+ logger$9.warn(error);
6321
6403
  return Promise.reject(new Error(error));
6322
6404
  }
6323
6405
  const options = {
@@ -6327,15 +6409,15 @@ class WebRTCClient extends Emitter {
6327
6409
  return session.accept(options).then(() => {
6328
6410
  if (session.isCanceled) {
6329
6411
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
6330
- logger$8.error(message, { id: session.id });
6412
+ logger$9.error(message, { id: session.id });
6331
6413
  this.onCallEnded(session);
6332
6414
 
6333
6415
  throw new CanceledCallError(message);
6334
6416
  }
6335
- logger$8.info('sdk webrtc answer, accepted.');
6417
+ logger$9.info('sdk webrtc answer, accepted.');
6336
6418
  this._onAccepted(session);
6337
6419
  }).catch(e => {
6338
- logger$8.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6420
+ logger$9.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6339
6421
 
6340
6422
  throw e;
6341
6423
  });
@@ -6343,7 +6425,7 @@ class WebRTCClient extends Emitter {
6343
6425
 
6344
6426
  hangup(session ) {
6345
6427
  const { state, id } = session;
6346
- logger$8.info('sdk webrtc hangup call', { id, state });
6428
+ logger$9.info('sdk webrtc hangup call', { id, state });
6347
6429
 
6348
6430
  try {
6349
6431
  this._stopSendingStats(session);
@@ -6372,24 +6454,24 @@ class WebRTCClient extends Emitter {
6372
6454
 
6373
6455
  return bye();
6374
6456
  } catch (error) {
6375
- logger$8.warn('sdk webrtc hangup, error', error);
6457
+ logger$9.warn('sdk webrtc hangup, error', error);
6376
6458
  }
6377
6459
 
6378
6460
  return null;
6379
6461
  }
6380
6462
 
6381
6463
  reject(session ) {
6382
- logger$8.info('sdk webrtc reject call', { id: session.id });
6464
+ logger$9.info('sdk webrtc reject call', { id: session.id });
6383
6465
 
6384
6466
  try {
6385
6467
  return session.reject ? session.reject() : session.cancel();
6386
6468
  } catch (e) {
6387
- logger$8.warn('Error when rejecting call', e.message, e.stack);
6469
+ logger$9.warn('Error when rejecting call', e.message, e.stack);
6388
6470
  }
6389
6471
  }
6390
6472
 
6391
6473
  async close() {
6392
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6474
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6393
6475
  this._cleanupMedia();
6394
6476
  this.connectionPromise = null;
6395
6477
 
@@ -6420,7 +6502,7 @@ class WebRTCClient extends Emitter {
6420
6502
  // eg: "INVITE not rejectable in state Completed"
6421
6503
  }
6422
6504
  this.userAgent = null;
6423
- logger$8.info('sdk webrtc client closed');
6505
+ logger$9.info('sdk webrtc client closed');
6424
6506
  }
6425
6507
 
6426
6508
  getNumber(session ) {
@@ -6433,13 +6515,13 @@ class WebRTCClient extends Emitter {
6433
6515
  }
6434
6516
 
6435
6517
  mute(session ) {
6436
- logger$8.info('sdk webrtc mute', { id: session.id });
6518
+ logger$9.info('sdk webrtc mute', { id: session.id });
6437
6519
 
6438
6520
  this._toggleAudio(session, true);
6439
6521
  }
6440
6522
 
6441
6523
  unmute(session ) {
6442
- logger$8.info('sdk webrtc unmute', { id: session.id });
6524
+ logger$9.info('sdk webrtc unmute', { id: session.id });
6443
6525
 
6444
6526
  this._toggleAudio(session, false);
6445
6527
  }
@@ -6456,12 +6538,18 @@ class WebRTCClient extends Emitter {
6456
6538
  }
6457
6539
 
6458
6540
  if (pc.getSenders) {
6541
+ if (!pc.getSenders().length) {
6542
+ return false;
6543
+ }
6459
6544
  pc.getSenders().forEach(sender => {
6460
6545
  if (sender && sender.track && sender.track.kind === 'audio') {
6461
6546
  muted = muted && !sender.track.enabled;
6462
6547
  }
6463
6548
  });
6464
6549
  } else {
6550
+ if (!pc.getLocalStreams().length) {
6551
+ return false;
6552
+ }
6465
6553
  pc.getLocalStreams().forEach(stream => {
6466
6554
  stream.getAudioTracks().forEach(track => {
6467
6555
  muted = muted && !track.enabled;
@@ -6473,20 +6561,20 @@ class WebRTCClient extends Emitter {
6473
6561
  }
6474
6562
 
6475
6563
  toggleCameraOn(session ) {
6476
- logger$8.info('sdk webrtc toggle camera on', { id: session.id });
6564
+ logger$9.info('sdk webrtc toggle camera on', { id: session.id });
6477
6565
 
6478
6566
  this._toggleVideo(session, false);
6479
6567
  }
6480
6568
 
6481
6569
  toggleCameraOff(session ) {
6482
- logger$8.info('sdk webrtc toggle camera off', { id: session.id });
6570
+ logger$9.info('sdk webrtc toggle camera off', { id: session.id });
6483
6571
 
6484
6572
  this._toggleVideo(session, true);
6485
6573
  }
6486
6574
 
6487
6575
  hold(session , isConference = false) {
6488
6576
  const sessionId = this.getSipSessionId(session);
6489
- logger$8.info('sdk webrtc hold', {
6577
+ logger$9.info('sdk webrtc hold', {
6490
6578
  sessionId,
6491
6579
  keys: Object.keys(this.heldSessions),
6492
6580
  pendingReinvite: !!session.pendingReinvite,
@@ -6520,6 +6608,8 @@ class WebRTCClient extends Emitter {
6520
6608
  }
6521
6609
  options.sessionDescriptionHandlerOptions = {
6522
6610
  constraints: options.constraints,
6611
+ hold: true,
6612
+ conference: isConference,
6523
6613
  };
6524
6614
 
6525
6615
  // Send re-INVITE
@@ -6529,7 +6619,7 @@ class WebRTCClient extends Emitter {
6529
6619
  unhold(session , isConference = false) {
6530
6620
  const sessionId = this.getSipSessionId(session);
6531
6621
 
6532
- logger$8.info('sdk webrtc unhold', {
6622
+ logger$9.info('sdk webrtc unhold', {
6533
6623
  sessionId,
6534
6624
  keys: Object.keys(this.heldSessions),
6535
6625
  pendingReinvite: !!session.pendingReinvite,
@@ -6562,6 +6652,8 @@ class WebRTCClient extends Emitter {
6562
6652
  }
6563
6653
  options.sessionDescriptionHandlerOptions = {
6564
6654
  constraints: options.constraints,
6655
+ hold: false,
6656
+ conference: isConference,
6565
6657
  };
6566
6658
 
6567
6659
  // Send re-INVITE
@@ -6620,7 +6712,7 @@ class WebRTCClient extends Emitter {
6620
6712
  return;
6621
6713
  }
6622
6714
 
6623
- logger$8.info('send WebRTC message', { sipId: sipSession.id, contentType });
6715
+ logger$9.info('send WebRTC message', { sipId: sipSession.id, contentType });
6624
6716
 
6625
6717
  try {
6626
6718
  sipSession.message({
@@ -6745,7 +6837,8 @@ class WebRTCClient extends Emitter {
6745
6837
  }
6746
6838
  const sdh = session.sessionDescriptionHandler;
6747
6839
  const pc = sdh.peerConnection;
6748
- const localStream = this.getLocalStream(this.getSipSessionId(session));
6840
+ const sessionId = this.getSipSessionId(session);
6841
+ const localStream = this.getLocalStream(sessionId);
6749
6842
 
6750
6843
  // Release old video stream
6751
6844
  if (localStream) {
@@ -6771,11 +6864,8 @@ class WebRTCClient extends Emitter {
6771
6864
 
6772
6865
  // let's update the local stream
6773
6866
  this.eventEmitter.emit('onVideoInputChange', stream);
6774
- try {
6775
- await sdh.setLocalMediaStream(stream);
6776
- } catch (_) {
6777
- // Nothing to do
6778
- }
6867
+ this.setLocalMediaStream(sessionId, stream);
6868
+
6779
6869
  return stream;
6780
6870
  });
6781
6871
  }
@@ -6987,7 +7077,7 @@ class WebRTCClient extends Emitter {
6987
7077
  }
6988
7078
 
6989
7079
  startHeartbeat() {
6990
- logger$8.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7080
+ logger$9.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
6991
7081
  if (!this.userAgent) {
6992
7082
  this.heartbeat.stop();
6993
7083
  return;
@@ -7000,7 +7090,7 @@ class WebRTCClient extends Emitter {
7000
7090
  }
7001
7091
 
7002
7092
  stopHeartbeat() {
7003
- logger$8.info('sdk webrtc stop heartbeat');
7093
+ logger$9.info('sdk webrtc stop heartbeat');
7004
7094
  this.heartbeat.stop();
7005
7095
  }
7006
7096
 
@@ -7020,7 +7110,7 @@ class WebRTCClient extends Emitter {
7020
7110
  }
7021
7111
 
7022
7112
  attemptReconnection() {
7023
- logger$8.info('attempt reconnection', { userAgent: !!this.userAgent });
7113
+ logger$9.info('attempt reconnection', { userAgent: !!this.userAgent });
7024
7114
  if (!this.userAgent) {
7025
7115
  return;
7026
7116
  }
@@ -7077,9 +7167,11 @@ class WebRTCClient extends Emitter {
7077
7167
  remoteStream.removeTrack(track);
7078
7168
  });
7079
7169
 
7080
- pc.getReceivers().forEach(receiver => {
7081
- remoteStream.addTrack(receiver.track);
7082
- });
7170
+ if (pc.getReceivers) {
7171
+ pc.getReceivers().forEach(receiver => {
7172
+ remoteStream.addTrack(receiver.track);
7173
+ });
7174
+ }
7083
7175
  }
7084
7176
 
7085
7177
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -7114,6 +7206,25 @@ class WebRTCClient extends Emitter {
7114
7206
  return sessionId in this.conferences;
7115
7207
  }
7116
7208
 
7209
+ createAudioElementFor(sessionId ) {
7210
+ const audio = document.createElement('audio');
7211
+ audio.setAttribute('id', `audio-${sessionId}`);
7212
+
7213
+ if (audio.setSinkId && this.audioOutputDeviceId) {
7214
+ audio.setSinkId(this.audioOutputDeviceId);
7215
+ }
7216
+
7217
+ if (document.body) {
7218
+ document.body.appendChild(audio);
7219
+ }
7220
+ this.audioElements[sessionId] = audio;
7221
+
7222
+ audio.volume = this.audioOutputVolume;
7223
+ audio.autoplay = true;
7224
+
7225
+ return audio;
7226
+ }
7227
+
7117
7228
  _onTransportError() {
7118
7229
  this.eventEmitter.emit(TRANSPORT_ERROR);
7119
7230
  this.attemptReconnection();
@@ -7123,7 +7234,7 @@ class WebRTCClient extends Emitter {
7123
7234
  const body = message && typeof message === 'object' ? message.data : message;
7124
7235
  if (body && body.indexOf('200 OK') !== -1) {
7125
7236
  if (this.hasHeartbeat()) {
7126
- logger$8.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7237
+ logger$9.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7127
7238
 
7128
7239
  this.heartbeat.onHeartbeat();
7129
7240
  if (this.heartbeatCb) {
@@ -7134,7 +7245,7 @@ class WebRTCClient extends Emitter {
7134
7245
  }
7135
7246
 
7136
7247
  async _onHeartbeatTimeout() {
7137
- logger$8.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7248
+ logger$9.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7138
7249
 
7139
7250
  if (this.heartbeatTimeoutCb) {
7140
7251
  this.heartbeatTimeoutCb();
@@ -7146,7 +7257,7 @@ class WebRTCClient extends Emitter {
7146
7257
  try {
7147
7258
  await this.userAgent.transport.disconnect();
7148
7259
  } catch (e) {
7149
- logger$8.error('Transport disconnection after heartbeat timeout, error', e);
7260
+ logger$9.error('Transport disconnection after heartbeat timeout, error', e);
7150
7261
  }
7151
7262
  }
7152
7263
 
@@ -7179,31 +7290,31 @@ class WebRTCClient extends Emitter {
7179
7290
  }
7180
7291
 
7181
7292
  _connectIfNeeded() {
7182
- logger$8.info('connect if needed, checking', { connected: this.isConnected() });
7293
+ logger$9.info('connect if needed, checking', { connected: this.isConnected() });
7183
7294
  if (!this.userAgent) {
7184
- logger$8.info('need to recreate User Agent');
7295
+ logger$9.info('need to recreate User Agent');
7185
7296
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
7186
7297
  }
7187
7298
 
7188
7299
  if (this.isConnected()) {
7189
- logger$8.info('webrtc sdk, already connected');
7300
+ logger$9.info('webrtc sdk, already connected');
7190
7301
  return Promise.resolve();
7191
7302
  }
7192
7303
 
7193
7304
  if (this.isConnecting()) {
7194
- logger$8.info('webrtc sdk, already connecting...');
7305
+ logger$9.info('webrtc sdk, already connecting...');
7195
7306
 
7196
7307
  this.connectionPromise = this.userAgent.transport.connectPromise;
7197
7308
  return this.connectionPromise;
7198
7309
  }
7199
7310
 
7200
7311
  if (this.connectionPromise) {
7201
- logger$8.info('webrtc sdk, connection promise connecting...');
7312
+ logger$9.info('webrtc sdk, connection promise connecting...');
7202
7313
  // $FlowFixMe
7203
7314
  return this.connectionPromise;
7204
7315
  }
7205
7316
 
7206
- logger$8.info('WebRTC UA needs to connect');
7317
+ logger$9.info('WebRTC UA needs to connect');
7207
7318
 
7208
7319
  // Force UA to reconnect
7209
7320
  if (this.userAgent && this.userAgent.state !== userAgentState.UserAgentState.Stopped) {
@@ -7328,7 +7439,7 @@ class WebRTCClient extends Emitter {
7328
7439
 
7329
7440
  sdh.peerConnectionDelegate = {
7330
7441
  onicecandidateerror: (error ) => {
7331
- logger$8.error('on icecandidate error', {
7442
+ logger$9.error('on icecandidate error', {
7332
7443
  address: error.address,
7333
7444
  port: error.port,
7334
7445
  errorCode: error.errorCode,
@@ -7343,7 +7454,7 @@ class WebRTCClient extends Emitter {
7343
7454
  let hadRemoteVideo = false;
7344
7455
 
7345
7456
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7346
- // Becase when `onInvite` is called we already got the video track
7457
+ // Because when `onInvite` is called we already got the video track
7347
7458
  session.onInviteRequest = (request) => {
7348
7459
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7349
7460
 
@@ -7357,7 +7468,7 @@ class WebRTCClient extends Emitter {
7357
7468
  updatedNumber = session.assertedIdentity.uri.normal.user;
7358
7469
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
7359
7470
  }
7360
- logger$8.info('re-invite received', { updatedCalleeName, updatedNumber });
7471
+ logger$9.info('re-invite received', { updatedCalleeName, updatedNumber });
7361
7472
 
7362
7473
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7363
7474
 
@@ -7378,7 +7489,7 @@ class WebRTCClient extends Emitter {
7378
7489
  }
7379
7490
 
7380
7491
  _onAccepted(session , sessionDialog , withEvent = true) {
7381
- logger$8.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7492
+ logger$9.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7382
7493
 
7383
7494
  this.storeSipSession(session);
7384
7495
 
@@ -7418,20 +7529,10 @@ class WebRTCClient extends Emitter {
7418
7529
  const isConference = this.isConference(sessionId);
7419
7530
 
7420
7531
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7421
- const audio = document.createElement('audio');
7422
- audio.setAttribute('id', `audio-${sessionId}`);
7423
-
7424
- if (audio.setSinkId && this.audioOutputDeviceId) {
7425
- audio.setSinkId(this.audioOutputDeviceId);
7426
- }
7427
-
7428
- if (document.body) {
7429
- document.body.appendChild(audio);
7430
- }
7431
- this.audioElements[sessionId] = audio;
7532
+ this.createAudioElementFor(sessionId);
7432
7533
  }
7433
7534
 
7434
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7535
+ const audioElement = this.audioElements[sessionId];
7435
7536
  const stream = newStream || this.getRemoteStream(sessionId);
7436
7537
 
7437
7538
  if (!this._isWeb() || !stream) {
@@ -7578,10 +7679,10 @@ class WebRTCClient extends Emitter {
7578
7679
 
7579
7680
  _stopSendingStats(session ) {
7580
7681
  const sessionId = this.getSipSessionId(session);
7581
- logger$8.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7682
+ logger$9.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7582
7683
 
7583
7684
  if (sessionId in this.statsIntervals) {
7584
- logger$8.trace('Stop sending stats for call', { sessionId });
7685
+ logger$9.trace('Stop sending stats for call', { sessionId });
7585
7686
  this.statsIntervals[sessionId]();
7586
7687
  delete this.statsIntervals[sessionId];
7587
7688
  }
@@ -7597,7 +7698,7 @@ class WebRTCClient extends Emitter {
7597
7698
  try {
7598
7699
  await this.userAgent.transport.disconnect();
7599
7700
  } catch (e) {
7600
- logger$8.error('WebRTC transport disconnect, error', e);
7701
+ logger$9.error('WebRTC transport disconnect, error', e);
7601
7702
  }
7602
7703
  }
7603
7704
  }
@@ -7658,6 +7759,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
7658
7759
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
7659
7760
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
7660
7761
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
7762
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
7763
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
7661
7764
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
7662
7765
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
7663
7766
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -7699,7 +7802,7 @@ const BLACKLIST_EVENTS = [
7699
7802
  ];
7700
7803
 
7701
7804
  const HEARTBEAT_ENGINE_VERSION = '20.09';
7702
- const logger$7 = IssueReporter$1.loggerFor('wazo-ws');
7805
+ const logger$8 = IssueReporter$1.loggerFor('wazo-ws');
7703
7806
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
7704
7807
 
7705
7808
  class WebSocketClient extends Emitter {
@@ -7748,19 +7851,19 @@ class WebSocketClient extends Emitter {
7748
7851
  }
7749
7852
 
7750
7853
  connect() {
7751
- logger$7.info('connect method started', { host: this.host, token: this.token });
7854
+ logger$8.info('connect method started', { host: this.host, token: this.token });
7752
7855
  this.socket = new ReconnectingWebSocket__default['default'](this._getUrl.bind(this), [], this.options);
7753
7856
  if (this.options.binaryType) {
7754
7857
  this.socket.binaryType = this.options.binaryType;
7755
7858
  }
7756
7859
 
7757
7860
  this.socket.onopen = () => {
7758
- logger$7.info('on Wazo WS open', { method: 'connect', host: this.host });
7861
+ logger$8.info('on Wazo WS open', { method: 'connect', host: this.host });
7759
7862
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
7760
7863
  };
7761
7864
 
7762
7865
  this.socket.onerror = event => {
7763
- logger$7.error('on Wazo WS error', event.target);
7866
+ logger$8.error('on Wazo WS error', event.target);
7764
7867
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
7765
7868
  };
7766
7869
 
@@ -7790,7 +7893,7 @@ class WebSocketClient extends Emitter {
7790
7893
 
7791
7894
  this.socket.onclose = event => {
7792
7895
  // Can't be converted to JSON (circular structure)
7793
- logger$7.info('on Wazo WS close', {
7896
+ logger$8.info('on Wazo WS close', {
7794
7897
  reason: event.reason,
7795
7898
  code: event.code,
7796
7899
  readyState: event.target.readyState,
@@ -7808,12 +7911,12 @@ class WebSocketClient extends Emitter {
7808
7911
  };
7809
7912
 
7810
7913
  this.socket.onerror = event => {
7811
- logger$7.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
7914
+ logger$8.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
7812
7915
  };
7813
7916
  }
7814
7917
 
7815
7918
  close(force = false) {
7816
- logger$7.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
7919
+ logger$8.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
7817
7920
 
7818
7921
  if (!this.socket) {
7819
7922
  return;
@@ -7831,7 +7934,7 @@ class WebSocketClient extends Emitter {
7831
7934
 
7832
7935
  updateToken(token ) {
7833
7936
  this.token = token;
7834
- logger$7.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
7937
+ logger$8.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
7835
7938
 
7836
7939
  if (this.socket) {
7837
7940
  // If still connected, send the token to the WS
@@ -7849,7 +7952,7 @@ class WebSocketClient extends Emitter {
7849
7952
  }
7850
7953
 
7851
7954
  startHeartbeat() {
7852
- logger$7.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
7955
+ logger$8.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
7853
7956
 
7854
7957
  if (!this.socket) {
7855
7958
  this.heartbeat.stop();
@@ -7863,7 +7966,7 @@ class WebSocketClient extends Emitter {
7863
7966
  }
7864
7967
 
7865
7968
  stopHeartbeat() {
7866
- logger$7.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
7969
+ logger$8.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
7867
7970
 
7868
7971
  this.heartbeat.stop();
7869
7972
  }
@@ -7893,7 +7996,7 @@ class WebSocketClient extends Emitter {
7893
7996
  }
7894
7997
 
7895
7998
  reconnect(reason ) {
7896
- logger$7.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
7999
+ logger$8.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
7897
8000
  if (!this.socket) {
7898
8001
  return;
7899
8002
  }
@@ -7949,7 +8052,7 @@ class WebSocketClient extends Emitter {
7949
8052
  this.close();
7950
8053
  }
7951
8054
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
7952
- logger$7.log('Wazo WS url computed to reconnect', { url });
8055
+ logger$8.log('Wazo WS url computed to reconnect', { url });
7953
8056
 
7954
8057
  return url;
7955
8058
  }
@@ -7957,12 +8060,12 @@ class WebSocketClient extends Emitter {
7957
8060
  _onHeartbeat(message ) {
7958
8061
  if (message.payload === 'pong') {
7959
8062
  this.heartbeat.onHeartbeat();
7960
- logger$7.log('on heartbeat received from Wazo WS');
8063
+ logger$8.log('on heartbeat received from Wazo WS');
7961
8064
  }
7962
8065
  }
7963
8066
 
7964
8067
  async _onHeartbeatTimeout() {
7965
- logger$7.log('heartbeat timed out', { host: this.host, token: this.token });
8068
+ logger$8.log('heartbeat timed out', { host: this.host, token: this.token });
7966
8069
 
7967
8070
  this.close();
7968
8071
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -8004,6 +8107,8 @@ WebSocketClient.eventLists = [
8004
8107
  CHATD_USER_ROOM_CREATED,
8005
8108
  CONFERENCE_USER_PARTICIPANT_JOINED,
8006
8109
  CONFERENCE_USER_PARTICIPANT_LEFT,
8110
+ MEETING_USER_PARTICIPANT_JOINED,
8111
+ MEETING_USER_PARTICIPANT_LEFT,
8007
8112
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
8008
8113
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
8009
8114
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -8074,6 +8179,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
8074
8179
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
8075
8180
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
8076
8181
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
8182
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
8183
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
8077
8184
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
8078
8185
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
8079
8186
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -8568,7 +8675,7 @@ const events = [
8568
8675
  ON_SIGNAL,
8569
8676
  ];
8570
8677
 
8571
- const logger$6 = IssueReporter$1.loggerFor('webrtc-phone');
8678
+ const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
8572
8679
 
8573
8680
  class WebRTCPhone extends Emitter {
8574
8681
 
@@ -8639,7 +8746,7 @@ class WebRTCPhone extends Emitter {
8639
8746
  }).catch(error => {
8640
8747
  // Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
8641
8748
  console.error('register error', error, error.message, error.stack);
8642
- logger$6.error('WebRTC register error', { message: error.message, stack: error.stack });
8749
+ logger$7.error('WebRTC register error', { message: error.message, stack: error.stack });
8643
8750
  });
8644
8751
  }
8645
8752
 
@@ -8654,7 +8761,7 @@ class WebRTCPhone extends Emitter {
8654
8761
  if (!this.client) {
8655
8762
  return;
8656
8763
  }
8657
- logger$6.info('WebRTC phone stop');
8764
+ logger$7.info('WebRTC phone stop');
8658
8765
  this.client.stop();
8659
8766
  }
8660
8767
 
@@ -8669,14 +8776,14 @@ class WebRTCPhone extends Emitter {
8669
8776
  async sendReinvite(callSession , constraints = null, conference = false,
8670
8777
  audioOnly = false) {
8671
8778
  const sipSession = this.findSipSession(callSession);
8672
- logger$6.info('WebRTC phone - send reinvite', {
8779
+ logger$7.info('WebRTC phone - send reinvite', {
8673
8780
  sessionId: sipSession ? sipSession.id : null,
8674
8781
  constraints,
8675
8782
  audioOnly,
8676
8783
  });
8677
8784
 
8678
8785
  if (!sipSession) {
8679
- return null;
8786
+ return false;
8680
8787
  }
8681
8788
 
8682
8789
  // $FlowFixMe
@@ -8686,19 +8793,17 @@ class WebRTCPhone extends Emitter {
8686
8793
  // Downgrade
8687
8794
  if (constraints && !isUpgrade) {
8688
8795
  // No reinvite needed
8689
- return this._downgradeToAudio(callSession);
8796
+ this._downgradeToAudio(callSession);
8797
+ return false;
8690
8798
  }
8691
8799
 
8692
8800
  if (isUpgrade) {
8693
8801
  const shouldReinvite = await this._upgradeToVideo(callSession, constraints, conference);
8694
8802
  if (!shouldReinvite) {
8695
- return;
8803
+ return false;
8696
8804
  }
8697
8805
  }
8698
8806
 
8699
- // Force reinvite in SDH
8700
- sipSession.sessionDescriptionHandler.localMediaStreamConstraints = null;
8701
-
8702
8807
  return this.client.reinvite(sipSession, constraints, conference, audioOnly);
8703
8808
  }
8704
8809
 
@@ -8707,7 +8812,7 @@ class WebRTCPhone extends Emitter {
8707
8812
  }
8708
8813
 
8709
8814
  startHeartbeat() {
8710
- logger$6.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8815
+ logger$7.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8711
8816
  if (!this.client || this.client.hasHeartbeat()) {
8712
8817
  return;
8713
8818
  }
@@ -8716,7 +8821,7 @@ class WebRTCPhone extends Emitter {
8716
8821
  }
8717
8822
 
8718
8823
  stopHeartbeat() {
8719
- logger$6.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8824
+ logger$7.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8720
8825
  if (!this.client) {
8721
8826
  return;
8722
8827
  }
@@ -8733,7 +8838,7 @@ class WebRTCPhone extends Emitter {
8733
8838
  }
8734
8839
 
8735
8840
  reconnect() {
8736
- logger$6.info('WebRTC phone - reconnect', { client: !!this.client });
8841
+ logger$7.info('WebRTC phone - reconnect', { client: !!this.client });
8737
8842
  if (!this.client) {
8738
8843
  return;
8739
8844
  }
@@ -8771,7 +8876,7 @@ class WebRTCPhone extends Emitter {
8771
8876
  _downgradeToAudio(callSession ) {
8772
8877
  const sipSession = this.findSipSession(callSession);
8773
8878
  if (!sipSession) {
8774
- return;
8879
+ return false;
8775
8880
  }
8776
8881
 
8777
8882
  // Release local video stream when downgrading to audio
@@ -8884,7 +8989,7 @@ class WebRTCPhone extends Emitter {
8884
8989
  // Monkey patch to know when canceled with the CANCEL message
8885
8990
  const onCancel = sipSession._onCancel.bind(sipSession);
8886
8991
  sipSession._onCancel = (message ) => {
8887
- logger$6.trace('on sip session canceled', { callId: message.callId });
8992
+ logger$7.trace('on sip session canceled', { callId: message.callId });
8888
8993
 
8889
8994
  onCancel(message);
8890
8995
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
@@ -8909,13 +9014,13 @@ class WebRTCPhone extends Emitter {
8909
9014
  this.audioOutputVolume,
8910
9015
  );
8911
9016
  case sessionState.SessionState.Terminating:
8912
- logger$6.info('WebRTC phone - call terminating', { sipId: sipSession.id });
9017
+ logger$7.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8913
9018
 
8914
9019
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
8915
9020
 
8916
9021
  break;
8917
9022
  case sessionState.SessionState.Terminated:
8918
- logger$6.info('WebRTC phone - call terminated', { sipId: sipSession.id });
9023
+ logger$7.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8919
9024
 
8920
9025
  this._onCallTerminated(sipSession);
8921
9026
 
@@ -8951,7 +9056,7 @@ class WebRTCPhone extends Emitter {
8951
9056
  }
8952
9057
 
8953
9058
  async startScreenSharing(constraints , callSession ) {
8954
- logger$6.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
9059
+ logger$7.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8955
9060
 
8956
9061
  const screenShareStream = await this._getStreamFromConstraints(constraints);
8957
9062
  if (!screenShareStream) {
@@ -8973,6 +9078,10 @@ class WebRTCPhone extends Emitter {
8973
9078
  localStream.removeTrack(videoTrack);
8974
9079
  }
8975
9080
 
9081
+ if (localStream) {
9082
+ localStream.addTrack(screenTrack);
9083
+ }
9084
+
8976
9085
  if (sender) {
8977
9086
  sender.replaceTrack(screenTrack);
8978
9087
  }
@@ -8987,7 +9096,8 @@ class WebRTCPhone extends Emitter {
8987
9096
  return;
8988
9097
  }
8989
9098
 
8990
- logger$6.info('WebRTC phone - stop screen sharing');
9099
+ logger$7.info('WebRTC phone - stop screen sharing');
9100
+ let reinvited = false;
8991
9101
 
8992
9102
  try {
8993
9103
  if (this.currentScreenShare.stream) {
@@ -9002,7 +9112,8 @@ class WebRTCPhone extends Emitter {
9002
9112
  // When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
9003
9113
  // We have to downgrade to audio.
9004
9114
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
9005
- await this.sendReinvite(targetCallSession, { audio: false, video: screenshareStopped }, conference);
9115
+ const constraints = { audio: false, video: screenshareStopped };
9116
+ reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
9006
9117
  }
9007
9118
  } catch (e) {
9008
9119
  console.warn(e);
@@ -9016,6 +9127,8 @@ class WebRTCPhone extends Emitter {
9016
9127
  );
9017
9128
 
9018
9129
  this.currentScreenShare = null;
9130
+
9131
+ return reinvited;
9019
9132
  }
9020
9133
 
9021
9134
  async _getStreamFromConstraints(constraints , conference = false) {
@@ -9053,7 +9166,7 @@ class WebRTCPhone extends Emitter {
9053
9166
  }
9054
9167
 
9055
9168
  _onCallAccepted(sipSession , cameraEnabled ) {
9056
- logger$6.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9169
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9057
9170
 
9058
9171
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9059
9172
  this.currentSipSession = sipSession;
@@ -9071,11 +9184,15 @@ class WebRTCPhone extends Emitter {
9071
9184
  }
9072
9185
 
9073
9186
  changeAudioDevice(id ) {
9074
- logger$6.info('WebRTC phone - change audio device', { deviceId: id });
9187
+ logger$7.info('WebRTC phone - change audio device', { deviceId: id });
9075
9188
  this.audioOutputDeviceId = id;
9076
9189
  this.client.changeAudioOutputDevice(id);
9077
9190
  }
9078
9191
 
9192
+ createAudioElementFor(sessionId ) {
9193
+ return this.client.createAudioElementFor(sessionId);
9194
+ }
9195
+
9079
9196
  changeRingDevice(id ) {
9080
9197
  this.audioRingDeviceId = id;
9081
9198
  }
@@ -9092,25 +9209,25 @@ class WebRTCPhone extends Emitter {
9092
9209
  }
9093
9210
 
9094
9211
  changeAudioInputDevice(id ) {
9095
- logger$6.info('WebRTC phone - changeAudio input device', { deviceId: id });
9212
+ logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
9096
9213
 
9097
9214
  return this.client.changeAudioInputDevice(id, this.currentSipSession);
9098
9215
  }
9099
9216
 
9100
9217
  changeVideoInputDevice(id ) {
9101
- logger$6.info('WebRTC phone - change video input device', { deviceId: id });
9218
+ logger$7.info('WebRTC phone - change video input device', { deviceId: id });
9102
9219
 
9103
9220
  return this.client.changeVideoInputDevice(id, this.currentSipSession);
9104
9221
  }
9105
9222
 
9106
9223
  changeSessionVideoInputDevice(id ) {
9107
- logger$6.info('WebRTC phone - change session video input device', { deviceId: id });
9224
+ logger$7.info('WebRTC phone - change session video input device', { deviceId: id });
9108
9225
 
9109
9226
  return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
9110
9227
  }
9111
9228
 
9112
9229
  _onCallTerminated(sipSession ) {
9113
- logger$6.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9230
+ logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9114
9231
 
9115
9232
  const callSession = this._createCallSession(sipSession);
9116
9233
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
@@ -9144,7 +9261,7 @@ class WebRTCPhone extends Emitter {
9144
9261
  const hasIncomingCallSession = this.hasIncomingCallSession();
9145
9262
 
9146
9263
  // Re-trigger incoming call event for remaining incoming calls
9147
- logger$6.info('WebRTC phone - check to re-trigger incoming call', {
9264
+ logger$7.info('WebRTC phone - check to re-trigger incoming call', {
9148
9265
  sipId: sipSession.id,
9149
9266
  shouldRetrigger,
9150
9267
  hasIncomingCallSession,
@@ -9233,37 +9350,37 @@ class WebRTCPhone extends Emitter {
9233
9350
 
9234
9351
  // Deprecated
9235
9352
  getLocalStreamForCall(callSession ) {
9236
- logger$6.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
9353
+ logger$7.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
9237
9354
 
9238
9355
  return this.getLocalStream(callSession);
9239
9356
  }
9240
9357
 
9241
9358
  // Deprecated
9242
9359
  getRemoteStreamForCall(callSession ) {
9243
- logger$6.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
9360
+ logger$7.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
9244
9361
 
9245
9362
  return this.getRemoteVideoStream(callSession);
9246
9363
  }
9247
9364
 
9248
9365
  getRemoteStreamsForCall(callSession ) {
9249
- logger$6.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
9366
+ logger$7.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
9250
9367
 
9251
9368
  return this.getRemoteStream(callSession);
9252
9369
  }
9253
9370
 
9254
9371
  accept(callSession , cameraEnabled ) {
9255
- logger$6.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
9372
+ logger$7.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
9256
9373
  if (this.currentSipSession) {
9257
9374
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
9258
9375
  }
9259
9376
 
9260
9377
  if (!callSession) {
9261
- logger$6.warn('no CallSession to accept.');
9378
+ logger$7.warn('no CallSession to accept.');
9262
9379
  return Promise.resolve(null);
9263
9380
  }
9264
9381
 
9265
9382
  if (callSession.getId() in this.acceptedSessions) {
9266
- logger$6.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
9383
+ logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
9267
9384
  return Promise.resolve(callSession.sipCallId);
9268
9385
  }
9269
9386
 
@@ -9275,24 +9392,24 @@ class WebRTCPhone extends Emitter {
9275
9392
  const sipSession = this.client.getSipSession(callSession.getId());
9276
9393
  if (sipSession) {
9277
9394
  if (sipSession.state === sessionState.SessionState.Terminated || sipSession.state === sessionState.SessionState.Terminating) {
9278
- logger$6.warn('Trying to answer a terminated sipSession.');
9395
+ logger$7.warn('Trying to answer a terminated sipSession.');
9279
9396
 
9280
9397
  return Promise.resolve(null);
9281
9398
  }
9282
9399
 
9283
- logger$6.info('accept call, session found', { sipId: sipSession.id });
9400
+ logger$7.info('accept call, session found', { sipId: sipSession.id });
9284
9401
 
9285
9402
  // $FlowFixMe
9286
9403
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
9287
9404
  return callSession.sipCallId;
9288
9405
  }).catch(e => {
9289
- logger$6.error(e);
9406
+ logger$7.error(e);
9290
9407
  this.endCurrentCall(callSession);
9291
9408
  throw e;
9292
9409
  });
9293
9410
  }
9294
9411
 
9295
- logger$6.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
9412
+ logger$7.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
9296
9413
 
9297
9414
  return Promise.resolve(null);
9298
9415
  }
@@ -9302,7 +9419,7 @@ class WebRTCPhone extends Emitter {
9302
9419
  }
9303
9420
 
9304
9421
  async reject(callSession ) {
9305
- logger$6.info('reject WebRTC called', { id: callSession.getId() });
9422
+ logger$7.info('reject WebRTC called', { id: callSession.getId() });
9306
9423
 
9307
9424
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call rejected locally');
9308
9425
  if (!callSession || callSession.getId() in this.rejectedSessions) {
@@ -9314,14 +9431,14 @@ class WebRTCPhone extends Emitter {
9314
9431
 
9315
9432
  const sipSession = this.findSipSession(callSession);
9316
9433
  if (sipSession) {
9317
- logger$6.info('WebRTC rejecting', { sipId: sipSession.id });
9434
+ logger$7.info('WebRTC rejecting', { sipId: sipSession.id });
9318
9435
 
9319
9436
  this.client.hangup(sipSession);
9320
9437
  }
9321
9438
  }
9322
9439
 
9323
9440
  async ignore(callSession ) {
9324
- logger$6.info('WebRTC ignore', { id: callSession.getId() });
9441
+ logger$7.info('WebRTC ignore', { id: callSession.getId() });
9325
9442
 
9326
9443
  // kill the ring
9327
9444
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'ignoring call');
@@ -9330,7 +9447,7 @@ class WebRTCPhone extends Emitter {
9330
9447
  }
9331
9448
 
9332
9449
  hold(callSession , withEvent = true, isConference = false) {
9333
- logger$6.info('WebRTC hold', { id: callSession.getId() });
9450
+ logger$7.info('WebRTC hold', { id: callSession.getId() });
9334
9451
 
9335
9452
  const sipSession = this.findSipSession(callSession);
9336
9453
 
@@ -9341,7 +9458,7 @@ class WebRTCPhone extends Emitter {
9341
9458
 
9342
9459
  // @Deprecated
9343
9460
  unhold(callSession , withEvent = true, isConference = false) {
9344
- logger$6.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
9461
+ logger$7.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
9345
9462
 
9346
9463
  console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
9347
9464
 
@@ -9356,7 +9473,7 @@ class WebRTCPhone extends Emitter {
9356
9473
  const sipSession = this.findSipSession(callSession);
9357
9474
 
9358
9475
  if (sipSession) {
9359
- logger$6.info('WebRTC atxfer', { sipId: sipSession.id });
9476
+ logger$7.info('WebRTC atxfer', { sipId: sipSession.id });
9360
9477
 
9361
9478
  return this.client.atxfer(sipSession);
9362
9479
  }
@@ -9371,7 +9488,7 @@ class WebRTCPhone extends Emitter {
9371
9488
  if (!sipSession) {
9372
9489
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
9373
9490
  }
9374
- logger$6.info('WebRTC hold sip session', { sipId: sipSession.id });
9491
+ logger$7.info('WebRTC hold sip session', { sipId: sipSession.id });
9375
9492
 
9376
9493
  const promise = this.client.hold(sipSession, isConference);
9377
9494
  if (withEvent) {
@@ -9390,7 +9507,7 @@ class WebRTCPhone extends Emitter {
9390
9507
  if (!sipSession) {
9391
9508
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
9392
9509
  }
9393
- logger$6.info('WebRTC unhold', { sipId: sipSession.id });
9510
+ logger$7.info('WebRTC unhold', { sipId: sipSession.id });
9394
9511
 
9395
9512
  const promise = this.client.unhold(sipSession, isConference);
9396
9513
  if (withEvent) {
@@ -9401,18 +9518,18 @@ class WebRTCPhone extends Emitter {
9401
9518
  }
9402
9519
 
9403
9520
  resume(callSession , isConference = false) {
9404
- logger$6.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
9521
+ logger$7.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
9405
9522
 
9406
9523
  const sipSession = this.findSipSession(callSession);
9407
9524
  if (!sipSession) {
9408
9525
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
9409
9526
  }
9410
9527
 
9411
- logger$6.info('WebRTC resuming', { sipId: sipSession.id });
9528
+ logger$7.info('WebRTC resuming', { sipId: sipSession.id });
9412
9529
 
9413
9530
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9414
9531
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9415
- logger$6.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9532
+ logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9416
9533
  this.holdSipSession(this.currentSipSession, callSession);
9417
9534
  }
9418
9535
 
@@ -9427,14 +9544,14 @@ class WebRTCPhone extends Emitter {
9427
9544
  }
9428
9545
 
9429
9546
  mute(callSession , withEvent = true) {
9430
- logger$6.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
9547
+ logger$7.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
9431
9548
 
9432
9549
  const sipSession = this.findSipSession(callSession);
9433
9550
  if (!sipSession) {
9434
9551
  return;
9435
9552
  }
9436
9553
 
9437
- logger$6.info('WebRTC muting', { sipId: sipSession.id });
9554
+ logger$7.info('WebRTC muting', { sipId: sipSession.id });
9438
9555
  this.client.mute(sipSession);
9439
9556
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: true });
9440
9557
 
@@ -9448,14 +9565,14 @@ class WebRTCPhone extends Emitter {
9448
9565
  }
9449
9566
 
9450
9567
  unmute(callSession , withEvent = true) {
9451
- logger$6.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
9568
+ logger$7.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
9452
9569
 
9453
9570
  const sipSession = this.findSipSession(callSession);
9454
9571
  if (!sipSession) {
9455
9572
  return;
9456
9573
  }
9457
9574
 
9458
- logger$6.info('WebRTC unmuting', { sipId: sipSession.id });
9575
+ logger$7.info('WebRTC unmuting', { sipId: sipSession.id });
9459
9576
  this.client.unmute(sipSession);
9460
9577
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: false });
9461
9578
 
@@ -9482,7 +9599,7 @@ class WebRTCPhone extends Emitter {
9482
9599
  if (!sipSession) {
9483
9600
  return;
9484
9601
  }
9485
- logger$6.info('WebRTC turn camera on', { sipId: sipSession.id });
9602
+ logger$7.info('WebRTC turn camera on', { sipId: sipSession.id });
9486
9603
 
9487
9604
  this.client.toggleCameraOn(sipSession);
9488
9605
 
@@ -9494,7 +9611,7 @@ class WebRTCPhone extends Emitter {
9494
9611
  if (!sipSession) {
9495
9612
  return;
9496
9613
  }
9497
- logger$6.info('WebRTC turn camera off', { sipId: sipSession.id });
9614
+ logger$7.info('WebRTC turn camera off', { sipId: sipSession.id });
9498
9615
 
9499
9616
  this.client.toggleCameraOff(sipSession);
9500
9617
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -9506,7 +9623,7 @@ class WebRTCPhone extends Emitter {
9506
9623
  return;
9507
9624
  }
9508
9625
 
9509
- logger$6.info('WebRTC send key', { sipId: sipSession.id, tone });
9626
+ logger$7.info('WebRTC send key', { sipId: sipSession.id, tone });
9510
9627
  this.client.sendDTMF(sipSession, tone);
9511
9628
  }
9512
9629
 
@@ -9514,7 +9631,7 @@ class WebRTCPhone extends Emitter {
9514
9631
  // @TODO: line is not used here
9515
9632
  async makeCall(number , line , cameraEnabled ,
9516
9633
  audioOnly = false, conference = false) {
9517
- logger$6.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9634
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9518
9635
  if (!number) {
9519
9636
  return Promise.resolve(null);
9520
9637
  }
@@ -9524,7 +9641,7 @@ class WebRTCPhone extends Emitter {
9524
9641
  }
9525
9642
  if (this.currentSipSession) {
9526
9643
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
9527
- logger$6.warn('Unable to hold current session when making another call', e);
9644
+ logger$7.warn('Unable to hold current session when making another call', e);
9528
9645
  });
9529
9646
  }
9530
9647
 
@@ -9534,7 +9651,7 @@ class WebRTCPhone extends Emitter {
9534
9651
  this._bindEvents(sipSession);
9535
9652
  } catch (error) {
9536
9653
  console.warn(error);
9537
- logger$6.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
9654
+ logger$7.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
9538
9655
  return Promise.resolve(null);
9539
9656
  }
9540
9657
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
@@ -9562,7 +9679,7 @@ class WebRTCPhone extends Emitter {
9562
9679
  return;
9563
9680
  }
9564
9681
 
9565
- logger$6.info('WebRTC transfer', { sipId: sipSession.id, target });
9682
+ logger$7.info('WebRTC transfer', { sipId: sipSession.id, target });
9566
9683
 
9567
9684
  this.client.transfer(sipSession, target);
9568
9685
  }
@@ -9571,7 +9688,7 @@ class WebRTCPhone extends Emitter {
9571
9688
  const sipSession = this.client.getSipSession(source.sipCallId);
9572
9689
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
9573
9690
 
9574
- logger$6.info('WebRTC indirect transfer', {
9691
+ logger$7.info('WebRTC indirect transfer', {
9575
9692
  sipId: sipSession ? sipSession.id : null,
9576
9693
  target: sipSessionTarget ? sipSessionTarget.id : null,
9577
9694
  });
@@ -9599,7 +9716,7 @@ class WebRTCPhone extends Emitter {
9599
9716
  return false;
9600
9717
  }
9601
9718
 
9602
- logger$6.info('WebRTC hangup', { sipId: sipSession.id });
9719
+ logger$7.info('WebRTC hangup', { sipId: sipSession.id });
9603
9720
 
9604
9721
  const sipSessionId = this.getSipSessionId(sipSession);
9605
9722
 
@@ -9644,7 +9761,7 @@ class WebRTCPhone extends Emitter {
9644
9761
  }
9645
9762
 
9646
9763
  async close() {
9647
- logger$6.info('WebRTC close');
9764
+ logger$7.info('WebRTC close');
9648
9765
 
9649
9766
  try {
9650
9767
  await Promise.race([
@@ -9652,7 +9769,7 @@ class WebRTCPhone extends Emitter {
9652
9769
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000)),
9653
9770
  ]);
9654
9771
  } catch (e) {
9655
- logger$6.error('WebRTC close, unregister error', e);
9772
+ logger$7.error('WebRTC close, unregister error', e);
9656
9773
  }
9657
9774
 
9658
9775
  this.client.close();
@@ -9670,12 +9787,12 @@ class WebRTCPhone extends Emitter {
9670
9787
  }
9671
9788
 
9672
9789
  enableRinging() {
9673
- logger$6.info('WebRTC enable ringing');
9790
+ logger$7.info('WebRTC enable ringing');
9674
9791
  this.ringingEnabled = true;
9675
9792
  }
9676
9793
 
9677
9794
  disableRinging() {
9678
- logger$6.info('WebRTC disable ringing');
9795
+ logger$7.info('WebRTC disable ringing');
9679
9796
  this.ringingEnabled = false;
9680
9797
  }
9681
9798
 
@@ -9715,7 +9832,7 @@ class WebRTCPhone extends Emitter {
9715
9832
 
9716
9833
  // Deprecated
9717
9834
  getLocalMediaStream(callSession ) {
9718
- logger$6.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9835
+ logger$7.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9719
9836
  return this.getLocalStream(callSession);
9720
9837
  }
9721
9838
 
@@ -9723,6 +9840,10 @@ class WebRTCPhone extends Emitter {
9723
9840
  return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
9724
9841
  }
9725
9842
 
9843
+ hasALocalVideoTrack(callSession ) {
9844
+ return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
9845
+ }
9846
+
9726
9847
  getRemoteStream(callSession ) {
9727
9848
  return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
9728
9849
  }
@@ -9745,7 +9866,7 @@ class WebRTCPhone extends Emitter {
9745
9866
  this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
9746
9867
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
9747
9868
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
9748
- logger$6.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9869
+ logger$7.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9749
9870
 
9750
9871
  const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
9751
9872
  this.incomingSessions.push(callSession.getId());
@@ -9768,7 +9889,7 @@ class WebRTCPhone extends Emitter {
9768
9889
  });
9769
9890
 
9770
9891
  this.client.on(this.client.ON_REINVITE, (...args) => {
9771
- logger$6.info('WebRTC on reinvite', {
9892
+ logger$7.info('WebRTC on reinvite', {
9772
9893
  sessionId: args[0].id,
9773
9894
  inviteId: args[1].id,
9774
9895
  updatedCalleeName: args[2],
@@ -9788,7 +9909,7 @@ class WebRTCPhone extends Emitter {
9788
9909
  });
9789
9910
 
9790
9911
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
9791
- logger$6.info('WebRTC call accepted', { sipId: sipSession.id });
9912
+ logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
9792
9913
 
9793
9914
  this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
9794
9915
 
@@ -9799,17 +9920,17 @@ class WebRTCPhone extends Emitter {
9799
9920
  this.client.on('ended', () => {});
9800
9921
 
9801
9922
  this.client.on(this.client.ON_ERROR, e => {
9802
- logger$6.error('WebRTC error', e);
9923
+ logger$7.error('WebRTC error', e);
9803
9924
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9804
9925
  });
9805
9926
 
9806
9927
  this.client.on(this.client.UNREGISTERED, () => {
9807
- logger$6.info('WebRTC unregistered');
9928
+ logger$7.info('WebRTC unregistered');
9808
9929
  this.eventEmitter.emit(ON_UNREGISTERED);
9809
9930
  });
9810
9931
 
9811
9932
  this.client.on(this.client.REGISTERED, () => {
9812
- logger$6.info('WebRTC registered', {
9933
+ logger$7.info('WebRTC registered', {
9813
9934
  shouldSendReinvite: this.shouldSendReinvite,
9814
9935
  state: this.currentSipSession ? this.currentSipSession.state : null,
9815
9936
  currentSipSession: !!this.currentSipSession,
@@ -9825,19 +9946,19 @@ class WebRTCPhone extends Emitter {
9825
9946
  try {
9826
9947
  this.sendReinvite(this.currentCallSession);
9827
9948
  } catch (e) {
9828
- logger$6.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9949
+ logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9829
9950
  }
9830
9951
  }
9831
9952
  });
9832
9953
 
9833
9954
  this.client.on(this.client.CONNECTED, () => {
9834
- logger$6.info('WebRTC client connected');
9955
+ logger$7.info('WebRTC client connected');
9835
9956
 
9836
9957
  this.stopHeartbeat();
9837
9958
  });
9838
9959
 
9839
9960
  this.client.on(this.client.DISCONNECTED, () => {
9840
- logger$6.info('WebRTC client disconnected');
9961
+ logger$7.info('WebRTC client disconnected');
9841
9962
 
9842
9963
  this.eventEmitter.emit(ON_UNREGISTERED);
9843
9964
 
@@ -10535,7 +10656,7 @@ var checks = [
10535
10656
 
10536
10657
  //
10537
10658
 
10538
- const logger$5 = IssueReporter$1.loggerFor('engine-check');
10659
+ const logger$6 = IssueReporter$1.loggerFor('engine-check');
10539
10660
 
10540
10661
  class Checker {
10541
10662
 
@@ -10553,28 +10674,28 @@ class Checker {
10553
10674
  async check(onCheckBegin = () => {}, onCheckResult = () => {}) {
10554
10675
  await this._addEngineVersion();
10555
10676
 
10556
- logger$5.info('Engine check starting');
10677
+ logger$6.info('Engine check starting');
10557
10678
 
10558
10679
  for (let i = 0; i < this.checks.length; i++) {
10559
10680
  const { name, check } = this.checks[i];
10560
10681
 
10561
- logger$5.info(`Checking ${name} ...`);
10682
+ logger$6.info(`Checking ${name} ...`);
10562
10683
 
10563
10684
  onCheckBegin(name);
10564
10685
  try {
10565
10686
  // eslint-disable-next-line no-await-in-loop
10566
10687
  const result = await check(this.server, this.session, this.externalAppConfig);
10567
- logger$5.info(`Checking ${name} success.`, { result });
10688
+ logger$6.info(`Checking ${name} success.`, { result });
10568
10689
 
10569
10690
  onCheckResult(name, result);
10570
10691
  } catch (e) {
10571
- logger$5.info(`Checking ${name} failure`, { message: e.message });
10692
+ logger$6.info(`Checking ${name} failure`, { message: e.message });
10572
10693
 
10573
10694
  onCheckResult(name, e);
10574
10695
  }
10575
10696
  }
10576
10697
 
10577
- logger$5.info('Engine check done.');
10698
+ logger$6.info('Engine check done.');
10578
10699
  }
10579
10700
 
10580
10701
  addCheck(check ) {
@@ -10668,7 +10789,7 @@ const getCallableNumber = (number , country ) => {
10668
10789
  class InvalidSubscription extends Error {}
10669
10790
  class InvalidAuthorization extends Error {}
10670
10791
 
10671
- const logger$4 = IssueReporter$1.loggerFor('simple-auth');
10792
+ const logger$5 = IssueReporter$1.loggerFor('simple-auth');
10672
10793
 
10673
10794
  class Auth {
10674
10795
 
@@ -10703,7 +10824,7 @@ class Auth {
10703
10824
  setApiClientId(this.clientId);
10704
10825
  setRefreshExpiration(this.expiration);
10705
10826
  setOnRefreshToken((token , session ) => {
10706
- logger$4.info('on refresh token done', { token });
10827
+ logger$5.info('on refresh token done', { token });
10707
10828
  setApiToken(token);
10708
10829
  Wazo.Websocket.updateToken(token);
10709
10830
 
@@ -11102,7 +11223,7 @@ class AdHocAPIConference {
11102
11223
 
11103
11224
  //
11104
11225
 
11105
- const logger$3 = IssueReporter$1.loggerFor('simple-phone');
11226
+ const logger$4 = IssueReporter$1.loggerFor('simple-phone');
11106
11227
  const sipLogger = IssueReporter$1.loggerFor('sip.js');
11107
11228
  const protocolLogger = IssueReporter$1.loggerFor('sip');
11108
11229
 
@@ -11209,7 +11330,7 @@ class Phone extends Emitter {
11209
11330
  async disconnect() {
11210
11331
  if (this.phone) {
11211
11332
  if (this.phone.hasAnActiveCall()) {
11212
- logger$3.info('hangup call on disconnect');
11333
+ logger$4.info('hangup call on disconnect');
11213
11334
  // $FlowFixMe
11214
11335
  await this.phone.hangup();
11215
11336
  }
@@ -11232,13 +11353,13 @@ class Phone extends Emitter {
11232
11353
  }
11233
11354
 
11234
11355
  async hangup(callSession ) {
11235
- logger$3.info('hangup via simple phone', { callId: callSession.getId() });
11356
+ logger$4.info('hangup via simple phone', { callId: callSession.getId() });
11236
11357
 
11237
11358
  return this.phone && this.phone.hangup(callSession);
11238
11359
  }
11239
11360
 
11240
11361
  async accept(callSession , cameraEnabled ) {
11241
- logger$3.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
11362
+ logger$4.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
11242
11363
 
11243
11364
  return this.phone && this.phone.accept(callSession, cameraEnabled);
11244
11365
  }
@@ -11258,13 +11379,18 @@ class Phone extends Emitter {
11258
11379
  return adHocConference.start();
11259
11380
  }
11260
11381
 
11261
- mute(callSession ) {
11262
- this.muteViaAPI(callSession);
11382
+ mute(callSession , withApi = true) {
11383
+ if (withApi) {
11384
+ this.muteViaAPI(callSession);
11385
+ }
11386
+
11263
11387
  return this.phone && this.phone.mute(callSession);
11264
11388
  }
11265
11389
 
11266
- unmute(callSession ) {
11267
- this.unmuteViaAPI(callSession);
11390
+ unmute(callSession , withApi = true) {
11391
+ if (withApi) {
11392
+ this.unmuteViaAPI(callSession);
11393
+ }
11268
11394
 
11269
11395
  return this.phone && this.phone.unmute(callSession);
11270
11396
  }
@@ -11272,7 +11398,7 @@ class Phone extends Emitter {
11272
11398
  muteViaAPI(callSession ) {
11273
11399
  if (callSession && callSession.callId) {
11274
11400
  Wazo.getApiClient().calld.mute(callSession.callId).catch(e => {
11275
- logger$3.error('Mute via API, error', e);
11401
+ logger$4.error('Mute via API, error', e);
11276
11402
  });
11277
11403
  }
11278
11404
  }
@@ -11280,7 +11406,7 @@ class Phone extends Emitter {
11280
11406
  unmuteViaAPI(callSession ) {
11281
11407
  if (callSession && callSession.callId) {
11282
11408
  Wazo.getApiClient().calld.unmute(callSession.callId).catch(e => {
11283
- logger$3.error('Unmute via API, error', e);
11409
+ logger$4.error('Unmute via API, error', e);
11284
11410
  });
11285
11411
  }
11286
11412
  }
@@ -11370,9 +11496,13 @@ class Phone extends Emitter {
11370
11496
  return this.phone && this.phone.hasLocalVideo(callSession);
11371
11497
  }
11372
11498
 
11499
+ hasALocalVideoTrack(callSession ) {
11500
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
11501
+ }
11502
+
11373
11503
  // @Deprecated
11374
11504
  getLocalMediaStream(callSession ) {
11375
- logger$3.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
11505
+ logger$4.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
11376
11506
 
11377
11507
  return this.phone && this.phone.getLocalStream(callSession);
11378
11508
  }
@@ -11391,20 +11521,20 @@ class Phone extends Emitter {
11391
11521
 
11392
11522
  // @Deprecated
11393
11523
  getRemoteStreamForCall(callSession ) {
11394
- logger$3.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
11524
+ logger$4.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
11395
11525
  return this.getRemoteStream(callSession);
11396
11526
  }
11397
11527
 
11398
11528
  // Returns remote streams directly from the peerConnection
11399
11529
  // @Deprecated
11400
11530
  getRemoteStreamsForCall(callSession ) {
11401
- logger$3.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
11531
+ logger$4.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
11402
11532
  return this.getLocalStream(callSession);
11403
11533
  }
11404
11534
 
11405
11535
  // @Deprecated
11406
11536
  getRemoteVideoStreamForCall(callSession ) {
11407
- logger$3.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
11537
+ logger$4.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
11408
11538
 
11409
11539
  return this.getRemoteVideoStream(callSession);
11410
11540
  }
@@ -11485,7 +11615,7 @@ var Phone$1 = global.wazoTelephonyInstance;
11485
11615
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
11486
11616
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
11487
11617
 
11488
- const logger$2 = IssueReporter$1.loggerFor('simple-ws-client');
11618
+ const logger$3 = IssueReporter$1.loggerFor('simple-ws-client');
11489
11619
 
11490
11620
  class Websocket extends Emitter {
11491
11621
 
@@ -11509,7 +11639,7 @@ class Websocket extends Emitter {
11509
11639
  }
11510
11640
 
11511
11641
  open(host , session ) {
11512
- logger$2.info('open simple WebSocket', { host, token: session.token });
11642
+ logger$3.info('open simple WebSocket', { host, token: session.token });
11513
11643
  this.ws = new WebSocketClient(
11514
11644
  {
11515
11645
  host,
@@ -11537,7 +11667,7 @@ class Websocket extends Emitter {
11537
11667
  }
11538
11668
 
11539
11669
  updateToken(token ) {
11540
- logger$2.info('update token via simple Websocket', { token, ws: !!this.ws });
11670
+ logger$3.info('update token via simple Websocket', { token, ws: !!this.ws });
11541
11671
 
11542
11672
  if (!this.ws) {
11543
11673
  return;
@@ -11565,7 +11695,7 @@ var Websocket$1 = global.wazoWebsocketInstance;
11565
11695
 
11566
11696
  //
11567
11697
 
11568
- const logger$1 = IssueReporter$1.loggerFor('room');
11698
+ const logger$2 = IssueReporter$1.loggerFor('room');
11569
11699
 
11570
11700
  class Participant extends Emitter {
11571
11701
 
@@ -11599,6 +11729,7 @@ class Participant extends Emitter {
11599
11729
 
11600
11730
 
11601
11731
  /**
11732
+ * @param room Room The room where the participant is
11602
11733
  * @param rawParticipant string Participant sent via the Wazo WS
11603
11734
  * @param extra Object extra status of the participant
11604
11735
  */
@@ -11686,7 +11817,7 @@ class Participant extends Emitter {
11686
11817
  }
11687
11818
 
11688
11819
  onTalking(isTalking ) {
11689
- logger$1.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
11820
+ logger$2.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
11690
11821
  this.isTalking = isTalking;
11691
11822
  // you may notice we're not broadcasting: since all participants are getting this info
11692
11823
  // directly from asterisk, there's no need to do so
@@ -11789,7 +11920,7 @@ class Participant extends Emitter {
11789
11920
  }
11790
11921
 
11791
11922
  updateStatus(status , broadcast = true) {
11792
- logger$1.info('updating participant status', { name: this.name, status });
11923
+ logger$2.info('updating participant status', { name: this.name, status });
11793
11924
 
11794
11925
  if (typeof status.audioMuted !== 'undefined' && status.audioMuted !== this.audioMuted) {
11795
11926
  if (status.audioMuted) {
@@ -11826,13 +11957,18 @@ class Participant extends Emitter {
11826
11957
  // Poor man's object comparison
11827
11958
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
11828
11959
  this.extra = { ...this.extra, ...status.extra };
11960
+
11961
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
11962
+ this.extra.contact = new Contact(this.extra.contact);
11963
+ }
11964
+
11829
11965
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
11830
11966
  }
11831
11967
  }
11832
11968
 
11833
11969
  broadcastStatus(inboundStatus = null) {
11834
11970
  const status = inboundStatus || this.getStatus();
11835
- logger$1.info('broadcasting participant status', { callId: this.callId, status });
11971
+ logger$2.info('broadcasting participant status', { callId: this.callId, status });
11836
11972
 
11837
11973
  this.room.sendSignal({
11838
11974
  type: SIGNAL_TYPE_PARTICIPANT_UPDATE,
@@ -11853,18 +11989,24 @@ class RemoteParticipant extends Participant {
11853
11989
  }
11854
11990
  }
11855
11991
 
11856
- /* global document */
11992
+ //
11993
+
11994
+ class LocalParticipant extends Participant {
11995
+ }
11996
+
11997
+ //
11857
11998
 
11858
11999
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
11859
12000
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
11860
12001
 
11861
- const logger = IssueReporter$1.loggerFor('sdk-room');
12002
+ const logger$1 = IssueReporter$1.loggerFor('sdk-room');
11862
12003
 
11863
12004
  class Room extends Emitter {
11864
12005
 
11865
12006
 
11866
12007
 
11867
12008
 
12009
+
11868
12010
 
11869
12011
 
11870
12012
 
@@ -11886,6 +12028,8 @@ class Room extends Emitter {
11886
12028
 
11887
12029
 
11888
12030
 
12031
+
12032
+
11889
12033
 
11890
12034
 
11891
12035
 
@@ -11903,6 +12047,7 @@ class Room extends Emitter {
11903
12047
  * @param extension string
11904
12048
  * @param sourceId number
11905
12049
  * @param callId string
12050
+ * @param meetingUuid string
11906
12051
  * @param extra Object
11907
12052
  */
11908
12053
  constructor(
@@ -11910,15 +12055,17 @@ class Room extends Emitter {
11910
12055
  extension ,
11911
12056
  sourceId ,
11912
12057
  callId ,
12058
+ meetingUuid ,
11913
12059
  extra = {},
11914
12060
  ) {
11915
12061
  super();
11916
- logger.info('room initialized', { callId, extension, sourceId });
12062
+ logger$1.info('room initialized', { callId, extension, sourceId, meetingUuid });
11917
12063
 
11918
12064
  // Represents the room callSession
11919
12065
  this.callSession = callSession;
11920
12066
  this.extension = extension;
11921
12067
  this.sourceId = sourceId;
12068
+ this.meetingUuid = meetingUuid;
11922
12069
  this.callId = callId;
11923
12070
  this.participants = [];
11924
12071
  this.connected = false;
@@ -11938,6 +12085,8 @@ class Room extends Emitter {
11938
12085
  // Sugar syntax for `room.EVENT_NAME`
11939
12086
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
11940
12087
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
12088
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
12089
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
11941
12090
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
11942
12091
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
11943
12092
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -11972,10 +12121,11 @@ class Room extends Emitter {
11972
12121
  * @param audioOnly boolean
11973
12122
  * @param extra Object
11974
12123
  * @param room ?Room
12124
+ * @param meeting ?Meeting
11975
12125
  * @returns {Promise<Room>}
11976
12126
  */
11977
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
11978
- logger.info('connecting to room', { extension, audioOnly, room: !!room });
12127
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
12128
+ logger$1.info('connecting to room', { extension, audioOnly, room: !!room });
11979
12129
 
11980
12130
  if (!room) {
11981
12131
  await Wazo.Phone.connect();
@@ -11988,7 +12138,7 @@ class Room extends Emitter {
11988
12138
 
11989
12139
  // Call_created is triggered before call_accepted, so we have to listen for it here.
11990
12140
  Wazo.Websocket.once(Wazo.Websocket.CALL_CREATED, ({ data }) => {
11991
- logger.info('room call received via WS', { callId: data.call_id });
12141
+ logger$1.info('room call received via WS', { callId: data.call_id });
11992
12142
  if (room) {
11993
12143
  room.setCallId(data.call_id);
11994
12144
  }
@@ -12009,34 +12159,44 @@ class Room extends Emitter {
12009
12159
  room.setCallId(room.callSession.call.id);
12010
12160
  }
12011
12161
 
12012
- // Fetch conference source
12013
- const sources = await getApiClient().dird.fetchConferenceSource('default');
12014
- // Retrieve conference sources
12015
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
12016
- // Retrieve conference
12017
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
12162
+ if (!meeting) {
12163
+ // Fetch conference source
12164
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
12165
+ // Retrieve conference sources
12166
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
12167
+ // Retrieve conference
12168
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
12018
12169
 
12019
- logger.info('connected to room', {
12020
- sourceId: conference ? conference.sourceId : null,
12021
- name: conference ? conference.name : null,
12022
- });
12170
+ logger$1.info('connected to room', {
12171
+ sourceId: conference ? conference.sourceId : null,
12172
+ name: conference ? conference.name : null,
12173
+ });
12023
12174
 
12024
- if (conference) {
12025
- room.setSourceId(conference.sourceId);
12026
- room.setName(conference.name);
12175
+ if (conference) {
12176
+ room.setSourceId(conference.sourceId);
12177
+ room.setName(conference.name);
12178
+ }
12179
+ } else if (meeting) {
12180
+ logger$1.info('Already connected to meeting', {
12181
+ uuid: meeting.uuid,
12182
+ name: meeting.name,
12183
+ });
12184
+
12185
+ room.setMeetingUuid(meeting.uuid);
12186
+ room.setName(meeting.name);
12027
12187
  }
12028
12188
 
12029
12189
  return room;
12030
12190
  }
12031
12191
 
12032
12192
  static disconnect() {
12033
- logger.info('static disconnection to room');
12193
+ logger$1.info('static disconnection to room');
12034
12194
 
12035
12195
  Wazo.Phone.disconnect();
12036
12196
  }
12037
12197
 
12038
12198
  async disconnect() {
12039
- logger.info('disconnection to room called');
12199
+ logger$1.info('disconnection to room called');
12040
12200
 
12041
12201
  await Wazo.Phone.hangup(this.callSession);
12042
12202
  this.callSession = null;
@@ -12051,20 +12211,24 @@ class Room extends Emitter {
12051
12211
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
12052
12212
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12053
12213
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12054
-
12055
- if (this.roomAudioElement && document.body) {
12056
- document.body.removeChild(this.roomAudioElement);
12057
- }
12214
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12215
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12058
12216
  }
12059
12217
 
12060
12218
  setSourceId(sourceId ) {
12061
- logger.info('set room source id', { sourceId });
12219
+ logger$1.info('set room source id', { sourceId });
12062
12220
 
12063
12221
  this.sourceId = sourceId;
12064
12222
  }
12065
12223
 
12224
+ setMeetingUuid(meetingUuid ) {
12225
+ logger$1.info('set meeting uuid', { meetingUuid });
12226
+
12227
+ this.meetingUuid = meetingUuid;
12228
+ }
12229
+
12066
12230
  setCallId(callId ) {
12067
- logger.info('set room call id', { callId });
12231
+ logger$1.info('set room call id', { callId });
12068
12232
 
12069
12233
  if (callId) {
12070
12234
  this.callId = callId;
@@ -12072,7 +12236,7 @@ class Room extends Emitter {
12072
12236
  }
12073
12237
 
12074
12238
  setName(name ) {
12075
- logger.info('set room name', { name });
12239
+ logger$1.info('set room name', { name });
12076
12240
 
12077
12241
  this.name = name;
12078
12242
  }
@@ -12091,7 +12255,7 @@ class Room extends Emitter {
12091
12255
  }
12092
12256
 
12093
12257
  async startScreenSharing(constraints ) {
12094
- logger.info('start room screen sharing', { constraints });
12258
+ logger$1.info('start room screen sharing', { constraints });
12095
12259
 
12096
12260
  const screensharingStream = await Wazo.Phone.startScreenSharing(constraints, this.callSession);
12097
12261
  if (!screensharingStream) {
@@ -12104,18 +12268,26 @@ class Room extends Emitter {
12104
12268
  return screensharingStream;
12105
12269
  }
12106
12270
 
12107
- stopScreenSharing(restoreLocalStream = true) {
12108
- logger.info('stop room screen sharing');
12271
+ async stopScreenSharing(restoreLocalStream = true) {
12272
+ logger$1.info('stop room screen sharing');
12109
12273
 
12110
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
12274
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
12111
12275
 
12112
12276
  if (this.localParticipant) {
12113
12277
  this.localParticipant.onStopScreensharing();
12114
12278
  }
12279
+
12280
+ if (!reinvited && this.localParticipant) {
12281
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
12282
+ // So not REINVITE even is fired, we have to restore the video stream manually
12283
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
12284
+ // $FlowFixMe
12285
+ this._associateStreamTo(localVideoStream, this.localParticipant);
12286
+ }
12115
12287
  }
12116
12288
 
12117
12289
  turnCameraOff() {
12118
- logger.info('turn room camera off');
12290
+ logger$1.info('turn room camera off');
12119
12291
 
12120
12292
  Wazo.Phone.turnCameraOff(this.callSession);
12121
12293
 
@@ -12125,7 +12297,7 @@ class Room extends Emitter {
12125
12297
  }
12126
12298
 
12127
12299
  turnCameraOn() {
12128
- logger.info('turn room camera on');
12300
+ logger$1.info('turn room camera on');
12129
12301
 
12130
12302
  Wazo.Phone.turnCameraOn(this.callSession);
12131
12303
 
@@ -12135,7 +12307,7 @@ class Room extends Emitter {
12135
12307
  }
12136
12308
 
12137
12309
  mute() {
12138
- logger.info('mute room');
12310
+ logger$1.info('mute room');
12139
12311
 
12140
12312
  Wazo.Phone.mute(this.callSession);
12141
12313
 
@@ -12143,7 +12315,7 @@ class Room extends Emitter {
12143
12315
  }
12144
12316
 
12145
12317
  unmute() {
12146
- logger.info('unmute room');
12318
+ logger$1.info('unmute room');
12147
12319
 
12148
12320
  Wazo.Phone.unmute(this.callSession);
12149
12321
 
@@ -12163,7 +12335,7 @@ class Room extends Emitter {
12163
12335
  }
12164
12336
 
12165
12337
  hold() {
12166
- logger.info('hold room');
12338
+ logger$1.info('hold room');
12167
12339
 
12168
12340
  Wazo.Phone.hold(this.callSession, true);
12169
12341
 
@@ -12173,7 +12345,7 @@ class Room extends Emitter {
12173
12345
  }
12174
12346
 
12175
12347
  resume() {
12176
- logger.info('resume room');
12348
+ logger$1.info('resume room');
12177
12349
 
12178
12350
  Wazo.Phone.resume(this.callSession, true);
12179
12351
 
@@ -12183,13 +12355,13 @@ class Room extends Emitter {
12183
12355
  }
12184
12356
 
12185
12357
  sendDTMF(tone ) {
12186
- logger.info('send room DTMF', { tone });
12358
+ logger$1.info('send room DTMF', { tone });
12187
12359
 
12188
12360
  Wazo.Phone.sendDTMF(tone, this.callSession);
12189
12361
  }
12190
12362
 
12191
12363
  async sendReinvite(newConstraints = null) {
12192
- logger.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
12364
+ logger$1.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
12193
12365
  const wasScreensharing = this.localParticipant && this.localParticipant.screensharing;
12194
12366
 
12195
12367
  Wazo.Phone.on(Wazo.Phone.ON_SHARE_SCREEN_STARTED, () => {
@@ -12214,6 +12386,22 @@ class Room extends Emitter {
12214
12386
  return response;
12215
12387
  }
12216
12388
 
12389
+ hasALocalVideoTrack() {
12390
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
12391
+ }
12392
+
12393
+ getLocalStream() {
12394
+ return Wazo.Phone.getLocalStream(this.callSession);
12395
+ }
12396
+
12397
+ getRemoteStream() {
12398
+ return Wazo.Phone.getRemoteStream(this.callSession);
12399
+ }
12400
+
12401
+ getRemoteVideoStream() {
12402
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
12403
+ }
12404
+
12217
12405
  _bindEvents() {
12218
12406
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
12219
12407
  return;
@@ -12232,35 +12420,18 @@ class Room extends Emitter {
12232
12420
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
12233
12421
 
12234
12422
  this.on(this.ON_AUDIO_STREAM, stream => {
12235
- logger.info('on room audio stream');
12423
+ logger$1.info('on room audio stream');
12236
12424
 
12237
12425
  this.audioStream = stream;
12238
- if (document.createElement) {
12239
- // $FlowFixMe
12240
- let roomAudioElement = document.getElementById('audio-room');
12241
- if (!this.roomAudioElement) {
12242
- roomAudioElement = document.createElement('audio');
12243
- // $FlowFixMe
12244
- document.body.appendChild(roomAudioElement);
12245
- }
12246
- if (!roomAudioElement) {
12247
- return;
12248
- }
12249
- this.roomAudioElement = roomAudioElement;
12426
+ if (!this.roomAudioElement) {
12427
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
12428
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
12250
12429
  this.roomAudioElement.srcObject = stream;
12251
- this.roomAudioElement.autoplay = true;
12252
- this.roomAudioElement.id = 'audio-room';
12253
-
12254
- // $FlowFixMe
12255
- if (this.roomAudioElement.setSinkId) {
12256
- // $FlowFixMe
12257
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
12258
- }
12259
12430
  }
12260
12431
  });
12261
12432
 
12262
12433
  this.on(this.ON_VIDEO_STREAM, (stream, streamId, event, sipSession) => {
12263
- logger.info('on room video stream', { streamId });
12434
+ logger$1.info('on room video stream', { streamId });
12264
12435
 
12265
12436
  this._mapMsid(sipSession.body.body);
12266
12437
 
@@ -12275,7 +12446,7 @@ class Room extends Emitter {
12275
12446
  });
12276
12447
 
12277
12448
  this.on(this.ON_REMOVE_STREAM, stream => {
12278
- logger.info('on room remove stream');
12449
+ logger$1.info('on room remove stream');
12279
12450
 
12280
12451
  const participant = this.participants.find(someParticipant =>
12281
12452
  someParticipant.streams.find(someStream => someStream && someStream.id === stream.id));
@@ -12330,6 +12501,9 @@ class Room extends Emitter {
12330
12501
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12331
12502
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12332
12503
 
12504
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12505
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12506
+
12333
12507
  // Phone events
12334
12508
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
12335
12509
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -12340,15 +12514,15 @@ class Room extends Emitter {
12340
12514
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
12341
12515
  }
12342
12516
 
12343
- _onMessage(message ) {
12517
+ _onMessage(message ) {
12344
12518
  if (message.method !== 'MESSAGE') {
12345
- return;
12519
+ return null;
12346
12520
  }
12347
12521
  let body;
12348
12522
  try {
12349
12523
  body = JSON.parse(message.body);
12350
12524
  } catch (e) {
12351
- return;
12525
+ return null;
12352
12526
  }
12353
12527
 
12354
12528
  switch (body.type) {
@@ -12367,6 +12541,8 @@ class Room extends Emitter {
12367
12541
  }
12368
12542
 
12369
12543
  this.eventEmitter.emit(this.ON_MESSAGE, body);
12544
+
12545
+ return body;
12370
12546
  }
12371
12547
 
12372
12548
  _onChat(content ) {
@@ -12402,7 +12578,7 @@ class Room extends Emitter {
12402
12578
  const requester = this._getParticipantFromCallId(origin.callId);
12403
12579
  if (requester) {
12404
12580
  // @FIXME?: when need to trigger an update on join-in; this is a bit of a hack
12405
- logger.info('trigger room requester status', { origin });
12581
+ logger$1.info('trigger room requester status', { origin });
12406
12582
  requester.triggerUpdate('REQUESTER_UPDATE');
12407
12583
  }
12408
12584
  break;
@@ -12431,25 +12607,26 @@ class Room extends Emitter {
12431
12607
  const session = Wazo.Auth.getSession();
12432
12608
  let participants = [];
12433
12609
 
12434
- // @TODO: we could use a better function name here
12435
- const isJoining = part => {
12436
- this.__associateStreams(part);
12437
- // @VALIDATE: no need to publicize ourselves, no?
12438
- if (part instanceof RemoteParticipant) {
12439
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
12440
- }
12441
- };
12442
-
12443
12610
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
12444
12611
  if (participant.user_uuid === session.uuid) {
12445
- logger.info('room current user joined');
12612
+ logger$1.info('room current user joined');
12446
12613
 
12447
12614
  // Retrieve participants via an API calls
12448
12615
  const conferenceId = this.sourceId || payload.data.conference_id;
12449
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
12450
- logger.info('fetching conference participants', { conferenceId });
12616
+ let response;
12617
+ try {
12618
+ if (this.meetingUuid) {
12619
+ logger$1.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
12620
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
12621
+ } else {
12622
+ logger$1.info('fetching conference participants', { conferenceId });
12623
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
12624
+ }
12625
+ } catch (e) {
12626
+ logger$1.error('room participants fetching, error', e);
12627
+ }
12451
12628
  if (response) {
12452
- logger.info('conference participants fetched', { nb: response.items.length });
12629
+ logger$1.info('conference participants fetched', { nb: response.items.length });
12453
12630
  participants = response.items.map(item => {
12454
12631
  const isMe = item.call_id === this.callId;
12455
12632
 
@@ -12462,25 +12639,10 @@ class Room extends Emitter {
12462
12639
 
12463
12640
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
12464
12641
  if (!this.localParticipant && localParticipant) {
12465
- this.localParticipant = localParticipant;
12466
-
12467
- const localVideoStream = this._getLocalVideoStream();
12468
- if (localVideoStream) {
12469
- this._saveLocalVideoStream(localVideoStream);
12470
- }
12471
-
12472
- this.connected = true;
12473
-
12474
- // we're in the room, now let's request everyone's status
12475
- if (this.localParticipant) {
12476
- this.sendSignal({
12477
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
12478
- origin: this.localParticipant.getStatus(),
12479
- });
12480
- }
12642
+ this._onLocalParticipantJoined(localParticipant);
12481
12643
  }
12482
12644
 
12483
- participants.forEach(someParticipant => isJoining(someParticipant));
12645
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
12484
12646
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
12485
12647
  }
12486
12648
 
@@ -12491,16 +12653,45 @@ class Room extends Emitter {
12491
12653
  ? new Wazo.RemoteParticipant(this, participant)
12492
12654
  : null;
12493
12655
 
12494
- logger.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
12656
+ logger$1.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
12495
12657
 
12496
12658
  if (remoteParticipant) {
12497
12659
  this.participants.push(remoteParticipant);
12498
- isJoining(remoteParticipant);
12660
+ this._isParticipantJoining(remoteParticipant);
12499
12661
  }
12500
12662
 
12501
12663
  return remoteParticipant;
12502
12664
  }
12503
12665
 
12666
+ _onLocalParticipantJoined(localParticipant ) {
12667
+ this.localParticipant = localParticipant;
12668
+
12669
+ const localVideoStream = this._getLocalVideoStream();
12670
+ if (localVideoStream) {
12671
+ this._saveLocalVideoStream(localVideoStream);
12672
+ }
12673
+
12674
+ this.connected = true;
12675
+
12676
+ localParticipant.broadcastStatus();
12677
+
12678
+ // we're in the room, now let's request everyone's status
12679
+ if (this.localParticipant) {
12680
+ this.sendSignal({
12681
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
12682
+ origin: this.localParticipant.getStatus(),
12683
+ });
12684
+ }
12685
+ }
12686
+
12687
+ _isParticipantJoining(participant ) {
12688
+ this.__associateStreams(participant);
12689
+ // @VALIDATE: no need to publicize ourselves, no?
12690
+ if (participant instanceof RemoteParticipant) {
12691
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
12692
+ }
12693
+ }
12694
+
12504
12695
  _saveLocalVideoStream(stream ) {
12505
12696
  const { localParticipant } = this;
12506
12697
 
@@ -12546,9 +12737,11 @@ class Room extends Emitter {
12546
12737
  _onParticipantTrackUpdate(oldParticipant , update ) {
12547
12738
  const newParticipant = oldParticipant;
12548
12739
 
12549
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
12740
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
12550
12741
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
12551
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
12742
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
12743
+ const stream = pc.getRemoteStreams().find(someStream =>
12744
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
12552
12745
 
12553
12746
  if (update === 'downgrade') {
12554
12747
  newParticipant.streams = [];
@@ -12578,15 +12771,42 @@ class Room extends Emitter {
12578
12771
  return;
12579
12772
  }
12580
12773
 
12581
- if (this._unassociatedVideoStreams[trackId]) {
12774
+ const streamId = this._getStreamIdFrTrackId(trackId);
12775
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
12776
+ const stream = this._unassociatedVideoStreams[key];
12777
+
12778
+ if (stream) {
12582
12779
  // Try to associate stream
12583
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
12780
+ this._associateStreamTo(stream, participant);
12584
12781
 
12585
- delete this._unassociatedVideoStreams[trackId];
12782
+ delete this._unassociatedVideoStreams[key];
12586
12783
  delete this._unassociatedParticipants[participant.callId];
12587
12784
  }
12588
12785
  }
12589
12786
 
12787
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
12788
+ // Find by trackId
12789
+ if (trackId in this._unassociatedVideoStreams) {
12790
+ return trackId;
12791
+ }
12792
+
12793
+ // Find by streamId
12794
+ if (streamId && streamId in this._unassociatedVideoStreams) {
12795
+ return streamId;
12796
+ }
12797
+
12798
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
12799
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12800
+ stream && stream.id === streamId);
12801
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12802
+ }
12803
+
12804
+ _getStreamIdFrTrackId(trackId ) {
12805
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
12806
+
12807
+ return mapping ? mapping.streamId : null;
12808
+ }
12809
+
12590
12810
  _associateStreamTo(rawStream , participant ) {
12591
12811
  const stream = new Wazo.Stream(rawStream, participant);
12592
12812
  participant.streams.push(stream);
@@ -12610,7 +12830,141 @@ class Room extends Emitter {
12610
12830
 
12611
12831
  //
12612
12832
 
12613
- class LocalParticipant extends Participant {
12833
+ const logger = IssueReporter$1.loggerFor('sdk-sip-room');
12834
+
12835
+ class SipRoom extends Room {
12836
+
12837
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
12838
+ logger.info('connecting to sip room', { extension, audioOnly, room: !!room });
12839
+
12840
+ if (!room) {
12841
+ await Wazo.Phone.connect();
12842
+
12843
+ const withCamera = constraints && !!constraints.video;
12844
+
12845
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
12846
+ // eslint-disable-next-line no-param-reassign
12847
+ room = new SipRoom(callSession, extension, null, null, extra);
12848
+ }
12849
+
12850
+ if (room && room.callSession && room.callSession.call) {
12851
+ room.setCallId(room.callSession.call.id);
12852
+ }
12853
+
12854
+ logger.info('connected to room', {
12855
+ extension: room.extension,
12856
+ });
12857
+
12858
+ return room;
12859
+ }
12860
+
12861
+ mute() {
12862
+ logger.info('mute sip room');
12863
+
12864
+ Wazo.Phone.mute(this.callSession, false);
12865
+
12866
+ this.sendMuteStatus();
12867
+ }
12868
+
12869
+ unmute() {
12870
+ logger.info('unmute sip room');
12871
+
12872
+ Wazo.Phone.unmute(this.callSession, false);
12873
+
12874
+ this.sendUnMuteStatus();
12875
+ }
12876
+
12877
+ getLocalGuestName() {
12878
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
12879
+ }
12880
+
12881
+ // Overridden to not listen to websocket messages
12882
+ _transferEvents() {
12883
+ // Phone events
12884
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
12885
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
12886
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
12887
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
12888
+
12889
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
12890
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
12891
+ }
12892
+
12893
+ _onMessage(message ) {
12894
+ // eslint-disable-next-line no-underscore-dangle
12895
+ const body = super._onMessage(message);
12896
+ if (!body) {
12897
+ return;
12898
+ }
12899
+
12900
+ const getChannel = () => body.channels[0];
12901
+
12902
+ switch (body.type) {
12903
+ case 'ConfbridgeWelcome':
12904
+ body.channels.forEach(channel => {
12905
+ this._onParticipantJoined(channel);
12906
+ });
12907
+
12908
+ break;
12909
+ case 'ConfbridgeJoin': {
12910
+ const channel = getChannel();
12911
+ this._onParticipantJoined(channel);
12912
+ break;
12913
+ }
12914
+ case 'ConfbridgeLeave': {
12915
+ const channel = getChannel();
12916
+ this._onParticipantLeft({
12917
+ data: {
12918
+ call_id: channel.id,
12919
+ },
12920
+ });
12921
+ break;
12922
+ }
12923
+ }
12924
+ }
12925
+
12926
+ async _onParticipantJoined(channel ) {
12927
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
12928
+ const callId = channel.id;
12929
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
12930
+ const name = channel.caller ? channel.caller.name : null;
12931
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
12932
+ const participant = new ParticipantClass(this, {
12933
+ caller_id_name: name,
12934
+ call_id: callId,
12935
+ }, extra);
12936
+
12937
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
12938
+ if (participantIdx !== -1 && name) {
12939
+ this.participants[participantIdx].name = name;
12940
+ return;
12941
+ }
12942
+
12943
+ if (isLocal) {
12944
+ // Should be updated by the Wazo WS but we don't have it for now
12945
+ if (this.callSession) {
12946
+ this.callSession.ringing = false;
12947
+ }
12948
+
12949
+ this._onLocalParticipantJoined(participant);
12950
+
12951
+ // Give some time for the stream to be updated
12952
+ setTimeout(() => {
12953
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
12954
+ }, 1000);
12955
+ }
12956
+
12957
+ this.participants.push(participant);
12958
+
12959
+ this._isParticipantJoining(participant);
12960
+
12961
+ return participant;
12962
+ }
12963
+
12964
+ _getCurrentSipCallIs() {
12965
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
12966
+ }
12967
+
12614
12968
  }
12615
12969
 
12616
12970
  /* global document */
@@ -12663,9 +13017,7 @@ class Stream {
12663
13017
  return false;
12664
13018
  }
12665
13019
 
12666
- // With canvas track (used to fake upgrade in conference), we don't have a width
12667
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
12668
- && track.readyState !== 'ended' && 'width' in track.getSettings());
13020
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
12669
13021
  }
12670
13022
 
12671
13023
  get id() {
@@ -12729,6 +13081,7 @@ const Wazo = {
12729
13081
  Phone: Phone$1,
12730
13082
  Websocket: Websocket$1,
12731
13083
  Room,
13084
+ SipRoom,
12732
13085
  RemoteParticipant,
12733
13086
  LocalParticipant,
12734
13087
  Stream,
@@ -12765,6 +13118,7 @@ const Wazo = {
12765
13118
  IndirectTransfer,
12766
13119
  SwitchboardCall,
12767
13120
  WebRTCPhone,
13121
+ Meeting,
12768
13122
  },
12769
13123
 
12770
13124
  // Api
@@ -12854,6 +13208,7 @@ var index = {
12854
13208
  SOCKET_EVENTS: SOCKET_EVENTS$1,
12855
13209
  Wazo,
12856
13210
  WebRTCPhone,
13211
+ Meeting,
12857
13212
  };
12858
13213
 
12859
13214
  module.exports = index;