@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
@@ -128,7 +128,7 @@ const isMobile = () => typeof navigator !== 'undefined' && navigator.product ===
128
128
 
129
129
  const methods = ['head', 'get', 'post', 'put', 'delete'];
130
130
 
131
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
131
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
132
132
 
133
133
  // Use a function here to be able to mock it in tests
134
134
  const realFetch = () => {
@@ -267,7 +267,7 @@ class ApiRequester {
267
267
  };
268
268
 
269
269
  if (this.refreshTokenPromise) {
270
- logger$b.info('A token is already refreshing, waiting ...', { url });
270
+ logger$c.info('A token is already refreshing, waiting ...', { url });
271
271
  await this.refreshTokenPromise;
272
272
  }
273
273
 
@@ -287,7 +287,7 @@ class ApiRequester {
287
287
  return promise.then(async (err ) => {
288
288
  // Check if the token is still valid
289
289
  if (firstCall && this._checkTokenExpired(response, err)) {
290
- logger$b.warn('token expired', { error: err.reason });
290
+ logger$c.warn('token expired', { error: err.reason });
291
291
  // Replay the call after refreshing the token
292
292
  return this._replayWithNewToken(err, path, method, body, headers, parse);
293
293
  }
@@ -297,7 +297,7 @@ class ApiRequester {
297
297
  : exceptionClass.fromResponse(err, response.status);
298
298
 
299
299
  if (this.shouldLogErrors) {
300
- logger$b.error('API error', error);
300
+ logger$c.error('API error', error);
301
301
  }
302
302
 
303
303
  throw error;
@@ -307,7 +307,7 @@ class ApiRequester {
307
307
  return newParse(response, isJson);
308
308
  }).catch(error => {
309
309
  if (this.shouldLogErrors) {
310
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
310
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
311
311
  }
312
312
 
313
313
  throw error;
@@ -335,13 +335,13 @@ class ApiRequester {
335
335
  ) {
336
336
  const isTokenNotFound = this._isTokenNotFound(err);
337
337
  let newPath = path;
338
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
338
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
339
339
 
340
340
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
341
341
 
342
342
  return this.refreshTokenPromise.then(() => {
343
343
  this.refreshTokenPromise = null;
344
- logger$b.info('token refreshed', { isTokenNotFound });
344
+ logger$c.info('token refreshed', { isTokenNotFound });
345
345
  if (isTokenNotFound) {
346
346
  const pathParts = path.split('/');
347
347
  pathParts.pop();
@@ -2538,6 +2538,65 @@ class ExternalApp {
2538
2538
  }
2539
2539
  }
2540
2540
 
2541
+ //
2542
+
2543
+
2544
+
2545
+
2546
+
2547
+
2548
+
2549
+
2550
+
2551
+
2552
+
2553
+ class Meeting {
2554
+
2555
+
2556
+
2557
+
2558
+
2559
+
2560
+
2561
+
2562
+
2563
+
2564
+ static parse(plain ) {
2565
+ return new Meeting({
2566
+ guestSipAuthorization: plain.guest_sip_authorization,
2567
+ hostname: plain.hostname,
2568
+ name: plain.name,
2569
+ ownerUuids: plain.owner_uuids,
2570
+ port: plain.port,
2571
+ uuid: plain.uuid,
2572
+ number: plain.number,
2573
+ });
2574
+ }
2575
+
2576
+ static newFrom(meeting ) {
2577
+ return newFrom(meeting, Meeting);
2578
+ }
2579
+
2580
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2581
+ this.guestSipAuthorization = guestSipAuthorization;
2582
+ this.hostname = hostname;
2583
+ this.name = name;
2584
+ this.ownerUuids = ownerUuids;
2585
+ this.port = port;
2586
+ this.uuid = uuid;
2587
+ this.number = number;
2588
+
2589
+ // Useful to compare instead of instanceof with minified code
2590
+ this.type = 'Meeting';
2591
+ }
2592
+
2593
+ getGuestSipCredentials() {
2594
+ // eslint-disable-next-line no-undef
2595
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2596
+ return { username, secret };
2597
+ }
2598
+ }
2599
+
2541
2600
  /* */
2542
2601
 
2543
2602
  var confdMethods = (client , baseUrl ) => ({
@@ -2602,6 +2661,18 @@ var confdMethods = (client , baseUrl ) => ({
2602
2661
  return null;
2603
2662
  }
2604
2663
  },
2664
+
2665
+ createMyMeeting: (name ) =>
2666
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2667
+
2668
+ deleteMyMeeting: (meetingUuid ) =>
2669
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2670
+
2671
+ getMeeting: (meetingUuid ) =>
2672
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2673
+
2674
+ guestGetMeeting: (meetingUuid ) =>
2675
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2605
2676
  });
2606
2677
 
2607
2678
  //
@@ -3518,7 +3589,11 @@ class CallLog {
3518
3589
  answered: plain.answered,
3519
3590
  callDirection: plain.call_direction,
3520
3591
  destination: {
3521
- extension: plain.requested_extension || plain.destination_extension,
3592
+ // @TEMP: Temporarily assuming empty numbers are meetings
3593
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3594
+ extension: plain.requested_extension
3595
+ || plain.destination_extension
3596
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3522
3597
  name: plain.requested_name || plain.destination_name || '',
3523
3598
  },
3524
3599
  source: {
@@ -3534,27 +3609,11 @@ class CallLog {
3534
3609
  }
3535
3610
 
3536
3611
  static parseNew(plain , session ) {
3537
- return new CallLog({
3538
- answer: plain.answer ? moment(plain.answer).toDate() : null,
3539
- answered: plain.answered,
3540
- callDirection: plain.call_direction,
3541
- destination: {
3542
- extension: plain.requested_extension || plain.destination_extension,
3543
- name: plain.requested_name || plain.destination_name || '',
3544
- },
3545
- source: {
3546
- extension: plain.source_extension,
3547
- name: plain.source_name,
3548
- },
3549
- id: plain.id,
3550
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3551
- start: moment(plain.start).toDate(),
3552
- end: plain.end ? moment(plain.end).toDate() : null,
3553
- recordings: Recording.parseMany(plain.recordings),
3554
- // @TODO: FIXME add verification declined vs missed call
3555
- newMissedCall: session
3556
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3557
- });
3612
+ const callLog = CallLog.parse(plain);
3613
+ // @TODO: FIXME add verification declined vs missed call
3614
+ callLog.newMissedCall = session
3615
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3616
+ return callLog;
3558
3617
  }
3559
3618
 
3560
3619
  static newFrom(profile ) {
@@ -3819,7 +3878,7 @@ const TRANSFER_FLOW_BLIND = 'blind';
3819
3878
 
3820
3879
  // const MINIMUM_WAZO_ENGINE_VERSION_FOR_CTI_HOLD = '20.11';
3821
3880
 
3822
- const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3881
+ const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3823
3882
 
3824
3883
  class CTIPhone extends Emitter {
3825
3884
 
@@ -3832,7 +3891,7 @@ class CTIPhone extends Emitter {
3832
3891
 
3833
3892
  constructor(session , isMobile = false, callbackAllLines = false) {
3834
3893
  super();
3835
- logger$a.info('CTI Phone created');
3894
+ logger$b.info('CTI Phone created');
3836
3895
  this.session = session;
3837
3896
  this.isMobile = isMobile;
3838
3897
  this.callbackAllLines = callbackAllLines;
@@ -3893,7 +3952,7 @@ class CTIPhone extends Emitter {
3893
3952
  }
3894
3953
 
3895
3954
  async makeCall(number , line ) {
3896
- logger$a.info('make CTI call', { number });
3955
+ logger$b.info('make CTI call', { number });
3897
3956
 
3898
3957
  if (!number) {
3899
3958
  return null;
@@ -3916,7 +3975,7 @@ class CTIPhone extends Emitter {
3916
3975
  if (!callSession) {
3917
3976
  return Promise.resolve(null);
3918
3977
  }
3919
- logger$a.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3978
+ logger$b.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3920
3979
 
3921
3980
  if (!this.currentCall) {
3922
3981
  this.currentCall = callSession.call;
@@ -3929,7 +3988,7 @@ class CTIPhone extends Emitter {
3929
3988
  if (!callSession) {
3930
3989
  return;
3931
3990
  }
3932
- logger$a.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
3991
+ logger$b.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
3933
3992
 
3934
3993
  this.currentCall = undefined;
3935
3994
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3939,7 +3998,7 @@ class CTIPhone extends Emitter {
3939
3998
  if (!callSession) {
3940
3999
  return Promise.resolve(false);
3941
4000
  }
3942
- logger$a.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4001
+ logger$b.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
3943
4002
 
3944
4003
  try {
3945
4004
  await CallApi.cancelCall(callSession);
@@ -3950,7 +4009,7 @@ class CTIPhone extends Emitter {
3950
4009
  this.eventEmitter.emit('onCallEnded', callSession);
3951
4010
  return true;
3952
4011
  } catch (e) {
3953
- logger$a.error('hangup CTI call, error', e);
4012
+ logger$b.error('hangup CTI call, error', e);
3954
4013
 
3955
4014
  this.eventEmitter.emit('onCallFailed', callSession);
3956
4015
  return false;
@@ -3963,7 +4022,7 @@ class CTIPhone extends Emitter {
3963
4022
  if (!callSession) {
3964
4023
  return;
3965
4024
  }
3966
- logger$a.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4025
+ logger$b.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
3967
4026
 
3968
4027
  await CallApi.cancelCall(callSession);
3969
4028
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3973,7 +4032,7 @@ class CTIPhone extends Emitter {
3973
4032
  if (!callSession) {
3974
4033
  return;
3975
4034
  }
3976
- logger$a.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4035
+ logger$b.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
3977
4036
 
3978
4037
  await CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_BLIND);
3979
4038
  }
@@ -3984,19 +4043,19 @@ class CTIPhone extends Emitter {
3984
4043
  if (!callSession) {
3985
4044
  return;
3986
4045
  }
3987
- logger$a.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4046
+ logger$b.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
3988
4047
 
3989
4048
  return CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_ATTENDED);
3990
4049
  }
3991
4050
 
3992
4051
  async cancelCTIIndirectTransfer(transferId ) {
3993
- logger$a.info('cancel CTI transfer', { transferId });
4052
+ logger$b.info('cancel CTI transfer', { transferId });
3994
4053
 
3995
4054
  return CallApi.cancelCallTransfer(transferId);
3996
4055
  }
3997
4056
 
3998
4057
  async confirmCTIIndirectTransfer(transferId ) {
3999
- logger$a.info('confirm CTI transfer', { transferId });
4058
+ logger$b.info('confirm CTI transfer', { transferId });
4000
4059
 
4001
4060
  return CallApi.confirmCallTransfer(transferId);
4002
4061
  }
@@ -4005,19 +4064,19 @@ class CTIPhone extends Emitter {
4005
4064
  if (!callSession) {
4006
4065
  return;
4007
4066
  }
4008
- logger$a.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4067
+ logger$b.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4009
4068
 
4010
4069
  return CallApi.sendDTMF(callSession.callId, digits);
4011
4070
  }
4012
4071
 
4013
4072
  onConnectionMade() {
4014
- logger$a.info('on CTI connection made');
4073
+ logger$b.info('on CTI connection made');
4015
4074
 
4016
4075
  this.eventEmitter.emit('onCallAccepted');
4017
4076
  }
4018
4077
 
4019
4078
  async close() {
4020
- logger$a.info('CTI close');
4079
+ logger$b.info('CTI close');
4021
4080
 
4022
4081
  return Promise.resolve();
4023
4082
  }
@@ -4026,7 +4085,7 @@ class CTIPhone extends Emitter {
4026
4085
  if (!callSession) {
4027
4086
  return;
4028
4087
  }
4029
- logger$a.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4088
+ logger$b.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4030
4089
 
4031
4090
  return CallApi.hold(callSession.callId);
4032
4091
  }
@@ -4035,7 +4094,7 @@ class CTIPhone extends Emitter {
4035
4094
  if (!callSession) {
4036
4095
  return;
4037
4096
  }
4038
- logger$a.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4097
+ logger$b.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4039
4098
 
4040
4099
  return CallApi.resume(callSession.callId);
4041
4100
  }
@@ -4044,7 +4103,7 @@ class CTIPhone extends Emitter {
4044
4103
  if (!callSession) {
4045
4104
  return;
4046
4105
  }
4047
- logger$a.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4106
+ logger$b.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4048
4107
 
4049
4108
  return CallApi.mute(callSession.callId);
4050
4109
  }
@@ -4053,7 +4112,7 @@ class CTIPhone extends Emitter {
4053
4112
  if (!callSession) {
4054
4113
  return;
4055
4114
  }
4056
- logger$a.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4115
+ logger$b.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4057
4116
 
4058
4117
  return CallApi.unmute(callSession.callId);
4059
4118
  }
@@ -4699,6 +4758,9 @@ var calldMethods = (client , baseUrl ) => ({
4699
4758
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4700
4759
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4701
4760
 
4761
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4762
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4763
+
4702
4764
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4703
4765
 
4704
4766
  mute: (callId ) =>
@@ -5052,7 +5114,7 @@ const AGENTD_VERSION = '1.0';
5052
5114
  const WEBHOOKD_VERSION = '1.0';
5053
5115
  const AMID_VERSION = '1.0';
5054
5116
 
5055
- const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5117
+ const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5056
5118
 
5057
5119
  class ApiClient {
5058
5120
 
@@ -5104,12 +5166,12 @@ class ApiClient {
5104
5166
  }
5105
5167
 
5106
5168
  async forceRefreshToken() {
5107
- logger$9.info('forcing refresh token, calling callback');
5169
+ logger$a.info('forcing refresh token, calling callback');
5108
5170
  return this.refreshTokenCallback();
5109
5171
  }
5110
5172
 
5111
5173
  async refreshTokenCallback() {
5112
- logger$9.info('refresh token callback called', {
5174
+ logger$a.info('refresh token callback called', {
5113
5175
  refreshToken: this.refreshToken,
5114
5176
  refreshBackend: this.refreshBackend,
5115
5177
  refreshExpiration: this.refreshExpiration,
@@ -5127,7 +5189,7 @@ class ApiClient {
5127
5189
  this.isMobile,
5128
5190
  );
5129
5191
 
5130
- logger$9.info('token refreshed', { token: session.token });
5192
+ logger$a.info('token refreshed', { token: session.token });
5131
5193
 
5132
5194
  if (this.onRefreshToken) {
5133
5195
  this.onRefreshToken(session.token, session);
@@ -5268,7 +5330,7 @@ var getApiClient = (forServer ) => {
5268
5330
  class InvalidSubscription extends Error {}
5269
5331
  class InvalidAuthorization extends Error {}
5270
5332
 
5271
- const logger$8 = IssueReporter$1.loggerFor('simple-auth');
5333
+ const logger$9 = IssueReporter$1.loggerFor('simple-auth');
5272
5334
 
5273
5335
  class Auth {
5274
5336
 
@@ -5303,7 +5365,7 @@ class Auth {
5303
5365
  setApiClientId(this.clientId);
5304
5366
  setRefreshExpiration(this.expiration);
5305
5367
  setOnRefreshToken((token , session ) => {
5306
- logger$8.info('on refresh token done', { token });
5368
+ logger$9.info('on refresh token done', { token });
5307
5369
  setApiToken(token);
5308
5370
  Wazo.Websocket.updateToken(token);
5309
5371
 
@@ -5862,7 +5924,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5862
5924
  .then(() => {
5863
5925
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5864
5926
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5865
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5927
+ if (this.peerConnection.addTransceiver) {
5928
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5929
+ }
5866
5930
  }
5867
5931
  })
5868
5932
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5889,12 +5953,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5889
5953
  };
5890
5954
  })
5891
5955
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5892
- .then((sessionDescription) => {
5893
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5894
- this.localMediaStreamConstraints = options.constraints;
5895
-
5896
- return sessionDescription;
5897
- })
5898
5956
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5899
5957
  .catch((error) => {
5900
5958
  wazoLogger.error('error when creating media', error);
@@ -6089,6 +6147,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6089
6147
 
6090
6148
  // set the transceiver direction to the answer direction
6091
6149
  this._peerConnection.getTransceivers().forEach((transceiver) => {
6150
+ if (transceiver.stopped) {
6151
+ return;
6152
+ }
6092
6153
  if (transceiver.direction /* guarding, but should always be true */) {
6093
6154
  const { receiver } = transceiver;
6094
6155
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -6133,10 +6194,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6133
6194
  if (kind !== 'audio' && kind !== 'video') {
6134
6195
  throw new Error(`Unknown new track kind ${kind}.`);
6135
6196
  }
6136
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
6197
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
6198
+ otherSender.track && otherSender.track.kind === kind);
6137
6199
 
6138
6200
  // Do not reuse sender video tracks in SFU
6139
6201
  if (sender && (!sfu || newTrack.kind === 'audio')) {
6202
+ if (sender.track) {
6203
+ // eslint-disable-next-line no-param-reassign
6204
+ newTrack.enabled = sender.track.enabled;
6205
+ }
6140
6206
  trackUpdates.push(
6141
6207
  new Promise((resolve) => {
6142
6208
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -6170,7 +6236,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6170
6236
  // Review: could make streamless tracks a configurable option?
6171
6237
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
6172
6238
  try {
6173
- pc.addTrack(newTrack, localStream);
6239
+ if (pc.addTrack) {
6240
+ pc.addTrack(newTrack, localStream);
6241
+ } else {
6242
+ pc.addStream(localStream);
6243
+ }
6174
6244
  } catch (error) {
6175
6245
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
6176
6246
  throw error;
@@ -6306,7 +6376,7 @@ const DEFAULT_ICE_TIMEOUT = 3000;
6306
6376
  const SEND_STATS_DELAY = 5000;
6307
6377
 
6308
6378
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
6309
- const logger$7 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6379
+ const logger$8 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6310
6380
  const statsLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-stats') : console;
6311
6381
 
6312
6382
  // events
@@ -6352,6 +6422,7 @@ const MAX_REGISTER_TRIES = 10;
6352
6422
 
6353
6423
 
6354
6424
 
6425
+
6355
6426
 
6356
6427
 
6357
6428
 
@@ -6378,6 +6449,7 @@ class WebRTCClient extends Emitter {
6378
6449
 
6379
6450
 
6380
6451
 
6452
+
6381
6453
 
6382
6454
  // sugar
6383
6455
 
@@ -6416,6 +6488,8 @@ class WebRTCClient extends Emitter {
6416
6488
  super();
6417
6489
  this.uaConfigOverrides = uaConfigOverrides;
6418
6490
  this.config = config;
6491
+ this.skipRegister = config.skipRegister;
6492
+
6419
6493
  this._buildConfig(config, session).then((newConfig ) => {
6420
6494
  this.config = newConfig;
6421
6495
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -6471,13 +6545,13 @@ class WebRTCClient extends Emitter {
6471
6545
 
6472
6546
  createUserAgent(configOverrides ) {
6473
6547
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
6474
- logger$7.info('sdk webrtc, creating UA', { webRTCConfiguration });
6548
+ logger$8.info('sdk webrtc, creating UA', { webRTCConfiguration });
6475
6549
 
6476
6550
  webRTCConfiguration.delegate = {
6477
6551
  onConnect: this.onConnect.bind(this),
6478
6552
  onDisconnect: this.onDisconnect.bind(this),
6479
6553
  onInvite: (invitation ) => {
6480
- logger$7.info('sdk webrtc on invite', {
6554
+ logger$8.info('sdk webrtc on invite', {
6481
6555
  method: 'delegate.onInvite',
6482
6556
  id: invitation.id,
6483
6557
  remoteURI: invitation.remoteURI,
@@ -6520,7 +6594,7 @@ class WebRTCClient extends Emitter {
6520
6594
  }
6521
6595
 
6522
6596
  onConnect() {
6523
- logger$7.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6597
+ logger$8.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6524
6598
  this.eventEmitter.emit(CONNECTED);
6525
6599
  if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
6526
6600
  this.registerer.waitingToggle(false);
@@ -6529,7 +6603,7 @@ class WebRTCClient extends Emitter {
6529
6603
  }
6530
6604
 
6531
6605
  async onDisconnect(error ) {
6532
- logger$7.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6606
+ logger$8.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6533
6607
  this.connectionPromise = null;
6534
6608
  // The UA will attempt to reconnect automatically when an error occurred
6535
6609
  this.eventEmitter.emit(DISCONNECTED, error);
@@ -6543,40 +6617,48 @@ class WebRTCClient extends Emitter {
6543
6617
  }
6544
6618
 
6545
6619
  register(tries = 0) {
6546
- logger$7.info('sdk webrtc registering...', {
6620
+ const logInfo = {
6547
6621
  userAgent: !!this.userAgent,
6548
6622
  registered: this.isRegistered(),
6549
6623
  connectionPromise: !!this.connectionPromise,
6550
6624
  registerer: !!this.registerer,
6551
6625
  waiting: this.registerer && this.registerer.waiting,
6552
6626
  tries,
6553
- });
6627
+ skipRegister: this.skipRegister,
6628
+ };
6629
+
6630
+ if (this.skipRegister) {
6631
+ logger$8.info('sdk webrtc skip register...', logInfo);
6632
+ return Promise.resolve();
6633
+ }
6634
+
6635
+ logger$8.info('sdk webrtc registering...', logInfo);
6554
6636
 
6555
6637
  if (!this.userAgent) {
6556
- logger$7.info('sdk webrtc recreating User Agent');
6638
+ logger$8.info('sdk webrtc recreating User Agent');
6557
6639
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6558
6640
  }
6559
6641
  if (!this.userAgent || this.isRegistered()) {
6560
- logger$7.info('sdk webrtc registering aborted, already registered or no UA can be created');
6642
+ logger$8.info('sdk webrtc registering aborted, already registered or no UA can be created');
6561
6643
  return Promise.resolve();
6562
6644
  }
6563
6645
 
6564
6646
  if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
6565
- logger$7.info('sdk webrtc registering aborted due to a registration in progress.');
6647
+ logger$8.info('sdk webrtc registering aborted due to a registration in progress.');
6566
6648
  return Promise.resolve();
6567
6649
  }
6568
6650
 
6569
6651
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6570
6652
 
6571
6653
  const onRegisterFailed = () => {
6572
- logger$7.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6654
+ logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6573
6655
  this.connectionPromise = null;
6574
6656
  if (this.registerer && this.registerer.waiting) {
6575
6657
  this.registerer.waitingToggle(false);
6576
6658
  }
6577
6659
 
6578
6660
  if (tries <= MAX_REGISTER_TRIES) {
6579
- logger$7.info('sdk webrtc registering, retrying...', { tries });
6661
+ logger$8.info('sdk webrtc registering, retrying...', { tries });
6580
6662
  setTimeout(() => this.register(tries + 1), 300);
6581
6663
  }
6582
6664
  };
@@ -6585,18 +6667,18 @@ class WebRTCClient extends Emitter {
6585
6667
  // Avoid race condition with the close method called just before register and setting userAgent to null
6586
6668
  // during the resolution of the primise.
6587
6669
  if (!this.userAgent) {
6588
- logger$7.info('sdk webrtc recreating User Agent after connection');
6670
+ logger$8.info('sdk webrtc recreating User Agent after connection');
6589
6671
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6590
6672
  }
6591
6673
 
6592
- logger$7.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6674
+ logger$8.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6593
6675
  this.registerer = new Registerer(this.userAgent, registerOptions);
6594
6676
  this.connectionPromise = null;
6595
6677
  this._monkeyPatchRegisterer(this.registerer);
6596
6678
 
6597
6679
  // Bind registerer events
6598
6680
  this.registerer.stateChange.addListener(newState => {
6599
- logger$7.info('sdk webrtc registering, state changed', { newState });
6681
+ logger$8.info('sdk webrtc registering, state changed', { newState });
6600
6682
 
6601
6683
  if (newState === RegistererState.Registered && this.registerer
6602
6684
  && this.registerer.state === RegistererState.Registered) {
@@ -6609,7 +6691,7 @@ class WebRTCClient extends Emitter {
6609
6691
  const options = {
6610
6692
  requestDelegate: {
6611
6693
  onReject: response => {
6612
- logger$7.error('sdk webrtc registering, rejected', { response });
6694
+ logger$8.error('sdk webrtc registering, rejected', { response });
6613
6695
 
6614
6696
  onRegisterFailed();
6615
6697
  },
@@ -6617,13 +6699,13 @@ class WebRTCClient extends Emitter {
6617
6699
  };
6618
6700
 
6619
6701
  return this.registerer.register(options).catch((e) => {
6620
- logger$7.error('sdk webrtc registering, error', e);
6702
+ logger$8.error('sdk webrtc registering, error', e);
6621
6703
 
6622
6704
  this.eventEmitter.emit(REGISTRATION_FAILED);
6623
6705
  return e;
6624
6706
  });
6625
6707
  }).catch(error => {
6626
- logger$7.error('sdk webrtc registering, transport error', error);
6708
+ logger$8.error('sdk webrtc registering, transport error', error);
6627
6709
  onRegisterFailed();
6628
6710
  });
6629
6711
  }
@@ -6652,21 +6734,21 @@ class WebRTCClient extends Emitter {
6652
6734
  }
6653
6735
 
6654
6736
  unregister() {
6655
- logger$7.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6737
+ logger$8.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6656
6738
  if (!this.registerer) {
6657
6739
  return Promise.resolve();
6658
6740
  }
6659
6741
 
6660
6742
  try {
6661
6743
  return this.registerer.unregister().then(() => {
6662
- logger$7.info('sdk webrtc unregistered');
6744
+ logger$8.info('sdk webrtc unregistered');
6663
6745
  this._cleanupRegister();
6664
6746
  }).catch(e => {
6665
- logger$7.error('sdk webrtc unregistering, promise error', e);
6747
+ logger$8.error('sdk webrtc unregistering, promise error', e);
6666
6748
  this._cleanupRegister();
6667
6749
  });
6668
6750
  } catch (e) {
6669
- logger$7.error('sdk webrtc unregistering, error', e);
6751
+ logger$8.error('sdk webrtc unregistering, error', e);
6670
6752
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
6671
6753
  // error when the registerer is in a bad state
6672
6754
  this._cleanupRegister();
@@ -6674,7 +6756,7 @@ class WebRTCClient extends Emitter {
6674
6756
  }
6675
6757
 
6676
6758
  stop() {
6677
- logger$7.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6759
+ logger$8.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6678
6760
  if (!this.userAgent) {
6679
6761
  return Promise.resolve();
6680
6762
  }
@@ -6682,12 +6764,12 @@ class WebRTCClient extends Emitter {
6682
6764
  return this.userAgent.stop().then(() => {
6683
6765
  return this._cleanupRegister();
6684
6766
  }).catch(e => {
6685
- logger$7.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6767
+ logger$8.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6686
6768
  });
6687
6769
  }
6688
6770
 
6689
6771
  call(number , enableVideo , audioOnly = false, conference = false) {
6690
- logger$7.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6772
+ logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6691
6773
  const inviterOptions = {
6692
6774
  sessionDescriptionHandlerOptionsReInvite: {
6693
6775
  conference,
@@ -6716,7 +6798,7 @@ class WebRTCClient extends Emitter {
6716
6798
  this._onAccepted(session, response.session, true);
6717
6799
  },
6718
6800
  onReject: (response ) => {
6719
- logger$7.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6801
+ logger$8.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6720
6802
  this._stopSendingStats(session);
6721
6803
 
6722
6804
  this.eventEmitter.emit(REJECTED, session, response);
@@ -6738,11 +6820,11 @@ class WebRTCClient extends Emitter {
6738
6820
  }
6739
6821
 
6740
6822
  answer(session , enableVideo ) {
6741
- logger$7.info('sdk webrtc answer call', { id: session.id, enableVideo });
6823
+ logger$8.info('sdk webrtc answer call', { id: session.id, enableVideo });
6742
6824
 
6743
6825
  if (!session || !session.accept) {
6744
6826
  const error = 'No session to answer, or not an invitation';
6745
- logger$7.warn(error);
6827
+ logger$8.warn(error);
6746
6828
  return Promise.reject(new Error(error));
6747
6829
  }
6748
6830
  const options = {
@@ -6752,15 +6834,15 @@ class WebRTCClient extends Emitter {
6752
6834
  return session.accept(options).then(() => {
6753
6835
  if (session.isCanceled) {
6754
6836
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
6755
- logger$7.error(message, { id: session.id });
6837
+ logger$8.error(message, { id: session.id });
6756
6838
  this.onCallEnded(session);
6757
6839
 
6758
6840
  throw new CanceledCallError(message);
6759
6841
  }
6760
- logger$7.info('sdk webrtc answer, accepted.');
6842
+ logger$8.info('sdk webrtc answer, accepted.');
6761
6843
  this._onAccepted(session);
6762
6844
  }).catch(e => {
6763
- logger$7.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6845
+ logger$8.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6764
6846
 
6765
6847
  throw e;
6766
6848
  });
@@ -6768,7 +6850,7 @@ class WebRTCClient extends Emitter {
6768
6850
 
6769
6851
  hangup(session ) {
6770
6852
  const { state, id } = session;
6771
- logger$7.info('sdk webrtc hangup call', { id, state });
6853
+ logger$8.info('sdk webrtc hangup call', { id, state });
6772
6854
 
6773
6855
  try {
6774
6856
  this._stopSendingStats(session);
@@ -6797,24 +6879,24 @@ class WebRTCClient extends Emitter {
6797
6879
 
6798
6880
  return bye();
6799
6881
  } catch (error) {
6800
- logger$7.warn('sdk webrtc hangup, error', error);
6882
+ logger$8.warn('sdk webrtc hangup, error', error);
6801
6883
  }
6802
6884
 
6803
6885
  return null;
6804
6886
  }
6805
6887
 
6806
6888
  reject(session ) {
6807
- logger$7.info('sdk webrtc reject call', { id: session.id });
6889
+ logger$8.info('sdk webrtc reject call', { id: session.id });
6808
6890
 
6809
6891
  try {
6810
6892
  return session.reject ? session.reject() : session.cancel();
6811
6893
  } catch (e) {
6812
- logger$7.warn('Error when rejecting call', e.message, e.stack);
6894
+ logger$8.warn('Error when rejecting call', e.message, e.stack);
6813
6895
  }
6814
6896
  }
6815
6897
 
6816
6898
  async close() {
6817
- logger$7.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6899
+ logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6818
6900
  this._cleanupMedia();
6819
6901
  this.connectionPromise = null;
6820
6902
 
@@ -6845,7 +6927,7 @@ class WebRTCClient extends Emitter {
6845
6927
  // eg: "INVITE not rejectable in state Completed"
6846
6928
  }
6847
6929
  this.userAgent = null;
6848
- logger$7.info('sdk webrtc client closed');
6930
+ logger$8.info('sdk webrtc client closed');
6849
6931
  }
6850
6932
 
6851
6933
  getNumber(session ) {
@@ -6858,13 +6940,13 @@ class WebRTCClient extends Emitter {
6858
6940
  }
6859
6941
 
6860
6942
  mute(session ) {
6861
- logger$7.info('sdk webrtc mute', { id: session.id });
6943
+ logger$8.info('sdk webrtc mute', { id: session.id });
6862
6944
 
6863
6945
  this._toggleAudio(session, true);
6864
6946
  }
6865
6947
 
6866
6948
  unmute(session ) {
6867
- logger$7.info('sdk webrtc unmute', { id: session.id });
6949
+ logger$8.info('sdk webrtc unmute', { id: session.id });
6868
6950
 
6869
6951
  this._toggleAudio(session, false);
6870
6952
  }
@@ -6881,12 +6963,18 @@ class WebRTCClient extends Emitter {
6881
6963
  }
6882
6964
 
6883
6965
  if (pc.getSenders) {
6966
+ if (!pc.getSenders().length) {
6967
+ return false;
6968
+ }
6884
6969
  pc.getSenders().forEach(sender => {
6885
6970
  if (sender && sender.track && sender.track.kind === 'audio') {
6886
6971
  muted = muted && !sender.track.enabled;
6887
6972
  }
6888
6973
  });
6889
6974
  } else {
6975
+ if (!pc.getLocalStreams().length) {
6976
+ return false;
6977
+ }
6890
6978
  pc.getLocalStreams().forEach(stream => {
6891
6979
  stream.getAudioTracks().forEach(track => {
6892
6980
  muted = muted && !track.enabled;
@@ -6898,20 +6986,20 @@ class WebRTCClient extends Emitter {
6898
6986
  }
6899
6987
 
6900
6988
  toggleCameraOn(session ) {
6901
- logger$7.info('sdk webrtc toggle camera on', { id: session.id });
6989
+ logger$8.info('sdk webrtc toggle camera on', { id: session.id });
6902
6990
 
6903
6991
  this._toggleVideo(session, false);
6904
6992
  }
6905
6993
 
6906
6994
  toggleCameraOff(session ) {
6907
- logger$7.info('sdk webrtc toggle camera off', { id: session.id });
6995
+ logger$8.info('sdk webrtc toggle camera off', { id: session.id });
6908
6996
 
6909
6997
  this._toggleVideo(session, true);
6910
6998
  }
6911
6999
 
6912
7000
  hold(session , isConference = false) {
6913
7001
  const sessionId = this.getSipSessionId(session);
6914
- logger$7.info('sdk webrtc hold', {
7002
+ logger$8.info('sdk webrtc hold', {
6915
7003
  sessionId,
6916
7004
  keys: Object.keys(this.heldSessions),
6917
7005
  pendingReinvite: !!session.pendingReinvite,
@@ -6945,6 +7033,8 @@ class WebRTCClient extends Emitter {
6945
7033
  }
6946
7034
  options.sessionDescriptionHandlerOptions = {
6947
7035
  constraints: options.constraints,
7036
+ hold: true,
7037
+ conference: isConference,
6948
7038
  };
6949
7039
 
6950
7040
  // Send re-INVITE
@@ -6954,7 +7044,7 @@ class WebRTCClient extends Emitter {
6954
7044
  unhold(session , isConference = false) {
6955
7045
  const sessionId = this.getSipSessionId(session);
6956
7046
 
6957
- logger$7.info('sdk webrtc unhold', {
7047
+ logger$8.info('sdk webrtc unhold', {
6958
7048
  sessionId,
6959
7049
  keys: Object.keys(this.heldSessions),
6960
7050
  pendingReinvite: !!session.pendingReinvite,
@@ -6987,6 +7077,8 @@ class WebRTCClient extends Emitter {
6987
7077
  }
6988
7078
  options.sessionDescriptionHandlerOptions = {
6989
7079
  constraints: options.constraints,
7080
+ hold: false,
7081
+ conference: isConference,
6990
7082
  };
6991
7083
 
6992
7084
  // Send re-INVITE
@@ -7045,7 +7137,7 @@ class WebRTCClient extends Emitter {
7045
7137
  return;
7046
7138
  }
7047
7139
 
7048
- logger$7.info('send WebRTC message', { sipId: sipSession.id, contentType });
7140
+ logger$8.info('send WebRTC message', { sipId: sipSession.id, contentType });
7049
7141
 
7050
7142
  try {
7051
7143
  sipSession.message({
@@ -7170,7 +7262,8 @@ class WebRTCClient extends Emitter {
7170
7262
  }
7171
7263
  const sdh = session.sessionDescriptionHandler;
7172
7264
  const pc = sdh.peerConnection;
7173
- const localStream = this.getLocalStream(this.getSipSessionId(session));
7265
+ const sessionId = this.getSipSessionId(session);
7266
+ const localStream = this.getLocalStream(sessionId);
7174
7267
 
7175
7268
  // Release old video stream
7176
7269
  if (localStream) {
@@ -7196,11 +7289,8 @@ class WebRTCClient extends Emitter {
7196
7289
 
7197
7290
  // let's update the local stream
7198
7291
  this.eventEmitter.emit('onVideoInputChange', stream);
7199
- try {
7200
- await sdh.setLocalMediaStream(stream);
7201
- } catch (_) {
7202
- // Nothing to do
7203
- }
7292
+ this.setLocalMediaStream(sessionId, stream);
7293
+
7204
7294
  return stream;
7205
7295
  });
7206
7296
  }
@@ -7412,7 +7502,7 @@ class WebRTCClient extends Emitter {
7412
7502
  }
7413
7503
 
7414
7504
  startHeartbeat() {
7415
- logger$7.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7505
+ logger$8.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7416
7506
  if (!this.userAgent) {
7417
7507
  this.heartbeat.stop();
7418
7508
  return;
@@ -7425,7 +7515,7 @@ class WebRTCClient extends Emitter {
7425
7515
  }
7426
7516
 
7427
7517
  stopHeartbeat() {
7428
- logger$7.info('sdk webrtc stop heartbeat');
7518
+ logger$8.info('sdk webrtc stop heartbeat');
7429
7519
  this.heartbeat.stop();
7430
7520
  }
7431
7521
 
@@ -7445,7 +7535,7 @@ class WebRTCClient extends Emitter {
7445
7535
  }
7446
7536
 
7447
7537
  attemptReconnection() {
7448
- logger$7.info('attempt reconnection', { userAgent: !!this.userAgent });
7538
+ logger$8.info('attempt reconnection', { userAgent: !!this.userAgent });
7449
7539
  if (!this.userAgent) {
7450
7540
  return;
7451
7541
  }
@@ -7502,9 +7592,11 @@ class WebRTCClient extends Emitter {
7502
7592
  remoteStream.removeTrack(track);
7503
7593
  });
7504
7594
 
7505
- pc.getReceivers().forEach(receiver => {
7506
- remoteStream.addTrack(receiver.track);
7507
- });
7595
+ if (pc.getReceivers) {
7596
+ pc.getReceivers().forEach(receiver => {
7597
+ remoteStream.addTrack(receiver.track);
7598
+ });
7599
+ }
7508
7600
  }
7509
7601
 
7510
7602
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -7539,6 +7631,25 @@ class WebRTCClient extends Emitter {
7539
7631
  return sessionId in this.conferences;
7540
7632
  }
7541
7633
 
7634
+ createAudioElementFor(sessionId ) {
7635
+ const audio = document.createElement('audio');
7636
+ audio.setAttribute('id', `audio-${sessionId}`);
7637
+
7638
+ if (audio.setSinkId && this.audioOutputDeviceId) {
7639
+ audio.setSinkId(this.audioOutputDeviceId);
7640
+ }
7641
+
7642
+ if (document.body) {
7643
+ document.body.appendChild(audio);
7644
+ }
7645
+ this.audioElements[sessionId] = audio;
7646
+
7647
+ audio.volume = this.audioOutputVolume;
7648
+ audio.autoplay = true;
7649
+
7650
+ return audio;
7651
+ }
7652
+
7542
7653
  _onTransportError() {
7543
7654
  this.eventEmitter.emit(TRANSPORT_ERROR);
7544
7655
  this.attemptReconnection();
@@ -7548,7 +7659,7 @@ class WebRTCClient extends Emitter {
7548
7659
  const body = message && typeof message === 'object' ? message.data : message;
7549
7660
  if (body && body.indexOf('200 OK') !== -1) {
7550
7661
  if (this.hasHeartbeat()) {
7551
- logger$7.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7662
+ logger$8.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7552
7663
 
7553
7664
  this.heartbeat.onHeartbeat();
7554
7665
  if (this.heartbeatCb) {
@@ -7559,7 +7670,7 @@ class WebRTCClient extends Emitter {
7559
7670
  }
7560
7671
 
7561
7672
  async _onHeartbeatTimeout() {
7562
- logger$7.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7673
+ logger$8.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7563
7674
 
7564
7675
  if (this.heartbeatTimeoutCb) {
7565
7676
  this.heartbeatTimeoutCb();
@@ -7571,7 +7682,7 @@ class WebRTCClient extends Emitter {
7571
7682
  try {
7572
7683
  await this.userAgent.transport.disconnect();
7573
7684
  } catch (e) {
7574
- logger$7.error('Transport disconnection after heartbeat timeout, error', e);
7685
+ logger$8.error('Transport disconnection after heartbeat timeout, error', e);
7575
7686
  }
7576
7687
  }
7577
7688
 
@@ -7604,31 +7715,31 @@ class WebRTCClient extends Emitter {
7604
7715
  }
7605
7716
 
7606
7717
  _connectIfNeeded() {
7607
- logger$7.info('connect if needed, checking', { connected: this.isConnected() });
7718
+ logger$8.info('connect if needed, checking', { connected: this.isConnected() });
7608
7719
  if (!this.userAgent) {
7609
- logger$7.info('need to recreate User Agent');
7720
+ logger$8.info('need to recreate User Agent');
7610
7721
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
7611
7722
  }
7612
7723
 
7613
7724
  if (this.isConnected()) {
7614
- logger$7.info('webrtc sdk, already connected');
7725
+ logger$8.info('webrtc sdk, already connected');
7615
7726
  return Promise.resolve();
7616
7727
  }
7617
7728
 
7618
7729
  if (this.isConnecting()) {
7619
- logger$7.info('webrtc sdk, already connecting...');
7730
+ logger$8.info('webrtc sdk, already connecting...');
7620
7731
 
7621
7732
  this.connectionPromise = this.userAgent.transport.connectPromise;
7622
7733
  return this.connectionPromise;
7623
7734
  }
7624
7735
 
7625
7736
  if (this.connectionPromise) {
7626
- logger$7.info('webrtc sdk, connection promise connecting...');
7737
+ logger$8.info('webrtc sdk, connection promise connecting...');
7627
7738
  // $FlowFixMe
7628
7739
  return this.connectionPromise;
7629
7740
  }
7630
7741
 
7631
- logger$7.info('WebRTC UA needs to connect');
7742
+ logger$8.info('WebRTC UA needs to connect');
7632
7743
 
7633
7744
  // Force UA to reconnect
7634
7745
  if (this.userAgent && this.userAgent.state !== UserAgentState.Stopped) {
@@ -7753,7 +7864,7 @@ class WebRTCClient extends Emitter {
7753
7864
 
7754
7865
  sdh.peerConnectionDelegate = {
7755
7866
  onicecandidateerror: (error ) => {
7756
- logger$7.error('on icecandidate error', {
7867
+ logger$8.error('on icecandidate error', {
7757
7868
  address: error.address,
7758
7869
  port: error.port,
7759
7870
  errorCode: error.errorCode,
@@ -7768,7 +7879,7 @@ class WebRTCClient extends Emitter {
7768
7879
  let hadRemoteVideo = false;
7769
7880
 
7770
7881
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7771
- // Becase when `onInvite` is called we already got the video track
7882
+ // Because when `onInvite` is called we already got the video track
7772
7883
  session.onInviteRequest = (request) => {
7773
7884
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7774
7885
 
@@ -7782,7 +7893,7 @@ class WebRTCClient extends Emitter {
7782
7893
  updatedNumber = session.assertedIdentity.uri.normal.user;
7783
7894
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
7784
7895
  }
7785
- logger$7.info('re-invite received', { updatedCalleeName, updatedNumber });
7896
+ logger$8.info('re-invite received', { updatedCalleeName, updatedNumber });
7786
7897
 
7787
7898
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7788
7899
 
@@ -7803,7 +7914,7 @@ class WebRTCClient extends Emitter {
7803
7914
  }
7804
7915
 
7805
7916
  _onAccepted(session , sessionDialog , withEvent = true) {
7806
- logger$7.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7917
+ logger$8.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7807
7918
 
7808
7919
  this.storeSipSession(session);
7809
7920
 
@@ -7843,20 +7954,10 @@ class WebRTCClient extends Emitter {
7843
7954
  const isConference = this.isConference(sessionId);
7844
7955
 
7845
7956
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7846
- const audio = document.createElement('audio');
7847
- audio.setAttribute('id', `audio-${sessionId}`);
7848
-
7849
- if (audio.setSinkId && this.audioOutputDeviceId) {
7850
- audio.setSinkId(this.audioOutputDeviceId);
7851
- }
7852
-
7853
- if (document.body) {
7854
- document.body.appendChild(audio);
7855
- }
7856
- this.audioElements[sessionId] = audio;
7957
+ this.createAudioElementFor(sessionId);
7857
7958
  }
7858
7959
 
7859
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7960
+ const audioElement = this.audioElements[sessionId];
7860
7961
  const stream = newStream || this.getRemoteStream(sessionId);
7861
7962
 
7862
7963
  if (!this._isWeb() || !stream) {
@@ -8003,10 +8104,10 @@ class WebRTCClient extends Emitter {
8003
8104
 
8004
8105
  _stopSendingStats(session ) {
8005
8106
  const sessionId = this.getSipSessionId(session);
8006
- logger$7.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
8107
+ logger$8.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
8007
8108
 
8008
8109
  if (sessionId in this.statsIntervals) {
8009
- logger$7.trace('Stop sending stats for call', { sessionId });
8110
+ logger$8.trace('Stop sending stats for call', { sessionId });
8010
8111
  this.statsIntervals[sessionId]();
8011
8112
  delete this.statsIntervals[sessionId];
8012
8113
  }
@@ -8022,7 +8123,7 @@ class WebRTCClient extends Emitter {
8022
8123
  try {
8023
8124
  await this.userAgent.transport.disconnect();
8024
8125
  } catch (e) {
8025
- logger$7.error('WebRTC transport disconnect, error', e);
8126
+ logger$8.error('WebRTC transport disconnect, error', e);
8026
8127
  }
8027
8128
  }
8028
8129
  }
@@ -8109,7 +8210,7 @@ const events = [
8109
8210
  ON_SIGNAL,
8110
8211
  ];
8111
8212
 
8112
- const logger$6 = IssueReporter$1.loggerFor('webrtc-phone');
8213
+ const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
8113
8214
 
8114
8215
  class WebRTCPhone extends Emitter {
8115
8216
 
@@ -8180,7 +8281,7 @@ class WebRTCPhone extends Emitter {
8180
8281
  }).catch(error => {
8181
8282
  // Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
8182
8283
  console.error('register error', error, error.message, error.stack);
8183
- logger$6.error('WebRTC register error', { message: error.message, stack: error.stack });
8284
+ logger$7.error('WebRTC register error', { message: error.message, stack: error.stack });
8184
8285
  });
8185
8286
  }
8186
8287
 
@@ -8195,7 +8296,7 @@ class WebRTCPhone extends Emitter {
8195
8296
  if (!this.client) {
8196
8297
  return;
8197
8298
  }
8198
- logger$6.info('WebRTC phone stop');
8299
+ logger$7.info('WebRTC phone stop');
8199
8300
  this.client.stop();
8200
8301
  }
8201
8302
 
@@ -8210,14 +8311,14 @@ class WebRTCPhone extends Emitter {
8210
8311
  async sendReinvite(callSession , constraints = null, conference = false,
8211
8312
  audioOnly = false) {
8212
8313
  const sipSession = this.findSipSession(callSession);
8213
- logger$6.info('WebRTC phone - send reinvite', {
8314
+ logger$7.info('WebRTC phone - send reinvite', {
8214
8315
  sessionId: sipSession ? sipSession.id : null,
8215
8316
  constraints,
8216
8317
  audioOnly,
8217
8318
  });
8218
8319
 
8219
8320
  if (!sipSession) {
8220
- return null;
8321
+ return false;
8221
8322
  }
8222
8323
 
8223
8324
  // $FlowFixMe
@@ -8227,19 +8328,17 @@ class WebRTCPhone extends Emitter {
8227
8328
  // Downgrade
8228
8329
  if (constraints && !isUpgrade) {
8229
8330
  // No reinvite needed
8230
- return this._downgradeToAudio(callSession);
8331
+ this._downgradeToAudio(callSession);
8332
+ return false;
8231
8333
  }
8232
8334
 
8233
8335
  if (isUpgrade) {
8234
8336
  const shouldReinvite = await this._upgradeToVideo(callSession, constraints, conference);
8235
8337
  if (!shouldReinvite) {
8236
- return;
8338
+ return false;
8237
8339
  }
8238
8340
  }
8239
8341
 
8240
- // Force reinvite in SDH
8241
- sipSession.sessionDescriptionHandler.localMediaStreamConstraints = null;
8242
-
8243
8342
  return this.client.reinvite(sipSession, constraints, conference, audioOnly);
8244
8343
  }
8245
8344
 
@@ -8248,7 +8347,7 @@ class WebRTCPhone extends Emitter {
8248
8347
  }
8249
8348
 
8250
8349
  startHeartbeat() {
8251
- logger$6.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8350
+ logger$7.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8252
8351
  if (!this.client || this.client.hasHeartbeat()) {
8253
8352
  return;
8254
8353
  }
@@ -8257,7 +8356,7 @@ class WebRTCPhone extends Emitter {
8257
8356
  }
8258
8357
 
8259
8358
  stopHeartbeat() {
8260
- logger$6.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8359
+ logger$7.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8261
8360
  if (!this.client) {
8262
8361
  return;
8263
8362
  }
@@ -8274,7 +8373,7 @@ class WebRTCPhone extends Emitter {
8274
8373
  }
8275
8374
 
8276
8375
  reconnect() {
8277
- logger$6.info('WebRTC phone - reconnect', { client: !!this.client });
8376
+ logger$7.info('WebRTC phone - reconnect', { client: !!this.client });
8278
8377
  if (!this.client) {
8279
8378
  return;
8280
8379
  }
@@ -8312,7 +8411,7 @@ class WebRTCPhone extends Emitter {
8312
8411
  _downgradeToAudio(callSession ) {
8313
8412
  const sipSession = this.findSipSession(callSession);
8314
8413
  if (!sipSession) {
8315
- return;
8414
+ return false;
8316
8415
  }
8317
8416
 
8318
8417
  // Release local video stream when downgrading to audio
@@ -8425,7 +8524,7 @@ class WebRTCPhone extends Emitter {
8425
8524
  // Monkey patch to know when canceled with the CANCEL message
8426
8525
  const onCancel = sipSession._onCancel.bind(sipSession);
8427
8526
  sipSession._onCancel = (message ) => {
8428
- logger$6.trace('on sip session canceled', { callId: message.callId });
8527
+ logger$7.trace('on sip session canceled', { callId: message.callId });
8429
8528
 
8430
8529
  onCancel(message);
8431
8530
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
@@ -8450,13 +8549,13 @@ class WebRTCPhone extends Emitter {
8450
8549
  this.audioOutputVolume,
8451
8550
  );
8452
8551
  case SessionState.Terminating:
8453
- logger$6.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8552
+ logger$7.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8454
8553
 
8455
8554
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
8456
8555
 
8457
8556
  break;
8458
8557
  case SessionState.Terminated:
8459
- logger$6.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8558
+ logger$7.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8460
8559
 
8461
8560
  this._onCallTerminated(sipSession);
8462
8561
 
@@ -8492,7 +8591,7 @@ class WebRTCPhone extends Emitter {
8492
8591
  }
8493
8592
 
8494
8593
  async startScreenSharing(constraints , callSession ) {
8495
- logger$6.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8594
+ logger$7.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8496
8595
 
8497
8596
  const screenShareStream = await this._getStreamFromConstraints(constraints);
8498
8597
  if (!screenShareStream) {
@@ -8514,6 +8613,10 @@ class WebRTCPhone extends Emitter {
8514
8613
  localStream.removeTrack(videoTrack);
8515
8614
  }
8516
8615
 
8616
+ if (localStream) {
8617
+ localStream.addTrack(screenTrack);
8618
+ }
8619
+
8517
8620
  if (sender) {
8518
8621
  sender.replaceTrack(screenTrack);
8519
8622
  }
@@ -8528,7 +8631,8 @@ class WebRTCPhone extends Emitter {
8528
8631
  return;
8529
8632
  }
8530
8633
 
8531
- logger$6.info('WebRTC phone - stop screen sharing');
8634
+ logger$7.info('WebRTC phone - stop screen sharing');
8635
+ let reinvited = false;
8532
8636
 
8533
8637
  try {
8534
8638
  if (this.currentScreenShare.stream) {
@@ -8543,7 +8647,8 @@ class WebRTCPhone extends Emitter {
8543
8647
  // When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
8544
8648
  // We have to downgrade to audio.
8545
8649
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8546
- await this.sendReinvite(targetCallSession, { audio: false, video: screenshareStopped }, conference);
8650
+ const constraints = { audio: false, video: screenshareStopped };
8651
+ reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8547
8652
  }
8548
8653
  } catch (e) {
8549
8654
  console.warn(e);
@@ -8557,6 +8662,8 @@ class WebRTCPhone extends Emitter {
8557
8662
  );
8558
8663
 
8559
8664
  this.currentScreenShare = null;
8665
+
8666
+ return reinvited;
8560
8667
  }
8561
8668
 
8562
8669
  async _getStreamFromConstraints(constraints , conference = false) {
@@ -8594,7 +8701,7 @@ class WebRTCPhone extends Emitter {
8594
8701
  }
8595
8702
 
8596
8703
  _onCallAccepted(sipSession , cameraEnabled ) {
8597
- logger$6.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8704
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8598
8705
 
8599
8706
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
8600
8707
  this.currentSipSession = sipSession;
@@ -8612,11 +8719,15 @@ class WebRTCPhone extends Emitter {
8612
8719
  }
8613
8720
 
8614
8721
  changeAudioDevice(id ) {
8615
- logger$6.info('WebRTC phone - change audio device', { deviceId: id });
8722
+ logger$7.info('WebRTC phone - change audio device', { deviceId: id });
8616
8723
  this.audioOutputDeviceId = id;
8617
8724
  this.client.changeAudioOutputDevice(id);
8618
8725
  }
8619
8726
 
8727
+ createAudioElementFor(sessionId ) {
8728
+ return this.client.createAudioElementFor(sessionId);
8729
+ }
8730
+
8620
8731
  changeRingDevice(id ) {
8621
8732
  this.audioRingDeviceId = id;
8622
8733
  }
@@ -8633,25 +8744,25 @@ class WebRTCPhone extends Emitter {
8633
8744
  }
8634
8745
 
8635
8746
  changeAudioInputDevice(id ) {
8636
- logger$6.info('WebRTC phone - changeAudio input device', { deviceId: id });
8747
+ logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
8637
8748
 
8638
8749
  return this.client.changeAudioInputDevice(id, this.currentSipSession);
8639
8750
  }
8640
8751
 
8641
8752
  changeVideoInputDevice(id ) {
8642
- logger$6.info('WebRTC phone - change video input device', { deviceId: id });
8753
+ logger$7.info('WebRTC phone - change video input device', { deviceId: id });
8643
8754
 
8644
8755
  return this.client.changeVideoInputDevice(id, this.currentSipSession);
8645
8756
  }
8646
8757
 
8647
8758
  changeSessionVideoInputDevice(id ) {
8648
- logger$6.info('WebRTC phone - change session video input device', { deviceId: id });
8759
+ logger$7.info('WebRTC phone - change session video input device', { deviceId: id });
8649
8760
 
8650
8761
  return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
8651
8762
  }
8652
8763
 
8653
8764
  _onCallTerminated(sipSession ) {
8654
- logger$6.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8765
+ logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8655
8766
 
8656
8767
  const callSession = this._createCallSession(sipSession);
8657
8768
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
@@ -8685,7 +8796,7 @@ class WebRTCPhone extends Emitter {
8685
8796
  const hasIncomingCallSession = this.hasIncomingCallSession();
8686
8797
 
8687
8798
  // Re-trigger incoming call event for remaining incoming calls
8688
- logger$6.info('WebRTC phone - check to re-trigger incoming call', {
8799
+ logger$7.info('WebRTC phone - check to re-trigger incoming call', {
8689
8800
  sipId: sipSession.id,
8690
8801
  shouldRetrigger,
8691
8802
  hasIncomingCallSession,
@@ -8774,37 +8885,37 @@ class WebRTCPhone extends Emitter {
8774
8885
 
8775
8886
  // Deprecated
8776
8887
  getLocalStreamForCall(callSession ) {
8777
- logger$6.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8888
+ logger$7.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8778
8889
 
8779
8890
  return this.getLocalStream(callSession);
8780
8891
  }
8781
8892
 
8782
8893
  // Deprecated
8783
8894
  getRemoteStreamForCall(callSession ) {
8784
- logger$6.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8895
+ logger$7.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8785
8896
 
8786
8897
  return this.getRemoteVideoStream(callSession);
8787
8898
  }
8788
8899
 
8789
8900
  getRemoteStreamsForCall(callSession ) {
8790
- logger$6.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8901
+ logger$7.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8791
8902
 
8792
8903
  return this.getRemoteStream(callSession);
8793
8904
  }
8794
8905
 
8795
8906
  accept(callSession , cameraEnabled ) {
8796
- logger$6.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8907
+ logger$7.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8797
8908
  if (this.currentSipSession) {
8798
8909
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
8799
8910
  }
8800
8911
 
8801
8912
  if (!callSession) {
8802
- logger$6.warn('no CallSession to accept.');
8913
+ logger$7.warn('no CallSession to accept.');
8803
8914
  return Promise.resolve(null);
8804
8915
  }
8805
8916
 
8806
8917
  if (callSession.getId() in this.acceptedSessions) {
8807
- logger$6.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8918
+ logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8808
8919
  return Promise.resolve(callSession.sipCallId);
8809
8920
  }
8810
8921
 
@@ -8816,24 +8927,24 @@ class WebRTCPhone extends Emitter {
8816
8927
  const sipSession = this.client.getSipSession(callSession.getId());
8817
8928
  if (sipSession) {
8818
8929
  if (sipSession.state === SessionState.Terminated || sipSession.state === SessionState.Terminating) {
8819
- logger$6.warn('Trying to answer a terminated sipSession.');
8930
+ logger$7.warn('Trying to answer a terminated sipSession.');
8820
8931
 
8821
8932
  return Promise.resolve(null);
8822
8933
  }
8823
8934
 
8824
- logger$6.info('accept call, session found', { sipId: sipSession.id });
8935
+ logger$7.info('accept call, session found', { sipId: sipSession.id });
8825
8936
 
8826
8937
  // $FlowFixMe
8827
8938
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
8828
8939
  return callSession.sipCallId;
8829
8940
  }).catch(e => {
8830
- logger$6.error(e);
8941
+ logger$7.error(e);
8831
8942
  this.endCurrentCall(callSession);
8832
8943
  throw e;
8833
8944
  });
8834
8945
  }
8835
8946
 
8836
- logger$6.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8947
+ logger$7.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8837
8948
 
8838
8949
  return Promise.resolve(null);
8839
8950
  }
@@ -8843,7 +8954,7 @@ class WebRTCPhone extends Emitter {
8843
8954
  }
8844
8955
 
8845
8956
  async reject(callSession ) {
8846
- logger$6.info('reject WebRTC called', { id: callSession.getId() });
8957
+ logger$7.info('reject WebRTC called', { id: callSession.getId() });
8847
8958
 
8848
8959
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call rejected locally');
8849
8960
  if (!callSession || callSession.getId() in this.rejectedSessions) {
@@ -8855,14 +8966,14 @@ class WebRTCPhone extends Emitter {
8855
8966
 
8856
8967
  const sipSession = this.findSipSession(callSession);
8857
8968
  if (sipSession) {
8858
- logger$6.info('WebRTC rejecting', { sipId: sipSession.id });
8969
+ logger$7.info('WebRTC rejecting', { sipId: sipSession.id });
8859
8970
 
8860
8971
  this.client.hangup(sipSession);
8861
8972
  }
8862
8973
  }
8863
8974
 
8864
8975
  async ignore(callSession ) {
8865
- logger$6.info('WebRTC ignore', { id: callSession.getId() });
8976
+ logger$7.info('WebRTC ignore', { id: callSession.getId() });
8866
8977
 
8867
8978
  // kill the ring
8868
8979
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'ignoring call');
@@ -8871,7 +8982,7 @@ class WebRTCPhone extends Emitter {
8871
8982
  }
8872
8983
 
8873
8984
  hold(callSession , withEvent = true, isConference = false) {
8874
- logger$6.info('WebRTC hold', { id: callSession.getId() });
8985
+ logger$7.info('WebRTC hold', { id: callSession.getId() });
8875
8986
 
8876
8987
  const sipSession = this.findSipSession(callSession);
8877
8988
 
@@ -8882,7 +8993,7 @@ class WebRTCPhone extends Emitter {
8882
8993
 
8883
8994
  // @Deprecated
8884
8995
  unhold(callSession , withEvent = true, isConference = false) {
8885
- logger$6.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8996
+ logger$7.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8886
8997
 
8887
8998
  console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
8888
8999
 
@@ -8897,7 +9008,7 @@ class WebRTCPhone extends Emitter {
8897
9008
  const sipSession = this.findSipSession(callSession);
8898
9009
 
8899
9010
  if (sipSession) {
8900
- logger$6.info('WebRTC atxfer', { sipId: sipSession.id });
9011
+ logger$7.info('WebRTC atxfer', { sipId: sipSession.id });
8901
9012
 
8902
9013
  return this.client.atxfer(sipSession);
8903
9014
  }
@@ -8912,7 +9023,7 @@ class WebRTCPhone extends Emitter {
8912
9023
  if (!sipSession) {
8913
9024
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
8914
9025
  }
8915
- logger$6.info('WebRTC hold sip session', { sipId: sipSession.id });
9026
+ logger$7.info('WebRTC hold sip session', { sipId: sipSession.id });
8916
9027
 
8917
9028
  const promise = this.client.hold(sipSession, isConference);
8918
9029
  if (withEvent) {
@@ -8931,7 +9042,7 @@ class WebRTCPhone extends Emitter {
8931
9042
  if (!sipSession) {
8932
9043
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
8933
9044
  }
8934
- logger$6.info('WebRTC unhold', { sipId: sipSession.id });
9045
+ logger$7.info('WebRTC unhold', { sipId: sipSession.id });
8935
9046
 
8936
9047
  const promise = this.client.unhold(sipSession, isConference);
8937
9048
  if (withEvent) {
@@ -8942,18 +9053,18 @@ class WebRTCPhone extends Emitter {
8942
9053
  }
8943
9054
 
8944
9055
  resume(callSession , isConference = false) {
8945
- logger$6.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
9056
+ logger$7.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8946
9057
 
8947
9058
  const sipSession = this.findSipSession(callSession);
8948
9059
  if (!sipSession) {
8949
9060
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
8950
9061
  }
8951
9062
 
8952
- logger$6.info('WebRTC resuming', { sipId: sipSession.id });
9063
+ logger$7.info('WebRTC resuming', { sipId: sipSession.id });
8953
9064
 
8954
9065
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
8955
9066
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
8956
- logger$6.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9067
+ logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8957
9068
  this.holdSipSession(this.currentSipSession, callSession);
8958
9069
  }
8959
9070
 
@@ -8968,14 +9079,14 @@ class WebRTCPhone extends Emitter {
8968
9079
  }
8969
9080
 
8970
9081
  mute(callSession , withEvent = true) {
8971
- logger$6.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
9082
+ logger$7.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8972
9083
 
8973
9084
  const sipSession = this.findSipSession(callSession);
8974
9085
  if (!sipSession) {
8975
9086
  return;
8976
9087
  }
8977
9088
 
8978
- logger$6.info('WebRTC muting', { sipId: sipSession.id });
9089
+ logger$7.info('WebRTC muting', { sipId: sipSession.id });
8979
9090
  this.client.mute(sipSession);
8980
9091
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: true });
8981
9092
 
@@ -8989,14 +9100,14 @@ class WebRTCPhone extends Emitter {
8989
9100
  }
8990
9101
 
8991
9102
  unmute(callSession , withEvent = true) {
8992
- logger$6.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
9103
+ logger$7.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8993
9104
 
8994
9105
  const sipSession = this.findSipSession(callSession);
8995
9106
  if (!sipSession) {
8996
9107
  return;
8997
9108
  }
8998
9109
 
8999
- logger$6.info('WebRTC unmuting', { sipId: sipSession.id });
9110
+ logger$7.info('WebRTC unmuting', { sipId: sipSession.id });
9000
9111
  this.client.unmute(sipSession);
9001
9112
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: false });
9002
9113
 
@@ -9023,7 +9134,7 @@ class WebRTCPhone extends Emitter {
9023
9134
  if (!sipSession) {
9024
9135
  return;
9025
9136
  }
9026
- logger$6.info('WebRTC turn camera on', { sipId: sipSession.id });
9137
+ logger$7.info('WebRTC turn camera on', { sipId: sipSession.id });
9027
9138
 
9028
9139
  this.client.toggleCameraOn(sipSession);
9029
9140
 
@@ -9035,7 +9146,7 @@ class WebRTCPhone extends Emitter {
9035
9146
  if (!sipSession) {
9036
9147
  return;
9037
9148
  }
9038
- logger$6.info('WebRTC turn camera off', { sipId: sipSession.id });
9149
+ logger$7.info('WebRTC turn camera off', { sipId: sipSession.id });
9039
9150
 
9040
9151
  this.client.toggleCameraOff(sipSession);
9041
9152
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -9047,7 +9158,7 @@ class WebRTCPhone extends Emitter {
9047
9158
  return;
9048
9159
  }
9049
9160
 
9050
- logger$6.info('WebRTC send key', { sipId: sipSession.id, tone });
9161
+ logger$7.info('WebRTC send key', { sipId: sipSession.id, tone });
9051
9162
  this.client.sendDTMF(sipSession, tone);
9052
9163
  }
9053
9164
 
@@ -9055,7 +9166,7 @@ class WebRTCPhone extends Emitter {
9055
9166
  // @TODO: line is not used here
9056
9167
  async makeCall(number , line , cameraEnabled ,
9057
9168
  audioOnly = false, conference = false) {
9058
- logger$6.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9169
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9059
9170
  if (!number) {
9060
9171
  return Promise.resolve(null);
9061
9172
  }
@@ -9065,7 +9176,7 @@ class WebRTCPhone extends Emitter {
9065
9176
  }
9066
9177
  if (this.currentSipSession) {
9067
9178
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
9068
- logger$6.warn('Unable to hold current session when making another call', e);
9179
+ logger$7.warn('Unable to hold current session when making another call', e);
9069
9180
  });
9070
9181
  }
9071
9182
 
@@ -9075,7 +9186,7 @@ class WebRTCPhone extends Emitter {
9075
9186
  this._bindEvents(sipSession);
9076
9187
  } catch (error) {
9077
9188
  console.warn(error);
9078
- logger$6.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
9189
+ logger$7.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
9079
9190
  return Promise.resolve(null);
9080
9191
  }
9081
9192
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
@@ -9103,7 +9214,7 @@ class WebRTCPhone extends Emitter {
9103
9214
  return;
9104
9215
  }
9105
9216
 
9106
- logger$6.info('WebRTC transfer', { sipId: sipSession.id, target });
9217
+ logger$7.info('WebRTC transfer', { sipId: sipSession.id, target });
9107
9218
 
9108
9219
  this.client.transfer(sipSession, target);
9109
9220
  }
@@ -9112,7 +9223,7 @@ class WebRTCPhone extends Emitter {
9112
9223
  const sipSession = this.client.getSipSession(source.sipCallId);
9113
9224
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
9114
9225
 
9115
- logger$6.info('WebRTC indirect transfer', {
9226
+ logger$7.info('WebRTC indirect transfer', {
9116
9227
  sipId: sipSession ? sipSession.id : null,
9117
9228
  target: sipSessionTarget ? sipSessionTarget.id : null,
9118
9229
  });
@@ -9140,7 +9251,7 @@ class WebRTCPhone extends Emitter {
9140
9251
  return false;
9141
9252
  }
9142
9253
 
9143
- logger$6.info('WebRTC hangup', { sipId: sipSession.id });
9254
+ logger$7.info('WebRTC hangup', { sipId: sipSession.id });
9144
9255
 
9145
9256
  const sipSessionId = this.getSipSessionId(sipSession);
9146
9257
 
@@ -9185,7 +9296,7 @@ class WebRTCPhone extends Emitter {
9185
9296
  }
9186
9297
 
9187
9298
  async close() {
9188
- logger$6.info('WebRTC close');
9299
+ logger$7.info('WebRTC close');
9189
9300
 
9190
9301
  try {
9191
9302
  await Promise.race([
@@ -9193,7 +9304,7 @@ class WebRTCPhone extends Emitter {
9193
9304
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000)),
9194
9305
  ]);
9195
9306
  } catch (e) {
9196
- logger$6.error('WebRTC close, unregister error', e);
9307
+ logger$7.error('WebRTC close, unregister error', e);
9197
9308
  }
9198
9309
 
9199
9310
  this.client.close();
@@ -9211,12 +9322,12 @@ class WebRTCPhone extends Emitter {
9211
9322
  }
9212
9323
 
9213
9324
  enableRinging() {
9214
- logger$6.info('WebRTC enable ringing');
9325
+ logger$7.info('WebRTC enable ringing');
9215
9326
  this.ringingEnabled = true;
9216
9327
  }
9217
9328
 
9218
9329
  disableRinging() {
9219
- logger$6.info('WebRTC disable ringing');
9330
+ logger$7.info('WebRTC disable ringing');
9220
9331
  this.ringingEnabled = false;
9221
9332
  }
9222
9333
 
@@ -9256,7 +9367,7 @@ class WebRTCPhone extends Emitter {
9256
9367
 
9257
9368
  // Deprecated
9258
9369
  getLocalMediaStream(callSession ) {
9259
- logger$6.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9370
+ logger$7.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9260
9371
  return this.getLocalStream(callSession);
9261
9372
  }
9262
9373
 
@@ -9264,6 +9375,10 @@ class WebRTCPhone extends Emitter {
9264
9375
  return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
9265
9376
  }
9266
9377
 
9378
+ hasALocalVideoTrack(callSession ) {
9379
+ return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
9380
+ }
9381
+
9267
9382
  getRemoteStream(callSession ) {
9268
9383
  return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
9269
9384
  }
@@ -9286,7 +9401,7 @@ class WebRTCPhone extends Emitter {
9286
9401
  this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
9287
9402
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
9288
9403
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
9289
- logger$6.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9404
+ logger$7.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9290
9405
 
9291
9406
  const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
9292
9407
  this.incomingSessions.push(callSession.getId());
@@ -9309,7 +9424,7 @@ class WebRTCPhone extends Emitter {
9309
9424
  });
9310
9425
 
9311
9426
  this.client.on(this.client.ON_REINVITE, (...args) => {
9312
- logger$6.info('WebRTC on reinvite', {
9427
+ logger$7.info('WebRTC on reinvite', {
9313
9428
  sessionId: args[0].id,
9314
9429
  inviteId: args[1].id,
9315
9430
  updatedCalleeName: args[2],
@@ -9329,7 +9444,7 @@ class WebRTCPhone extends Emitter {
9329
9444
  });
9330
9445
 
9331
9446
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
9332
- logger$6.info('WebRTC call accepted', { sipId: sipSession.id });
9447
+ logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
9333
9448
 
9334
9449
  this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
9335
9450
 
@@ -9340,17 +9455,17 @@ class WebRTCPhone extends Emitter {
9340
9455
  this.client.on('ended', () => {});
9341
9456
 
9342
9457
  this.client.on(this.client.ON_ERROR, e => {
9343
- logger$6.error('WebRTC error', e);
9458
+ logger$7.error('WebRTC error', e);
9344
9459
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9345
9460
  });
9346
9461
 
9347
9462
  this.client.on(this.client.UNREGISTERED, () => {
9348
- logger$6.info('WebRTC unregistered');
9463
+ logger$7.info('WebRTC unregistered');
9349
9464
  this.eventEmitter.emit(ON_UNREGISTERED);
9350
9465
  });
9351
9466
 
9352
9467
  this.client.on(this.client.REGISTERED, () => {
9353
- logger$6.info('WebRTC registered', {
9468
+ logger$7.info('WebRTC registered', {
9354
9469
  shouldSendReinvite: this.shouldSendReinvite,
9355
9470
  state: this.currentSipSession ? this.currentSipSession.state : null,
9356
9471
  currentSipSession: !!this.currentSipSession,
@@ -9366,19 +9481,19 @@ class WebRTCPhone extends Emitter {
9366
9481
  try {
9367
9482
  this.sendReinvite(this.currentCallSession);
9368
9483
  } catch (e) {
9369
- logger$6.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9484
+ logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9370
9485
  }
9371
9486
  }
9372
9487
  });
9373
9488
 
9374
9489
  this.client.on(this.client.CONNECTED, () => {
9375
- logger$6.info('WebRTC client connected');
9490
+ logger$7.info('WebRTC client connected');
9376
9491
 
9377
9492
  this.stopHeartbeat();
9378
9493
  });
9379
9494
 
9380
9495
  this.client.on(this.client.DISCONNECTED, () => {
9381
- logger$6.info('WebRTC client disconnected');
9496
+ logger$7.info('WebRTC client disconnected');
9382
9497
 
9383
9498
  this.eventEmitter.emit(ON_UNREGISTERED);
9384
9499
 
@@ -9610,7 +9725,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
9610
9725
 
9611
9726
  //
9612
9727
 
9613
- const logger$5 = IssueReporter$1.loggerFor('simple-phone');
9728
+ const logger$6 = IssueReporter$1.loggerFor('simple-phone');
9614
9729
  const sipLogger = IssueReporter$1.loggerFor('sip.js');
9615
9730
  const protocolLogger = IssueReporter$1.loggerFor('sip');
9616
9731
 
@@ -9717,7 +9832,7 @@ class Phone extends Emitter {
9717
9832
  async disconnect() {
9718
9833
  if (this.phone) {
9719
9834
  if (this.phone.hasAnActiveCall()) {
9720
- logger$5.info('hangup call on disconnect');
9835
+ logger$6.info('hangup call on disconnect');
9721
9836
  // $FlowFixMe
9722
9837
  await this.phone.hangup();
9723
9838
  }
@@ -9740,13 +9855,13 @@ class Phone extends Emitter {
9740
9855
  }
9741
9856
 
9742
9857
  async hangup(callSession ) {
9743
- logger$5.info('hangup via simple phone', { callId: callSession.getId() });
9858
+ logger$6.info('hangup via simple phone', { callId: callSession.getId() });
9744
9859
 
9745
9860
  return this.phone && this.phone.hangup(callSession);
9746
9861
  }
9747
9862
 
9748
9863
  async accept(callSession , cameraEnabled ) {
9749
- logger$5.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
9864
+ logger$6.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
9750
9865
 
9751
9866
  return this.phone && this.phone.accept(callSession, cameraEnabled);
9752
9867
  }
@@ -9766,13 +9881,18 @@ class Phone extends Emitter {
9766
9881
  return adHocConference.start();
9767
9882
  }
9768
9883
 
9769
- mute(callSession ) {
9770
- this.muteViaAPI(callSession);
9884
+ mute(callSession , withApi = true) {
9885
+ if (withApi) {
9886
+ this.muteViaAPI(callSession);
9887
+ }
9888
+
9771
9889
  return this.phone && this.phone.mute(callSession);
9772
9890
  }
9773
9891
 
9774
- unmute(callSession ) {
9775
- this.unmuteViaAPI(callSession);
9892
+ unmute(callSession , withApi = true) {
9893
+ if (withApi) {
9894
+ this.unmuteViaAPI(callSession);
9895
+ }
9776
9896
 
9777
9897
  return this.phone && this.phone.unmute(callSession);
9778
9898
  }
@@ -9780,7 +9900,7 @@ class Phone extends Emitter {
9780
9900
  muteViaAPI(callSession ) {
9781
9901
  if (callSession && callSession.callId) {
9782
9902
  Wazo.getApiClient().calld.mute(callSession.callId).catch(e => {
9783
- logger$5.error('Mute via API, error', e);
9903
+ logger$6.error('Mute via API, error', e);
9784
9904
  });
9785
9905
  }
9786
9906
  }
@@ -9788,7 +9908,7 @@ class Phone extends Emitter {
9788
9908
  unmuteViaAPI(callSession ) {
9789
9909
  if (callSession && callSession.callId) {
9790
9910
  Wazo.getApiClient().calld.unmute(callSession.callId).catch(e => {
9791
- logger$5.error('Unmute via API, error', e);
9911
+ logger$6.error('Unmute via API, error', e);
9792
9912
  });
9793
9913
  }
9794
9914
  }
@@ -9878,9 +9998,13 @@ class Phone extends Emitter {
9878
9998
  return this.phone && this.phone.hasLocalVideo(callSession);
9879
9999
  }
9880
10000
 
10001
+ hasALocalVideoTrack(callSession ) {
10002
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
10003
+ }
10004
+
9881
10005
  // @Deprecated
9882
10006
  getLocalMediaStream(callSession ) {
9883
- logger$5.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
10007
+ logger$6.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
9884
10008
 
9885
10009
  return this.phone && this.phone.getLocalStream(callSession);
9886
10010
  }
@@ -9899,20 +10023,20 @@ class Phone extends Emitter {
9899
10023
 
9900
10024
  // @Deprecated
9901
10025
  getRemoteStreamForCall(callSession ) {
9902
- logger$5.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
10026
+ logger$6.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
9903
10027
  return this.getRemoteStream(callSession);
9904
10028
  }
9905
10029
 
9906
10030
  // Returns remote streams directly from the peerConnection
9907
10031
  // @Deprecated
9908
10032
  getRemoteStreamsForCall(callSession ) {
9909
- logger$5.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
10033
+ logger$6.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
9910
10034
  return this.getLocalStream(callSession);
9911
10035
  }
9912
10036
 
9913
10037
  // @Deprecated
9914
10038
  getRemoteVideoStreamForCall(callSession ) {
9915
- logger$5.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
10039
+ logger$6.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
9916
10040
 
9917
10041
  return this.getRemoteVideoStream(callSession);
9918
10042
  }
@@ -10042,6 +10166,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
10042
10166
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
10043
10167
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
10044
10168
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
10169
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
10170
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
10045
10171
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
10046
10172
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
10047
10173
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -10083,7 +10209,7 @@ const BLACKLIST_EVENTS = [
10083
10209
  ];
10084
10210
 
10085
10211
  const HEARTBEAT_ENGINE_VERSION = '20.09';
10086
- const logger$4 = IssueReporter$1.loggerFor('wazo-ws');
10212
+ const logger$5 = IssueReporter$1.loggerFor('wazo-ws');
10087
10213
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
10088
10214
 
10089
10215
  class WebSocketClient extends Emitter {
@@ -10132,19 +10258,19 @@ class WebSocketClient extends Emitter {
10132
10258
  }
10133
10259
 
10134
10260
  connect() {
10135
- logger$4.info('connect method started', { host: this.host, token: this.token });
10261
+ logger$5.info('connect method started', { host: this.host, token: this.token });
10136
10262
  this.socket = new ReconnectingWebSocket(this._getUrl.bind(this), [], this.options);
10137
10263
  if (this.options.binaryType) {
10138
10264
  this.socket.binaryType = this.options.binaryType;
10139
10265
  }
10140
10266
 
10141
10267
  this.socket.onopen = () => {
10142
- logger$4.info('on Wazo WS open', { method: 'connect', host: this.host });
10268
+ logger$5.info('on Wazo WS open', { method: 'connect', host: this.host });
10143
10269
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
10144
10270
  };
10145
10271
 
10146
10272
  this.socket.onerror = event => {
10147
- logger$4.error('on Wazo WS error', event.target);
10273
+ logger$5.error('on Wazo WS error', event.target);
10148
10274
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
10149
10275
  };
10150
10276
 
@@ -10174,7 +10300,7 @@ class WebSocketClient extends Emitter {
10174
10300
 
10175
10301
  this.socket.onclose = event => {
10176
10302
  // Can't be converted to JSON (circular structure)
10177
- logger$4.info('on Wazo WS close', {
10303
+ logger$5.info('on Wazo WS close', {
10178
10304
  reason: event.reason,
10179
10305
  code: event.code,
10180
10306
  readyState: event.target.readyState,
@@ -10192,12 +10318,12 @@ class WebSocketClient extends Emitter {
10192
10318
  };
10193
10319
 
10194
10320
  this.socket.onerror = event => {
10195
- logger$4.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
10321
+ logger$5.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
10196
10322
  };
10197
10323
  }
10198
10324
 
10199
10325
  close(force = false) {
10200
- logger$4.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
10326
+ logger$5.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
10201
10327
 
10202
10328
  if (!this.socket) {
10203
10329
  return;
@@ -10215,7 +10341,7 @@ class WebSocketClient extends Emitter {
10215
10341
 
10216
10342
  updateToken(token ) {
10217
10343
  this.token = token;
10218
- logger$4.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
10344
+ logger$5.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
10219
10345
 
10220
10346
  if (this.socket) {
10221
10347
  // If still connected, send the token to the WS
@@ -10233,7 +10359,7 @@ class WebSocketClient extends Emitter {
10233
10359
  }
10234
10360
 
10235
10361
  startHeartbeat() {
10236
- logger$4.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
10362
+ logger$5.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
10237
10363
 
10238
10364
  if (!this.socket) {
10239
10365
  this.heartbeat.stop();
@@ -10247,7 +10373,7 @@ class WebSocketClient extends Emitter {
10247
10373
  }
10248
10374
 
10249
10375
  stopHeartbeat() {
10250
- logger$4.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
10376
+ logger$5.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
10251
10377
 
10252
10378
  this.heartbeat.stop();
10253
10379
  }
@@ -10277,7 +10403,7 @@ class WebSocketClient extends Emitter {
10277
10403
  }
10278
10404
 
10279
10405
  reconnect(reason ) {
10280
- logger$4.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10406
+ logger$5.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10281
10407
  if (!this.socket) {
10282
10408
  return;
10283
10409
  }
@@ -10333,7 +10459,7 @@ class WebSocketClient extends Emitter {
10333
10459
  this.close();
10334
10460
  }
10335
10461
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
10336
- logger$4.log('Wazo WS url computed to reconnect', { url });
10462
+ logger$5.log('Wazo WS url computed to reconnect', { url });
10337
10463
 
10338
10464
  return url;
10339
10465
  }
@@ -10341,12 +10467,12 @@ class WebSocketClient extends Emitter {
10341
10467
  _onHeartbeat(message ) {
10342
10468
  if (message.payload === 'pong') {
10343
10469
  this.heartbeat.onHeartbeat();
10344
- logger$4.log('on heartbeat received from Wazo WS');
10470
+ logger$5.log('on heartbeat received from Wazo WS');
10345
10471
  }
10346
10472
  }
10347
10473
 
10348
10474
  async _onHeartbeatTimeout() {
10349
- logger$4.log('heartbeat timed out', { host: this.host, token: this.token });
10475
+ logger$5.log('heartbeat timed out', { host: this.host, token: this.token });
10350
10476
 
10351
10477
  this.close();
10352
10478
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -10388,6 +10514,8 @@ WebSocketClient.eventLists = [
10388
10514
  CHATD_USER_ROOM_CREATED,
10389
10515
  CONFERENCE_USER_PARTICIPANT_JOINED,
10390
10516
  CONFERENCE_USER_PARTICIPANT_LEFT,
10517
+ MEETING_USER_PARTICIPANT_JOINED,
10518
+ MEETING_USER_PARTICIPANT_LEFT,
10391
10519
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10392
10520
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10393
10521
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -10458,6 +10586,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10458
10586
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
10459
10587
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10460
10588
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10589
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
10590
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
10461
10591
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
10462
10592
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
10463
10593
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -10499,7 +10629,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10499
10629
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
10500
10630
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
10501
10631
 
10502
- const logger$3 = IssueReporter$1.loggerFor('simple-ws-client');
10632
+ const logger$4 = IssueReporter$1.loggerFor('simple-ws-client');
10503
10633
 
10504
10634
  class Websocket extends Emitter {
10505
10635
 
@@ -10523,7 +10653,7 @@ class Websocket extends Emitter {
10523
10653
  }
10524
10654
 
10525
10655
  open(host , session ) {
10526
- logger$3.info('open simple WebSocket', { host, token: session.token });
10656
+ logger$4.info('open simple WebSocket', { host, token: session.token });
10527
10657
  this.ws = new WebSocketClient(
10528
10658
  {
10529
10659
  host,
@@ -10551,7 +10681,7 @@ class Websocket extends Emitter {
10551
10681
  }
10552
10682
 
10553
10683
  updateToken(token ) {
10554
- logger$3.info('update token via simple Websocket', { token, ws: !!this.ws });
10684
+ logger$4.info('update token via simple Websocket', { token, ws: !!this.ws });
10555
10685
 
10556
10686
  if (!this.ws) {
10557
10687
  return;
@@ -10579,6 +10709,145 @@ var Websocket$1 = global.wazoWebsocketInstance;
10579
10709
 
10580
10710
  //
10581
10711
 
10712
+ const logger$3 = IssueReporter$1.loggerFor('sdk-sip-room');
10713
+
10714
+ class SipRoom extends Room {
10715
+
10716
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
10717
+ logger$3.info('connecting to sip room', { extension, audioOnly, room: !!room });
10718
+
10719
+ if (!room) {
10720
+ await Wazo.Phone.connect();
10721
+
10722
+ const withCamera = constraints && !!constraints.video;
10723
+
10724
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
10725
+ // eslint-disable-next-line no-param-reassign
10726
+ room = new SipRoom(callSession, extension, null, null, extra);
10727
+ }
10728
+
10729
+ if (room && room.callSession && room.callSession.call) {
10730
+ room.setCallId(room.callSession.call.id);
10731
+ }
10732
+
10733
+ logger$3.info('connected to room', {
10734
+ extension: room.extension,
10735
+ });
10736
+
10737
+ return room;
10738
+ }
10739
+
10740
+ mute() {
10741
+ logger$3.info('mute sip room');
10742
+
10743
+ Wazo.Phone.mute(this.callSession, false);
10744
+
10745
+ this.sendMuteStatus();
10746
+ }
10747
+
10748
+ unmute() {
10749
+ logger$3.info('unmute sip room');
10750
+
10751
+ Wazo.Phone.unmute(this.callSession, false);
10752
+
10753
+ this.sendUnMuteStatus();
10754
+ }
10755
+
10756
+ getLocalGuestName() {
10757
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
10758
+ }
10759
+
10760
+ // Overridden to not listen to websocket messages
10761
+ _transferEvents() {
10762
+ // Phone events
10763
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
10764
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
10765
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
10766
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
10767
+
10768
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
10769
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
10770
+ }
10771
+
10772
+ _onMessage(message ) {
10773
+ // eslint-disable-next-line no-underscore-dangle
10774
+ const body = super._onMessage(message);
10775
+ if (!body) {
10776
+ return;
10777
+ }
10778
+
10779
+ const getChannel = () => body.channels[0];
10780
+
10781
+ switch (body.type) {
10782
+ case 'ConfbridgeWelcome':
10783
+ body.channels.forEach(channel => {
10784
+ this._onParticipantJoined(channel);
10785
+ });
10786
+
10787
+ break;
10788
+ case 'ConfbridgeJoin': {
10789
+ const channel = getChannel();
10790
+ this._onParticipantJoined(channel);
10791
+ break;
10792
+ }
10793
+ case 'ConfbridgeLeave': {
10794
+ const channel = getChannel();
10795
+ this._onParticipantLeft({
10796
+ data: {
10797
+ call_id: channel.id,
10798
+ },
10799
+ });
10800
+ break;
10801
+ }
10802
+ }
10803
+ }
10804
+
10805
+ async _onParticipantJoined(channel ) {
10806
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
10807
+ const callId = channel.id;
10808
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
10809
+ const name = channel.caller ? channel.caller.name : null;
10810
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
10811
+ const participant = new ParticipantClass(this, {
10812
+ caller_id_name: name,
10813
+ call_id: callId,
10814
+ }, extra);
10815
+
10816
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
10817
+ if (participantIdx !== -1 && name) {
10818
+ this.participants[participantIdx].name = name;
10819
+ return;
10820
+ }
10821
+
10822
+ if (isLocal) {
10823
+ // Should be updated by the Wazo WS but we don't have it for now
10824
+ if (this.callSession) {
10825
+ this.callSession.ringing = false;
10826
+ }
10827
+
10828
+ this._onLocalParticipantJoined(participant);
10829
+
10830
+ // Give some time for the stream to be updated
10831
+ setTimeout(() => {
10832
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
10833
+ }, 1000);
10834
+ }
10835
+
10836
+ this.participants.push(participant);
10837
+
10838
+ this._isParticipantJoining(participant);
10839
+
10840
+ return participant;
10841
+ }
10842
+
10843
+ _getCurrentSipCallIs() {
10844
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
10845
+ }
10846
+
10847
+ }
10848
+
10849
+ //
10850
+
10582
10851
  class RemoteParticipant extends Participant {
10583
10852
  constructor(room , rawParticipant = {}, extra = {}) {
10584
10853
  super(room, rawParticipant, extra);
@@ -10638,9 +10907,7 @@ class Stream {
10638
10907
  return false;
10639
10908
  }
10640
10909
 
10641
- // With canvas track (used to fake upgrade in conference), we don't have a width
10642
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
10643
- && track.readyState !== 'ended' && 'width' in track.getSettings());
10910
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
10644
10911
  }
10645
10912
 
10646
10913
  get id() {
@@ -11541,6 +11808,7 @@ const Wazo = {
11541
11808
  Phone: Phone$1,
11542
11809
  Websocket: Websocket$1,
11543
11810
  Room,
11811
+ SipRoom,
11544
11812
  RemoteParticipant,
11545
11813
  LocalParticipant,
11546
11814
  Stream,
@@ -11577,6 +11845,7 @@ const Wazo = {
11577
11845
  IndirectTransfer,
11578
11846
  SwitchboardCall,
11579
11847
  WebRTCPhone,
11848
+ Meeting,
11580
11849
  },
11581
11850
 
11582
11851
  // Api
@@ -11605,7 +11874,7 @@ if (global) {
11605
11874
  global.Wazo = Wazo;
11606
11875
  }
11607
11876
 
11608
- /* global document */
11877
+ //
11609
11878
 
11610
11879
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
11611
11880
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
@@ -11617,6 +11886,7 @@ class Room extends Emitter {
11617
11886
 
11618
11887
 
11619
11888
 
11889
+
11620
11890
 
11621
11891
 
11622
11892
 
@@ -11638,6 +11908,8 @@ class Room extends Emitter {
11638
11908
 
11639
11909
 
11640
11910
 
11911
+
11912
+
11641
11913
 
11642
11914
 
11643
11915
 
@@ -11655,6 +11927,7 @@ class Room extends Emitter {
11655
11927
  * @param extension string
11656
11928
  * @param sourceId number
11657
11929
  * @param callId string
11930
+ * @param meetingUuid string
11658
11931
  * @param extra Object
11659
11932
  */
11660
11933
  constructor(
@@ -11662,15 +11935,17 @@ class Room extends Emitter {
11662
11935
  extension ,
11663
11936
  sourceId ,
11664
11937
  callId ,
11938
+ meetingUuid ,
11665
11939
  extra = {},
11666
11940
  ) {
11667
11941
  super();
11668
- logger$1.info('room initialized', { callId, extension, sourceId });
11942
+ logger$1.info('room initialized', { callId, extension, sourceId, meetingUuid });
11669
11943
 
11670
11944
  // Represents the room callSession
11671
11945
  this.callSession = callSession;
11672
11946
  this.extension = extension;
11673
11947
  this.sourceId = sourceId;
11948
+ this.meetingUuid = meetingUuid;
11674
11949
  this.callId = callId;
11675
11950
  this.participants = [];
11676
11951
  this.connected = false;
@@ -11690,6 +11965,8 @@ class Room extends Emitter {
11690
11965
  // Sugar syntax for `room.EVENT_NAME`
11691
11966
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
11692
11967
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
11968
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
11969
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
11693
11970
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
11694
11971
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
11695
11972
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -11724,9 +12001,10 @@ class Room extends Emitter {
11724
12001
  * @param audioOnly boolean
11725
12002
  * @param extra Object
11726
12003
  * @param room ?Room
12004
+ * @param meeting ?Meeting
11727
12005
  * @returns {Promise<Room>}
11728
12006
  */
11729
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
12007
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
11730
12008
  logger$1.info('connecting to room', { extension, audioOnly, room: !!room });
11731
12009
 
11732
12010
  if (!room) {
@@ -11761,21 +12039,31 @@ class Room extends Emitter {
11761
12039
  room.setCallId(room.callSession.call.id);
11762
12040
  }
11763
12041
 
11764
- // Fetch conference source
11765
- const sources = await getApiClient().dird.fetchConferenceSource('default');
11766
- // Retrieve conference sources
11767
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
11768
- // Retrieve conference
11769
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
12042
+ if (!meeting) {
12043
+ // Fetch conference source
12044
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
12045
+ // Retrieve conference sources
12046
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
12047
+ // Retrieve conference
12048
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
11770
12049
 
11771
- logger$1.info('connected to room', {
11772
- sourceId: conference ? conference.sourceId : null,
11773
- name: conference ? conference.name : null,
11774
- });
12050
+ logger$1.info('connected to room', {
12051
+ sourceId: conference ? conference.sourceId : null,
12052
+ name: conference ? conference.name : null,
12053
+ });
11775
12054
 
11776
- if (conference) {
11777
- room.setSourceId(conference.sourceId);
11778
- room.setName(conference.name);
12055
+ if (conference) {
12056
+ room.setSourceId(conference.sourceId);
12057
+ room.setName(conference.name);
12058
+ }
12059
+ } else if (meeting) {
12060
+ logger$1.info('Already connected to meeting', {
12061
+ uuid: meeting.uuid,
12062
+ name: meeting.name,
12063
+ });
12064
+
12065
+ room.setMeetingUuid(meeting.uuid);
12066
+ room.setName(meeting.name);
11779
12067
  }
11780
12068
 
11781
12069
  return room;
@@ -11803,10 +12091,8 @@ class Room extends Emitter {
11803
12091
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
11804
12092
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11805
12093
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11806
-
11807
- if (this.roomAudioElement && document.body) {
11808
- document.body.removeChild(this.roomAudioElement);
11809
- }
12094
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12095
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11810
12096
  }
11811
12097
 
11812
12098
  setSourceId(sourceId ) {
@@ -11815,6 +12101,12 @@ class Room extends Emitter {
11815
12101
  this.sourceId = sourceId;
11816
12102
  }
11817
12103
 
12104
+ setMeetingUuid(meetingUuid ) {
12105
+ logger$1.info('set meeting uuid', { meetingUuid });
12106
+
12107
+ this.meetingUuid = meetingUuid;
12108
+ }
12109
+
11818
12110
  setCallId(callId ) {
11819
12111
  logger$1.info('set room call id', { callId });
11820
12112
 
@@ -11856,14 +12148,22 @@ class Room extends Emitter {
11856
12148
  return screensharingStream;
11857
12149
  }
11858
12150
 
11859
- stopScreenSharing(restoreLocalStream = true) {
12151
+ async stopScreenSharing(restoreLocalStream = true) {
11860
12152
  logger$1.info('stop room screen sharing');
11861
12153
 
11862
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
12154
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
11863
12155
 
11864
12156
  if (this.localParticipant) {
11865
12157
  this.localParticipant.onStopScreensharing();
11866
12158
  }
12159
+
12160
+ if (!reinvited && this.localParticipant) {
12161
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
12162
+ // So not REINVITE even is fired, we have to restore the video stream manually
12163
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
12164
+ // $FlowFixMe
12165
+ this._associateStreamTo(localVideoStream, this.localParticipant);
12166
+ }
11867
12167
  }
11868
12168
 
11869
12169
  turnCameraOff() {
@@ -11966,6 +12266,22 @@ class Room extends Emitter {
11966
12266
  return response;
11967
12267
  }
11968
12268
 
12269
+ hasALocalVideoTrack() {
12270
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
12271
+ }
12272
+
12273
+ getLocalStream() {
12274
+ return Wazo.Phone.getLocalStream(this.callSession);
12275
+ }
12276
+
12277
+ getRemoteStream() {
12278
+ return Wazo.Phone.getRemoteStream(this.callSession);
12279
+ }
12280
+
12281
+ getRemoteVideoStream() {
12282
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
12283
+ }
12284
+
11969
12285
  _bindEvents() {
11970
12286
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
11971
12287
  return;
@@ -11987,27 +12303,10 @@ class Room extends Emitter {
11987
12303
  logger$1.info('on room audio stream');
11988
12304
 
11989
12305
  this.audioStream = stream;
11990
- if (document.createElement) {
11991
- // $FlowFixMe
11992
- let roomAudioElement = document.getElementById('audio-room');
11993
- if (!this.roomAudioElement) {
11994
- roomAudioElement = document.createElement('audio');
11995
- // $FlowFixMe
11996
- document.body.appendChild(roomAudioElement);
11997
- }
11998
- if (!roomAudioElement) {
11999
- return;
12000
- }
12001
- this.roomAudioElement = roomAudioElement;
12306
+ if (!this.roomAudioElement) {
12307
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
12308
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
12002
12309
  this.roomAudioElement.srcObject = stream;
12003
- this.roomAudioElement.autoplay = true;
12004
- this.roomAudioElement.id = 'audio-room';
12005
-
12006
- // $FlowFixMe
12007
- if (this.roomAudioElement.setSinkId) {
12008
- // $FlowFixMe
12009
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
12010
- }
12011
12310
  }
12012
12311
  });
12013
12312
 
@@ -12082,6 +12381,9 @@ class Room extends Emitter {
12082
12381
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12083
12382
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12084
12383
 
12384
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
12385
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
12386
+
12085
12387
  // Phone events
12086
12388
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
12087
12389
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -12092,15 +12394,15 @@ class Room extends Emitter {
12092
12394
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
12093
12395
  }
12094
12396
 
12095
- _onMessage(message ) {
12397
+ _onMessage(message ) {
12096
12398
  if (message.method !== 'MESSAGE') {
12097
- return;
12399
+ return null;
12098
12400
  }
12099
12401
  let body;
12100
12402
  try {
12101
12403
  body = JSON.parse(message.body);
12102
12404
  } catch (e) {
12103
- return;
12405
+ return null;
12104
12406
  }
12105
12407
 
12106
12408
  switch (body.type) {
@@ -12119,6 +12421,8 @@ class Room extends Emitter {
12119
12421
  }
12120
12422
 
12121
12423
  this.eventEmitter.emit(this.ON_MESSAGE, body);
12424
+
12425
+ return body;
12122
12426
  }
12123
12427
 
12124
12428
  _onChat(content ) {
@@ -12183,23 +12487,24 @@ class Room extends Emitter {
12183
12487
  const session = Wazo.Auth.getSession();
12184
12488
  let participants = [];
12185
12489
 
12186
- // @TODO: we could use a better function name here
12187
- const isJoining = part => {
12188
- this.__associateStreams(part);
12189
- // @VALIDATE: no need to publicize ourselves, no?
12190
- if (part instanceof RemoteParticipant) {
12191
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
12192
- }
12193
- };
12194
-
12195
12490
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
12196
12491
  if (participant.user_uuid === session.uuid) {
12197
12492
  logger$1.info('room current user joined');
12198
12493
 
12199
12494
  // Retrieve participants via an API calls
12200
12495
  const conferenceId = this.sourceId || payload.data.conference_id;
12201
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
12202
- logger$1.info('fetching conference participants', { conferenceId });
12496
+ let response;
12497
+ try {
12498
+ if (this.meetingUuid) {
12499
+ logger$1.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
12500
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
12501
+ } else {
12502
+ logger$1.info('fetching conference participants', { conferenceId });
12503
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
12504
+ }
12505
+ } catch (e) {
12506
+ logger$1.error('room participants fetching, error', e);
12507
+ }
12203
12508
  if (response) {
12204
12509
  logger$1.info('conference participants fetched', { nb: response.items.length });
12205
12510
  participants = response.items.map(item => {
@@ -12214,25 +12519,10 @@ class Room extends Emitter {
12214
12519
 
12215
12520
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
12216
12521
  if (!this.localParticipant && localParticipant) {
12217
- this.localParticipant = localParticipant;
12218
-
12219
- const localVideoStream = this._getLocalVideoStream();
12220
- if (localVideoStream) {
12221
- this._saveLocalVideoStream(localVideoStream);
12222
- }
12223
-
12224
- this.connected = true;
12225
-
12226
- // we're in the room, now let's request everyone's status
12227
- if (this.localParticipant) {
12228
- this.sendSignal({
12229
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
12230
- origin: this.localParticipant.getStatus(),
12231
- });
12232
- }
12522
+ this._onLocalParticipantJoined(localParticipant);
12233
12523
  }
12234
12524
 
12235
- participants.forEach(someParticipant => isJoining(someParticipant));
12525
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
12236
12526
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
12237
12527
  }
12238
12528
 
@@ -12247,12 +12537,41 @@ class Room extends Emitter {
12247
12537
 
12248
12538
  if (remoteParticipant) {
12249
12539
  this.participants.push(remoteParticipant);
12250
- isJoining(remoteParticipant);
12540
+ this._isParticipantJoining(remoteParticipant);
12251
12541
  }
12252
12542
 
12253
12543
  return remoteParticipant;
12254
12544
  }
12255
12545
 
12546
+ _onLocalParticipantJoined(localParticipant ) {
12547
+ this.localParticipant = localParticipant;
12548
+
12549
+ const localVideoStream = this._getLocalVideoStream();
12550
+ if (localVideoStream) {
12551
+ this._saveLocalVideoStream(localVideoStream);
12552
+ }
12553
+
12554
+ this.connected = true;
12555
+
12556
+ localParticipant.broadcastStatus();
12557
+
12558
+ // we're in the room, now let's request everyone's status
12559
+ if (this.localParticipant) {
12560
+ this.sendSignal({
12561
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
12562
+ origin: this.localParticipant.getStatus(),
12563
+ });
12564
+ }
12565
+ }
12566
+
12567
+ _isParticipantJoining(participant ) {
12568
+ this.__associateStreams(participant);
12569
+ // @VALIDATE: no need to publicize ourselves, no?
12570
+ if (participant instanceof RemoteParticipant) {
12571
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
12572
+ }
12573
+ }
12574
+
12256
12575
  _saveLocalVideoStream(stream ) {
12257
12576
  const { localParticipant } = this;
12258
12577
 
@@ -12298,9 +12617,11 @@ class Room extends Emitter {
12298
12617
  _onParticipantTrackUpdate(oldParticipant , update ) {
12299
12618
  const newParticipant = oldParticipant;
12300
12619
 
12301
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
12620
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
12302
12621
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
12303
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
12622
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
12623
+ const stream = pc.getRemoteStreams().find(someStream =>
12624
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
12304
12625
 
12305
12626
  if (update === 'downgrade') {
12306
12627
  newParticipant.streams = [];
@@ -12330,15 +12651,42 @@ class Room extends Emitter {
12330
12651
  return;
12331
12652
  }
12332
12653
 
12333
- if (this._unassociatedVideoStreams[trackId]) {
12654
+ const streamId = this._getStreamIdFrTrackId(trackId);
12655
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
12656
+ const stream = this._unassociatedVideoStreams[key];
12657
+
12658
+ if (stream) {
12334
12659
  // Try to associate stream
12335
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
12660
+ this._associateStreamTo(stream, participant);
12336
12661
 
12337
- delete this._unassociatedVideoStreams[trackId];
12662
+ delete this._unassociatedVideoStreams[key];
12338
12663
  delete this._unassociatedParticipants[participant.callId];
12339
12664
  }
12340
12665
  }
12341
12666
 
12667
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
12668
+ // Find by trackId
12669
+ if (trackId in this._unassociatedVideoStreams) {
12670
+ return trackId;
12671
+ }
12672
+
12673
+ // Find by streamId
12674
+ if (streamId && streamId in this._unassociatedVideoStreams) {
12675
+ return streamId;
12676
+ }
12677
+
12678
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
12679
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
12680
+ stream && stream.id === streamId);
12681
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
12682
+ }
12683
+
12684
+ _getStreamIdFrTrackId(trackId ) {
12685
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
12686
+
12687
+ return mapping ? mapping.streamId : null;
12688
+ }
12689
+
12342
12690
  _associateStreamTo(rawStream , participant ) {
12343
12691
  const stream = new Wazo.Stream(rawStream, participant);
12344
12692
  participant.streams.push(stream);
@@ -12396,6 +12744,7 @@ class Participant extends Emitter {
12396
12744
 
12397
12745
 
12398
12746
  /**
12747
+ * @param room Room The room where the participant is
12399
12748
  * @param rawParticipant string Participant sent via the Wazo WS
12400
12749
  * @param extra Object extra status of the participant
12401
12750
  */
@@ -12623,6 +12972,11 @@ class Participant extends Emitter {
12623
12972
  // Poor man's object comparison
12624
12973
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
12625
12974
  this.extra = { ...this.extra, ...status.extra };
12975
+
12976
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
12977
+ this.extra.contact = new Contact(this.extra.contact);
12978
+ }
12979
+
12626
12980
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
12627
12981
  }
12628
12982
  }