@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
@@ -1848,7 +1848,7 @@ var IssueReporter$1 = new IssueReporter();
1848
1848
 
1849
1849
  const methods = ['head', 'get', 'post', 'put', 'delete'];
1850
1850
 
1851
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1851
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1852
1852
 
1853
1853
  // Use a function here to be able to mock it in tests
1854
1854
  const realFetch = () => {
@@ -1987,7 +1987,7 @@ class ApiRequester {
1987
1987
  };
1988
1988
 
1989
1989
  if (this.refreshTokenPromise) {
1990
- logger$b.info('A token is already refreshing, waiting ...', { url });
1990
+ logger$c.info('A token is already refreshing, waiting ...', { url });
1991
1991
  await this.refreshTokenPromise;
1992
1992
  }
1993
1993
 
@@ -2007,7 +2007,7 @@ class ApiRequester {
2007
2007
  return promise.then(async (err ) => {
2008
2008
  // Check if the token is still valid
2009
2009
  if (firstCall && this._checkTokenExpired(response, err)) {
2010
- logger$b.warn('token expired', { error: err.reason });
2010
+ logger$c.warn('token expired', { error: err.reason });
2011
2011
  // Replay the call after refreshing the token
2012
2012
  return this._replayWithNewToken(err, path, method, body, headers, parse);
2013
2013
  }
@@ -2017,7 +2017,7 @@ class ApiRequester {
2017
2017
  : exceptionClass.fromResponse(err, response.status);
2018
2018
 
2019
2019
  if (this.shouldLogErrors) {
2020
- logger$b.error('API error', error);
2020
+ logger$c.error('API error', error);
2021
2021
  }
2022
2022
 
2023
2023
  throw error;
@@ -2027,7 +2027,7 @@ class ApiRequester {
2027
2027
  return newParse(response, isJson);
2028
2028
  }).catch(error => {
2029
2029
  if (this.shouldLogErrors) {
2030
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
2030
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
2031
2031
  }
2032
2032
 
2033
2033
  throw error;
@@ -2055,13 +2055,13 @@ class ApiRequester {
2055
2055
  ) {
2056
2056
  const isTokenNotFound = this._isTokenNotFound(err);
2057
2057
  let newPath = path;
2058
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
2058
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
2059
2059
 
2060
2060
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
2061
2061
 
2062
2062
  return this.refreshTokenPromise.then(() => {
2063
2063
  this.refreshTokenPromise = null;
2064
- logger$b.info('token refreshed', { isTokenNotFound });
2064
+ logger$c.info('token refreshed', { isTokenNotFound });
2065
2065
  if (isTokenNotFound) {
2066
2066
  const pathParts = path.split('/');
2067
2067
  pathParts.pop();
@@ -2522,6 +2522,65 @@ class ExternalApp {
2522
2522
  }
2523
2523
  }
2524
2524
 
2525
+ //
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+ class Meeting {
2538
+
2539
+
2540
+
2541
+
2542
+
2543
+
2544
+
2545
+
2546
+
2547
+
2548
+ static parse(plain ) {
2549
+ return new Meeting({
2550
+ guestSipAuthorization: plain.guest_sip_authorization,
2551
+ hostname: plain.hostname,
2552
+ name: plain.name,
2553
+ ownerUuids: plain.owner_uuids,
2554
+ port: plain.port,
2555
+ uuid: plain.uuid,
2556
+ number: plain.number,
2557
+ });
2558
+ }
2559
+
2560
+ static newFrom(meeting ) {
2561
+ return newFrom(meeting, Meeting);
2562
+ }
2563
+
2564
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2565
+ this.guestSipAuthorization = guestSipAuthorization;
2566
+ this.hostname = hostname;
2567
+ this.name = name;
2568
+ this.ownerUuids = ownerUuids;
2569
+ this.port = port;
2570
+ this.uuid = uuid;
2571
+ this.number = number;
2572
+
2573
+ // Useful to compare instead of instanceof with minified code
2574
+ this.type = 'Meeting';
2575
+ }
2576
+
2577
+ getGuestSipCredentials() {
2578
+ // eslint-disable-next-line no-undef
2579
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2580
+ return { username, secret };
2581
+ }
2582
+ }
2583
+
2525
2584
  /* */
2526
2585
 
2527
2586
  var confdMethods = (client , baseUrl ) => ({
@@ -2586,6 +2645,18 @@ var confdMethods = (client , baseUrl ) => ({
2586
2645
  return null;
2587
2646
  }
2588
2647
  },
2648
+
2649
+ createMyMeeting: (name ) =>
2650
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2651
+
2652
+ deleteMyMeeting: (meetingUuid ) =>
2653
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2654
+
2655
+ getMeeting: (meetingUuid ) =>
2656
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2657
+
2658
+ guestGetMeeting: (meetingUuid ) =>
2659
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2589
2660
  });
2590
2661
 
2591
2662
  //
@@ -3528,7 +3599,11 @@ class CallLog {
3528
3599
  answered: plain.answered,
3529
3600
  callDirection: plain.call_direction,
3530
3601
  destination: {
3531
- extension: plain.requested_extension || plain.destination_extension,
3602
+ // @TEMP: Temporarily assuming empty numbers are meetings
3603
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3604
+ extension: plain.requested_extension
3605
+ || plain.destination_extension
3606
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3532
3607
  name: plain.requested_name || plain.destination_name || '',
3533
3608
  },
3534
3609
  source: {
@@ -3544,27 +3619,11 @@ class CallLog {
3544
3619
  }
3545
3620
 
3546
3621
  static parseNew(plain , session ) {
3547
- return new CallLog({
3548
- answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3549
- answered: plain.answered,
3550
- callDirection: plain.call_direction,
3551
- destination: {
3552
- extension: plain.requested_extension || plain.destination_extension,
3553
- name: plain.requested_name || plain.destination_name || '',
3554
- },
3555
- source: {
3556
- extension: plain.source_extension,
3557
- name: plain.source_name,
3558
- },
3559
- id: plain.id,
3560
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3561
- start: moment__default['default'](plain.start).toDate(),
3562
- end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3563
- recordings: Recording.parseMany(plain.recordings),
3564
- // @TODO: FIXME add verification declined vs missed call
3565
- newMissedCall: session
3566
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3567
- });
3622
+ const callLog = CallLog.parse(plain);
3623
+ // @TODO: FIXME add verification declined vs missed call
3624
+ callLog.newMissedCall = session
3625
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3626
+ return callLog;
3568
3627
  }
3569
3628
 
3570
3629
  static newFrom(profile ) {
@@ -3829,7 +3888,7 @@ const TRANSFER_FLOW_BLIND = 'blind';
3829
3888
 
3830
3889
  // const MINIMUM_WAZO_ENGINE_VERSION_FOR_CTI_HOLD = '20.11';
3831
3890
 
3832
- const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3891
+ const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3833
3892
 
3834
3893
  class CTIPhone extends Emitter {
3835
3894
 
@@ -3842,7 +3901,7 @@ class CTIPhone extends Emitter {
3842
3901
 
3843
3902
  constructor(session , isMobile = false, callbackAllLines = false) {
3844
3903
  super();
3845
- logger$a.info('CTI Phone created');
3904
+ logger$b.info('CTI Phone created');
3846
3905
  this.session = session;
3847
3906
  this.isMobile = isMobile;
3848
3907
  this.callbackAllLines = callbackAllLines;
@@ -3903,7 +3962,7 @@ class CTIPhone extends Emitter {
3903
3962
  }
3904
3963
 
3905
3964
  async makeCall(number , line ) {
3906
- logger$a.info('make CTI call', { number });
3965
+ logger$b.info('make CTI call', { number });
3907
3966
 
3908
3967
  if (!number) {
3909
3968
  return null;
@@ -3926,7 +3985,7 @@ class CTIPhone extends Emitter {
3926
3985
  if (!callSession) {
3927
3986
  return Promise.resolve(null);
3928
3987
  }
3929
- logger$a.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3988
+ logger$b.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3930
3989
 
3931
3990
  if (!this.currentCall) {
3932
3991
  this.currentCall = callSession.call;
@@ -3939,7 +3998,7 @@ class CTIPhone extends Emitter {
3939
3998
  if (!callSession) {
3940
3999
  return;
3941
4000
  }
3942
- logger$a.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
4001
+ logger$b.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
3943
4002
 
3944
4003
  this.currentCall = undefined;
3945
4004
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3949,7 +4008,7 @@ class CTIPhone extends Emitter {
3949
4008
  if (!callSession) {
3950
4009
  return Promise.resolve(false);
3951
4010
  }
3952
- logger$a.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4011
+ logger$b.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
3953
4012
 
3954
4013
  try {
3955
4014
  await CallApi.cancelCall(callSession);
@@ -3960,7 +4019,7 @@ class CTIPhone extends Emitter {
3960
4019
  this.eventEmitter.emit('onCallEnded', callSession);
3961
4020
  return true;
3962
4021
  } catch (e) {
3963
- logger$a.error('hangup CTI call, error', e);
4022
+ logger$b.error('hangup CTI call, error', e);
3964
4023
 
3965
4024
  this.eventEmitter.emit('onCallFailed', callSession);
3966
4025
  return false;
@@ -3973,7 +4032,7 @@ class CTIPhone extends Emitter {
3973
4032
  if (!callSession) {
3974
4033
  return;
3975
4034
  }
3976
- logger$a.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4035
+ logger$b.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
3977
4036
 
3978
4037
  await CallApi.cancelCall(callSession);
3979
4038
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3983,7 +4042,7 @@ class CTIPhone extends Emitter {
3983
4042
  if (!callSession) {
3984
4043
  return;
3985
4044
  }
3986
- logger$a.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4045
+ logger$b.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
3987
4046
 
3988
4047
  await CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_BLIND);
3989
4048
  }
@@ -3994,19 +4053,19 @@ class CTIPhone extends Emitter {
3994
4053
  if (!callSession) {
3995
4054
  return;
3996
4055
  }
3997
- logger$a.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4056
+ logger$b.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
3998
4057
 
3999
4058
  return CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_ATTENDED);
4000
4059
  }
4001
4060
 
4002
4061
  async cancelCTIIndirectTransfer(transferId ) {
4003
- logger$a.info('cancel CTI transfer', { transferId });
4062
+ logger$b.info('cancel CTI transfer', { transferId });
4004
4063
 
4005
4064
  return CallApi.cancelCallTransfer(transferId);
4006
4065
  }
4007
4066
 
4008
4067
  async confirmCTIIndirectTransfer(transferId ) {
4009
- logger$a.info('confirm CTI transfer', { transferId });
4068
+ logger$b.info('confirm CTI transfer', { transferId });
4010
4069
 
4011
4070
  return CallApi.confirmCallTransfer(transferId);
4012
4071
  }
@@ -4015,19 +4074,19 @@ class CTIPhone extends Emitter {
4015
4074
  if (!callSession) {
4016
4075
  return;
4017
4076
  }
4018
- logger$a.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4077
+ logger$b.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4019
4078
 
4020
4079
  return CallApi.sendDTMF(callSession.callId, digits);
4021
4080
  }
4022
4081
 
4023
4082
  onConnectionMade() {
4024
- logger$a.info('on CTI connection made');
4083
+ logger$b.info('on CTI connection made');
4025
4084
 
4026
4085
  this.eventEmitter.emit('onCallAccepted');
4027
4086
  }
4028
4087
 
4029
4088
  async close() {
4030
- logger$a.info('CTI close');
4089
+ logger$b.info('CTI close');
4031
4090
 
4032
4091
  return Promise.resolve();
4033
4092
  }
@@ -4036,7 +4095,7 @@ class CTIPhone extends Emitter {
4036
4095
  if (!callSession) {
4037
4096
  return;
4038
4097
  }
4039
- logger$a.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4098
+ logger$b.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4040
4099
 
4041
4100
  return CallApi.hold(callSession.callId);
4042
4101
  }
@@ -4045,7 +4104,7 @@ class CTIPhone extends Emitter {
4045
4104
  if (!callSession) {
4046
4105
  return;
4047
4106
  }
4048
- logger$a.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4107
+ logger$b.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4049
4108
 
4050
4109
  return CallApi.resume(callSession.callId);
4051
4110
  }
@@ -4054,7 +4113,7 @@ class CTIPhone extends Emitter {
4054
4113
  if (!callSession) {
4055
4114
  return;
4056
4115
  }
4057
- logger$a.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4116
+ logger$b.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4058
4117
 
4059
4118
  return CallApi.mute(callSession.callId);
4060
4119
  }
@@ -4063,7 +4122,7 @@ class CTIPhone extends Emitter {
4063
4122
  if (!callSession) {
4064
4123
  return;
4065
4124
  }
4066
- logger$a.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4125
+ logger$b.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4067
4126
 
4068
4127
  return CallApi.unmute(callSession.callId);
4069
4128
  }
@@ -4709,6 +4768,9 @@ var calldMethods = (client , baseUrl ) => ({
4709
4768
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4710
4769
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4711
4770
 
4771
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4772
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4773
+
4712
4774
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4713
4775
 
4714
4776
  mute: (callId ) =>
@@ -5062,7 +5124,7 @@ const AGENTD_VERSION = '1.0';
5062
5124
  const WEBHOOKD_VERSION = '1.0';
5063
5125
  const AMID_VERSION = '1.0';
5064
5126
 
5065
- const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5127
+ const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5066
5128
 
5067
5129
  class ApiClient {
5068
5130
 
@@ -5114,12 +5176,12 @@ class ApiClient {
5114
5176
  }
5115
5177
 
5116
5178
  async forceRefreshToken() {
5117
- logger$9.info('forcing refresh token, calling callback');
5179
+ logger$a.info('forcing refresh token, calling callback');
5118
5180
  return this.refreshTokenCallback();
5119
5181
  }
5120
5182
 
5121
5183
  async refreshTokenCallback() {
5122
- logger$9.info('refresh token callback called', {
5184
+ logger$a.info('refresh token callback called', {
5123
5185
  refreshToken: this.refreshToken,
5124
5186
  refreshBackend: this.refreshBackend,
5125
5187
  refreshExpiration: this.refreshExpiration,
@@ -5137,7 +5199,7 @@ class ApiClient {
5137
5199
  this.isMobile,
5138
5200
  );
5139
5201
 
5140
- logger$9.info('token refreshed', { token: session.token });
5202
+ logger$a.info('token refreshed', { token: session.token });
5141
5203
 
5142
5204
  if (this.onRefreshToken) {
5143
5205
  this.onRefreshToken(session.token, session);
@@ -5610,7 +5672,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5610
5672
  .then(() => {
5611
5673
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5612
5674
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5613
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5675
+ if (this.peerConnection.addTransceiver) {
5676
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5677
+ }
5614
5678
  }
5615
5679
  })
5616
5680
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5637,12 +5701,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5637
5701
  };
5638
5702
  })
5639
5703
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5640
- .then((sessionDescription) => {
5641
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5642
- this.localMediaStreamConstraints = options.constraints;
5643
-
5644
- return sessionDescription;
5645
- })
5646
5704
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5647
5705
  .catch((error) => {
5648
5706
  wazoLogger.error('error when creating media', error);
@@ -5837,6 +5895,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5837
5895
 
5838
5896
  // set the transceiver direction to the answer direction
5839
5897
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5898
+ if (transceiver.stopped) {
5899
+ return;
5900
+ }
5840
5901
  if (transceiver.direction /* guarding, but should always be true */) {
5841
5902
  const { receiver } = transceiver;
5842
5903
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -5881,10 +5942,15 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5881
5942
  if (kind !== 'audio' && kind !== 'video') {
5882
5943
  throw new Error(`Unknown new track kind ${kind}.`);
5883
5944
  }
5884
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5945
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
5946
+ otherSender.track && otherSender.track.kind === kind);
5885
5947
 
5886
5948
  // Do not reuse sender video tracks in SFU
5887
5949
  if (sender && (!sfu || newTrack.kind === 'audio')) {
5950
+ if (sender.track) {
5951
+ // eslint-disable-next-line no-param-reassign
5952
+ newTrack.enabled = sender.track.enabled;
5953
+ }
5888
5954
  trackUpdates.push(
5889
5955
  new Promise((resolve) => {
5890
5956
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5918,7 +5984,11 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5918
5984
  // Review: could make streamless tracks a configurable option?
5919
5985
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
5920
5986
  try {
5921
- pc.addTrack(newTrack, localStream);
5987
+ if (pc.addTrack) {
5988
+ pc.addTrack(newTrack, localStream);
5989
+ } else {
5990
+ pc.addStream(localStream);
5991
+ }
5922
5992
  } catch (error) {
5923
5993
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
5924
5994
  throw error;
@@ -6054,7 +6124,7 @@ const DEFAULT_ICE_TIMEOUT = 3000;
6054
6124
  const SEND_STATS_DELAY = 5000;
6055
6125
 
6056
6126
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
6057
- const logger$8 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6127
+ const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6058
6128
  const statsLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-stats') : console;
6059
6129
 
6060
6130
  // events
@@ -6100,6 +6170,7 @@ const MAX_REGISTER_TRIES = 10;
6100
6170
 
6101
6171
 
6102
6172
 
6173
+
6103
6174
 
6104
6175
 
6105
6176
 
@@ -6126,6 +6197,7 @@ class WebRTCClient extends Emitter {
6126
6197
 
6127
6198
 
6128
6199
 
6200
+
6129
6201
 
6130
6202
  // sugar
6131
6203
 
@@ -6164,6 +6236,8 @@ class WebRTCClient extends Emitter {
6164
6236
  super();
6165
6237
  this.uaConfigOverrides = uaConfigOverrides;
6166
6238
  this.config = config;
6239
+ this.skipRegister = config.skipRegister;
6240
+
6167
6241
  this._buildConfig(config, session).then((newConfig ) => {
6168
6242
  this.config = newConfig;
6169
6243
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -6219,13 +6293,13 @@ class WebRTCClient extends Emitter {
6219
6293
 
6220
6294
  createUserAgent(configOverrides ) {
6221
6295
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
6222
- logger$8.info('sdk webrtc, creating UA', { webRTCConfiguration });
6296
+ logger$9.info('sdk webrtc, creating UA', { webRTCConfiguration });
6223
6297
 
6224
6298
  webRTCConfiguration.delegate = {
6225
6299
  onConnect: this.onConnect.bind(this),
6226
6300
  onDisconnect: this.onDisconnect.bind(this),
6227
6301
  onInvite: (invitation ) => {
6228
- logger$8.info('sdk webrtc on invite', {
6302
+ logger$9.info('sdk webrtc on invite', {
6229
6303
  method: 'delegate.onInvite',
6230
6304
  id: invitation.id,
6231
6305
  remoteURI: invitation.remoteURI,
@@ -6268,7 +6342,7 @@ class WebRTCClient extends Emitter {
6268
6342
  }
6269
6343
 
6270
6344
  onConnect() {
6271
- logger$8.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6345
+ logger$9.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6272
6346
  this.eventEmitter.emit(CONNECTED);
6273
6347
  if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
6274
6348
  this.registerer.waitingToggle(false);
@@ -6277,7 +6351,7 @@ class WebRTCClient extends Emitter {
6277
6351
  }
6278
6352
 
6279
6353
  async onDisconnect(error ) {
6280
- logger$8.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6354
+ logger$9.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6281
6355
  this.connectionPromise = null;
6282
6356
  // The UA will attempt to reconnect automatically when an error occurred
6283
6357
  this.eventEmitter.emit(DISCONNECTED, error);
@@ -6291,40 +6365,48 @@ class WebRTCClient extends Emitter {
6291
6365
  }
6292
6366
 
6293
6367
  register(tries = 0) {
6294
- logger$8.info('sdk webrtc registering...', {
6368
+ const logInfo = {
6295
6369
  userAgent: !!this.userAgent,
6296
6370
  registered: this.isRegistered(),
6297
6371
  connectionPromise: !!this.connectionPromise,
6298
6372
  registerer: !!this.registerer,
6299
6373
  waiting: this.registerer && this.registerer.waiting,
6300
6374
  tries,
6301
- });
6375
+ skipRegister: this.skipRegister,
6376
+ };
6377
+
6378
+ if (this.skipRegister) {
6379
+ logger$9.info('sdk webrtc skip register...', logInfo);
6380
+ return Promise.resolve();
6381
+ }
6382
+
6383
+ logger$9.info('sdk webrtc registering...', logInfo);
6302
6384
 
6303
6385
  if (!this.userAgent) {
6304
- logger$8.info('sdk webrtc recreating User Agent');
6386
+ logger$9.info('sdk webrtc recreating User Agent');
6305
6387
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6306
6388
  }
6307
6389
  if (!this.userAgent || this.isRegistered()) {
6308
- logger$8.info('sdk webrtc registering aborted, already registered or no UA can be created');
6390
+ logger$9.info('sdk webrtc registering aborted, already registered or no UA can be created');
6309
6391
  return Promise.resolve();
6310
6392
  }
6311
6393
 
6312
6394
  if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
6313
- logger$8.info('sdk webrtc registering aborted due to a registration in progress.');
6395
+ logger$9.info('sdk webrtc registering aborted due to a registration in progress.');
6314
6396
  return Promise.resolve();
6315
6397
  }
6316
6398
 
6317
6399
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6318
6400
 
6319
6401
  const onRegisterFailed = () => {
6320
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6402
+ logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6321
6403
  this.connectionPromise = null;
6322
6404
  if (this.registerer && this.registerer.waiting) {
6323
6405
  this.registerer.waitingToggle(false);
6324
6406
  }
6325
6407
 
6326
6408
  if (tries <= MAX_REGISTER_TRIES) {
6327
- logger$8.info('sdk webrtc registering, retrying...', { tries });
6409
+ logger$9.info('sdk webrtc registering, retrying...', { tries });
6328
6410
  setTimeout(() => this.register(tries + 1), 300);
6329
6411
  }
6330
6412
  };
@@ -6333,18 +6415,18 @@ class WebRTCClient extends Emitter {
6333
6415
  // Avoid race condition with the close method called just before register and setting userAgent to null
6334
6416
  // during the resolution of the primise.
6335
6417
  if (!this.userAgent) {
6336
- logger$8.info('sdk webrtc recreating User Agent after connection');
6418
+ logger$9.info('sdk webrtc recreating User Agent after connection');
6337
6419
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6338
6420
  }
6339
6421
 
6340
- logger$8.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6422
+ logger$9.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6341
6423
  this.registerer = new registerer.Registerer(this.userAgent, registerOptions);
6342
6424
  this.connectionPromise = null;
6343
6425
  this._monkeyPatchRegisterer(this.registerer);
6344
6426
 
6345
6427
  // Bind registerer events
6346
6428
  this.registerer.stateChange.addListener(newState => {
6347
- logger$8.info('sdk webrtc registering, state changed', { newState });
6429
+ logger$9.info('sdk webrtc registering, state changed', { newState });
6348
6430
 
6349
6431
  if (newState === registererState.RegistererState.Registered && this.registerer
6350
6432
  && this.registerer.state === registererState.RegistererState.Registered) {
@@ -6357,7 +6439,7 @@ class WebRTCClient extends Emitter {
6357
6439
  const options = {
6358
6440
  requestDelegate: {
6359
6441
  onReject: response => {
6360
- logger$8.error('sdk webrtc registering, rejected', { response });
6442
+ logger$9.error('sdk webrtc registering, rejected', { response });
6361
6443
 
6362
6444
  onRegisterFailed();
6363
6445
  },
@@ -6365,13 +6447,13 @@ class WebRTCClient extends Emitter {
6365
6447
  };
6366
6448
 
6367
6449
  return this.registerer.register(options).catch((e) => {
6368
- logger$8.error('sdk webrtc registering, error', e);
6450
+ logger$9.error('sdk webrtc registering, error', e);
6369
6451
 
6370
6452
  this.eventEmitter.emit(REGISTRATION_FAILED);
6371
6453
  return e;
6372
6454
  });
6373
6455
  }).catch(error => {
6374
- logger$8.error('sdk webrtc registering, transport error', error);
6456
+ logger$9.error('sdk webrtc registering, transport error', error);
6375
6457
  onRegisterFailed();
6376
6458
  });
6377
6459
  }
@@ -6400,21 +6482,21 @@ class WebRTCClient extends Emitter {
6400
6482
  }
6401
6483
 
6402
6484
  unregister() {
6403
- logger$8.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6485
+ logger$9.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6404
6486
  if (!this.registerer) {
6405
6487
  return Promise.resolve();
6406
6488
  }
6407
6489
 
6408
6490
  try {
6409
6491
  return this.registerer.unregister().then(() => {
6410
- logger$8.info('sdk webrtc unregistered');
6492
+ logger$9.info('sdk webrtc unregistered');
6411
6493
  this._cleanupRegister();
6412
6494
  }).catch(e => {
6413
- logger$8.error('sdk webrtc unregistering, promise error', e);
6495
+ logger$9.error('sdk webrtc unregistering, promise error', e);
6414
6496
  this._cleanupRegister();
6415
6497
  });
6416
6498
  } catch (e) {
6417
- logger$8.error('sdk webrtc unregistering, error', e);
6499
+ logger$9.error('sdk webrtc unregistering, error', e);
6418
6500
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
6419
6501
  // error when the registerer is in a bad state
6420
6502
  this._cleanupRegister();
@@ -6422,7 +6504,7 @@ class WebRTCClient extends Emitter {
6422
6504
  }
6423
6505
 
6424
6506
  stop() {
6425
- logger$8.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6507
+ logger$9.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6426
6508
  if (!this.userAgent) {
6427
6509
  return Promise.resolve();
6428
6510
  }
@@ -6430,12 +6512,12 @@ class WebRTCClient extends Emitter {
6430
6512
  return this.userAgent.stop().then(() => {
6431
6513
  return this._cleanupRegister();
6432
6514
  }).catch(e => {
6433
- logger$8.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6515
+ logger$9.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6434
6516
  });
6435
6517
  }
6436
6518
 
6437
6519
  call(number , enableVideo , audioOnly = false, conference = false) {
6438
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6520
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6439
6521
  const inviterOptions = {
6440
6522
  sessionDescriptionHandlerOptionsReInvite: {
6441
6523
  conference,
@@ -6464,7 +6546,7 @@ class WebRTCClient extends Emitter {
6464
6546
  this._onAccepted(session, response.session, true);
6465
6547
  },
6466
6548
  onReject: (response ) => {
6467
- logger$8.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6549
+ logger$9.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6468
6550
  this._stopSendingStats(session);
6469
6551
 
6470
6552
  this.eventEmitter.emit(REJECTED, session, response);
@@ -6486,11 +6568,11 @@ class WebRTCClient extends Emitter {
6486
6568
  }
6487
6569
 
6488
6570
  answer(session , enableVideo ) {
6489
- logger$8.info('sdk webrtc answer call', { id: session.id, enableVideo });
6571
+ logger$9.info('sdk webrtc answer call', { id: session.id, enableVideo });
6490
6572
 
6491
6573
  if (!session || !session.accept) {
6492
6574
  const error = 'No session to answer, or not an invitation';
6493
- logger$8.warn(error);
6575
+ logger$9.warn(error);
6494
6576
  return Promise.reject(new Error(error));
6495
6577
  }
6496
6578
  const options = {
@@ -6500,15 +6582,15 @@ class WebRTCClient extends Emitter {
6500
6582
  return session.accept(options).then(() => {
6501
6583
  if (session.isCanceled) {
6502
6584
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
6503
- logger$8.error(message, { id: session.id });
6585
+ logger$9.error(message, { id: session.id });
6504
6586
  this.onCallEnded(session);
6505
6587
 
6506
6588
  throw new CanceledCallError(message);
6507
6589
  }
6508
- logger$8.info('sdk webrtc answer, accepted.');
6590
+ logger$9.info('sdk webrtc answer, accepted.');
6509
6591
  this._onAccepted(session);
6510
6592
  }).catch(e => {
6511
- logger$8.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6593
+ logger$9.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6512
6594
 
6513
6595
  throw e;
6514
6596
  });
@@ -6516,7 +6598,7 @@ class WebRTCClient extends Emitter {
6516
6598
 
6517
6599
  hangup(session ) {
6518
6600
  const { state, id } = session;
6519
- logger$8.info('sdk webrtc hangup call', { id, state });
6601
+ logger$9.info('sdk webrtc hangup call', { id, state });
6520
6602
 
6521
6603
  try {
6522
6604
  this._stopSendingStats(session);
@@ -6545,24 +6627,24 @@ class WebRTCClient extends Emitter {
6545
6627
 
6546
6628
  return bye();
6547
6629
  } catch (error) {
6548
- logger$8.warn('sdk webrtc hangup, error', error);
6630
+ logger$9.warn('sdk webrtc hangup, error', error);
6549
6631
  }
6550
6632
 
6551
6633
  return null;
6552
6634
  }
6553
6635
 
6554
6636
  reject(session ) {
6555
- logger$8.info('sdk webrtc reject call', { id: session.id });
6637
+ logger$9.info('sdk webrtc reject call', { id: session.id });
6556
6638
 
6557
6639
  try {
6558
6640
  return session.reject ? session.reject() : session.cancel();
6559
6641
  } catch (e) {
6560
- logger$8.warn('Error when rejecting call', e.message, e.stack);
6642
+ logger$9.warn('Error when rejecting call', e.message, e.stack);
6561
6643
  }
6562
6644
  }
6563
6645
 
6564
6646
  async close() {
6565
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6647
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6566
6648
  this._cleanupMedia();
6567
6649
  this.connectionPromise = null;
6568
6650
 
@@ -6593,7 +6675,7 @@ class WebRTCClient extends Emitter {
6593
6675
  // eg: "INVITE not rejectable in state Completed"
6594
6676
  }
6595
6677
  this.userAgent = null;
6596
- logger$8.info('sdk webrtc client closed');
6678
+ logger$9.info('sdk webrtc client closed');
6597
6679
  }
6598
6680
 
6599
6681
  getNumber(session ) {
@@ -6606,13 +6688,13 @@ class WebRTCClient extends Emitter {
6606
6688
  }
6607
6689
 
6608
6690
  mute(session ) {
6609
- logger$8.info('sdk webrtc mute', { id: session.id });
6691
+ logger$9.info('sdk webrtc mute', { id: session.id });
6610
6692
 
6611
6693
  this._toggleAudio(session, true);
6612
6694
  }
6613
6695
 
6614
6696
  unmute(session ) {
6615
- logger$8.info('sdk webrtc unmute', { id: session.id });
6697
+ logger$9.info('sdk webrtc unmute', { id: session.id });
6616
6698
 
6617
6699
  this._toggleAudio(session, false);
6618
6700
  }
@@ -6629,12 +6711,18 @@ class WebRTCClient extends Emitter {
6629
6711
  }
6630
6712
 
6631
6713
  if (pc.getSenders) {
6714
+ if (!pc.getSenders().length) {
6715
+ return false;
6716
+ }
6632
6717
  pc.getSenders().forEach(sender => {
6633
6718
  if (sender && sender.track && sender.track.kind === 'audio') {
6634
6719
  muted = muted && !sender.track.enabled;
6635
6720
  }
6636
6721
  });
6637
6722
  } else {
6723
+ if (!pc.getLocalStreams().length) {
6724
+ return false;
6725
+ }
6638
6726
  pc.getLocalStreams().forEach(stream => {
6639
6727
  stream.getAudioTracks().forEach(track => {
6640
6728
  muted = muted && !track.enabled;
@@ -6646,20 +6734,20 @@ class WebRTCClient extends Emitter {
6646
6734
  }
6647
6735
 
6648
6736
  toggleCameraOn(session ) {
6649
- logger$8.info('sdk webrtc toggle camera on', { id: session.id });
6737
+ logger$9.info('sdk webrtc toggle camera on', { id: session.id });
6650
6738
 
6651
6739
  this._toggleVideo(session, false);
6652
6740
  }
6653
6741
 
6654
6742
  toggleCameraOff(session ) {
6655
- logger$8.info('sdk webrtc toggle camera off', { id: session.id });
6743
+ logger$9.info('sdk webrtc toggle camera off', { id: session.id });
6656
6744
 
6657
6745
  this._toggleVideo(session, true);
6658
6746
  }
6659
6747
 
6660
6748
  hold(session , isConference = false) {
6661
6749
  const sessionId = this.getSipSessionId(session);
6662
- logger$8.info('sdk webrtc hold', {
6750
+ logger$9.info('sdk webrtc hold', {
6663
6751
  sessionId,
6664
6752
  keys: Object.keys(this.heldSessions),
6665
6753
  pendingReinvite: !!session.pendingReinvite,
@@ -6693,6 +6781,8 @@ class WebRTCClient extends Emitter {
6693
6781
  }
6694
6782
  options.sessionDescriptionHandlerOptions = {
6695
6783
  constraints: options.constraints,
6784
+ hold: true,
6785
+ conference: isConference,
6696
6786
  };
6697
6787
 
6698
6788
  // Send re-INVITE
@@ -6702,7 +6792,7 @@ class WebRTCClient extends Emitter {
6702
6792
  unhold(session , isConference = false) {
6703
6793
  const sessionId = this.getSipSessionId(session);
6704
6794
 
6705
- logger$8.info('sdk webrtc unhold', {
6795
+ logger$9.info('sdk webrtc unhold', {
6706
6796
  sessionId,
6707
6797
  keys: Object.keys(this.heldSessions),
6708
6798
  pendingReinvite: !!session.pendingReinvite,
@@ -6735,6 +6825,8 @@ class WebRTCClient extends Emitter {
6735
6825
  }
6736
6826
  options.sessionDescriptionHandlerOptions = {
6737
6827
  constraints: options.constraints,
6828
+ hold: false,
6829
+ conference: isConference,
6738
6830
  };
6739
6831
 
6740
6832
  // Send re-INVITE
@@ -6793,7 +6885,7 @@ class WebRTCClient extends Emitter {
6793
6885
  return;
6794
6886
  }
6795
6887
 
6796
- logger$8.info('send WebRTC message', { sipId: sipSession.id, contentType });
6888
+ logger$9.info('send WebRTC message', { sipId: sipSession.id, contentType });
6797
6889
 
6798
6890
  try {
6799
6891
  sipSession.message({
@@ -6918,7 +7010,8 @@ class WebRTCClient extends Emitter {
6918
7010
  }
6919
7011
  const sdh = session.sessionDescriptionHandler;
6920
7012
  const pc = sdh.peerConnection;
6921
- const localStream = this.getLocalStream(this.getSipSessionId(session));
7013
+ const sessionId = this.getSipSessionId(session);
7014
+ const localStream = this.getLocalStream(sessionId);
6922
7015
 
6923
7016
  // Release old video stream
6924
7017
  if (localStream) {
@@ -6944,11 +7037,8 @@ class WebRTCClient extends Emitter {
6944
7037
 
6945
7038
  // let's update the local stream
6946
7039
  this.eventEmitter.emit('onVideoInputChange', stream);
6947
- try {
6948
- await sdh.setLocalMediaStream(stream);
6949
- } catch (_) {
6950
- // Nothing to do
6951
- }
7040
+ this.setLocalMediaStream(sessionId, stream);
7041
+
6952
7042
  return stream;
6953
7043
  });
6954
7044
  }
@@ -7160,7 +7250,7 @@ class WebRTCClient extends Emitter {
7160
7250
  }
7161
7251
 
7162
7252
  startHeartbeat() {
7163
- logger$8.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7253
+ logger$9.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7164
7254
  if (!this.userAgent) {
7165
7255
  this.heartbeat.stop();
7166
7256
  return;
@@ -7173,7 +7263,7 @@ class WebRTCClient extends Emitter {
7173
7263
  }
7174
7264
 
7175
7265
  stopHeartbeat() {
7176
- logger$8.info('sdk webrtc stop heartbeat');
7266
+ logger$9.info('sdk webrtc stop heartbeat');
7177
7267
  this.heartbeat.stop();
7178
7268
  }
7179
7269
 
@@ -7193,7 +7283,7 @@ class WebRTCClient extends Emitter {
7193
7283
  }
7194
7284
 
7195
7285
  attemptReconnection() {
7196
- logger$8.info('attempt reconnection', { userAgent: !!this.userAgent });
7286
+ logger$9.info('attempt reconnection', { userAgent: !!this.userAgent });
7197
7287
  if (!this.userAgent) {
7198
7288
  return;
7199
7289
  }
@@ -7250,9 +7340,11 @@ class WebRTCClient extends Emitter {
7250
7340
  remoteStream.removeTrack(track);
7251
7341
  });
7252
7342
 
7253
- pc.getReceivers().forEach(receiver => {
7254
- remoteStream.addTrack(receiver.track);
7255
- });
7343
+ if (pc.getReceivers) {
7344
+ pc.getReceivers().forEach(receiver => {
7345
+ remoteStream.addTrack(receiver.track);
7346
+ });
7347
+ }
7256
7348
  }
7257
7349
 
7258
7350
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -7287,6 +7379,25 @@ class WebRTCClient extends Emitter {
7287
7379
  return sessionId in this.conferences;
7288
7380
  }
7289
7381
 
7382
+ createAudioElementFor(sessionId ) {
7383
+ const audio = document.createElement('audio');
7384
+ audio.setAttribute('id', `audio-${sessionId}`);
7385
+
7386
+ if (audio.setSinkId && this.audioOutputDeviceId) {
7387
+ audio.setSinkId(this.audioOutputDeviceId);
7388
+ }
7389
+
7390
+ if (document.body) {
7391
+ document.body.appendChild(audio);
7392
+ }
7393
+ this.audioElements[sessionId] = audio;
7394
+
7395
+ audio.volume = this.audioOutputVolume;
7396
+ audio.autoplay = true;
7397
+
7398
+ return audio;
7399
+ }
7400
+
7290
7401
  _onTransportError() {
7291
7402
  this.eventEmitter.emit(TRANSPORT_ERROR);
7292
7403
  this.attemptReconnection();
@@ -7296,7 +7407,7 @@ class WebRTCClient extends Emitter {
7296
7407
  const body = message && typeof message === 'object' ? message.data : message;
7297
7408
  if (body && body.indexOf('200 OK') !== -1) {
7298
7409
  if (this.hasHeartbeat()) {
7299
- logger$8.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7410
+ logger$9.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7300
7411
 
7301
7412
  this.heartbeat.onHeartbeat();
7302
7413
  if (this.heartbeatCb) {
@@ -7307,7 +7418,7 @@ class WebRTCClient extends Emitter {
7307
7418
  }
7308
7419
 
7309
7420
  async _onHeartbeatTimeout() {
7310
- logger$8.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7421
+ logger$9.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7311
7422
 
7312
7423
  if (this.heartbeatTimeoutCb) {
7313
7424
  this.heartbeatTimeoutCb();
@@ -7319,7 +7430,7 @@ class WebRTCClient extends Emitter {
7319
7430
  try {
7320
7431
  await this.userAgent.transport.disconnect();
7321
7432
  } catch (e) {
7322
- logger$8.error('Transport disconnection after heartbeat timeout, error', e);
7433
+ logger$9.error('Transport disconnection after heartbeat timeout, error', e);
7323
7434
  }
7324
7435
  }
7325
7436
 
@@ -7352,31 +7463,31 @@ class WebRTCClient extends Emitter {
7352
7463
  }
7353
7464
 
7354
7465
  _connectIfNeeded() {
7355
- logger$8.info('connect if needed, checking', { connected: this.isConnected() });
7466
+ logger$9.info('connect if needed, checking', { connected: this.isConnected() });
7356
7467
  if (!this.userAgent) {
7357
- logger$8.info('need to recreate User Agent');
7468
+ logger$9.info('need to recreate User Agent');
7358
7469
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
7359
7470
  }
7360
7471
 
7361
7472
  if (this.isConnected()) {
7362
- logger$8.info('webrtc sdk, already connected');
7473
+ logger$9.info('webrtc sdk, already connected');
7363
7474
  return Promise.resolve();
7364
7475
  }
7365
7476
 
7366
7477
  if (this.isConnecting()) {
7367
- logger$8.info('webrtc sdk, already connecting...');
7478
+ logger$9.info('webrtc sdk, already connecting...');
7368
7479
 
7369
7480
  this.connectionPromise = this.userAgent.transport.connectPromise;
7370
7481
  return this.connectionPromise;
7371
7482
  }
7372
7483
 
7373
7484
  if (this.connectionPromise) {
7374
- logger$8.info('webrtc sdk, connection promise connecting...');
7485
+ logger$9.info('webrtc sdk, connection promise connecting...');
7375
7486
  // $FlowFixMe
7376
7487
  return this.connectionPromise;
7377
7488
  }
7378
7489
 
7379
- logger$8.info('WebRTC UA needs to connect');
7490
+ logger$9.info('WebRTC UA needs to connect');
7380
7491
 
7381
7492
  // Force UA to reconnect
7382
7493
  if (this.userAgent && this.userAgent.state !== userAgentState.UserAgentState.Stopped) {
@@ -7501,7 +7612,7 @@ class WebRTCClient extends Emitter {
7501
7612
 
7502
7613
  sdh.peerConnectionDelegate = {
7503
7614
  onicecandidateerror: (error ) => {
7504
- logger$8.error('on icecandidate error', {
7615
+ logger$9.error('on icecandidate error', {
7505
7616
  address: error.address,
7506
7617
  port: error.port,
7507
7618
  errorCode: error.errorCode,
@@ -7516,7 +7627,7 @@ class WebRTCClient extends Emitter {
7516
7627
  let hadRemoteVideo = false;
7517
7628
 
7518
7629
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7519
- // Becase when `onInvite` is called we already got the video track
7630
+ // Because when `onInvite` is called we already got the video track
7520
7631
  session.onInviteRequest = (request) => {
7521
7632
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7522
7633
 
@@ -7530,7 +7641,7 @@ class WebRTCClient extends Emitter {
7530
7641
  updatedNumber = session.assertedIdentity.uri.normal.user;
7531
7642
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
7532
7643
  }
7533
- logger$8.info('re-invite received', { updatedCalleeName, updatedNumber });
7644
+ logger$9.info('re-invite received', { updatedCalleeName, updatedNumber });
7534
7645
 
7535
7646
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7536
7647
 
@@ -7551,7 +7662,7 @@ class WebRTCClient extends Emitter {
7551
7662
  }
7552
7663
 
7553
7664
  _onAccepted(session , sessionDialog , withEvent = true) {
7554
- logger$8.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7665
+ logger$9.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7555
7666
 
7556
7667
  this.storeSipSession(session);
7557
7668
 
@@ -7591,20 +7702,10 @@ class WebRTCClient extends Emitter {
7591
7702
  const isConference = this.isConference(sessionId);
7592
7703
 
7593
7704
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7594
- const audio = document.createElement('audio');
7595
- audio.setAttribute('id', `audio-${sessionId}`);
7596
-
7597
- if (audio.setSinkId && this.audioOutputDeviceId) {
7598
- audio.setSinkId(this.audioOutputDeviceId);
7599
- }
7600
-
7601
- if (document.body) {
7602
- document.body.appendChild(audio);
7603
- }
7604
- this.audioElements[sessionId] = audio;
7705
+ this.createAudioElementFor(sessionId);
7605
7706
  }
7606
7707
 
7607
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7708
+ const audioElement = this.audioElements[sessionId];
7608
7709
  const stream = newStream || this.getRemoteStream(sessionId);
7609
7710
 
7610
7711
  if (!this._isWeb() || !stream) {
@@ -7751,10 +7852,10 @@ class WebRTCClient extends Emitter {
7751
7852
 
7752
7853
  _stopSendingStats(session ) {
7753
7854
  const sessionId = this.getSipSessionId(session);
7754
- logger$8.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7855
+ logger$9.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7755
7856
 
7756
7857
  if (sessionId in this.statsIntervals) {
7757
- logger$8.trace('Stop sending stats for call', { sessionId });
7858
+ logger$9.trace('Stop sending stats for call', { sessionId });
7758
7859
  this.statsIntervals[sessionId]();
7759
7860
  delete this.statsIntervals[sessionId];
7760
7861
  }
@@ -7770,7 +7871,7 @@ class WebRTCClient extends Emitter {
7770
7871
  try {
7771
7872
  await this.userAgent.transport.disconnect();
7772
7873
  } catch (e) {
7773
- logger$8.error('WebRTC transport disconnect, error', e);
7874
+ logger$9.error('WebRTC transport disconnect, error', e);
7774
7875
  }
7775
7876
  }
7776
7877
  }
@@ -7857,7 +7958,7 @@ const events = [
7857
7958
  ON_SIGNAL,
7858
7959
  ];
7859
7960
 
7860
- const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
7961
+ const logger$8 = IssueReporter$1.loggerFor('webrtc-phone');
7861
7962
 
7862
7963
  class WebRTCPhone extends Emitter {
7863
7964
 
@@ -7928,7 +8029,7 @@ class WebRTCPhone extends Emitter {
7928
8029
  }).catch(error => {
7929
8030
  // Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
7930
8031
  console.error('register error', error, error.message, error.stack);
7931
- logger$7.error('WebRTC register error', { message: error.message, stack: error.stack });
8032
+ logger$8.error('WebRTC register error', { message: error.message, stack: error.stack });
7932
8033
  });
7933
8034
  }
7934
8035
 
@@ -7943,7 +8044,7 @@ class WebRTCPhone extends Emitter {
7943
8044
  if (!this.client) {
7944
8045
  return;
7945
8046
  }
7946
- logger$7.info('WebRTC phone stop');
8047
+ logger$8.info('WebRTC phone stop');
7947
8048
  this.client.stop();
7948
8049
  }
7949
8050
 
@@ -7958,14 +8059,14 @@ class WebRTCPhone extends Emitter {
7958
8059
  async sendReinvite(callSession , constraints = null, conference = false,
7959
8060
  audioOnly = false) {
7960
8061
  const sipSession = this.findSipSession(callSession);
7961
- logger$7.info('WebRTC phone - send reinvite', {
8062
+ logger$8.info('WebRTC phone - send reinvite', {
7962
8063
  sessionId: sipSession ? sipSession.id : null,
7963
8064
  constraints,
7964
8065
  audioOnly,
7965
8066
  });
7966
8067
 
7967
8068
  if (!sipSession) {
7968
- return null;
8069
+ return false;
7969
8070
  }
7970
8071
 
7971
8072
  // $FlowFixMe
@@ -7975,19 +8076,17 @@ class WebRTCPhone extends Emitter {
7975
8076
  // Downgrade
7976
8077
  if (constraints && !isUpgrade) {
7977
8078
  // No reinvite needed
7978
- return this._downgradeToAudio(callSession);
8079
+ this._downgradeToAudio(callSession);
8080
+ return false;
7979
8081
  }
7980
8082
 
7981
8083
  if (isUpgrade) {
7982
8084
  const shouldReinvite = await this._upgradeToVideo(callSession, constraints, conference);
7983
8085
  if (!shouldReinvite) {
7984
- return;
8086
+ return false;
7985
8087
  }
7986
8088
  }
7987
8089
 
7988
- // Force reinvite in SDH
7989
- sipSession.sessionDescriptionHandler.localMediaStreamConstraints = null;
7990
-
7991
8090
  return this.client.reinvite(sipSession, constraints, conference, audioOnly);
7992
8091
  }
7993
8092
 
@@ -7996,7 +8095,7 @@ class WebRTCPhone extends Emitter {
7996
8095
  }
7997
8096
 
7998
8097
  startHeartbeat() {
7999
- logger$7.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8098
+ logger$8.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8000
8099
  if (!this.client || this.client.hasHeartbeat()) {
8001
8100
  return;
8002
8101
  }
@@ -8005,7 +8104,7 @@ class WebRTCPhone extends Emitter {
8005
8104
  }
8006
8105
 
8007
8106
  stopHeartbeat() {
8008
- logger$7.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8107
+ logger$8.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8009
8108
  if (!this.client) {
8010
8109
  return;
8011
8110
  }
@@ -8022,7 +8121,7 @@ class WebRTCPhone extends Emitter {
8022
8121
  }
8023
8122
 
8024
8123
  reconnect() {
8025
- logger$7.info('WebRTC phone - reconnect', { client: !!this.client });
8124
+ logger$8.info('WebRTC phone - reconnect', { client: !!this.client });
8026
8125
  if (!this.client) {
8027
8126
  return;
8028
8127
  }
@@ -8060,7 +8159,7 @@ class WebRTCPhone extends Emitter {
8060
8159
  _downgradeToAudio(callSession ) {
8061
8160
  const sipSession = this.findSipSession(callSession);
8062
8161
  if (!sipSession) {
8063
- return;
8162
+ return false;
8064
8163
  }
8065
8164
 
8066
8165
  // Release local video stream when downgrading to audio
@@ -8173,7 +8272,7 @@ class WebRTCPhone extends Emitter {
8173
8272
  // Monkey patch to know when canceled with the CANCEL message
8174
8273
  const onCancel = sipSession._onCancel.bind(sipSession);
8175
8274
  sipSession._onCancel = (message ) => {
8176
- logger$7.trace('on sip session canceled', { callId: message.callId });
8275
+ logger$8.trace('on sip session canceled', { callId: message.callId });
8177
8276
 
8178
8277
  onCancel(message);
8179
8278
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
@@ -8198,13 +8297,13 @@ class WebRTCPhone extends Emitter {
8198
8297
  this.audioOutputVolume,
8199
8298
  );
8200
8299
  case sessionState.SessionState.Terminating:
8201
- logger$7.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8300
+ logger$8.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8202
8301
 
8203
8302
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
8204
8303
 
8205
8304
  break;
8206
8305
  case sessionState.SessionState.Terminated:
8207
- logger$7.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8306
+ logger$8.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8208
8307
 
8209
8308
  this._onCallTerminated(sipSession);
8210
8309
 
@@ -8240,7 +8339,7 @@ class WebRTCPhone extends Emitter {
8240
8339
  }
8241
8340
 
8242
8341
  async startScreenSharing(constraints , callSession ) {
8243
- logger$7.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8342
+ logger$8.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8244
8343
 
8245
8344
  const screenShareStream = await this._getStreamFromConstraints(constraints);
8246
8345
  if (!screenShareStream) {
@@ -8262,6 +8361,10 @@ class WebRTCPhone extends Emitter {
8262
8361
  localStream.removeTrack(videoTrack);
8263
8362
  }
8264
8363
 
8364
+ if (localStream) {
8365
+ localStream.addTrack(screenTrack);
8366
+ }
8367
+
8265
8368
  if (sender) {
8266
8369
  sender.replaceTrack(screenTrack);
8267
8370
  }
@@ -8276,7 +8379,8 @@ class WebRTCPhone extends Emitter {
8276
8379
  return;
8277
8380
  }
8278
8381
 
8279
- logger$7.info('WebRTC phone - stop screen sharing');
8382
+ logger$8.info('WebRTC phone - stop screen sharing');
8383
+ let reinvited = false;
8280
8384
 
8281
8385
  try {
8282
8386
  if (this.currentScreenShare.stream) {
@@ -8291,7 +8395,8 @@ class WebRTCPhone extends Emitter {
8291
8395
  // When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
8292
8396
  // We have to downgrade to audio.
8293
8397
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8294
- await this.sendReinvite(targetCallSession, { audio: false, video: screenshareStopped }, conference);
8398
+ const constraints = { audio: false, video: screenshareStopped };
8399
+ reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8295
8400
  }
8296
8401
  } catch (e) {
8297
8402
  console.warn(e);
@@ -8305,6 +8410,8 @@ class WebRTCPhone extends Emitter {
8305
8410
  );
8306
8411
 
8307
8412
  this.currentScreenShare = null;
8413
+
8414
+ return reinvited;
8308
8415
  }
8309
8416
 
8310
8417
  async _getStreamFromConstraints(constraints , conference = false) {
@@ -8342,7 +8449,7 @@ class WebRTCPhone extends Emitter {
8342
8449
  }
8343
8450
 
8344
8451
  _onCallAccepted(sipSession , cameraEnabled ) {
8345
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8452
+ logger$8.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8346
8453
 
8347
8454
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
8348
8455
  this.currentSipSession = sipSession;
@@ -8360,11 +8467,15 @@ class WebRTCPhone extends Emitter {
8360
8467
  }
8361
8468
 
8362
8469
  changeAudioDevice(id ) {
8363
- logger$7.info('WebRTC phone - change audio device', { deviceId: id });
8470
+ logger$8.info('WebRTC phone - change audio device', { deviceId: id });
8364
8471
  this.audioOutputDeviceId = id;
8365
8472
  this.client.changeAudioOutputDevice(id);
8366
8473
  }
8367
8474
 
8475
+ createAudioElementFor(sessionId ) {
8476
+ return this.client.createAudioElementFor(sessionId);
8477
+ }
8478
+
8368
8479
  changeRingDevice(id ) {
8369
8480
  this.audioRingDeviceId = id;
8370
8481
  }
@@ -8381,25 +8492,25 @@ class WebRTCPhone extends Emitter {
8381
8492
  }
8382
8493
 
8383
8494
  changeAudioInputDevice(id ) {
8384
- logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
8495
+ logger$8.info('WebRTC phone - changeAudio input device', { deviceId: id });
8385
8496
 
8386
8497
  return this.client.changeAudioInputDevice(id, this.currentSipSession);
8387
8498
  }
8388
8499
 
8389
8500
  changeVideoInputDevice(id ) {
8390
- logger$7.info('WebRTC phone - change video input device', { deviceId: id });
8501
+ logger$8.info('WebRTC phone - change video input device', { deviceId: id });
8391
8502
 
8392
8503
  return this.client.changeVideoInputDevice(id, this.currentSipSession);
8393
8504
  }
8394
8505
 
8395
8506
  changeSessionVideoInputDevice(id ) {
8396
- logger$7.info('WebRTC phone - change session video input device', { deviceId: id });
8507
+ logger$8.info('WebRTC phone - change session video input device', { deviceId: id });
8397
8508
 
8398
8509
  return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
8399
8510
  }
8400
8511
 
8401
8512
  _onCallTerminated(sipSession ) {
8402
- logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8513
+ logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8403
8514
 
8404
8515
  const callSession = this._createCallSession(sipSession);
8405
8516
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
@@ -8433,7 +8544,7 @@ class WebRTCPhone extends Emitter {
8433
8544
  const hasIncomingCallSession = this.hasIncomingCallSession();
8434
8545
 
8435
8546
  // Re-trigger incoming call event for remaining incoming calls
8436
- logger$7.info('WebRTC phone - check to re-trigger incoming call', {
8547
+ logger$8.info('WebRTC phone - check to re-trigger incoming call', {
8437
8548
  sipId: sipSession.id,
8438
8549
  shouldRetrigger,
8439
8550
  hasIncomingCallSession,
@@ -8522,37 +8633,37 @@ class WebRTCPhone extends Emitter {
8522
8633
 
8523
8634
  // Deprecated
8524
8635
  getLocalStreamForCall(callSession ) {
8525
- logger$7.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8636
+ logger$8.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8526
8637
 
8527
8638
  return this.getLocalStream(callSession);
8528
8639
  }
8529
8640
 
8530
8641
  // Deprecated
8531
8642
  getRemoteStreamForCall(callSession ) {
8532
- logger$7.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8643
+ logger$8.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8533
8644
 
8534
8645
  return this.getRemoteVideoStream(callSession);
8535
8646
  }
8536
8647
 
8537
8648
  getRemoteStreamsForCall(callSession ) {
8538
- logger$7.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8649
+ logger$8.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8539
8650
 
8540
8651
  return this.getRemoteStream(callSession);
8541
8652
  }
8542
8653
 
8543
8654
  accept(callSession , cameraEnabled ) {
8544
- logger$7.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8655
+ logger$8.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8545
8656
  if (this.currentSipSession) {
8546
8657
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
8547
8658
  }
8548
8659
 
8549
8660
  if (!callSession) {
8550
- logger$7.warn('no CallSession to accept.');
8661
+ logger$8.warn('no CallSession to accept.');
8551
8662
  return Promise.resolve(null);
8552
8663
  }
8553
8664
 
8554
8665
  if (callSession.getId() in this.acceptedSessions) {
8555
- logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8666
+ logger$8.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8556
8667
  return Promise.resolve(callSession.sipCallId);
8557
8668
  }
8558
8669
 
@@ -8564,24 +8675,24 @@ class WebRTCPhone extends Emitter {
8564
8675
  const sipSession = this.client.getSipSession(callSession.getId());
8565
8676
  if (sipSession) {
8566
8677
  if (sipSession.state === sessionState.SessionState.Terminated || sipSession.state === sessionState.SessionState.Terminating) {
8567
- logger$7.warn('Trying to answer a terminated sipSession.');
8678
+ logger$8.warn('Trying to answer a terminated sipSession.');
8568
8679
 
8569
8680
  return Promise.resolve(null);
8570
8681
  }
8571
8682
 
8572
- logger$7.info('accept call, session found', { sipId: sipSession.id });
8683
+ logger$8.info('accept call, session found', { sipId: sipSession.id });
8573
8684
 
8574
8685
  // $FlowFixMe
8575
8686
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
8576
8687
  return callSession.sipCallId;
8577
8688
  }).catch(e => {
8578
- logger$7.error(e);
8689
+ logger$8.error(e);
8579
8690
  this.endCurrentCall(callSession);
8580
8691
  throw e;
8581
8692
  });
8582
8693
  }
8583
8694
 
8584
- logger$7.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8695
+ logger$8.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8585
8696
 
8586
8697
  return Promise.resolve(null);
8587
8698
  }
@@ -8591,7 +8702,7 @@ class WebRTCPhone extends Emitter {
8591
8702
  }
8592
8703
 
8593
8704
  async reject(callSession ) {
8594
- logger$7.info('reject WebRTC called', { id: callSession.getId() });
8705
+ logger$8.info('reject WebRTC called', { id: callSession.getId() });
8595
8706
 
8596
8707
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call rejected locally');
8597
8708
  if (!callSession || callSession.getId() in this.rejectedSessions) {
@@ -8603,14 +8714,14 @@ class WebRTCPhone extends Emitter {
8603
8714
 
8604
8715
  const sipSession = this.findSipSession(callSession);
8605
8716
  if (sipSession) {
8606
- logger$7.info('WebRTC rejecting', { sipId: sipSession.id });
8717
+ logger$8.info('WebRTC rejecting', { sipId: sipSession.id });
8607
8718
 
8608
8719
  this.client.hangup(sipSession);
8609
8720
  }
8610
8721
  }
8611
8722
 
8612
8723
  async ignore(callSession ) {
8613
- logger$7.info('WebRTC ignore', { id: callSession.getId() });
8724
+ logger$8.info('WebRTC ignore', { id: callSession.getId() });
8614
8725
 
8615
8726
  // kill the ring
8616
8727
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'ignoring call');
@@ -8619,7 +8730,7 @@ class WebRTCPhone extends Emitter {
8619
8730
  }
8620
8731
 
8621
8732
  hold(callSession , withEvent = true, isConference = false) {
8622
- logger$7.info('WebRTC hold', { id: callSession.getId() });
8733
+ logger$8.info('WebRTC hold', { id: callSession.getId() });
8623
8734
 
8624
8735
  const sipSession = this.findSipSession(callSession);
8625
8736
 
@@ -8630,7 +8741,7 @@ class WebRTCPhone extends Emitter {
8630
8741
 
8631
8742
  // @Deprecated
8632
8743
  unhold(callSession , withEvent = true, isConference = false) {
8633
- logger$7.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8744
+ logger$8.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8634
8745
 
8635
8746
  console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
8636
8747
 
@@ -8645,7 +8756,7 @@ class WebRTCPhone extends Emitter {
8645
8756
  const sipSession = this.findSipSession(callSession);
8646
8757
 
8647
8758
  if (sipSession) {
8648
- logger$7.info('WebRTC atxfer', { sipId: sipSession.id });
8759
+ logger$8.info('WebRTC atxfer', { sipId: sipSession.id });
8649
8760
 
8650
8761
  return this.client.atxfer(sipSession);
8651
8762
  }
@@ -8660,7 +8771,7 @@ class WebRTCPhone extends Emitter {
8660
8771
  if (!sipSession) {
8661
8772
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
8662
8773
  }
8663
- logger$7.info('WebRTC hold sip session', { sipId: sipSession.id });
8774
+ logger$8.info('WebRTC hold sip session', { sipId: sipSession.id });
8664
8775
 
8665
8776
  const promise = this.client.hold(sipSession, isConference);
8666
8777
  if (withEvent) {
@@ -8679,7 +8790,7 @@ class WebRTCPhone extends Emitter {
8679
8790
  if (!sipSession) {
8680
8791
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
8681
8792
  }
8682
- logger$7.info('WebRTC unhold', { sipId: sipSession.id });
8793
+ logger$8.info('WebRTC unhold', { sipId: sipSession.id });
8683
8794
 
8684
8795
  const promise = this.client.unhold(sipSession, isConference);
8685
8796
  if (withEvent) {
@@ -8690,18 +8801,18 @@ class WebRTCPhone extends Emitter {
8690
8801
  }
8691
8802
 
8692
8803
  resume(callSession , isConference = false) {
8693
- logger$7.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8804
+ logger$8.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8694
8805
 
8695
8806
  const sipSession = this.findSipSession(callSession);
8696
8807
  if (!sipSession) {
8697
8808
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
8698
8809
  }
8699
8810
 
8700
- logger$7.info('WebRTC resuming', { sipId: sipSession.id });
8811
+ logger$8.info('WebRTC resuming', { sipId: sipSession.id });
8701
8812
 
8702
8813
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
8703
8814
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
8704
- logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8815
+ logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8705
8816
  this.holdSipSession(this.currentSipSession, callSession);
8706
8817
  }
8707
8818
 
@@ -8716,14 +8827,14 @@ class WebRTCPhone extends Emitter {
8716
8827
  }
8717
8828
 
8718
8829
  mute(callSession , withEvent = true) {
8719
- logger$7.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8830
+ logger$8.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8720
8831
 
8721
8832
  const sipSession = this.findSipSession(callSession);
8722
8833
  if (!sipSession) {
8723
8834
  return;
8724
8835
  }
8725
8836
 
8726
- logger$7.info('WebRTC muting', { sipId: sipSession.id });
8837
+ logger$8.info('WebRTC muting', { sipId: sipSession.id });
8727
8838
  this.client.mute(sipSession);
8728
8839
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: true });
8729
8840
 
@@ -8737,14 +8848,14 @@ class WebRTCPhone extends Emitter {
8737
8848
  }
8738
8849
 
8739
8850
  unmute(callSession , withEvent = true) {
8740
- logger$7.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8851
+ logger$8.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8741
8852
 
8742
8853
  const sipSession = this.findSipSession(callSession);
8743
8854
  if (!sipSession) {
8744
8855
  return;
8745
8856
  }
8746
8857
 
8747
- logger$7.info('WebRTC unmuting', { sipId: sipSession.id });
8858
+ logger$8.info('WebRTC unmuting', { sipId: sipSession.id });
8748
8859
  this.client.unmute(sipSession);
8749
8860
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: false });
8750
8861
 
@@ -8771,7 +8882,7 @@ class WebRTCPhone extends Emitter {
8771
8882
  if (!sipSession) {
8772
8883
  return;
8773
8884
  }
8774
- logger$7.info('WebRTC turn camera on', { sipId: sipSession.id });
8885
+ logger$8.info('WebRTC turn camera on', { sipId: sipSession.id });
8775
8886
 
8776
8887
  this.client.toggleCameraOn(sipSession);
8777
8888
 
@@ -8783,7 +8894,7 @@ class WebRTCPhone extends Emitter {
8783
8894
  if (!sipSession) {
8784
8895
  return;
8785
8896
  }
8786
- logger$7.info('WebRTC turn camera off', { sipId: sipSession.id });
8897
+ logger$8.info('WebRTC turn camera off', { sipId: sipSession.id });
8787
8898
 
8788
8899
  this.client.toggleCameraOff(sipSession);
8789
8900
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -8795,7 +8906,7 @@ class WebRTCPhone extends Emitter {
8795
8906
  return;
8796
8907
  }
8797
8908
 
8798
- logger$7.info('WebRTC send key', { sipId: sipSession.id, tone });
8909
+ logger$8.info('WebRTC send key', { sipId: sipSession.id, tone });
8799
8910
  this.client.sendDTMF(sipSession, tone);
8800
8911
  }
8801
8912
 
@@ -8803,7 +8914,7 @@ class WebRTCPhone extends Emitter {
8803
8914
  // @TODO: line is not used here
8804
8915
  async makeCall(number , line , cameraEnabled ,
8805
8916
  audioOnly = false, conference = false) {
8806
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
8917
+ logger$8.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
8807
8918
  if (!number) {
8808
8919
  return Promise.resolve(null);
8809
8920
  }
@@ -8813,7 +8924,7 @@ class WebRTCPhone extends Emitter {
8813
8924
  }
8814
8925
  if (this.currentSipSession) {
8815
8926
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
8816
- logger$7.warn('Unable to hold current session when making another call', e);
8927
+ logger$8.warn('Unable to hold current session when making another call', e);
8817
8928
  });
8818
8929
  }
8819
8930
 
@@ -8823,7 +8934,7 @@ class WebRTCPhone extends Emitter {
8823
8934
  this._bindEvents(sipSession);
8824
8935
  } catch (error) {
8825
8936
  console.warn(error);
8826
- logger$7.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
8937
+ logger$8.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
8827
8938
  return Promise.resolve(null);
8828
8939
  }
8829
8940
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
@@ -8851,7 +8962,7 @@ class WebRTCPhone extends Emitter {
8851
8962
  return;
8852
8963
  }
8853
8964
 
8854
- logger$7.info('WebRTC transfer', { sipId: sipSession.id, target });
8965
+ logger$8.info('WebRTC transfer', { sipId: sipSession.id, target });
8855
8966
 
8856
8967
  this.client.transfer(sipSession, target);
8857
8968
  }
@@ -8860,7 +8971,7 @@ class WebRTCPhone extends Emitter {
8860
8971
  const sipSession = this.client.getSipSession(source.sipCallId);
8861
8972
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
8862
8973
 
8863
- logger$7.info('WebRTC indirect transfer', {
8974
+ logger$8.info('WebRTC indirect transfer', {
8864
8975
  sipId: sipSession ? sipSession.id : null,
8865
8976
  target: sipSessionTarget ? sipSessionTarget.id : null,
8866
8977
  });
@@ -8888,7 +8999,7 @@ class WebRTCPhone extends Emitter {
8888
8999
  return false;
8889
9000
  }
8890
9001
 
8891
- logger$7.info('WebRTC hangup', { sipId: sipSession.id });
9002
+ logger$8.info('WebRTC hangup', { sipId: sipSession.id });
8892
9003
 
8893
9004
  const sipSessionId = this.getSipSessionId(sipSession);
8894
9005
 
@@ -8933,7 +9044,7 @@ class WebRTCPhone extends Emitter {
8933
9044
  }
8934
9045
 
8935
9046
  async close() {
8936
- logger$7.info('WebRTC close');
9047
+ logger$8.info('WebRTC close');
8937
9048
 
8938
9049
  try {
8939
9050
  await Promise.race([
@@ -8941,7 +9052,7 @@ class WebRTCPhone extends Emitter {
8941
9052
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000)),
8942
9053
  ]);
8943
9054
  } catch (e) {
8944
- logger$7.error('WebRTC close, unregister error', e);
9055
+ logger$8.error('WebRTC close, unregister error', e);
8945
9056
  }
8946
9057
 
8947
9058
  this.client.close();
@@ -8959,12 +9070,12 @@ class WebRTCPhone extends Emitter {
8959
9070
  }
8960
9071
 
8961
9072
  enableRinging() {
8962
- logger$7.info('WebRTC enable ringing');
9073
+ logger$8.info('WebRTC enable ringing');
8963
9074
  this.ringingEnabled = true;
8964
9075
  }
8965
9076
 
8966
9077
  disableRinging() {
8967
- logger$7.info('WebRTC disable ringing');
9078
+ logger$8.info('WebRTC disable ringing');
8968
9079
  this.ringingEnabled = false;
8969
9080
  }
8970
9081
 
@@ -9004,7 +9115,7 @@ class WebRTCPhone extends Emitter {
9004
9115
 
9005
9116
  // Deprecated
9006
9117
  getLocalMediaStream(callSession ) {
9007
- logger$7.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9118
+ logger$8.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9008
9119
  return this.getLocalStream(callSession);
9009
9120
  }
9010
9121
 
@@ -9012,6 +9123,10 @@ class WebRTCPhone extends Emitter {
9012
9123
  return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
9013
9124
  }
9014
9125
 
9126
+ hasALocalVideoTrack(callSession ) {
9127
+ return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
9128
+ }
9129
+
9015
9130
  getRemoteStream(callSession ) {
9016
9131
  return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
9017
9132
  }
@@ -9034,7 +9149,7 @@ class WebRTCPhone extends Emitter {
9034
9149
  this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
9035
9150
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
9036
9151
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
9037
- logger$7.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9152
+ logger$8.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9038
9153
 
9039
9154
  const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
9040
9155
  this.incomingSessions.push(callSession.getId());
@@ -9057,7 +9172,7 @@ class WebRTCPhone extends Emitter {
9057
9172
  });
9058
9173
 
9059
9174
  this.client.on(this.client.ON_REINVITE, (...args) => {
9060
- logger$7.info('WebRTC on reinvite', {
9175
+ logger$8.info('WebRTC on reinvite', {
9061
9176
  sessionId: args[0].id,
9062
9177
  inviteId: args[1].id,
9063
9178
  updatedCalleeName: args[2],
@@ -9077,7 +9192,7 @@ class WebRTCPhone extends Emitter {
9077
9192
  });
9078
9193
 
9079
9194
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
9080
- logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
9195
+ logger$8.info('WebRTC call accepted', { sipId: sipSession.id });
9081
9196
 
9082
9197
  this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
9083
9198
 
@@ -9088,17 +9203,17 @@ class WebRTCPhone extends Emitter {
9088
9203
  this.client.on('ended', () => {});
9089
9204
 
9090
9205
  this.client.on(this.client.ON_ERROR, e => {
9091
- logger$7.error('WebRTC error', e);
9206
+ logger$8.error('WebRTC error', e);
9092
9207
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9093
9208
  });
9094
9209
 
9095
9210
  this.client.on(this.client.UNREGISTERED, () => {
9096
- logger$7.info('WebRTC unregistered');
9211
+ logger$8.info('WebRTC unregistered');
9097
9212
  this.eventEmitter.emit(ON_UNREGISTERED);
9098
9213
  });
9099
9214
 
9100
9215
  this.client.on(this.client.REGISTERED, () => {
9101
- logger$7.info('WebRTC registered', {
9216
+ logger$8.info('WebRTC registered', {
9102
9217
  shouldSendReinvite: this.shouldSendReinvite,
9103
9218
  state: this.currentSipSession ? this.currentSipSession.state : null,
9104
9219
  currentSipSession: !!this.currentSipSession,
@@ -9114,19 +9229,19 @@ class WebRTCPhone extends Emitter {
9114
9229
  try {
9115
9230
  this.sendReinvite(this.currentCallSession);
9116
9231
  } catch (e) {
9117
- logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9232
+ logger$8.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9118
9233
  }
9119
9234
  }
9120
9235
  });
9121
9236
 
9122
9237
  this.client.on(this.client.CONNECTED, () => {
9123
- logger$7.info('WebRTC client connected');
9238
+ logger$8.info('WebRTC client connected');
9124
9239
 
9125
9240
  this.stopHeartbeat();
9126
9241
  });
9127
9242
 
9128
9243
  this.client.on(this.client.DISCONNECTED, () => {
9129
- logger$7.info('WebRTC client disconnected');
9244
+ logger$8.info('WebRTC client disconnected');
9130
9245
 
9131
9246
  this.eventEmitter.emit(ON_UNREGISTERED);
9132
9247
 
@@ -9358,7 +9473,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
9358
9473
 
9359
9474
  //
9360
9475
 
9361
- const logger$6 = IssueReporter$1.loggerFor('simple-phone');
9476
+ const logger$7 = IssueReporter$1.loggerFor('simple-phone');
9362
9477
  const sipLogger = IssueReporter$1.loggerFor('sip.js');
9363
9478
  const protocolLogger = IssueReporter$1.loggerFor('sip');
9364
9479
 
@@ -9465,7 +9580,7 @@ class Phone extends Emitter {
9465
9580
  async disconnect() {
9466
9581
  if (this.phone) {
9467
9582
  if (this.phone.hasAnActiveCall()) {
9468
- logger$6.info('hangup call on disconnect');
9583
+ logger$7.info('hangup call on disconnect');
9469
9584
  // $FlowFixMe
9470
9585
  await this.phone.hangup();
9471
9586
  }
@@ -9488,13 +9603,13 @@ class Phone extends Emitter {
9488
9603
  }
9489
9604
 
9490
9605
  async hangup(callSession ) {
9491
- logger$6.info('hangup via simple phone', { callId: callSession.getId() });
9606
+ logger$7.info('hangup via simple phone', { callId: callSession.getId() });
9492
9607
 
9493
9608
  return this.phone && this.phone.hangup(callSession);
9494
9609
  }
9495
9610
 
9496
9611
  async accept(callSession , cameraEnabled ) {
9497
- logger$6.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
9612
+ logger$7.info('accept via simple phone', { callId: callSession.getId(), cameraEnabled });
9498
9613
 
9499
9614
  return this.phone && this.phone.accept(callSession, cameraEnabled);
9500
9615
  }
@@ -9514,13 +9629,18 @@ class Phone extends Emitter {
9514
9629
  return adHocConference.start();
9515
9630
  }
9516
9631
 
9517
- mute(callSession ) {
9518
- this.muteViaAPI(callSession);
9632
+ mute(callSession , withApi = true) {
9633
+ if (withApi) {
9634
+ this.muteViaAPI(callSession);
9635
+ }
9636
+
9519
9637
  return this.phone && this.phone.mute(callSession);
9520
9638
  }
9521
9639
 
9522
- unmute(callSession ) {
9523
- this.unmuteViaAPI(callSession);
9640
+ unmute(callSession , withApi = true) {
9641
+ if (withApi) {
9642
+ this.unmuteViaAPI(callSession);
9643
+ }
9524
9644
 
9525
9645
  return this.phone && this.phone.unmute(callSession);
9526
9646
  }
@@ -9528,7 +9648,7 @@ class Phone extends Emitter {
9528
9648
  muteViaAPI(callSession ) {
9529
9649
  if (callSession && callSession.callId) {
9530
9650
  Wazo.getApiClient().calld.mute(callSession.callId).catch(e => {
9531
- logger$6.error('Mute via API, error', e);
9651
+ logger$7.error('Mute via API, error', e);
9532
9652
  });
9533
9653
  }
9534
9654
  }
@@ -9536,7 +9656,7 @@ class Phone extends Emitter {
9536
9656
  unmuteViaAPI(callSession ) {
9537
9657
  if (callSession && callSession.callId) {
9538
9658
  Wazo.getApiClient().calld.unmute(callSession.callId).catch(e => {
9539
- logger$6.error('Unmute via API, error', e);
9659
+ logger$7.error('Unmute via API, error', e);
9540
9660
  });
9541
9661
  }
9542
9662
  }
@@ -9626,9 +9746,13 @@ class Phone extends Emitter {
9626
9746
  return this.phone && this.phone.hasLocalVideo(callSession);
9627
9747
  }
9628
9748
 
9749
+ hasALocalVideoTrack(callSession ) {
9750
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
9751
+ }
9752
+
9629
9753
  // @Deprecated
9630
9754
  getLocalMediaStream(callSession ) {
9631
- logger$6.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
9755
+ logger$7.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');
9632
9756
 
9633
9757
  return this.phone && this.phone.getLocalStream(callSession);
9634
9758
  }
@@ -9647,20 +9771,20 @@ class Phone extends Emitter {
9647
9771
 
9648
9772
  // @Deprecated
9649
9773
  getRemoteStreamForCall(callSession ) {
9650
- logger$6.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
9774
+ logger$7.warn('Phone.getRemoteStreamForCall is deprecated, use Phone.getRemoteStream instead');
9651
9775
  return this.getRemoteStream(callSession);
9652
9776
  }
9653
9777
 
9654
9778
  // Returns remote streams directly from the peerConnection
9655
9779
  // @Deprecated
9656
9780
  getRemoteStreamsForCall(callSession ) {
9657
- logger$6.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
9781
+ logger$7.warn('Phone.getRemoteStreamsForCall is deprecated, use Phone.getLocalStream instead');
9658
9782
  return this.getLocalStream(callSession);
9659
9783
  }
9660
9784
 
9661
9785
  // @Deprecated
9662
9786
  getRemoteVideoStreamForCall(callSession ) {
9663
- logger$6.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
9787
+ logger$7.warn('Phone.getRemoteVideoStreamForCall is deprecated, use Phone.getRemoteVideoStream instead');
9664
9788
 
9665
9789
  return this.getRemoteVideoStream(callSession);
9666
9790
  }
@@ -9790,6 +9914,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
9790
9914
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
9791
9915
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
9792
9916
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
9917
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
9918
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
9793
9919
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
9794
9920
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
9795
9921
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -9831,7 +9957,7 @@ const BLACKLIST_EVENTS = [
9831
9957
  ];
9832
9958
 
9833
9959
  const HEARTBEAT_ENGINE_VERSION = '20.09';
9834
- const logger$5 = IssueReporter$1.loggerFor('wazo-ws');
9960
+ const logger$6 = IssueReporter$1.loggerFor('wazo-ws');
9835
9961
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
9836
9962
 
9837
9963
  class WebSocketClient extends Emitter {
@@ -9880,19 +10006,19 @@ class WebSocketClient extends Emitter {
9880
10006
  }
9881
10007
 
9882
10008
  connect() {
9883
- logger$5.info('connect method started', { host: this.host, token: this.token });
10009
+ logger$6.info('connect method started', { host: this.host, token: this.token });
9884
10010
  this.socket = new ReconnectingWebSocket__default['default'](this._getUrl.bind(this), [], this.options);
9885
10011
  if (this.options.binaryType) {
9886
10012
  this.socket.binaryType = this.options.binaryType;
9887
10013
  }
9888
10014
 
9889
10015
  this.socket.onopen = () => {
9890
- logger$5.info('on Wazo WS open', { method: 'connect', host: this.host });
10016
+ logger$6.info('on Wazo WS open', { method: 'connect', host: this.host });
9891
10017
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
9892
10018
  };
9893
10019
 
9894
10020
  this.socket.onerror = event => {
9895
- logger$5.error('on Wazo WS error', event.target);
10021
+ logger$6.error('on Wazo WS error', event.target);
9896
10022
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
9897
10023
  };
9898
10024
 
@@ -9922,7 +10048,7 @@ class WebSocketClient extends Emitter {
9922
10048
 
9923
10049
  this.socket.onclose = event => {
9924
10050
  // Can't be converted to JSON (circular structure)
9925
- logger$5.info('on Wazo WS close', {
10051
+ logger$6.info('on Wazo WS close', {
9926
10052
  reason: event.reason,
9927
10053
  code: event.code,
9928
10054
  readyState: event.target.readyState,
@@ -9940,12 +10066,12 @@ class WebSocketClient extends Emitter {
9940
10066
  };
9941
10067
 
9942
10068
  this.socket.onerror = event => {
9943
- logger$5.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
10069
+ logger$6.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
9944
10070
  };
9945
10071
  }
9946
10072
 
9947
10073
  close(force = false) {
9948
- logger$5.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
10074
+ logger$6.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
9949
10075
 
9950
10076
  if (!this.socket) {
9951
10077
  return;
@@ -9963,7 +10089,7 @@ class WebSocketClient extends Emitter {
9963
10089
 
9964
10090
  updateToken(token ) {
9965
10091
  this.token = token;
9966
- logger$5.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
10092
+ logger$6.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
9967
10093
 
9968
10094
  if (this.socket) {
9969
10095
  // If still connected, send the token to the WS
@@ -9981,7 +10107,7 @@ class WebSocketClient extends Emitter {
9981
10107
  }
9982
10108
 
9983
10109
  startHeartbeat() {
9984
- logger$5.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
10110
+ logger$6.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
9985
10111
 
9986
10112
  if (!this.socket) {
9987
10113
  this.heartbeat.stop();
@@ -9995,7 +10121,7 @@ class WebSocketClient extends Emitter {
9995
10121
  }
9996
10122
 
9997
10123
  stopHeartbeat() {
9998
- logger$5.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
10124
+ logger$6.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
9999
10125
 
10000
10126
  this.heartbeat.stop();
10001
10127
  }
@@ -10025,7 +10151,7 @@ class WebSocketClient extends Emitter {
10025
10151
  }
10026
10152
 
10027
10153
  reconnect(reason ) {
10028
- logger$5.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10154
+ logger$6.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10029
10155
  if (!this.socket) {
10030
10156
  return;
10031
10157
  }
@@ -10081,7 +10207,7 @@ class WebSocketClient extends Emitter {
10081
10207
  this.close();
10082
10208
  }
10083
10209
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
10084
- logger$5.log('Wazo WS url computed to reconnect', { url });
10210
+ logger$6.log('Wazo WS url computed to reconnect', { url });
10085
10211
 
10086
10212
  return url;
10087
10213
  }
@@ -10089,12 +10215,12 @@ class WebSocketClient extends Emitter {
10089
10215
  _onHeartbeat(message ) {
10090
10216
  if (message.payload === 'pong') {
10091
10217
  this.heartbeat.onHeartbeat();
10092
- logger$5.log('on heartbeat received from Wazo WS');
10218
+ logger$6.log('on heartbeat received from Wazo WS');
10093
10219
  }
10094
10220
  }
10095
10221
 
10096
10222
  async _onHeartbeatTimeout() {
10097
- logger$5.log('heartbeat timed out', { host: this.host, token: this.token });
10223
+ logger$6.log('heartbeat timed out', { host: this.host, token: this.token });
10098
10224
 
10099
10225
  this.close();
10100
10226
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -10136,6 +10262,8 @@ WebSocketClient.eventLists = [
10136
10262
  CHATD_USER_ROOM_CREATED,
10137
10263
  CONFERENCE_USER_PARTICIPANT_JOINED,
10138
10264
  CONFERENCE_USER_PARTICIPANT_LEFT,
10265
+ MEETING_USER_PARTICIPANT_JOINED,
10266
+ MEETING_USER_PARTICIPANT_LEFT,
10139
10267
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10140
10268
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10141
10269
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -10206,6 +10334,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10206
10334
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
10207
10335
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10208
10336
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10337
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
10338
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
10209
10339
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
10210
10340
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
10211
10341
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -10247,7 +10377,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10247
10377
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
10248
10378
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
10249
10379
 
10250
- const logger$4 = IssueReporter$1.loggerFor('simple-ws-client');
10380
+ const logger$5 = IssueReporter$1.loggerFor('simple-ws-client');
10251
10381
 
10252
10382
  class Websocket extends Emitter {
10253
10383
 
@@ -10271,7 +10401,7 @@ class Websocket extends Emitter {
10271
10401
  }
10272
10402
 
10273
10403
  open(host , session ) {
10274
- logger$4.info('open simple WebSocket', { host, token: session.token });
10404
+ logger$5.info('open simple WebSocket', { host, token: session.token });
10275
10405
  this.ws = new WebSocketClient(
10276
10406
  {
10277
10407
  host,
@@ -10299,7 +10429,7 @@ class Websocket extends Emitter {
10299
10429
  }
10300
10430
 
10301
10431
  updateToken(token ) {
10302
- logger$4.info('update token via simple Websocket', { token, ws: !!this.ws });
10432
+ logger$5.info('update token via simple Websocket', { token, ws: !!this.ws });
10303
10433
 
10304
10434
  if (!this.ws) {
10305
10435
  return;
@@ -10327,7 +10457,7 @@ var Websocket$1 = global.wazoWebsocketInstance;
10327
10457
 
10328
10458
  //
10329
10459
 
10330
- const logger$3 = IssueReporter$1.loggerFor('room');
10460
+ const logger$4 = IssueReporter$1.loggerFor('room');
10331
10461
 
10332
10462
  class Participant extends Emitter {
10333
10463
 
@@ -10361,6 +10491,7 @@ class Participant extends Emitter {
10361
10491
 
10362
10492
 
10363
10493
  /**
10494
+ * @param room Room The room where the participant is
10364
10495
  * @param rawParticipant string Participant sent via the Wazo WS
10365
10496
  * @param extra Object extra status of the participant
10366
10497
  */
@@ -10448,7 +10579,7 @@ class Participant extends Emitter {
10448
10579
  }
10449
10580
 
10450
10581
  onTalking(isTalking ) {
10451
- logger$3.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10582
+ logger$4.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10452
10583
  this.isTalking = isTalking;
10453
10584
  // you may notice we're not broadcasting: since all participants are getting this info
10454
10585
  // directly from asterisk, there's no need to do so
@@ -10551,7 +10682,7 @@ class Participant extends Emitter {
10551
10682
  }
10552
10683
 
10553
10684
  updateStatus(status , broadcast = true) {
10554
- logger$3.info('updating participant status', { name: this.name, status });
10685
+ logger$4.info('updating participant status', { name: this.name, status });
10555
10686
 
10556
10687
  if (typeof status.audioMuted !== 'undefined' && status.audioMuted !== this.audioMuted) {
10557
10688
  if (status.audioMuted) {
@@ -10588,13 +10719,18 @@ class Participant extends Emitter {
10588
10719
  // Poor man's object comparison
10589
10720
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
10590
10721
  this.extra = { ...this.extra, ...status.extra };
10722
+
10723
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
10724
+ this.extra.contact = new Contact(this.extra.contact);
10725
+ }
10726
+
10591
10727
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
10592
10728
  }
10593
10729
  }
10594
10730
 
10595
10731
  broadcastStatus(inboundStatus = null) {
10596
10732
  const status = inboundStatus || this.getStatus();
10597
- logger$3.info('broadcasting participant status', { callId: this.callId, status });
10733
+ logger$4.info('broadcasting participant status', { callId: this.callId, status });
10598
10734
 
10599
10735
  this.room.sendSignal({
10600
10736
  type: SIGNAL_TYPE_PARTICIPANT_UPDATE,
@@ -10615,18 +10751,24 @@ class RemoteParticipant extends Participant {
10615
10751
  }
10616
10752
  }
10617
10753
 
10618
- /* global document */
10754
+ //
10755
+
10756
+ class LocalParticipant extends Participant {
10757
+ }
10758
+
10759
+ //
10619
10760
 
10620
10761
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
10621
10762
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
10622
10763
 
10623
- const logger$2 = IssueReporter$1.loggerFor('sdk-room');
10764
+ const logger$3 = IssueReporter$1.loggerFor('sdk-room');
10624
10765
 
10625
10766
  class Room$1 extends Emitter {
10626
10767
 
10627
10768
 
10628
10769
 
10629
10770
 
10771
+
10630
10772
 
10631
10773
 
10632
10774
 
@@ -10648,6 +10790,8 @@ class Room$1 extends Emitter {
10648
10790
 
10649
10791
 
10650
10792
 
10793
+
10794
+
10651
10795
 
10652
10796
 
10653
10797
 
@@ -10665,6 +10809,7 @@ class Room$1 extends Emitter {
10665
10809
  * @param extension string
10666
10810
  * @param sourceId number
10667
10811
  * @param callId string
10812
+ * @param meetingUuid string
10668
10813
  * @param extra Object
10669
10814
  */
10670
10815
  constructor(
@@ -10672,15 +10817,17 @@ class Room$1 extends Emitter {
10672
10817
  extension ,
10673
10818
  sourceId ,
10674
10819
  callId ,
10820
+ meetingUuid ,
10675
10821
  extra = {},
10676
10822
  ) {
10677
10823
  super();
10678
- logger$2.info('room initialized', { callId, extension, sourceId });
10824
+ logger$3.info('room initialized', { callId, extension, sourceId, meetingUuid });
10679
10825
 
10680
10826
  // Represents the room callSession
10681
10827
  this.callSession = callSession;
10682
10828
  this.extension = extension;
10683
10829
  this.sourceId = sourceId;
10830
+ this.meetingUuid = meetingUuid;
10684
10831
  this.callId = callId;
10685
10832
  this.participants = [];
10686
10833
  this.connected = false;
@@ -10700,6 +10847,8 @@ class Room$1 extends Emitter {
10700
10847
  // Sugar syntax for `room.EVENT_NAME`
10701
10848
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
10702
10849
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
10850
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
10851
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
10703
10852
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
10704
10853
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
10705
10854
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -10734,10 +10883,11 @@ class Room$1 extends Emitter {
10734
10883
  * @param audioOnly boolean
10735
10884
  * @param extra Object
10736
10885
  * @param room ?Room
10886
+ * @param meeting ?Meeting
10737
10887
  * @returns {Promise<Room>}
10738
10888
  */
10739
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
10740
- logger$2.info('connecting to room', { extension, audioOnly, room: !!room });
10889
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
10890
+ logger$3.info('connecting to room', { extension, audioOnly, room: !!room });
10741
10891
 
10742
10892
  if (!room) {
10743
10893
  await Wazo.Phone.connect();
@@ -10750,7 +10900,7 @@ class Room$1 extends Emitter {
10750
10900
 
10751
10901
  // Call_created is triggered before call_accepted, so we have to listen for it here.
10752
10902
  Wazo.Websocket.once(Wazo.Websocket.CALL_CREATED, ({ data }) => {
10753
- logger$2.info('room call received via WS', { callId: data.call_id });
10903
+ logger$3.info('room call received via WS', { callId: data.call_id });
10754
10904
  if (room) {
10755
10905
  room.setCallId(data.call_id);
10756
10906
  }
@@ -10771,34 +10921,44 @@ class Room$1 extends Emitter {
10771
10921
  room.setCallId(room.callSession.call.id);
10772
10922
  }
10773
10923
 
10774
- // Fetch conference source
10775
- const sources = await getApiClient().dird.fetchConferenceSource('default');
10776
- // Retrieve conference sources
10777
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10778
- // Retrieve conference
10779
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10924
+ if (!meeting) {
10925
+ // Fetch conference source
10926
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
10927
+ // Retrieve conference sources
10928
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10929
+ // Retrieve conference
10930
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10780
10931
 
10781
- logger$2.info('connected to room', {
10782
- sourceId: conference ? conference.sourceId : null,
10783
- name: conference ? conference.name : null,
10784
- });
10932
+ logger$3.info('connected to room', {
10933
+ sourceId: conference ? conference.sourceId : null,
10934
+ name: conference ? conference.name : null,
10935
+ });
10785
10936
 
10786
- if (conference) {
10787
- room.setSourceId(conference.sourceId);
10788
- room.setName(conference.name);
10937
+ if (conference) {
10938
+ room.setSourceId(conference.sourceId);
10939
+ room.setName(conference.name);
10940
+ }
10941
+ } else if (meeting) {
10942
+ logger$3.info('Already connected to meeting', {
10943
+ uuid: meeting.uuid,
10944
+ name: meeting.name,
10945
+ });
10946
+
10947
+ room.setMeetingUuid(meeting.uuid);
10948
+ room.setName(meeting.name);
10789
10949
  }
10790
10950
 
10791
10951
  return room;
10792
10952
  }
10793
10953
 
10794
10954
  static disconnect() {
10795
- logger$2.info('static disconnection to room');
10955
+ logger$3.info('static disconnection to room');
10796
10956
 
10797
10957
  Wazo.Phone.disconnect();
10798
10958
  }
10799
10959
 
10800
10960
  async disconnect() {
10801
- logger$2.info('disconnection to room called');
10961
+ logger$3.info('disconnection to room called');
10802
10962
 
10803
10963
  await Wazo.Phone.hangup(this.callSession);
10804
10964
  this.callSession = null;
@@ -10813,20 +10973,24 @@ class Room$1 extends Emitter {
10813
10973
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10814
10974
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10815
10975
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10816
-
10817
- if (this.roomAudioElement && document.body) {
10818
- document.body.removeChild(this.roomAudioElement);
10819
- }
10976
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10977
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10820
10978
  }
10821
10979
 
10822
10980
  setSourceId(sourceId ) {
10823
- logger$2.info('set room source id', { sourceId });
10981
+ logger$3.info('set room source id', { sourceId });
10824
10982
 
10825
10983
  this.sourceId = sourceId;
10826
10984
  }
10827
10985
 
10986
+ setMeetingUuid(meetingUuid ) {
10987
+ logger$3.info('set meeting uuid', { meetingUuid });
10988
+
10989
+ this.meetingUuid = meetingUuid;
10990
+ }
10991
+
10828
10992
  setCallId(callId ) {
10829
- logger$2.info('set room call id', { callId });
10993
+ logger$3.info('set room call id', { callId });
10830
10994
 
10831
10995
  if (callId) {
10832
10996
  this.callId = callId;
@@ -10834,7 +10998,7 @@ class Room$1 extends Emitter {
10834
10998
  }
10835
10999
 
10836
11000
  setName(name ) {
10837
- logger$2.info('set room name', { name });
11001
+ logger$3.info('set room name', { name });
10838
11002
 
10839
11003
  this.name = name;
10840
11004
  }
@@ -10853,7 +11017,7 @@ class Room$1 extends Emitter {
10853
11017
  }
10854
11018
 
10855
11019
  async startScreenSharing(constraints ) {
10856
- logger$2.info('start room screen sharing', { constraints });
11020
+ logger$3.info('start room screen sharing', { constraints });
10857
11021
 
10858
11022
  const screensharingStream = await Wazo.Phone.startScreenSharing(constraints, this.callSession);
10859
11023
  if (!screensharingStream) {
@@ -10866,18 +11030,26 @@ class Room$1 extends Emitter {
10866
11030
  return screensharingStream;
10867
11031
  }
10868
11032
 
10869
- stopScreenSharing(restoreLocalStream = true) {
10870
- logger$2.info('stop room screen sharing');
11033
+ async stopScreenSharing(restoreLocalStream = true) {
11034
+ logger$3.info('stop room screen sharing');
10871
11035
 
10872
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
11036
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
10873
11037
 
10874
11038
  if (this.localParticipant) {
10875
11039
  this.localParticipant.onStopScreensharing();
10876
11040
  }
11041
+
11042
+ if (!reinvited && this.localParticipant) {
11043
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
11044
+ // So not REINVITE even is fired, we have to restore the video stream manually
11045
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
11046
+ // $FlowFixMe
11047
+ this._associateStreamTo(localVideoStream, this.localParticipant);
11048
+ }
10877
11049
  }
10878
11050
 
10879
11051
  turnCameraOff() {
10880
- logger$2.info('turn room camera off');
11052
+ logger$3.info('turn room camera off');
10881
11053
 
10882
11054
  Wazo.Phone.turnCameraOff(this.callSession);
10883
11055
 
@@ -10887,7 +11059,7 @@ class Room$1 extends Emitter {
10887
11059
  }
10888
11060
 
10889
11061
  turnCameraOn() {
10890
- logger$2.info('turn room camera on');
11062
+ logger$3.info('turn room camera on');
10891
11063
 
10892
11064
  Wazo.Phone.turnCameraOn(this.callSession);
10893
11065
 
@@ -10897,7 +11069,7 @@ class Room$1 extends Emitter {
10897
11069
  }
10898
11070
 
10899
11071
  mute() {
10900
- logger$2.info('mute room');
11072
+ logger$3.info('mute room');
10901
11073
 
10902
11074
  Wazo.Phone.mute(this.callSession);
10903
11075
 
@@ -10905,7 +11077,7 @@ class Room$1 extends Emitter {
10905
11077
  }
10906
11078
 
10907
11079
  unmute() {
10908
- logger$2.info('unmute room');
11080
+ logger$3.info('unmute room');
10909
11081
 
10910
11082
  Wazo.Phone.unmute(this.callSession);
10911
11083
 
@@ -10925,7 +11097,7 @@ class Room$1 extends Emitter {
10925
11097
  }
10926
11098
 
10927
11099
  hold() {
10928
- logger$2.info('hold room');
11100
+ logger$3.info('hold room');
10929
11101
 
10930
11102
  Wazo.Phone.hold(this.callSession, true);
10931
11103
 
@@ -10935,7 +11107,7 @@ class Room$1 extends Emitter {
10935
11107
  }
10936
11108
 
10937
11109
  resume() {
10938
- logger$2.info('resume room');
11110
+ logger$3.info('resume room');
10939
11111
 
10940
11112
  Wazo.Phone.resume(this.callSession, true);
10941
11113
 
@@ -10945,13 +11117,13 @@ class Room$1 extends Emitter {
10945
11117
  }
10946
11118
 
10947
11119
  sendDTMF(tone ) {
10948
- logger$2.info('send room DTMF', { tone });
11120
+ logger$3.info('send room DTMF', { tone });
10949
11121
 
10950
11122
  Wazo.Phone.sendDTMF(tone, this.callSession);
10951
11123
  }
10952
11124
 
10953
11125
  async sendReinvite(newConstraints = null) {
10954
- logger$2.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
11126
+ logger$3.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
10955
11127
  const wasScreensharing = this.localParticipant && this.localParticipant.screensharing;
10956
11128
 
10957
11129
  Wazo.Phone.on(Wazo.Phone.ON_SHARE_SCREEN_STARTED, () => {
@@ -10976,6 +11148,22 @@ class Room$1 extends Emitter {
10976
11148
  return response;
10977
11149
  }
10978
11150
 
11151
+ hasALocalVideoTrack() {
11152
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
11153
+ }
11154
+
11155
+ getLocalStream() {
11156
+ return Wazo.Phone.getLocalStream(this.callSession);
11157
+ }
11158
+
11159
+ getRemoteStream() {
11160
+ return Wazo.Phone.getRemoteStream(this.callSession);
11161
+ }
11162
+
11163
+ getRemoteVideoStream() {
11164
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
11165
+ }
11166
+
10979
11167
  _bindEvents() {
10980
11168
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
10981
11169
  return;
@@ -10994,35 +11182,18 @@ class Room$1 extends Emitter {
10994
11182
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10995
11183
 
10996
11184
  this.on(this.ON_AUDIO_STREAM, stream => {
10997
- logger$2.info('on room audio stream');
11185
+ logger$3.info('on room audio stream');
10998
11186
 
10999
11187
  this.audioStream = stream;
11000
- if (document.createElement) {
11001
- // $FlowFixMe
11002
- let roomAudioElement = document.getElementById('audio-room');
11003
- if (!this.roomAudioElement) {
11004
- roomAudioElement = document.createElement('audio');
11005
- // $FlowFixMe
11006
- document.body.appendChild(roomAudioElement);
11007
- }
11008
- if (!roomAudioElement) {
11009
- return;
11010
- }
11011
- this.roomAudioElement = roomAudioElement;
11188
+ if (!this.roomAudioElement) {
11189
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11190
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
11012
11191
  this.roomAudioElement.srcObject = stream;
11013
- this.roomAudioElement.autoplay = true;
11014
- this.roomAudioElement.id = 'audio-room';
11015
-
11016
- // $FlowFixMe
11017
- if (this.roomAudioElement.setSinkId) {
11018
- // $FlowFixMe
11019
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
11020
- }
11021
11192
  }
11022
11193
  });
11023
11194
 
11024
11195
  this.on(this.ON_VIDEO_STREAM, (stream, streamId, event, sipSession) => {
11025
- logger$2.info('on room video stream', { streamId });
11196
+ logger$3.info('on room video stream', { streamId });
11026
11197
 
11027
11198
  this._mapMsid(sipSession.body.body);
11028
11199
 
@@ -11037,7 +11208,7 @@ class Room$1 extends Emitter {
11037
11208
  });
11038
11209
 
11039
11210
  this.on(this.ON_REMOVE_STREAM, stream => {
11040
- logger$2.info('on room remove stream');
11211
+ logger$3.info('on room remove stream');
11041
11212
 
11042
11213
  const participant = this.participants.find(someParticipant =>
11043
11214
  someParticipant.streams.find(someStream => someStream && someStream.id === stream.id));
@@ -11092,6 +11263,9 @@ class Room$1 extends Emitter {
11092
11263
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11093
11264
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11094
11265
 
11266
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11267
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11268
+
11095
11269
  // Phone events
11096
11270
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
11097
11271
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -11102,15 +11276,15 @@ class Room$1 extends Emitter {
11102
11276
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
11103
11277
  }
11104
11278
 
11105
- _onMessage(message ) {
11279
+ _onMessage(message ) {
11106
11280
  if (message.method !== 'MESSAGE') {
11107
- return;
11281
+ return null;
11108
11282
  }
11109
11283
  let body;
11110
11284
  try {
11111
11285
  body = JSON.parse(message.body);
11112
11286
  } catch (e) {
11113
- return;
11287
+ return null;
11114
11288
  }
11115
11289
 
11116
11290
  switch (body.type) {
@@ -11129,6 +11303,8 @@ class Room$1 extends Emitter {
11129
11303
  }
11130
11304
 
11131
11305
  this.eventEmitter.emit(this.ON_MESSAGE, body);
11306
+
11307
+ return body;
11132
11308
  }
11133
11309
 
11134
11310
  _onChat(content ) {
@@ -11164,7 +11340,7 @@ class Room$1 extends Emitter {
11164
11340
  const requester = this._getParticipantFromCallId(origin.callId);
11165
11341
  if (requester) {
11166
11342
  // @FIXME?: when need to trigger an update on join-in; this is a bit of a hack
11167
- logger$2.info('trigger room requester status', { origin });
11343
+ logger$3.info('trigger room requester status', { origin });
11168
11344
  requester.triggerUpdate('REQUESTER_UPDATE');
11169
11345
  }
11170
11346
  break;
@@ -11193,25 +11369,26 @@ class Room$1 extends Emitter {
11193
11369
  const session = Wazo.Auth.getSession();
11194
11370
  let participants = [];
11195
11371
 
11196
- // @TODO: we could use a better function name here
11197
- const isJoining = part => {
11198
- this.__associateStreams(part);
11199
- // @VALIDATE: no need to publicize ourselves, no?
11200
- if (part instanceof RemoteParticipant) {
11201
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
11202
- }
11203
- };
11204
-
11205
11372
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
11206
11373
  if (participant.user_uuid === session.uuid) {
11207
- logger$2.info('room current user joined');
11374
+ logger$3.info('room current user joined');
11208
11375
 
11209
11376
  // Retrieve participants via an API calls
11210
11377
  const conferenceId = this.sourceId || payload.data.conference_id;
11211
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11212
- logger$2.info('fetching conference participants', { conferenceId });
11378
+ let response;
11379
+ try {
11380
+ if (this.meetingUuid) {
11381
+ logger$3.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
11382
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
11383
+ } else {
11384
+ logger$3.info('fetching conference participants', { conferenceId });
11385
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11386
+ }
11387
+ } catch (e) {
11388
+ logger$3.error('room participants fetching, error', e);
11389
+ }
11213
11390
  if (response) {
11214
- logger$2.info('conference participants fetched', { nb: response.items.length });
11391
+ logger$3.info('conference participants fetched', { nb: response.items.length });
11215
11392
  participants = response.items.map(item => {
11216
11393
  const isMe = item.call_id === this.callId;
11217
11394
 
@@ -11224,25 +11401,10 @@ class Room$1 extends Emitter {
11224
11401
 
11225
11402
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
11226
11403
  if (!this.localParticipant && localParticipant) {
11227
- this.localParticipant = localParticipant;
11228
-
11229
- const localVideoStream = this._getLocalVideoStream();
11230
- if (localVideoStream) {
11231
- this._saveLocalVideoStream(localVideoStream);
11232
- }
11233
-
11234
- this.connected = true;
11235
-
11236
- // we're in the room, now let's request everyone's status
11237
- if (this.localParticipant) {
11238
- this.sendSignal({
11239
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11240
- origin: this.localParticipant.getStatus(),
11241
- });
11242
- }
11404
+ this._onLocalParticipantJoined(localParticipant);
11243
11405
  }
11244
11406
 
11245
- participants.forEach(someParticipant => isJoining(someParticipant));
11407
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
11246
11408
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
11247
11409
  }
11248
11410
 
@@ -11253,16 +11415,45 @@ class Room$1 extends Emitter {
11253
11415
  ? new Wazo.RemoteParticipant(this, participant)
11254
11416
  : null;
11255
11417
 
11256
- logger$2.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11418
+ logger$3.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11257
11419
 
11258
11420
  if (remoteParticipant) {
11259
11421
  this.participants.push(remoteParticipant);
11260
- isJoining(remoteParticipant);
11422
+ this._isParticipantJoining(remoteParticipant);
11261
11423
  }
11262
11424
 
11263
11425
  return remoteParticipant;
11264
11426
  }
11265
11427
 
11428
+ _onLocalParticipantJoined(localParticipant ) {
11429
+ this.localParticipant = localParticipant;
11430
+
11431
+ const localVideoStream = this._getLocalVideoStream();
11432
+ if (localVideoStream) {
11433
+ this._saveLocalVideoStream(localVideoStream);
11434
+ }
11435
+
11436
+ this.connected = true;
11437
+
11438
+ localParticipant.broadcastStatus();
11439
+
11440
+ // we're in the room, now let's request everyone's status
11441
+ if (this.localParticipant) {
11442
+ this.sendSignal({
11443
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11444
+ origin: this.localParticipant.getStatus(),
11445
+ });
11446
+ }
11447
+ }
11448
+
11449
+ _isParticipantJoining(participant ) {
11450
+ this.__associateStreams(participant);
11451
+ // @VALIDATE: no need to publicize ourselves, no?
11452
+ if (participant instanceof RemoteParticipant) {
11453
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
11454
+ }
11455
+ }
11456
+
11266
11457
  _saveLocalVideoStream(stream ) {
11267
11458
  const { localParticipant } = this;
11268
11459
 
@@ -11308,9 +11499,11 @@ class Room$1 extends Emitter {
11308
11499
  _onParticipantTrackUpdate(oldParticipant , update ) {
11309
11500
  const newParticipant = oldParticipant;
11310
11501
 
11311
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11502
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11312
11503
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
11313
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
11504
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
11505
+ const stream = pc.getRemoteStreams().find(someStream =>
11506
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
11314
11507
 
11315
11508
  if (update === 'downgrade') {
11316
11509
  newParticipant.streams = [];
@@ -11340,15 +11533,42 @@ class Room$1 extends Emitter {
11340
11533
  return;
11341
11534
  }
11342
11535
 
11343
- if (this._unassociatedVideoStreams[trackId]) {
11536
+ const streamId = this._getStreamIdFrTrackId(trackId);
11537
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
11538
+ const stream = this._unassociatedVideoStreams[key];
11539
+
11540
+ if (stream) {
11344
11541
  // Try to associate stream
11345
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
11542
+ this._associateStreamTo(stream, participant);
11346
11543
 
11347
- delete this._unassociatedVideoStreams[trackId];
11544
+ delete this._unassociatedVideoStreams[key];
11348
11545
  delete this._unassociatedParticipants[participant.callId];
11349
11546
  }
11350
11547
  }
11351
11548
 
11549
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
11550
+ // Find by trackId
11551
+ if (trackId in this._unassociatedVideoStreams) {
11552
+ return trackId;
11553
+ }
11554
+
11555
+ // Find by streamId
11556
+ if (streamId && streamId in this._unassociatedVideoStreams) {
11557
+ return streamId;
11558
+ }
11559
+
11560
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
11561
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11562
+ stream && stream.id === streamId);
11563
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11564
+ }
11565
+
11566
+ _getStreamIdFrTrackId(trackId ) {
11567
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
11568
+
11569
+ return mapping ? mapping.streamId : null;
11570
+ }
11571
+
11352
11572
  _associateStreamTo(rawStream , participant ) {
11353
11573
  const stream = new Wazo.Stream(rawStream, participant);
11354
11574
  participant.streams.push(stream);
@@ -11372,7 +11592,141 @@ class Room$1 extends Emitter {
11372
11592
 
11373
11593
  //
11374
11594
 
11375
- class LocalParticipant extends Participant {
11595
+ const logger$2 = IssueReporter$1.loggerFor('sdk-sip-room');
11596
+
11597
+ class SipRoom extends Room$1 {
11598
+
11599
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
11600
+ logger$2.info('connecting to sip room', { extension, audioOnly, room: !!room });
11601
+
11602
+ if (!room) {
11603
+ await Wazo.Phone.connect();
11604
+
11605
+ const withCamera = constraints && !!constraints.video;
11606
+
11607
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
11608
+ // eslint-disable-next-line no-param-reassign
11609
+ room = new SipRoom(callSession, extension, null, null, extra);
11610
+ }
11611
+
11612
+ if (room && room.callSession && room.callSession.call) {
11613
+ room.setCallId(room.callSession.call.id);
11614
+ }
11615
+
11616
+ logger$2.info('connected to room', {
11617
+ extension: room.extension,
11618
+ });
11619
+
11620
+ return room;
11621
+ }
11622
+
11623
+ mute() {
11624
+ logger$2.info('mute sip room');
11625
+
11626
+ Wazo.Phone.mute(this.callSession, false);
11627
+
11628
+ this.sendMuteStatus();
11629
+ }
11630
+
11631
+ unmute() {
11632
+ logger$2.info('unmute sip room');
11633
+
11634
+ Wazo.Phone.unmute(this.callSession, false);
11635
+
11636
+ this.sendUnMuteStatus();
11637
+ }
11638
+
11639
+ getLocalGuestName() {
11640
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
11641
+ }
11642
+
11643
+ // Overridden to not listen to websocket messages
11644
+ _transferEvents() {
11645
+ // Phone events
11646
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
11647
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
11648
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
11649
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
11650
+
11651
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
11652
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
11653
+ }
11654
+
11655
+ _onMessage(message ) {
11656
+ // eslint-disable-next-line no-underscore-dangle
11657
+ const body = super._onMessage(message);
11658
+ if (!body) {
11659
+ return;
11660
+ }
11661
+
11662
+ const getChannel = () => body.channels[0];
11663
+
11664
+ switch (body.type) {
11665
+ case 'ConfbridgeWelcome':
11666
+ body.channels.forEach(channel => {
11667
+ this._onParticipantJoined(channel);
11668
+ });
11669
+
11670
+ break;
11671
+ case 'ConfbridgeJoin': {
11672
+ const channel = getChannel();
11673
+ this._onParticipantJoined(channel);
11674
+ break;
11675
+ }
11676
+ case 'ConfbridgeLeave': {
11677
+ const channel = getChannel();
11678
+ this._onParticipantLeft({
11679
+ data: {
11680
+ call_id: channel.id,
11681
+ },
11682
+ });
11683
+ break;
11684
+ }
11685
+ }
11686
+ }
11687
+
11688
+ async _onParticipantJoined(channel ) {
11689
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
11690
+ const callId = channel.id;
11691
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
11692
+ const name = channel.caller ? channel.caller.name : null;
11693
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
11694
+ const participant = new ParticipantClass(this, {
11695
+ caller_id_name: name,
11696
+ call_id: callId,
11697
+ }, extra);
11698
+
11699
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
11700
+ if (participantIdx !== -1 && name) {
11701
+ this.participants[participantIdx].name = name;
11702
+ return;
11703
+ }
11704
+
11705
+ if (isLocal) {
11706
+ // Should be updated by the Wazo WS but we don't have it for now
11707
+ if (this.callSession) {
11708
+ this.callSession.ringing = false;
11709
+ }
11710
+
11711
+ this._onLocalParticipantJoined(participant);
11712
+
11713
+ // Give some time for the stream to be updated
11714
+ setTimeout(() => {
11715
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
11716
+ }, 1000);
11717
+ }
11718
+
11719
+ this.participants.push(participant);
11720
+
11721
+ this._isParticipantJoining(participant);
11722
+
11723
+ return participant;
11724
+ }
11725
+
11726
+ _getCurrentSipCallIs() {
11727
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11728
+ }
11729
+
11376
11730
  }
11377
11731
 
11378
11732
  /* global document */
@@ -11425,9 +11779,7 @@ class Stream {
11425
11779
  return false;
11426
11780
  }
11427
11781
 
11428
- // With canvas track (used to fake upgrade in conference), we don't have a width
11429
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
11430
- && track.readyState !== 'ended' && 'width' in track.getSettings());
11782
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
11431
11783
  }
11432
11784
 
11433
11785
  get id() {
@@ -12311,6 +12663,7 @@ const Wazo = {
12311
12663
  Phone: Phone$1,
12312
12664
  Websocket: Websocket$1,
12313
12665
  Room: Room$1,
12666
+ SipRoom,
12314
12667
  RemoteParticipant,
12315
12668
  LocalParticipant,
12316
12669
  Stream,
@@ -12347,6 +12700,7 @@ const Wazo = {
12347
12700
  IndirectTransfer,
12348
12701
  SwitchboardCall,
12349
12702
  WebRTCPhone,
12703
+ Meeting,
12350
12704
  },
12351
12705
 
12352
12706
  // Api