@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
@@ -916,7 +916,7 @@ var IssueReporter$1 = new IssueReporter();
916
916
 
917
917
  const methods = ['head', 'get', 'post', 'put', 'delete'];
918
918
 
919
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
919
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
920
920
 
921
921
  // Use a function here to be able to mock it in tests
922
922
  const realFetch = () => {
@@ -1055,7 +1055,7 @@ class ApiRequester {
1055
1055
  };
1056
1056
 
1057
1057
  if (this.refreshTokenPromise) {
1058
- logger$b.info('A token is already refreshing, waiting ...', { url });
1058
+ logger$c.info('A token is already refreshing, waiting ...', { url });
1059
1059
  await this.refreshTokenPromise;
1060
1060
  }
1061
1061
 
@@ -1075,7 +1075,7 @@ class ApiRequester {
1075
1075
  return promise.then(async (err ) => {
1076
1076
  // Check if the token is still valid
1077
1077
  if (firstCall && this._checkTokenExpired(response, err)) {
1078
- logger$b.warn('token expired', { error: err.reason });
1078
+ logger$c.warn('token expired', { error: err.reason });
1079
1079
  // Replay the call after refreshing the token
1080
1080
  return this._replayWithNewToken(err, path, method, body, headers, parse);
1081
1081
  }
@@ -1085,7 +1085,7 @@ class ApiRequester {
1085
1085
  : exceptionClass.fromResponse(err, response.status);
1086
1086
 
1087
1087
  if (this.shouldLogErrors) {
1088
- logger$b.error('API error', error);
1088
+ logger$c.error('API error', error);
1089
1089
  }
1090
1090
 
1091
1091
  throw error;
@@ -1095,7 +1095,7 @@ class ApiRequester {
1095
1095
  return newParse(response, isJson);
1096
1096
  }).catch(error => {
1097
1097
  if (this.shouldLogErrors) {
1098
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
1098
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
1099
1099
  }
1100
1100
 
1101
1101
  throw error;
@@ -1123,13 +1123,13 @@ class ApiRequester {
1123
1123
  ) {
1124
1124
  const isTokenNotFound = this._isTokenNotFound(err);
1125
1125
  let newPath = path;
1126
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
1126
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
1127
1127
 
1128
1128
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
1129
1129
 
1130
1130
  return this.refreshTokenPromise.then(() => {
1131
1131
  this.refreshTokenPromise = null;
1132
- logger$b.info('token refreshed', { isTokenNotFound });
1132
+ logger$c.info('token refreshed', { isTokenNotFound });
1133
1133
  if (isTokenNotFound) {
1134
1134
  const pathParts = path.split('/');
1135
1135
  pathParts.pop();
@@ -3060,6 +3060,65 @@ class ExternalApp {
3060
3060
  }
3061
3061
  }
3062
3062
 
3063
+ //
3064
+
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+ class Meeting {
3076
+
3077
+
3078
+
3079
+
3080
+
3081
+
3082
+
3083
+
3084
+
3085
+
3086
+ static parse(plain ) {
3087
+ return new Meeting({
3088
+ guestSipAuthorization: plain.guest_sip_authorization,
3089
+ hostname: plain.hostname,
3090
+ name: plain.name,
3091
+ ownerUuids: plain.owner_uuids,
3092
+ port: plain.port,
3093
+ uuid: plain.uuid,
3094
+ number: plain.number,
3095
+ });
3096
+ }
3097
+
3098
+ static newFrom(meeting ) {
3099
+ return newFrom(meeting, Meeting);
3100
+ }
3101
+
3102
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
3103
+ this.guestSipAuthorization = guestSipAuthorization;
3104
+ this.hostname = hostname;
3105
+ this.name = name;
3106
+ this.ownerUuids = ownerUuids;
3107
+ this.port = port;
3108
+ this.uuid = uuid;
3109
+ this.number = number;
3110
+
3111
+ // Useful to compare instead of instanceof with minified code
3112
+ this.type = 'Meeting';
3113
+ }
3114
+
3115
+ getGuestSipCredentials() {
3116
+ // eslint-disable-next-line no-undef
3117
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
3118
+ return { username, secret };
3119
+ }
3120
+ }
3121
+
3063
3122
  /* */
3064
3123
 
3065
3124
  var confdMethods = (client , baseUrl ) => ({
@@ -3124,6 +3183,18 @@ var confdMethods = (client , baseUrl ) => ({
3124
3183
  return null;
3125
3184
  }
3126
3185
  },
3186
+
3187
+ createMyMeeting: (name ) =>
3188
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
3189
+
3190
+ deleteMyMeeting: (meetingUuid ) =>
3191
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
3192
+
3193
+ getMeeting: (meetingUuid ) =>
3194
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
3195
+
3196
+ guestGetMeeting: (meetingUuid ) =>
3197
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
3127
3198
  });
3128
3199
 
3129
3200
  //
@@ -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
 
@@ -9361,7 +9476,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
9361
9476
  class InvalidSubscription extends Error {}
9362
9477
  class InvalidAuthorization extends Error {}
9363
9478
 
9364
- const logger$6 = IssueReporter$1.loggerFor('simple-auth');
9479
+ const logger$7 = IssueReporter$1.loggerFor('simple-auth');
9365
9480
 
9366
9481
  class Auth {
9367
9482
 
@@ -9396,7 +9511,7 @@ class Auth {
9396
9511
  setApiClientId(this.clientId);
9397
9512
  setRefreshExpiration(this.expiration);
9398
9513
  setOnRefreshToken((token , session ) => {
9399
- logger$6.info('on refresh token done', { token });
9514
+ logger$7.info('on refresh token done', { token });
9400
9515
  setApiToken(token);
9401
9516
  Wazo.Websocket.updateToken(token);
9402
9517
 
@@ -9672,6 +9787,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
9672
9787
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
9673
9788
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
9674
9789
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
9790
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
9791
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
9675
9792
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
9676
9793
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
9677
9794
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -9713,7 +9830,7 @@ const BLACKLIST_EVENTS = [
9713
9830
  ];
9714
9831
 
9715
9832
  const HEARTBEAT_ENGINE_VERSION = '20.09';
9716
- const logger$5 = IssueReporter$1.loggerFor('wazo-ws');
9833
+ const logger$6 = IssueReporter$1.loggerFor('wazo-ws');
9717
9834
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
9718
9835
 
9719
9836
  class WebSocketClient extends Emitter {
@@ -9762,19 +9879,19 @@ class WebSocketClient extends Emitter {
9762
9879
  }
9763
9880
 
9764
9881
  connect() {
9765
- logger$5.info('connect method started', { host: this.host, token: this.token });
9882
+ logger$6.info('connect method started', { host: this.host, token: this.token });
9766
9883
  this.socket = new ReconnectingWebSocket__default['default'](this._getUrl.bind(this), [], this.options);
9767
9884
  if (this.options.binaryType) {
9768
9885
  this.socket.binaryType = this.options.binaryType;
9769
9886
  }
9770
9887
 
9771
9888
  this.socket.onopen = () => {
9772
- logger$5.info('on Wazo WS open', { method: 'connect', host: this.host });
9889
+ logger$6.info('on Wazo WS open', { method: 'connect', host: this.host });
9773
9890
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
9774
9891
  };
9775
9892
 
9776
9893
  this.socket.onerror = event => {
9777
- logger$5.error('on Wazo WS error', event.target);
9894
+ logger$6.error('on Wazo WS error', event.target);
9778
9895
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
9779
9896
  };
9780
9897
 
@@ -9804,7 +9921,7 @@ class WebSocketClient extends Emitter {
9804
9921
 
9805
9922
  this.socket.onclose = event => {
9806
9923
  // Can't be converted to JSON (circular structure)
9807
- logger$5.info('on Wazo WS close', {
9924
+ logger$6.info('on Wazo WS close', {
9808
9925
  reason: event.reason,
9809
9926
  code: event.code,
9810
9927
  readyState: event.target.readyState,
@@ -9822,12 +9939,12 @@ class WebSocketClient extends Emitter {
9822
9939
  };
9823
9940
 
9824
9941
  this.socket.onerror = event => {
9825
- logger$5.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
9942
+ logger$6.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
9826
9943
  };
9827
9944
  }
9828
9945
 
9829
9946
  close(force = false) {
9830
- logger$5.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
9947
+ logger$6.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
9831
9948
 
9832
9949
  if (!this.socket) {
9833
9950
  return;
@@ -9845,7 +9962,7 @@ class WebSocketClient extends Emitter {
9845
9962
 
9846
9963
  updateToken(token ) {
9847
9964
  this.token = token;
9848
- logger$5.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
9965
+ logger$6.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
9849
9966
 
9850
9967
  if (this.socket) {
9851
9968
  // If still connected, send the token to the WS
@@ -9863,7 +9980,7 @@ class WebSocketClient extends Emitter {
9863
9980
  }
9864
9981
 
9865
9982
  startHeartbeat() {
9866
- logger$5.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
9983
+ logger$6.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
9867
9984
 
9868
9985
  if (!this.socket) {
9869
9986
  this.heartbeat.stop();
@@ -9877,7 +9994,7 @@ class WebSocketClient extends Emitter {
9877
9994
  }
9878
9995
 
9879
9996
  stopHeartbeat() {
9880
- logger$5.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
9997
+ logger$6.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
9881
9998
 
9882
9999
  this.heartbeat.stop();
9883
10000
  }
@@ -9907,7 +10024,7 @@ class WebSocketClient extends Emitter {
9907
10024
  }
9908
10025
 
9909
10026
  reconnect(reason ) {
9910
- logger$5.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10027
+ logger$6.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
9911
10028
  if (!this.socket) {
9912
10029
  return;
9913
10030
  }
@@ -9963,7 +10080,7 @@ class WebSocketClient extends Emitter {
9963
10080
  this.close();
9964
10081
  }
9965
10082
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
9966
- logger$5.log('Wazo WS url computed to reconnect', { url });
10083
+ logger$6.log('Wazo WS url computed to reconnect', { url });
9967
10084
 
9968
10085
  return url;
9969
10086
  }
@@ -9971,12 +10088,12 @@ class WebSocketClient extends Emitter {
9971
10088
  _onHeartbeat(message ) {
9972
10089
  if (message.payload === 'pong') {
9973
10090
  this.heartbeat.onHeartbeat();
9974
- logger$5.log('on heartbeat received from Wazo WS');
10091
+ logger$6.log('on heartbeat received from Wazo WS');
9975
10092
  }
9976
10093
  }
9977
10094
 
9978
10095
  async _onHeartbeatTimeout() {
9979
- logger$5.log('heartbeat timed out', { host: this.host, token: this.token });
10096
+ logger$6.log('heartbeat timed out', { host: this.host, token: this.token });
9980
10097
 
9981
10098
  this.close();
9982
10099
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -10018,6 +10135,8 @@ WebSocketClient.eventLists = [
10018
10135
  CHATD_USER_ROOM_CREATED,
10019
10136
  CONFERENCE_USER_PARTICIPANT_JOINED,
10020
10137
  CONFERENCE_USER_PARTICIPANT_LEFT,
10138
+ MEETING_USER_PARTICIPANT_JOINED,
10139
+ MEETING_USER_PARTICIPANT_LEFT,
10021
10140
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10022
10141
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10023
10142
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -10088,6 +10207,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10088
10207
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
10089
10208
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10090
10209
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10210
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
10211
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
10091
10212
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
10092
10213
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
10093
10214
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -10129,7 +10250,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10129
10250
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
10130
10251
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
10131
10252
 
10132
- const logger$4 = IssueReporter$1.loggerFor('simple-ws-client');
10253
+ const logger$5 = IssueReporter$1.loggerFor('simple-ws-client');
10133
10254
 
10134
10255
  class Websocket extends Emitter {
10135
10256
 
@@ -10153,7 +10274,7 @@ class Websocket extends Emitter {
10153
10274
  }
10154
10275
 
10155
10276
  open(host , session ) {
10156
- logger$4.info('open simple WebSocket', { host, token: session.token });
10277
+ logger$5.info('open simple WebSocket', { host, token: session.token });
10157
10278
  this.ws = new WebSocketClient(
10158
10279
  {
10159
10280
  host,
@@ -10181,7 +10302,7 @@ class Websocket extends Emitter {
10181
10302
  }
10182
10303
 
10183
10304
  updateToken(token ) {
10184
- logger$4.info('update token via simple Websocket', { token, ws: !!this.ws });
10305
+ logger$5.info('update token via simple Websocket', { token, ws: !!this.ws });
10185
10306
 
10186
10307
  if (!this.ws) {
10187
10308
  return;
@@ -10209,7 +10330,7 @@ var Websocket$1 = global.wazoWebsocketInstance;
10209
10330
 
10210
10331
  //
10211
10332
 
10212
- const logger$3 = IssueReporter$1.loggerFor('room');
10333
+ const logger$4 = IssueReporter$1.loggerFor('room');
10213
10334
 
10214
10335
  class Participant extends Emitter {
10215
10336
 
@@ -10243,6 +10364,7 @@ class Participant extends Emitter {
10243
10364
 
10244
10365
 
10245
10366
  /**
10367
+ * @param room Room The room where the participant is
10246
10368
  * @param rawParticipant string Participant sent via the Wazo WS
10247
10369
  * @param extra Object extra status of the participant
10248
10370
  */
@@ -10330,7 +10452,7 @@ class Participant extends Emitter {
10330
10452
  }
10331
10453
 
10332
10454
  onTalking(isTalking ) {
10333
- logger$3.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10455
+ logger$4.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10334
10456
  this.isTalking = isTalking;
10335
10457
  // you may notice we're not broadcasting: since all participants are getting this info
10336
10458
  // directly from asterisk, there's no need to do so
@@ -10433,7 +10555,7 @@ class Participant extends Emitter {
10433
10555
  }
10434
10556
 
10435
10557
  updateStatus(status , broadcast = true) {
10436
- logger$3.info('updating participant status', { name: this.name, status });
10558
+ logger$4.info('updating participant status', { name: this.name, status });
10437
10559
 
10438
10560
  if (typeof status.audioMuted !== 'undefined' && status.audioMuted !== this.audioMuted) {
10439
10561
  if (status.audioMuted) {
@@ -10470,13 +10592,18 @@ class Participant extends Emitter {
10470
10592
  // Poor man's object comparison
10471
10593
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
10472
10594
  this.extra = { ...this.extra, ...status.extra };
10595
+
10596
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
10597
+ this.extra.contact = new Contact(this.extra.contact);
10598
+ }
10599
+
10473
10600
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
10474
10601
  }
10475
10602
  }
10476
10603
 
10477
10604
  broadcastStatus(inboundStatus = null) {
10478
10605
  const status = inboundStatus || this.getStatus();
10479
- logger$3.info('broadcasting participant status', { callId: this.callId, status });
10606
+ logger$4.info('broadcasting participant status', { callId: this.callId, status });
10480
10607
 
10481
10608
  this.room.sendSignal({
10482
10609
  type: SIGNAL_TYPE_PARTICIPANT_UPDATE,
@@ -10497,18 +10624,24 @@ class RemoteParticipant extends Participant {
10497
10624
  }
10498
10625
  }
10499
10626
 
10500
- /* global document */
10627
+ //
10628
+
10629
+ class LocalParticipant extends Participant {
10630
+ }
10631
+
10632
+ //
10501
10633
 
10502
10634
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
10503
10635
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
10504
10636
 
10505
- const logger$2 = IssueReporter$1.loggerFor('sdk-room');
10637
+ const logger$3 = IssueReporter$1.loggerFor('sdk-room');
10506
10638
 
10507
10639
  class Room$1 extends Emitter {
10508
10640
 
10509
10641
 
10510
10642
 
10511
10643
 
10644
+
10512
10645
 
10513
10646
 
10514
10647
 
@@ -10530,6 +10663,8 @@ class Room$1 extends Emitter {
10530
10663
 
10531
10664
 
10532
10665
 
10666
+
10667
+
10533
10668
 
10534
10669
 
10535
10670
 
@@ -10547,6 +10682,7 @@ class Room$1 extends Emitter {
10547
10682
  * @param extension string
10548
10683
  * @param sourceId number
10549
10684
  * @param callId string
10685
+ * @param meetingUuid string
10550
10686
  * @param extra Object
10551
10687
  */
10552
10688
  constructor(
@@ -10554,15 +10690,17 @@ class Room$1 extends Emitter {
10554
10690
  extension ,
10555
10691
  sourceId ,
10556
10692
  callId ,
10693
+ meetingUuid ,
10557
10694
  extra = {},
10558
10695
  ) {
10559
10696
  super();
10560
- logger$2.info('room initialized', { callId, extension, sourceId });
10697
+ logger$3.info('room initialized', { callId, extension, sourceId, meetingUuid });
10561
10698
 
10562
10699
  // Represents the room callSession
10563
10700
  this.callSession = callSession;
10564
10701
  this.extension = extension;
10565
10702
  this.sourceId = sourceId;
10703
+ this.meetingUuid = meetingUuid;
10566
10704
  this.callId = callId;
10567
10705
  this.participants = [];
10568
10706
  this.connected = false;
@@ -10582,6 +10720,8 @@ class Room$1 extends Emitter {
10582
10720
  // Sugar syntax for `room.EVENT_NAME`
10583
10721
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
10584
10722
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
10723
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
10724
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
10585
10725
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
10586
10726
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
10587
10727
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -10616,10 +10756,11 @@ class Room$1 extends Emitter {
10616
10756
  * @param audioOnly boolean
10617
10757
  * @param extra Object
10618
10758
  * @param room ?Room
10759
+ * @param meeting ?Meeting
10619
10760
  * @returns {Promise<Room>}
10620
10761
  */
10621
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
10622
- logger$2.info('connecting to room', { extension, audioOnly, room: !!room });
10762
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
10763
+ logger$3.info('connecting to room', { extension, audioOnly, room: !!room });
10623
10764
 
10624
10765
  if (!room) {
10625
10766
  await Wazo.Phone.connect();
@@ -10632,7 +10773,7 @@ class Room$1 extends Emitter {
10632
10773
 
10633
10774
  // Call_created is triggered before call_accepted, so we have to listen for it here.
10634
10775
  Wazo.Websocket.once(Wazo.Websocket.CALL_CREATED, ({ data }) => {
10635
- logger$2.info('room call received via WS', { callId: data.call_id });
10776
+ logger$3.info('room call received via WS', { callId: data.call_id });
10636
10777
  if (room) {
10637
10778
  room.setCallId(data.call_id);
10638
10779
  }
@@ -10653,34 +10794,44 @@ class Room$1 extends Emitter {
10653
10794
  room.setCallId(room.callSession.call.id);
10654
10795
  }
10655
10796
 
10656
- // Fetch conference source
10657
- const sources = await getApiClient().dird.fetchConferenceSource('default');
10658
- // Retrieve conference sources
10659
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10660
- // Retrieve conference
10661
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10797
+ if (!meeting) {
10798
+ // Fetch conference source
10799
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
10800
+ // Retrieve conference sources
10801
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10802
+ // Retrieve conference
10803
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10662
10804
 
10663
- logger$2.info('connected to room', {
10664
- sourceId: conference ? conference.sourceId : null,
10665
- name: conference ? conference.name : null,
10666
- });
10805
+ logger$3.info('connected to room', {
10806
+ sourceId: conference ? conference.sourceId : null,
10807
+ name: conference ? conference.name : null,
10808
+ });
10667
10809
 
10668
- if (conference) {
10669
- room.setSourceId(conference.sourceId);
10670
- room.setName(conference.name);
10810
+ if (conference) {
10811
+ room.setSourceId(conference.sourceId);
10812
+ room.setName(conference.name);
10813
+ }
10814
+ } else if (meeting) {
10815
+ logger$3.info('Already connected to meeting', {
10816
+ uuid: meeting.uuid,
10817
+ name: meeting.name,
10818
+ });
10819
+
10820
+ room.setMeetingUuid(meeting.uuid);
10821
+ room.setName(meeting.name);
10671
10822
  }
10672
10823
 
10673
10824
  return room;
10674
10825
  }
10675
10826
 
10676
10827
  static disconnect() {
10677
- logger$2.info('static disconnection to room');
10828
+ logger$3.info('static disconnection to room');
10678
10829
 
10679
10830
  Wazo.Phone.disconnect();
10680
10831
  }
10681
10832
 
10682
10833
  async disconnect() {
10683
- logger$2.info('disconnection to room called');
10834
+ logger$3.info('disconnection to room called');
10684
10835
 
10685
10836
  await Wazo.Phone.hangup(this.callSession);
10686
10837
  this.callSession = null;
@@ -10695,20 +10846,24 @@ class Room$1 extends Emitter {
10695
10846
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10696
10847
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10697
10848
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10698
-
10699
- if (this.roomAudioElement && document.body) {
10700
- document.body.removeChild(this.roomAudioElement);
10701
- }
10849
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10850
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10702
10851
  }
10703
10852
 
10704
10853
  setSourceId(sourceId ) {
10705
- logger$2.info('set room source id', { sourceId });
10854
+ logger$3.info('set room source id', { sourceId });
10706
10855
 
10707
10856
  this.sourceId = sourceId;
10708
10857
  }
10709
10858
 
10859
+ setMeetingUuid(meetingUuid ) {
10860
+ logger$3.info('set meeting uuid', { meetingUuid });
10861
+
10862
+ this.meetingUuid = meetingUuid;
10863
+ }
10864
+
10710
10865
  setCallId(callId ) {
10711
- logger$2.info('set room call id', { callId });
10866
+ logger$3.info('set room call id', { callId });
10712
10867
 
10713
10868
  if (callId) {
10714
10869
  this.callId = callId;
@@ -10716,7 +10871,7 @@ class Room$1 extends Emitter {
10716
10871
  }
10717
10872
 
10718
10873
  setName(name ) {
10719
- logger$2.info('set room name', { name });
10874
+ logger$3.info('set room name', { name });
10720
10875
 
10721
10876
  this.name = name;
10722
10877
  }
@@ -10735,7 +10890,7 @@ class Room$1 extends Emitter {
10735
10890
  }
10736
10891
 
10737
10892
  async startScreenSharing(constraints ) {
10738
- logger$2.info('start room screen sharing', { constraints });
10893
+ logger$3.info('start room screen sharing', { constraints });
10739
10894
 
10740
10895
  const screensharingStream = await Wazo.Phone.startScreenSharing(constraints, this.callSession);
10741
10896
  if (!screensharingStream) {
@@ -10748,18 +10903,26 @@ class Room$1 extends Emitter {
10748
10903
  return screensharingStream;
10749
10904
  }
10750
10905
 
10751
- stopScreenSharing(restoreLocalStream = true) {
10752
- logger$2.info('stop room screen sharing');
10906
+ async stopScreenSharing(restoreLocalStream = true) {
10907
+ logger$3.info('stop room screen sharing');
10753
10908
 
10754
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
10909
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
10755
10910
 
10756
10911
  if (this.localParticipant) {
10757
10912
  this.localParticipant.onStopScreensharing();
10758
10913
  }
10914
+
10915
+ if (!reinvited && this.localParticipant) {
10916
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
10917
+ // So not REINVITE even is fired, we have to restore the video stream manually
10918
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
10919
+ // $FlowFixMe
10920
+ this._associateStreamTo(localVideoStream, this.localParticipant);
10921
+ }
10759
10922
  }
10760
10923
 
10761
10924
  turnCameraOff() {
10762
- logger$2.info('turn room camera off');
10925
+ logger$3.info('turn room camera off');
10763
10926
 
10764
10927
  Wazo.Phone.turnCameraOff(this.callSession);
10765
10928
 
@@ -10769,7 +10932,7 @@ class Room$1 extends Emitter {
10769
10932
  }
10770
10933
 
10771
10934
  turnCameraOn() {
10772
- logger$2.info('turn room camera on');
10935
+ logger$3.info('turn room camera on');
10773
10936
 
10774
10937
  Wazo.Phone.turnCameraOn(this.callSession);
10775
10938
 
@@ -10779,7 +10942,7 @@ class Room$1 extends Emitter {
10779
10942
  }
10780
10943
 
10781
10944
  mute() {
10782
- logger$2.info('mute room');
10945
+ logger$3.info('mute room');
10783
10946
 
10784
10947
  Wazo.Phone.mute(this.callSession);
10785
10948
 
@@ -10787,7 +10950,7 @@ class Room$1 extends Emitter {
10787
10950
  }
10788
10951
 
10789
10952
  unmute() {
10790
- logger$2.info('unmute room');
10953
+ logger$3.info('unmute room');
10791
10954
 
10792
10955
  Wazo.Phone.unmute(this.callSession);
10793
10956
 
@@ -10807,7 +10970,7 @@ class Room$1 extends Emitter {
10807
10970
  }
10808
10971
 
10809
10972
  hold() {
10810
- logger$2.info('hold room');
10973
+ logger$3.info('hold room');
10811
10974
 
10812
10975
  Wazo.Phone.hold(this.callSession, true);
10813
10976
 
@@ -10817,7 +10980,7 @@ class Room$1 extends Emitter {
10817
10980
  }
10818
10981
 
10819
10982
  resume() {
10820
- logger$2.info('resume room');
10983
+ logger$3.info('resume room');
10821
10984
 
10822
10985
  Wazo.Phone.resume(this.callSession, true);
10823
10986
 
@@ -10827,13 +10990,13 @@ class Room$1 extends Emitter {
10827
10990
  }
10828
10991
 
10829
10992
  sendDTMF(tone ) {
10830
- logger$2.info('send room DTMF', { tone });
10993
+ logger$3.info('send room DTMF', { tone });
10831
10994
 
10832
10995
  Wazo.Phone.sendDTMF(tone, this.callSession);
10833
10996
  }
10834
10997
 
10835
10998
  async sendReinvite(newConstraints = null) {
10836
- logger$2.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
10999
+ logger$3.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
10837
11000
  const wasScreensharing = this.localParticipant && this.localParticipant.screensharing;
10838
11001
 
10839
11002
  Wazo.Phone.on(Wazo.Phone.ON_SHARE_SCREEN_STARTED, () => {
@@ -10858,6 +11021,22 @@ class Room$1 extends Emitter {
10858
11021
  return response;
10859
11022
  }
10860
11023
 
11024
+ hasALocalVideoTrack() {
11025
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
11026
+ }
11027
+
11028
+ getLocalStream() {
11029
+ return Wazo.Phone.getLocalStream(this.callSession);
11030
+ }
11031
+
11032
+ getRemoteStream() {
11033
+ return Wazo.Phone.getRemoteStream(this.callSession);
11034
+ }
11035
+
11036
+ getRemoteVideoStream() {
11037
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
11038
+ }
11039
+
10861
11040
  _bindEvents() {
10862
11041
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
10863
11042
  return;
@@ -10876,35 +11055,18 @@ class Room$1 extends Emitter {
10876
11055
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10877
11056
 
10878
11057
  this.on(this.ON_AUDIO_STREAM, stream => {
10879
- logger$2.info('on room audio stream');
11058
+ logger$3.info('on room audio stream');
10880
11059
 
10881
11060
  this.audioStream = stream;
10882
- if (document.createElement) {
10883
- // $FlowFixMe
10884
- let roomAudioElement = document.getElementById('audio-room');
10885
- if (!this.roomAudioElement) {
10886
- roomAudioElement = document.createElement('audio');
10887
- // $FlowFixMe
10888
- document.body.appendChild(roomAudioElement);
10889
- }
10890
- if (!roomAudioElement) {
10891
- return;
10892
- }
10893
- this.roomAudioElement = roomAudioElement;
11061
+ if (!this.roomAudioElement) {
11062
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11063
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
10894
11064
  this.roomAudioElement.srcObject = stream;
10895
- this.roomAudioElement.autoplay = true;
10896
- this.roomAudioElement.id = 'audio-room';
10897
-
10898
- // $FlowFixMe
10899
- if (this.roomAudioElement.setSinkId) {
10900
- // $FlowFixMe
10901
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
10902
- }
10903
11065
  }
10904
11066
  });
10905
11067
 
10906
11068
  this.on(this.ON_VIDEO_STREAM, (stream, streamId, event, sipSession) => {
10907
- logger$2.info('on room video stream', { streamId });
11069
+ logger$3.info('on room video stream', { streamId });
10908
11070
 
10909
11071
  this._mapMsid(sipSession.body.body);
10910
11072
 
@@ -10919,7 +11081,7 @@ class Room$1 extends Emitter {
10919
11081
  });
10920
11082
 
10921
11083
  this.on(this.ON_REMOVE_STREAM, stream => {
10922
- logger$2.info('on room remove stream');
11084
+ logger$3.info('on room remove stream');
10923
11085
 
10924
11086
  const participant = this.participants.find(someParticipant =>
10925
11087
  someParticipant.streams.find(someStream => someStream && someStream.id === stream.id));
@@ -10974,6 +11136,9 @@ class Room$1 extends Emitter {
10974
11136
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10975
11137
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10976
11138
 
11139
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11140
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11141
+
10977
11142
  // Phone events
10978
11143
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
10979
11144
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -10984,15 +11149,15 @@ class Room$1 extends Emitter {
10984
11149
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
10985
11150
  }
10986
11151
 
10987
- _onMessage(message ) {
11152
+ _onMessage(message ) {
10988
11153
  if (message.method !== 'MESSAGE') {
10989
- return;
11154
+ return null;
10990
11155
  }
10991
11156
  let body;
10992
11157
  try {
10993
11158
  body = JSON.parse(message.body);
10994
11159
  } catch (e) {
10995
- return;
11160
+ return null;
10996
11161
  }
10997
11162
 
10998
11163
  switch (body.type) {
@@ -11011,6 +11176,8 @@ class Room$1 extends Emitter {
11011
11176
  }
11012
11177
 
11013
11178
  this.eventEmitter.emit(this.ON_MESSAGE, body);
11179
+
11180
+ return body;
11014
11181
  }
11015
11182
 
11016
11183
  _onChat(content ) {
@@ -11046,7 +11213,7 @@ class Room$1 extends Emitter {
11046
11213
  const requester = this._getParticipantFromCallId(origin.callId);
11047
11214
  if (requester) {
11048
11215
  // @FIXME?: when need to trigger an update on join-in; this is a bit of a hack
11049
- logger$2.info('trigger room requester status', { origin });
11216
+ logger$3.info('trigger room requester status', { origin });
11050
11217
  requester.triggerUpdate('REQUESTER_UPDATE');
11051
11218
  }
11052
11219
  break;
@@ -11075,25 +11242,26 @@ class Room$1 extends Emitter {
11075
11242
  const session = Wazo.Auth.getSession();
11076
11243
  let participants = [];
11077
11244
 
11078
- // @TODO: we could use a better function name here
11079
- const isJoining = part => {
11080
- this.__associateStreams(part);
11081
- // @VALIDATE: no need to publicize ourselves, no?
11082
- if (part instanceof RemoteParticipant) {
11083
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
11084
- }
11085
- };
11086
-
11087
11245
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
11088
11246
  if (participant.user_uuid === session.uuid) {
11089
- logger$2.info('room current user joined');
11247
+ logger$3.info('room current user joined');
11090
11248
 
11091
11249
  // Retrieve participants via an API calls
11092
11250
  const conferenceId = this.sourceId || payload.data.conference_id;
11093
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11094
- logger$2.info('fetching conference participants', { conferenceId });
11251
+ let response;
11252
+ try {
11253
+ if (this.meetingUuid) {
11254
+ logger$3.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
11255
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
11256
+ } else {
11257
+ logger$3.info('fetching conference participants', { conferenceId });
11258
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11259
+ }
11260
+ } catch (e) {
11261
+ logger$3.error('room participants fetching, error', e);
11262
+ }
11095
11263
  if (response) {
11096
- logger$2.info('conference participants fetched', { nb: response.items.length });
11264
+ logger$3.info('conference participants fetched', { nb: response.items.length });
11097
11265
  participants = response.items.map(item => {
11098
11266
  const isMe = item.call_id === this.callId;
11099
11267
 
@@ -11106,25 +11274,10 @@ class Room$1 extends Emitter {
11106
11274
 
11107
11275
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
11108
11276
  if (!this.localParticipant && localParticipant) {
11109
- this.localParticipant = localParticipant;
11110
-
11111
- const localVideoStream = this._getLocalVideoStream();
11112
- if (localVideoStream) {
11113
- this._saveLocalVideoStream(localVideoStream);
11114
- }
11115
-
11116
- this.connected = true;
11117
-
11118
- // we're in the room, now let's request everyone's status
11119
- if (this.localParticipant) {
11120
- this.sendSignal({
11121
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11122
- origin: this.localParticipant.getStatus(),
11123
- });
11124
- }
11277
+ this._onLocalParticipantJoined(localParticipant);
11125
11278
  }
11126
11279
 
11127
- participants.forEach(someParticipant => isJoining(someParticipant));
11280
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
11128
11281
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
11129
11282
  }
11130
11283
 
@@ -11135,16 +11288,45 @@ class Room$1 extends Emitter {
11135
11288
  ? new Wazo.RemoteParticipant(this, participant)
11136
11289
  : null;
11137
11290
 
11138
- logger$2.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11291
+ logger$3.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11139
11292
 
11140
11293
  if (remoteParticipant) {
11141
11294
  this.participants.push(remoteParticipant);
11142
- isJoining(remoteParticipant);
11295
+ this._isParticipantJoining(remoteParticipant);
11143
11296
  }
11144
11297
 
11145
11298
  return remoteParticipant;
11146
11299
  }
11147
11300
 
11301
+ _onLocalParticipantJoined(localParticipant ) {
11302
+ this.localParticipant = localParticipant;
11303
+
11304
+ const localVideoStream = this._getLocalVideoStream();
11305
+ if (localVideoStream) {
11306
+ this._saveLocalVideoStream(localVideoStream);
11307
+ }
11308
+
11309
+ this.connected = true;
11310
+
11311
+ localParticipant.broadcastStatus();
11312
+
11313
+ // we're in the room, now let's request everyone's status
11314
+ if (this.localParticipant) {
11315
+ this.sendSignal({
11316
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11317
+ origin: this.localParticipant.getStatus(),
11318
+ });
11319
+ }
11320
+ }
11321
+
11322
+ _isParticipantJoining(participant ) {
11323
+ this.__associateStreams(participant);
11324
+ // @VALIDATE: no need to publicize ourselves, no?
11325
+ if (participant instanceof RemoteParticipant) {
11326
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
11327
+ }
11328
+ }
11329
+
11148
11330
  _saveLocalVideoStream(stream ) {
11149
11331
  const { localParticipant } = this;
11150
11332
 
@@ -11190,9 +11372,11 @@ class Room$1 extends Emitter {
11190
11372
  _onParticipantTrackUpdate(oldParticipant , update ) {
11191
11373
  const newParticipant = oldParticipant;
11192
11374
 
11193
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11375
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11194
11376
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
11195
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
11377
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
11378
+ const stream = pc.getRemoteStreams().find(someStream =>
11379
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
11196
11380
 
11197
11381
  if (update === 'downgrade') {
11198
11382
  newParticipant.streams = [];
@@ -11222,15 +11406,42 @@ class Room$1 extends Emitter {
11222
11406
  return;
11223
11407
  }
11224
11408
 
11225
- if (this._unassociatedVideoStreams[trackId]) {
11409
+ const streamId = this._getStreamIdFrTrackId(trackId);
11410
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
11411
+ const stream = this._unassociatedVideoStreams[key];
11412
+
11413
+ if (stream) {
11226
11414
  // Try to associate stream
11227
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
11415
+ this._associateStreamTo(stream, participant);
11228
11416
 
11229
- delete this._unassociatedVideoStreams[trackId];
11417
+ delete this._unassociatedVideoStreams[key];
11230
11418
  delete this._unassociatedParticipants[participant.callId];
11231
11419
  }
11232
11420
  }
11233
11421
 
11422
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
11423
+ // Find by trackId
11424
+ if (trackId in this._unassociatedVideoStreams) {
11425
+ return trackId;
11426
+ }
11427
+
11428
+ // Find by streamId
11429
+ if (streamId && streamId in this._unassociatedVideoStreams) {
11430
+ return streamId;
11431
+ }
11432
+
11433
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
11434
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11435
+ stream && stream.id === streamId);
11436
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11437
+ }
11438
+
11439
+ _getStreamIdFrTrackId(trackId ) {
11440
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
11441
+
11442
+ return mapping ? mapping.streamId : null;
11443
+ }
11444
+
11234
11445
  _associateStreamTo(rawStream , participant ) {
11235
11446
  const stream = new Wazo.Stream(rawStream, participant);
11236
11447
  participant.streams.push(stream);
@@ -11254,7 +11465,141 @@ class Room$1 extends Emitter {
11254
11465
 
11255
11466
  //
11256
11467
 
11257
- class LocalParticipant extends Participant {
11468
+ const logger$2 = IssueReporter$1.loggerFor('sdk-sip-room');
11469
+
11470
+ class SipRoom extends Room$1 {
11471
+
11472
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
11473
+ logger$2.info('connecting to sip room', { extension, audioOnly, room: !!room });
11474
+
11475
+ if (!room) {
11476
+ await Wazo.Phone.connect();
11477
+
11478
+ const withCamera = constraints && !!constraints.video;
11479
+
11480
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
11481
+ // eslint-disable-next-line no-param-reassign
11482
+ room = new SipRoom(callSession, extension, null, null, extra);
11483
+ }
11484
+
11485
+ if (room && room.callSession && room.callSession.call) {
11486
+ room.setCallId(room.callSession.call.id);
11487
+ }
11488
+
11489
+ logger$2.info('connected to room', {
11490
+ extension: room.extension,
11491
+ });
11492
+
11493
+ return room;
11494
+ }
11495
+
11496
+ mute() {
11497
+ logger$2.info('mute sip room');
11498
+
11499
+ Wazo.Phone.mute(this.callSession, false);
11500
+
11501
+ this.sendMuteStatus();
11502
+ }
11503
+
11504
+ unmute() {
11505
+ logger$2.info('unmute sip room');
11506
+
11507
+ Wazo.Phone.unmute(this.callSession, false);
11508
+
11509
+ this.sendUnMuteStatus();
11510
+ }
11511
+
11512
+ getLocalGuestName() {
11513
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
11514
+ }
11515
+
11516
+ // Overridden to not listen to websocket messages
11517
+ _transferEvents() {
11518
+ // Phone events
11519
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
11520
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
11521
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
11522
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
11523
+
11524
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
11525
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
11526
+ }
11527
+
11528
+ _onMessage(message ) {
11529
+ // eslint-disable-next-line no-underscore-dangle
11530
+ const body = super._onMessage(message);
11531
+ if (!body) {
11532
+ return;
11533
+ }
11534
+
11535
+ const getChannel = () => body.channels[0];
11536
+
11537
+ switch (body.type) {
11538
+ case 'ConfbridgeWelcome':
11539
+ body.channels.forEach(channel => {
11540
+ this._onParticipantJoined(channel);
11541
+ });
11542
+
11543
+ break;
11544
+ case 'ConfbridgeJoin': {
11545
+ const channel = getChannel();
11546
+ this._onParticipantJoined(channel);
11547
+ break;
11548
+ }
11549
+ case 'ConfbridgeLeave': {
11550
+ const channel = getChannel();
11551
+ this._onParticipantLeft({
11552
+ data: {
11553
+ call_id: channel.id,
11554
+ },
11555
+ });
11556
+ break;
11557
+ }
11558
+ }
11559
+ }
11560
+
11561
+ async _onParticipantJoined(channel ) {
11562
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
11563
+ const callId = channel.id;
11564
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
11565
+ const name = channel.caller ? channel.caller.name : null;
11566
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
11567
+ const participant = new ParticipantClass(this, {
11568
+ caller_id_name: name,
11569
+ call_id: callId,
11570
+ }, extra);
11571
+
11572
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
11573
+ if (participantIdx !== -1 && name) {
11574
+ this.participants[participantIdx].name = name;
11575
+ return;
11576
+ }
11577
+
11578
+ if (isLocal) {
11579
+ // Should be updated by the Wazo WS but we don't have it for now
11580
+ if (this.callSession) {
11581
+ this.callSession.ringing = false;
11582
+ }
11583
+
11584
+ this._onLocalParticipantJoined(participant);
11585
+
11586
+ // Give some time for the stream to be updated
11587
+ setTimeout(() => {
11588
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
11589
+ }, 1000);
11590
+ }
11591
+
11592
+ this.participants.push(participant);
11593
+
11594
+ this._isParticipantJoining(participant);
11595
+
11596
+ return participant;
11597
+ }
11598
+
11599
+ _getCurrentSipCallIs() {
11600
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11601
+ }
11602
+
11258
11603
  }
11259
11604
 
11260
11605
  /* global document */
@@ -11307,9 +11652,7 @@ class Stream {
11307
11652
  return false;
11308
11653
  }
11309
11654
 
11310
- // With canvas track (used to fake upgrade in conference), we don't have a width
11311
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
11312
- && track.readyState !== 'ended' && 'width' in track.getSettings());
11655
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
11313
11656
  }
11314
11657
 
11315
11658
  get id() {
@@ -12210,6 +12553,7 @@ const Wazo = {
12210
12553
  Phone: Phone$1,
12211
12554
  Websocket: Websocket$1,
12212
12555
  Room: Room$1,
12556
+ SipRoom,
12213
12557
  RemoteParticipant,
12214
12558
  LocalParticipant,
12215
12559
  Stream,
@@ -12246,6 +12590,7 @@ const Wazo = {
12246
12590
  IndirectTransfer,
12247
12591
  SwitchboardCall,
12248
12592
  WebRTCPhone,
12593
+ Meeting,
12249
12594
  },
12250
12595
 
12251
12596
  // Api
@@ -12432,13 +12777,18 @@ class Phone extends Emitter {
12432
12777
  return adHocConference.start();
12433
12778
  }
12434
12779
 
12435
- mute(callSession ) {
12436
- this.muteViaAPI(callSession);
12780
+ mute(callSession , withApi = true) {
12781
+ if (withApi) {
12782
+ this.muteViaAPI(callSession);
12783
+ }
12784
+
12437
12785
  return this.phone && this.phone.mute(callSession);
12438
12786
  }
12439
12787
 
12440
- unmute(callSession ) {
12441
- this.unmuteViaAPI(callSession);
12788
+ unmute(callSession , withApi = true) {
12789
+ if (withApi) {
12790
+ this.unmuteViaAPI(callSession);
12791
+ }
12442
12792
 
12443
12793
  return this.phone && this.phone.unmute(callSession);
12444
12794
  }
@@ -12544,6 +12894,10 @@ class Phone extends Emitter {
12544
12894
  return this.phone && this.phone.hasLocalVideo(callSession);
12545
12895
  }
12546
12896
 
12897
+ hasALocalVideoTrack(callSession ) {
12898
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
12899
+ }
12900
+
12547
12901
  // @Deprecated
12548
12902
  getLocalMediaStream(callSession ) {
12549
12903
  logger.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');