@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
@@ -906,7 +906,7 @@ var IssueReporter$1 = new IssueReporter();
906
906
 
907
907
  const methods = ['head', 'get', 'post', 'put', 'delete'];
908
908
 
909
- const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
909
+ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
910
910
 
911
911
  // Use a function here to be able to mock it in tests
912
912
  const realFetch = () => {
@@ -1045,7 +1045,7 @@ class ApiRequester {
1045
1045
  };
1046
1046
 
1047
1047
  if (this.refreshTokenPromise) {
1048
- logger$b.info('A token is already refreshing, waiting ...', { url });
1048
+ logger$c.info('A token is already refreshing, waiting ...', { url });
1049
1049
  await this.refreshTokenPromise;
1050
1050
  }
1051
1051
 
@@ -1065,7 +1065,7 @@ class ApiRequester {
1065
1065
  return promise.then(async (err ) => {
1066
1066
  // Check if the token is still valid
1067
1067
  if (firstCall && this._checkTokenExpired(response, err)) {
1068
- logger$b.warn('token expired', { error: err.reason });
1068
+ logger$c.warn('token expired', { error: err.reason });
1069
1069
  // Replay the call after refreshing the token
1070
1070
  return this._replayWithNewToken(err, path, method, body, headers, parse);
1071
1071
  }
@@ -1075,7 +1075,7 @@ class ApiRequester {
1075
1075
  : exceptionClass.fromResponse(err, response.status);
1076
1076
 
1077
1077
  if (this.shouldLogErrors) {
1078
- logger$b.error('API error', error);
1078
+ logger$c.error('API error', error);
1079
1079
  }
1080
1080
 
1081
1081
  throw error;
@@ -1085,7 +1085,7 @@ class ApiRequester {
1085
1085
  return newParse(response, isJson);
1086
1086
  }).catch(error => {
1087
1087
  if (this.shouldLogErrors) {
1088
- logger$b.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
1088
+ logger$c.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
1089
1089
  }
1090
1090
 
1091
1091
  throw error;
@@ -1113,13 +1113,13 @@ class ApiRequester {
1113
1113
  ) {
1114
1114
  const isTokenNotFound = this._isTokenNotFound(err);
1115
1115
  let newPath = path;
1116
- logger$b.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
1116
+ logger$c.info('refreshing token', { inProgress: !!this.refreshTokenPromise });
1117
1117
 
1118
1118
  this.refreshTokenPromise = this.refreshTokenPromise || this.refreshTokenCallback();
1119
1119
 
1120
1120
  return this.refreshTokenPromise.then(() => {
1121
1121
  this.refreshTokenPromise = null;
1122
- logger$b.info('token refreshed', { isTokenNotFound });
1122
+ logger$c.info('token refreshed', { isTokenNotFound });
1123
1123
  if (isTokenNotFound) {
1124
1124
  const pathParts = path.split('/');
1125
1125
  pathParts.pop();
@@ -3050,6 +3050,65 @@ class ExternalApp {
3050
3050
  }
3051
3051
  }
3052
3052
 
3053
+ //
3054
+
3055
+
3056
+
3057
+
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+ class Meeting {
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+ static parse(plain ) {
3077
+ return new Meeting({
3078
+ guestSipAuthorization: plain.guest_sip_authorization,
3079
+ hostname: plain.hostname,
3080
+ name: plain.name,
3081
+ ownerUuids: plain.owner_uuids,
3082
+ port: plain.port,
3083
+ uuid: plain.uuid,
3084
+ number: plain.number,
3085
+ });
3086
+ }
3087
+
3088
+ static newFrom(meeting ) {
3089
+ return newFrom(meeting, Meeting);
3090
+ }
3091
+
3092
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
3093
+ this.guestSipAuthorization = guestSipAuthorization;
3094
+ this.hostname = hostname;
3095
+ this.name = name;
3096
+ this.ownerUuids = ownerUuids;
3097
+ this.port = port;
3098
+ this.uuid = uuid;
3099
+ this.number = number;
3100
+
3101
+ // Useful to compare instead of instanceof with minified code
3102
+ this.type = 'Meeting';
3103
+ }
3104
+
3105
+ getGuestSipCredentials() {
3106
+ // eslint-disable-next-line no-undef
3107
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
3108
+ return { username, secret };
3109
+ }
3110
+ }
3111
+
3053
3112
  /* */
3054
3113
 
3055
3114
  var confdMethods = (client , baseUrl ) => ({
@@ -3114,6 +3173,18 @@ var confdMethods = (client , baseUrl ) => ({
3114
3173
  return null;
3115
3174
  }
3116
3175
  },
3176
+
3177
+ createMyMeeting: (name ) =>
3178
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
3179
+
3180
+ deleteMyMeeting: (meetingUuid ) =>
3181
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
3182
+
3183
+ getMeeting: (meetingUuid ) =>
3184
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
3185
+
3186
+ guestGetMeeting: (meetingUuid ) =>
3187
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
3117
3188
  });
3118
3189
 
3119
3190
  //
@@ -3518,7 +3589,11 @@ class CallLog {
3518
3589
  answered: plain.answered,
3519
3590
  callDirection: plain.call_direction,
3520
3591
  destination: {
3521
- extension: plain.requested_extension || plain.destination_extension,
3592
+ // @TEMP: Temporarily assuming empty numbers are meetings
3593
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3594
+ extension: plain.requested_extension
3595
+ || plain.destination_extension
3596
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3522
3597
  name: plain.requested_name || plain.destination_name || '',
3523
3598
  },
3524
3599
  source: {
@@ -3534,27 +3609,11 @@ class CallLog {
3534
3609
  }
3535
3610
 
3536
3611
  static parseNew(plain , session ) {
3537
- return new CallLog({
3538
- answer: plain.answer ? moment(plain.answer).toDate() : null,
3539
- answered: plain.answered,
3540
- callDirection: plain.call_direction,
3541
- destination: {
3542
- extension: plain.requested_extension || plain.destination_extension,
3543
- name: plain.requested_name || plain.destination_name || '',
3544
- },
3545
- source: {
3546
- extension: plain.source_extension,
3547
- name: plain.source_name,
3548
- },
3549
- id: plain.id,
3550
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3551
- start: moment(plain.start).toDate(),
3552
- end: plain.end ? moment(plain.end).toDate() : null,
3553
- recordings: Recording.parseMany(plain.recordings),
3554
- // @TODO: FIXME add verification declined vs missed call
3555
- newMissedCall: session
3556
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3557
- });
3612
+ const callLog = CallLog.parse(plain);
3613
+ // @TODO: FIXME add verification declined vs missed call
3614
+ callLog.newMissedCall = session
3615
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3616
+ return callLog;
3558
3617
  }
3559
3618
 
3560
3619
  static newFrom(profile ) {
@@ -3819,7 +3878,7 @@ const TRANSFER_FLOW_BLIND = 'blind';
3819
3878
 
3820
3879
  // const MINIMUM_WAZO_ENGINE_VERSION_FOR_CTI_HOLD = '20.11';
3821
3880
 
3822
- const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3881
+ const logger$b = IssueReporter$1 ? IssueReporter$1.loggerFor('cti-phone') : console;
3823
3882
 
3824
3883
  class CTIPhone extends Emitter {
3825
3884
 
@@ -3832,7 +3891,7 @@ class CTIPhone extends Emitter {
3832
3891
 
3833
3892
  constructor(session , isMobile = false, callbackAllLines = false) {
3834
3893
  super();
3835
- logger$a.info('CTI Phone created');
3894
+ logger$b.info('CTI Phone created');
3836
3895
  this.session = session;
3837
3896
  this.isMobile = isMobile;
3838
3897
  this.callbackAllLines = callbackAllLines;
@@ -3893,7 +3952,7 @@ class CTIPhone extends Emitter {
3893
3952
  }
3894
3953
 
3895
3954
  async makeCall(number , line ) {
3896
- logger$a.info('make CTI call', { number });
3955
+ logger$b.info('make CTI call', { number });
3897
3956
 
3898
3957
  if (!number) {
3899
3958
  return null;
@@ -3916,7 +3975,7 @@ class CTIPhone extends Emitter {
3916
3975
  if (!callSession) {
3917
3976
  return Promise.resolve(null);
3918
3977
  }
3919
- logger$a.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3978
+ logger$b.info('accept CTI call', { callId: callSession.getId(), number: callSession.number });
3920
3979
 
3921
3980
  if (!this.currentCall) {
3922
3981
  this.currentCall = callSession.call;
@@ -3929,7 +3988,7 @@ class CTIPhone extends Emitter {
3929
3988
  if (!callSession) {
3930
3989
  return;
3931
3990
  }
3932
- logger$a.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
3991
+ logger$b.info('end current CTI call', { callId: callSession.getId(), number: callSession.number });
3933
3992
 
3934
3993
  this.currentCall = undefined;
3935
3994
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3939,7 +3998,7 @@ class CTIPhone extends Emitter {
3939
3998
  if (!callSession) {
3940
3999
  return Promise.resolve(false);
3941
4000
  }
3942
- logger$a.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
4001
+ logger$b.info('hangup CTI call', { callId: callSession.getId(), number: callSession.number });
3943
4002
 
3944
4003
  try {
3945
4004
  await CallApi.cancelCall(callSession);
@@ -3950,7 +4009,7 @@ class CTIPhone extends Emitter {
3950
4009
  this.eventEmitter.emit('onCallEnded', callSession);
3951
4010
  return true;
3952
4011
  } catch (e) {
3953
- logger$a.error('hangup CTI call, error', e);
4012
+ logger$b.error('hangup CTI call, error', e);
3954
4013
 
3955
4014
  this.eventEmitter.emit('onCallFailed', callSession);
3956
4015
  return false;
@@ -3963,7 +4022,7 @@ class CTIPhone extends Emitter {
3963
4022
  if (!callSession) {
3964
4023
  return;
3965
4024
  }
3966
- logger$a.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
4025
+ logger$b.info('reject CTI call', { callId: callSession.getId(), number: callSession.number });
3967
4026
 
3968
4027
  await CallApi.cancelCall(callSession);
3969
4028
  this.eventEmitter.emit('onCallEnded', callSession);
@@ -3973,7 +4032,7 @@ class CTIPhone extends Emitter {
3973
4032
  if (!callSession) {
3974
4033
  return;
3975
4034
  }
3976
- logger$a.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
4035
+ logger$b.info('transfer CTI call', { callId: callSession.getId(), number: callSession.number, to: number });
3977
4036
 
3978
4037
  await CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_BLIND);
3979
4038
  }
@@ -3984,19 +4043,19 @@ class CTIPhone extends Emitter {
3984
4043
  if (!callSession) {
3985
4044
  return;
3986
4045
  }
3987
- logger$a.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
4046
+ logger$b.info('indirect CTI transfer', { callId: callSession.getId(), number: callSession.number, to: number });
3988
4047
 
3989
4048
  return CallApi.transferCall(callSession.callId, number, TRANSFER_FLOW_ATTENDED);
3990
4049
  }
3991
4050
 
3992
4051
  async cancelCTIIndirectTransfer(transferId ) {
3993
- logger$a.info('cancel CTI transfer', { transferId });
4052
+ logger$b.info('cancel CTI transfer', { transferId });
3994
4053
 
3995
4054
  return CallApi.cancelCallTransfer(transferId);
3996
4055
  }
3997
4056
 
3998
4057
  async confirmCTIIndirectTransfer(transferId ) {
3999
- logger$a.info('confirm CTI transfer', { transferId });
4058
+ logger$b.info('confirm CTI transfer', { transferId });
4000
4059
 
4001
4060
  return CallApi.confirmCallTransfer(transferId);
4002
4061
  }
@@ -4005,19 +4064,19 @@ class CTIPhone extends Emitter {
4005
4064
  if (!callSession) {
4006
4065
  return;
4007
4066
  }
4008
- logger$a.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4067
+ logger$b.info('send CTI key', { callId: callSession.getId(), number: callSession.number, digits });
4009
4068
 
4010
4069
  return CallApi.sendDTMF(callSession.callId, digits);
4011
4070
  }
4012
4071
 
4013
4072
  onConnectionMade() {
4014
- logger$a.info('on CTI connection made');
4073
+ logger$b.info('on CTI connection made');
4015
4074
 
4016
4075
  this.eventEmitter.emit('onCallAccepted');
4017
4076
  }
4018
4077
 
4019
4078
  async close() {
4020
- logger$a.info('CTI close');
4079
+ logger$b.info('CTI close');
4021
4080
 
4022
4081
  return Promise.resolve();
4023
4082
  }
@@ -4026,7 +4085,7 @@ class CTIPhone extends Emitter {
4026
4085
  if (!callSession) {
4027
4086
  return;
4028
4087
  }
4029
- logger$a.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4088
+ logger$b.info('CTI hold', { callId: callSession.getId(), number: callSession.number });
4030
4089
 
4031
4090
  return CallApi.hold(callSession.callId);
4032
4091
  }
@@ -4035,7 +4094,7 @@ class CTIPhone extends Emitter {
4035
4094
  if (!callSession) {
4036
4095
  return;
4037
4096
  }
4038
- logger$a.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4097
+ logger$b.info('CTI resume', { callId: callSession.getId(), number: callSession.number });
4039
4098
 
4040
4099
  return CallApi.resume(callSession.callId);
4041
4100
  }
@@ -4044,7 +4103,7 @@ class CTIPhone extends Emitter {
4044
4103
  if (!callSession) {
4045
4104
  return;
4046
4105
  }
4047
- logger$a.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4106
+ logger$b.info('CTI mute', { callId: callSession.getId(), number: callSession.number });
4048
4107
 
4049
4108
  return CallApi.mute(callSession.callId);
4050
4109
  }
@@ -4053,7 +4112,7 @@ class CTIPhone extends Emitter {
4053
4112
  if (!callSession) {
4054
4113
  return;
4055
4114
  }
4056
- logger$a.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4115
+ logger$b.info('CTI unmute', { callId: callSession.getId(), number: callSession.number });
4057
4116
 
4058
4117
  return CallApi.unmute(callSession.callId);
4059
4118
  }
@@ -4699,6 +4758,9 @@ var calldMethods = (client , baseUrl ) => ({
4699
4758
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4700
4759
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4701
4760
 
4761
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4762
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4763
+
4702
4764
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4703
4765
 
4704
4766
  mute: (callId ) =>
@@ -5052,7 +5114,7 @@ const AGENTD_VERSION = '1.0';
5052
5114
  const WEBHOOKD_VERSION = '1.0';
5053
5115
  const AMID_VERSION = '1.0';
5054
5116
 
5055
- const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5117
+ const logger$a = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
5056
5118
 
5057
5119
  class ApiClient {
5058
5120
 
@@ -5104,12 +5166,12 @@ class ApiClient {
5104
5166
  }
5105
5167
 
5106
5168
  async forceRefreshToken() {
5107
- logger$9.info('forcing refresh token, calling callback');
5169
+ logger$a.info('forcing refresh token, calling callback');
5108
5170
  return this.refreshTokenCallback();
5109
5171
  }
5110
5172
 
5111
5173
  async refreshTokenCallback() {
5112
- logger$9.info('refresh token callback called', {
5174
+ logger$a.info('refresh token callback called', {
5113
5175
  refreshToken: this.refreshToken,
5114
5176
  refreshBackend: this.refreshBackend,
5115
5177
  refreshExpiration: this.refreshExpiration,
@@ -5127,7 +5189,7 @@ class ApiClient {
5127
5189
  this.isMobile,
5128
5190
  );
5129
5191
 
5130
- logger$9.info('token refreshed', { token: session.token });
5192
+ logger$a.info('token refreshed', { token: session.token });
5131
5193
 
5132
5194
  if (this.onRefreshToken) {
5133
5195
  this.onRefreshToken(session.token, session);
@@ -5600,7 +5662,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5600
5662
  .then(() => {
5601
5663
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5602
5664
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5603
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5665
+ if (this.peerConnection.addTransceiver) {
5666
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5667
+ }
5604
5668
  }
5605
5669
  })
5606
5670
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -5627,12 +5691,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5627
5691
  };
5628
5692
  })
5629
5693
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
5630
- .then((sessionDescription) => {
5631
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
5632
- this.localMediaStreamConstraints = options.constraints;
5633
-
5634
- return sessionDescription;
5635
- })
5636
5694
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
5637
5695
  .catch((error) => {
5638
5696
  wazoLogger.error('error when creating media', error);
@@ -5827,6 +5885,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5827
5885
 
5828
5886
  // set the transceiver direction to the answer direction
5829
5887
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5888
+ if (transceiver.stopped) {
5889
+ return;
5890
+ }
5830
5891
  if (transceiver.direction /* guarding, but should always be true */) {
5831
5892
  const { receiver } = transceiver;
5832
5893
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -5871,10 +5932,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5871
5932
  if (kind !== 'audio' && kind !== 'video') {
5872
5933
  throw new Error(`Unknown new track kind ${kind}.`);
5873
5934
  }
5874
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5935
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
5936
+ otherSender.track && otherSender.track.kind === kind);
5875
5937
 
5876
5938
  // Do not reuse sender video tracks in SFU
5877
5939
  if (sender && (!sfu || newTrack.kind === 'audio')) {
5940
+ if (sender.track) {
5941
+ // eslint-disable-next-line no-param-reassign
5942
+ newTrack.enabled = sender.track.enabled;
5943
+ }
5878
5944
  trackUpdates.push(
5879
5945
  new Promise((resolve) => {
5880
5946
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5908,7 +5974,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5908
5974
  // Review: could make streamless tracks a configurable option?
5909
5975
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
5910
5976
  try {
5911
- pc.addTrack(newTrack, localStream);
5977
+ if (pc.addTrack) {
5978
+ pc.addTrack(newTrack, localStream);
5979
+ } else {
5980
+ pc.addStream(localStream);
5981
+ }
5912
5982
  } catch (error) {
5913
5983
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
5914
5984
  throw error;
@@ -6044,7 +6114,7 @@ const DEFAULT_ICE_TIMEOUT = 3000;
6044
6114
  const SEND_STATS_DELAY = 5000;
6045
6115
 
6046
6116
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
6047
- const logger$8 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6117
+ const logger$9 = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-client') : console;
6048
6118
  const statsLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-stats') : console;
6049
6119
 
6050
6120
  // events
@@ -6090,6 +6160,7 @@ const MAX_REGISTER_TRIES = 10;
6090
6160
 
6091
6161
 
6092
6162
 
6163
+
6093
6164
 
6094
6165
 
6095
6166
 
@@ -6116,6 +6187,7 @@ class WebRTCClient extends Emitter {
6116
6187
 
6117
6188
 
6118
6189
 
6190
+
6119
6191
 
6120
6192
  // sugar
6121
6193
 
@@ -6154,6 +6226,8 @@ class WebRTCClient extends Emitter {
6154
6226
  super();
6155
6227
  this.uaConfigOverrides = uaConfigOverrides;
6156
6228
  this.config = config;
6229
+ this.skipRegister = config.skipRegister;
6230
+
6157
6231
  this._buildConfig(config, session).then((newConfig ) => {
6158
6232
  this.config = newConfig;
6159
6233
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -6209,13 +6283,13 @@ class WebRTCClient extends Emitter {
6209
6283
 
6210
6284
  createUserAgent(configOverrides ) {
6211
6285
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
6212
- logger$8.info('sdk webrtc, creating UA', { webRTCConfiguration });
6286
+ logger$9.info('sdk webrtc, creating UA', { webRTCConfiguration });
6213
6287
 
6214
6288
  webRTCConfiguration.delegate = {
6215
6289
  onConnect: this.onConnect.bind(this),
6216
6290
  onDisconnect: this.onDisconnect.bind(this),
6217
6291
  onInvite: (invitation ) => {
6218
- logger$8.info('sdk webrtc on invite', {
6292
+ logger$9.info('sdk webrtc on invite', {
6219
6293
  method: 'delegate.onInvite',
6220
6294
  id: invitation.id,
6221
6295
  remoteURI: invitation.remoteURI,
@@ -6258,7 +6332,7 @@ class WebRTCClient extends Emitter {
6258
6332
  }
6259
6333
 
6260
6334
  onConnect() {
6261
- logger$8.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6335
+ logger$9.info('sdk webrtc connected', { method: 'delegate.onConnect' });
6262
6336
  this.eventEmitter.emit(CONNECTED);
6263
6337
  if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
6264
6338
  this.registerer.waitingToggle(false);
@@ -6267,7 +6341,7 @@ class WebRTCClient extends Emitter {
6267
6341
  }
6268
6342
 
6269
6343
  async onDisconnect(error ) {
6270
- logger$8.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6344
+ logger$9.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
6271
6345
  this.connectionPromise = null;
6272
6346
  // The UA will attempt to reconnect automatically when an error occurred
6273
6347
  this.eventEmitter.emit(DISCONNECTED, error);
@@ -6281,40 +6355,48 @@ class WebRTCClient extends Emitter {
6281
6355
  }
6282
6356
 
6283
6357
  register(tries = 0) {
6284
- logger$8.info('sdk webrtc registering...', {
6358
+ const logInfo = {
6285
6359
  userAgent: !!this.userAgent,
6286
6360
  registered: this.isRegistered(),
6287
6361
  connectionPromise: !!this.connectionPromise,
6288
6362
  registerer: !!this.registerer,
6289
6363
  waiting: this.registerer && this.registerer.waiting,
6290
6364
  tries,
6291
- });
6365
+ skipRegister: this.skipRegister,
6366
+ };
6367
+
6368
+ if (this.skipRegister) {
6369
+ logger$9.info('sdk webrtc skip register...', logInfo);
6370
+ return Promise.resolve();
6371
+ }
6372
+
6373
+ logger$9.info('sdk webrtc registering...', logInfo);
6292
6374
 
6293
6375
  if (!this.userAgent) {
6294
- logger$8.info('sdk webrtc recreating User Agent');
6376
+ logger$9.info('sdk webrtc recreating User Agent');
6295
6377
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6296
6378
  }
6297
6379
  if (!this.userAgent || this.isRegistered()) {
6298
- logger$8.info('sdk webrtc registering aborted, already registered or no UA can be created');
6380
+ logger$9.info('sdk webrtc registering aborted, already registered or no UA can be created');
6299
6381
  return Promise.resolve();
6300
6382
  }
6301
6383
 
6302
6384
  if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
6303
- logger$8.info('sdk webrtc registering aborted due to a registration in progress.');
6385
+ logger$9.info('sdk webrtc registering aborted due to a registration in progress.');
6304
6386
  return Promise.resolve();
6305
6387
  }
6306
6388
 
6307
6389
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6308
6390
 
6309
6391
  const onRegisterFailed = () => {
6310
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6392
+ logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6311
6393
  this.connectionPromise = null;
6312
6394
  if (this.registerer && this.registerer.waiting) {
6313
6395
  this.registerer.waitingToggle(false);
6314
6396
  }
6315
6397
 
6316
6398
  if (tries <= MAX_REGISTER_TRIES) {
6317
- logger$8.info('sdk webrtc registering, retrying...', { tries });
6399
+ logger$9.info('sdk webrtc registering, retrying...', { tries });
6318
6400
  setTimeout(() => this.register(tries + 1), 300);
6319
6401
  }
6320
6402
  };
@@ -6323,18 +6405,18 @@ class WebRTCClient extends Emitter {
6323
6405
  // Avoid race condition with the close method called just before register and setting userAgent to null
6324
6406
  // during the resolution of the primise.
6325
6407
  if (!this.userAgent) {
6326
- logger$8.info('sdk webrtc recreating User Agent after connection');
6408
+ logger$9.info('sdk webrtc recreating User Agent after connection');
6327
6409
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
6328
6410
  }
6329
6411
 
6330
- logger$8.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6412
+ logger$9.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
6331
6413
  this.registerer = new Registerer(this.userAgent, registerOptions);
6332
6414
  this.connectionPromise = null;
6333
6415
  this._monkeyPatchRegisterer(this.registerer);
6334
6416
 
6335
6417
  // Bind registerer events
6336
6418
  this.registerer.stateChange.addListener(newState => {
6337
- logger$8.info('sdk webrtc registering, state changed', { newState });
6419
+ logger$9.info('sdk webrtc registering, state changed', { newState });
6338
6420
 
6339
6421
  if (newState === RegistererState.Registered && this.registerer
6340
6422
  && this.registerer.state === RegistererState.Registered) {
@@ -6347,7 +6429,7 @@ class WebRTCClient extends Emitter {
6347
6429
  const options = {
6348
6430
  requestDelegate: {
6349
6431
  onReject: response => {
6350
- logger$8.error('sdk webrtc registering, rejected', { response });
6432
+ logger$9.error('sdk webrtc registering, rejected', { response });
6351
6433
 
6352
6434
  onRegisterFailed();
6353
6435
  },
@@ -6355,13 +6437,13 @@ class WebRTCClient extends Emitter {
6355
6437
  };
6356
6438
 
6357
6439
  return this.registerer.register(options).catch((e) => {
6358
- logger$8.error('sdk webrtc registering, error', e);
6440
+ logger$9.error('sdk webrtc registering, error', e);
6359
6441
 
6360
6442
  this.eventEmitter.emit(REGISTRATION_FAILED);
6361
6443
  return e;
6362
6444
  });
6363
6445
  }).catch(error => {
6364
- logger$8.error('sdk webrtc registering, transport error', error);
6446
+ logger$9.error('sdk webrtc registering, transport error', error);
6365
6447
  onRegisterFailed();
6366
6448
  });
6367
6449
  }
@@ -6390,21 +6472,21 @@ class WebRTCClient extends Emitter {
6390
6472
  }
6391
6473
 
6392
6474
  unregister() {
6393
- logger$8.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6475
+ logger$9.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
6394
6476
  if (!this.registerer) {
6395
6477
  return Promise.resolve();
6396
6478
  }
6397
6479
 
6398
6480
  try {
6399
6481
  return this.registerer.unregister().then(() => {
6400
- logger$8.info('sdk webrtc unregistered');
6482
+ logger$9.info('sdk webrtc unregistered');
6401
6483
  this._cleanupRegister();
6402
6484
  }).catch(e => {
6403
- logger$8.error('sdk webrtc unregistering, promise error', e);
6485
+ logger$9.error('sdk webrtc unregistering, promise error', e);
6404
6486
  this._cleanupRegister();
6405
6487
  });
6406
6488
  } catch (e) {
6407
- logger$8.error('sdk webrtc unregistering, error', e);
6489
+ logger$9.error('sdk webrtc unregistering, error', e);
6408
6490
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
6409
6491
  // error when the registerer is in a bad state
6410
6492
  this._cleanupRegister();
@@ -6412,7 +6494,7 @@ class WebRTCClient extends Emitter {
6412
6494
  }
6413
6495
 
6414
6496
  stop() {
6415
- logger$8.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6497
+ logger$9.info('sdk webrtc stop', { userAgent: !!this.userAgent });
6416
6498
  if (!this.userAgent) {
6417
6499
  return Promise.resolve();
6418
6500
  }
@@ -6420,12 +6502,12 @@ class WebRTCClient extends Emitter {
6420
6502
  return this.userAgent.stop().then(() => {
6421
6503
  return this._cleanupRegister();
6422
6504
  }).catch(e => {
6423
- logger$8.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6505
+ logger$9.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
6424
6506
  });
6425
6507
  }
6426
6508
 
6427
6509
  call(number , enableVideo , audioOnly = false, conference = false) {
6428
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6510
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6429
6511
  const inviterOptions = {
6430
6512
  sessionDescriptionHandlerOptionsReInvite: {
6431
6513
  conference,
@@ -6454,7 +6536,7 @@ class WebRTCClient extends Emitter {
6454
6536
  this._onAccepted(session, response.session, true);
6455
6537
  },
6456
6538
  onReject: (response ) => {
6457
- logger$8.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6539
+ logger$9.info('on call rejected', { id: session.id, fromTag: session.fromTag });
6458
6540
  this._stopSendingStats(session);
6459
6541
 
6460
6542
  this.eventEmitter.emit(REJECTED, session, response);
@@ -6476,11 +6558,11 @@ class WebRTCClient extends Emitter {
6476
6558
  }
6477
6559
 
6478
6560
  answer(session , enableVideo ) {
6479
- logger$8.info('sdk webrtc answer call', { id: session.id, enableVideo });
6561
+ logger$9.info('sdk webrtc answer call', { id: session.id, enableVideo });
6480
6562
 
6481
6563
  if (!session || !session.accept) {
6482
6564
  const error = 'No session to answer, or not an invitation';
6483
- logger$8.warn(error);
6565
+ logger$9.warn(error);
6484
6566
  return Promise.reject(new Error(error));
6485
6567
  }
6486
6568
  const options = {
@@ -6490,15 +6572,15 @@ class WebRTCClient extends Emitter {
6490
6572
  return session.accept(options).then(() => {
6491
6573
  if (session.isCanceled) {
6492
6574
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
6493
- logger$8.error(message, { id: session.id });
6575
+ logger$9.error(message, { id: session.id });
6494
6576
  this.onCallEnded(session);
6495
6577
 
6496
6578
  throw new CanceledCallError(message);
6497
6579
  }
6498
- logger$8.info('sdk webrtc answer, accepted.');
6580
+ logger$9.info('sdk webrtc answer, accepted.');
6499
6581
  this._onAccepted(session);
6500
6582
  }).catch(e => {
6501
- logger$8.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6583
+ logger$9.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
6502
6584
 
6503
6585
  throw e;
6504
6586
  });
@@ -6506,7 +6588,7 @@ class WebRTCClient extends Emitter {
6506
6588
 
6507
6589
  hangup(session ) {
6508
6590
  const { state, id } = session;
6509
- logger$8.info('sdk webrtc hangup call', { id, state });
6591
+ logger$9.info('sdk webrtc hangup call', { id, state });
6510
6592
 
6511
6593
  try {
6512
6594
  this._stopSendingStats(session);
@@ -6535,24 +6617,24 @@ class WebRTCClient extends Emitter {
6535
6617
 
6536
6618
  return bye();
6537
6619
  } catch (error) {
6538
- logger$8.warn('sdk webrtc hangup, error', error);
6620
+ logger$9.warn('sdk webrtc hangup, error', error);
6539
6621
  }
6540
6622
 
6541
6623
  return null;
6542
6624
  }
6543
6625
 
6544
6626
  reject(session ) {
6545
- logger$8.info('sdk webrtc reject call', { id: session.id });
6627
+ logger$9.info('sdk webrtc reject call', { id: session.id });
6546
6628
 
6547
6629
  try {
6548
6630
  return session.reject ? session.reject() : session.cancel();
6549
6631
  } catch (e) {
6550
- logger$8.warn('Error when rejecting call', e.message, e.stack);
6632
+ logger$9.warn('Error when rejecting call', e.message, e.stack);
6551
6633
  }
6552
6634
  }
6553
6635
 
6554
6636
  async close() {
6555
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6637
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6556
6638
  this._cleanupMedia();
6557
6639
  this.connectionPromise = null;
6558
6640
 
@@ -6583,7 +6665,7 @@ class WebRTCClient extends Emitter {
6583
6665
  // eg: "INVITE not rejectable in state Completed"
6584
6666
  }
6585
6667
  this.userAgent = null;
6586
- logger$8.info('sdk webrtc client closed');
6668
+ logger$9.info('sdk webrtc client closed');
6587
6669
  }
6588
6670
 
6589
6671
  getNumber(session ) {
@@ -6596,13 +6678,13 @@ class WebRTCClient extends Emitter {
6596
6678
  }
6597
6679
 
6598
6680
  mute(session ) {
6599
- logger$8.info('sdk webrtc mute', { id: session.id });
6681
+ logger$9.info('sdk webrtc mute', { id: session.id });
6600
6682
 
6601
6683
  this._toggleAudio(session, true);
6602
6684
  }
6603
6685
 
6604
6686
  unmute(session ) {
6605
- logger$8.info('sdk webrtc unmute', { id: session.id });
6687
+ logger$9.info('sdk webrtc unmute', { id: session.id });
6606
6688
 
6607
6689
  this._toggleAudio(session, false);
6608
6690
  }
@@ -6619,12 +6701,18 @@ class WebRTCClient extends Emitter {
6619
6701
  }
6620
6702
 
6621
6703
  if (pc.getSenders) {
6704
+ if (!pc.getSenders().length) {
6705
+ return false;
6706
+ }
6622
6707
  pc.getSenders().forEach(sender => {
6623
6708
  if (sender && sender.track && sender.track.kind === 'audio') {
6624
6709
  muted = muted && !sender.track.enabled;
6625
6710
  }
6626
6711
  });
6627
6712
  } else {
6713
+ if (!pc.getLocalStreams().length) {
6714
+ return false;
6715
+ }
6628
6716
  pc.getLocalStreams().forEach(stream => {
6629
6717
  stream.getAudioTracks().forEach(track => {
6630
6718
  muted = muted && !track.enabled;
@@ -6636,20 +6724,20 @@ class WebRTCClient extends Emitter {
6636
6724
  }
6637
6725
 
6638
6726
  toggleCameraOn(session ) {
6639
- logger$8.info('sdk webrtc toggle camera on', { id: session.id });
6727
+ logger$9.info('sdk webrtc toggle camera on', { id: session.id });
6640
6728
 
6641
6729
  this._toggleVideo(session, false);
6642
6730
  }
6643
6731
 
6644
6732
  toggleCameraOff(session ) {
6645
- logger$8.info('sdk webrtc toggle camera off', { id: session.id });
6733
+ logger$9.info('sdk webrtc toggle camera off', { id: session.id });
6646
6734
 
6647
6735
  this._toggleVideo(session, true);
6648
6736
  }
6649
6737
 
6650
6738
  hold(session , isConference = false) {
6651
6739
  const sessionId = this.getSipSessionId(session);
6652
- logger$8.info('sdk webrtc hold', {
6740
+ logger$9.info('sdk webrtc hold', {
6653
6741
  sessionId,
6654
6742
  keys: Object.keys(this.heldSessions),
6655
6743
  pendingReinvite: !!session.pendingReinvite,
@@ -6683,6 +6771,8 @@ class WebRTCClient extends Emitter {
6683
6771
  }
6684
6772
  options.sessionDescriptionHandlerOptions = {
6685
6773
  constraints: options.constraints,
6774
+ hold: true,
6775
+ conference: isConference,
6686
6776
  };
6687
6777
 
6688
6778
  // Send re-INVITE
@@ -6692,7 +6782,7 @@ class WebRTCClient extends Emitter {
6692
6782
  unhold(session , isConference = false) {
6693
6783
  const sessionId = this.getSipSessionId(session);
6694
6784
 
6695
- logger$8.info('sdk webrtc unhold', {
6785
+ logger$9.info('sdk webrtc unhold', {
6696
6786
  sessionId,
6697
6787
  keys: Object.keys(this.heldSessions),
6698
6788
  pendingReinvite: !!session.pendingReinvite,
@@ -6725,6 +6815,8 @@ class WebRTCClient extends Emitter {
6725
6815
  }
6726
6816
  options.sessionDescriptionHandlerOptions = {
6727
6817
  constraints: options.constraints,
6818
+ hold: false,
6819
+ conference: isConference,
6728
6820
  };
6729
6821
 
6730
6822
  // Send re-INVITE
@@ -6783,7 +6875,7 @@ class WebRTCClient extends Emitter {
6783
6875
  return;
6784
6876
  }
6785
6877
 
6786
- logger$8.info('send WebRTC message', { sipId: sipSession.id, contentType });
6878
+ logger$9.info('send WebRTC message', { sipId: sipSession.id, contentType });
6787
6879
 
6788
6880
  try {
6789
6881
  sipSession.message({
@@ -6908,7 +7000,8 @@ class WebRTCClient extends Emitter {
6908
7000
  }
6909
7001
  const sdh = session.sessionDescriptionHandler;
6910
7002
  const pc = sdh.peerConnection;
6911
- const localStream = this.getLocalStream(this.getSipSessionId(session));
7003
+ const sessionId = this.getSipSessionId(session);
7004
+ const localStream = this.getLocalStream(sessionId);
6912
7005
 
6913
7006
  // Release old video stream
6914
7007
  if (localStream) {
@@ -6934,11 +7027,8 @@ class WebRTCClient extends Emitter {
6934
7027
 
6935
7028
  // let's update the local stream
6936
7029
  this.eventEmitter.emit('onVideoInputChange', stream);
6937
- try {
6938
- await sdh.setLocalMediaStream(stream);
6939
- } catch (_) {
6940
- // Nothing to do
6941
- }
7030
+ this.setLocalMediaStream(sessionId, stream);
7031
+
6942
7032
  return stream;
6943
7033
  });
6944
7034
  }
@@ -7150,7 +7240,7 @@ class WebRTCClient extends Emitter {
7150
7240
  }
7151
7241
 
7152
7242
  startHeartbeat() {
7153
- logger$8.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7243
+ logger$9.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
7154
7244
  if (!this.userAgent) {
7155
7245
  this.heartbeat.stop();
7156
7246
  return;
@@ -7163,7 +7253,7 @@ class WebRTCClient extends Emitter {
7163
7253
  }
7164
7254
 
7165
7255
  stopHeartbeat() {
7166
- logger$8.info('sdk webrtc stop heartbeat');
7256
+ logger$9.info('sdk webrtc stop heartbeat');
7167
7257
  this.heartbeat.stop();
7168
7258
  }
7169
7259
 
@@ -7183,7 +7273,7 @@ class WebRTCClient extends Emitter {
7183
7273
  }
7184
7274
 
7185
7275
  attemptReconnection() {
7186
- logger$8.info('attempt reconnection', { userAgent: !!this.userAgent });
7276
+ logger$9.info('attempt reconnection', { userAgent: !!this.userAgent });
7187
7277
  if (!this.userAgent) {
7188
7278
  return;
7189
7279
  }
@@ -7240,9 +7330,11 @@ class WebRTCClient extends Emitter {
7240
7330
  remoteStream.removeTrack(track);
7241
7331
  });
7242
7332
 
7243
- pc.getReceivers().forEach(receiver => {
7244
- remoteStream.addTrack(receiver.track);
7245
- });
7333
+ if (pc.getReceivers) {
7334
+ pc.getReceivers().forEach(receiver => {
7335
+ remoteStream.addTrack(receiver.track);
7336
+ });
7337
+ }
7246
7338
  }
7247
7339
 
7248
7340
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -7277,6 +7369,25 @@ class WebRTCClient extends Emitter {
7277
7369
  return sessionId in this.conferences;
7278
7370
  }
7279
7371
 
7372
+ createAudioElementFor(sessionId ) {
7373
+ const audio = document.createElement('audio');
7374
+ audio.setAttribute('id', `audio-${sessionId}`);
7375
+
7376
+ if (audio.setSinkId && this.audioOutputDeviceId) {
7377
+ audio.setSinkId(this.audioOutputDeviceId);
7378
+ }
7379
+
7380
+ if (document.body) {
7381
+ document.body.appendChild(audio);
7382
+ }
7383
+ this.audioElements[sessionId] = audio;
7384
+
7385
+ audio.volume = this.audioOutputVolume;
7386
+ audio.autoplay = true;
7387
+
7388
+ return audio;
7389
+ }
7390
+
7280
7391
  _onTransportError() {
7281
7392
  this.eventEmitter.emit(TRANSPORT_ERROR);
7282
7393
  this.attemptReconnection();
@@ -7286,7 +7397,7 @@ class WebRTCClient extends Emitter {
7286
7397
  const body = message && typeof message === 'object' ? message.data : message;
7287
7398
  if (body && body.indexOf('200 OK') !== -1) {
7288
7399
  if (this.hasHeartbeat()) {
7289
- logger$8.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7400
+ logger$9.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
7290
7401
 
7291
7402
  this.heartbeat.onHeartbeat();
7292
7403
  if (this.heartbeatCb) {
@@ -7297,7 +7408,7 @@ class WebRTCClient extends Emitter {
7297
7408
  }
7298
7409
 
7299
7410
  async _onHeartbeatTimeout() {
7300
- logger$8.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7411
+ logger$9.info('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
7301
7412
 
7302
7413
  if (this.heartbeatTimeoutCb) {
7303
7414
  this.heartbeatTimeoutCb();
@@ -7309,7 +7420,7 @@ class WebRTCClient extends Emitter {
7309
7420
  try {
7310
7421
  await this.userAgent.transport.disconnect();
7311
7422
  } catch (e) {
7312
- logger$8.error('Transport disconnection after heartbeat timeout, error', e);
7423
+ logger$9.error('Transport disconnection after heartbeat timeout, error', e);
7313
7424
  }
7314
7425
  }
7315
7426
 
@@ -7342,31 +7453,31 @@ class WebRTCClient extends Emitter {
7342
7453
  }
7343
7454
 
7344
7455
  _connectIfNeeded() {
7345
- logger$8.info('connect if needed, checking', { connected: this.isConnected() });
7456
+ logger$9.info('connect if needed, checking', { connected: this.isConnected() });
7346
7457
  if (!this.userAgent) {
7347
- logger$8.info('need to recreate User Agent');
7458
+ logger$9.info('need to recreate User Agent');
7348
7459
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
7349
7460
  }
7350
7461
 
7351
7462
  if (this.isConnected()) {
7352
- logger$8.info('webrtc sdk, already connected');
7463
+ logger$9.info('webrtc sdk, already connected');
7353
7464
  return Promise.resolve();
7354
7465
  }
7355
7466
 
7356
7467
  if (this.isConnecting()) {
7357
- logger$8.info('webrtc sdk, already connecting...');
7468
+ logger$9.info('webrtc sdk, already connecting...');
7358
7469
 
7359
7470
  this.connectionPromise = this.userAgent.transport.connectPromise;
7360
7471
  return this.connectionPromise;
7361
7472
  }
7362
7473
 
7363
7474
  if (this.connectionPromise) {
7364
- logger$8.info('webrtc sdk, connection promise connecting...');
7475
+ logger$9.info('webrtc sdk, connection promise connecting...');
7365
7476
  // $FlowFixMe
7366
7477
  return this.connectionPromise;
7367
7478
  }
7368
7479
 
7369
- logger$8.info('WebRTC UA needs to connect');
7480
+ logger$9.info('WebRTC UA needs to connect');
7370
7481
 
7371
7482
  // Force UA to reconnect
7372
7483
  if (this.userAgent && this.userAgent.state !== UserAgentState.Stopped) {
@@ -7491,7 +7602,7 @@ class WebRTCClient extends Emitter {
7491
7602
 
7492
7603
  sdh.peerConnectionDelegate = {
7493
7604
  onicecandidateerror: (error ) => {
7494
- logger$8.error('on icecandidate error', {
7605
+ logger$9.error('on icecandidate error', {
7495
7606
  address: error.address,
7496
7607
  port: error.port,
7497
7608
  errorCode: error.errorCode,
@@ -7506,7 +7617,7 @@ class WebRTCClient extends Emitter {
7506
7617
  let hadRemoteVideo = false;
7507
7618
 
7508
7619
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7509
- // Becase when `onInvite` is called we already got the video track
7620
+ // Because when `onInvite` is called we already got the video track
7510
7621
  session.onInviteRequest = (request) => {
7511
7622
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7512
7623
 
@@ -7520,7 +7631,7 @@ class WebRTCClient extends Emitter {
7520
7631
  updatedNumber = session.assertedIdentity.uri.normal.user;
7521
7632
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
7522
7633
  }
7523
- logger$8.info('re-invite received', { updatedCalleeName, updatedNumber });
7634
+ logger$9.info('re-invite received', { updatedCalleeName, updatedNumber });
7524
7635
 
7525
7636
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7526
7637
 
@@ -7541,7 +7652,7 @@ class WebRTCClient extends Emitter {
7541
7652
  }
7542
7653
 
7543
7654
  _onAccepted(session , sessionDialog , withEvent = true) {
7544
- logger$8.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7655
+ logger$9.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
7545
7656
 
7546
7657
  this.storeSipSession(session);
7547
7658
 
@@ -7581,20 +7692,10 @@ class WebRTCClient extends Emitter {
7581
7692
  const isConference = this.isConference(sessionId);
7582
7693
 
7583
7694
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
7584
- const audio = document.createElement('audio');
7585
- audio.setAttribute('id', `audio-${sessionId}`);
7586
-
7587
- if (audio.setSinkId && this.audioOutputDeviceId) {
7588
- audio.setSinkId(this.audioOutputDeviceId);
7589
- }
7590
-
7591
- if (document.body) {
7592
- document.body.appendChild(audio);
7593
- }
7594
- this.audioElements[sessionId] = audio;
7695
+ this.createAudioElementFor(sessionId);
7595
7696
  }
7596
7697
 
7597
- const audioElement = this.audioElements[this.getSipSessionId(session)];
7698
+ const audioElement = this.audioElements[sessionId];
7598
7699
  const stream = newStream || this.getRemoteStream(sessionId);
7599
7700
 
7600
7701
  if (!this._isWeb() || !stream) {
@@ -7741,10 +7842,10 @@ class WebRTCClient extends Emitter {
7741
7842
 
7742
7843
  _stopSendingStats(session ) {
7743
7844
  const sessionId = this.getSipSessionId(session);
7744
- logger$8.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7845
+ logger$9.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
7745
7846
 
7746
7847
  if (sessionId in this.statsIntervals) {
7747
- logger$8.trace('Stop sending stats for call', { sessionId });
7848
+ logger$9.trace('Stop sending stats for call', { sessionId });
7748
7849
  this.statsIntervals[sessionId]();
7749
7850
  delete this.statsIntervals[sessionId];
7750
7851
  }
@@ -7760,7 +7861,7 @@ class WebRTCClient extends Emitter {
7760
7861
  try {
7761
7862
  await this.userAgent.transport.disconnect();
7762
7863
  } catch (e) {
7763
- logger$8.error('WebRTC transport disconnect, error', e);
7864
+ logger$9.error('WebRTC transport disconnect, error', e);
7764
7865
  }
7765
7866
  }
7766
7867
  }
@@ -7847,7 +7948,7 @@ const events = [
7847
7948
  ON_SIGNAL,
7848
7949
  ];
7849
7950
 
7850
- const logger$7 = IssueReporter$1.loggerFor('webrtc-phone');
7951
+ const logger$8 = IssueReporter$1.loggerFor('webrtc-phone');
7851
7952
 
7852
7953
  class WebRTCPhone extends Emitter {
7853
7954
 
@@ -7918,7 +8019,7 @@ class WebRTCPhone extends Emitter {
7918
8019
  }).catch(error => {
7919
8020
  // Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
7920
8021
  console.error('register error', error, error.message, error.stack);
7921
- logger$7.error('WebRTC register error', { message: error.message, stack: error.stack });
8022
+ logger$8.error('WebRTC register error', { message: error.message, stack: error.stack });
7922
8023
  });
7923
8024
  }
7924
8025
 
@@ -7933,7 +8034,7 @@ class WebRTCPhone extends Emitter {
7933
8034
  if (!this.client) {
7934
8035
  return;
7935
8036
  }
7936
- logger$7.info('WebRTC phone stop');
8037
+ logger$8.info('WebRTC phone stop');
7937
8038
  this.client.stop();
7938
8039
  }
7939
8040
 
@@ -7948,14 +8049,14 @@ class WebRTCPhone extends Emitter {
7948
8049
  async sendReinvite(callSession , constraints = null, conference = false,
7949
8050
  audioOnly = false) {
7950
8051
  const sipSession = this.findSipSession(callSession);
7951
- logger$7.info('WebRTC phone - send reinvite', {
8052
+ logger$8.info('WebRTC phone - send reinvite', {
7952
8053
  sessionId: sipSession ? sipSession.id : null,
7953
8054
  constraints,
7954
8055
  audioOnly,
7955
8056
  });
7956
8057
 
7957
8058
  if (!sipSession) {
7958
- return null;
8059
+ return false;
7959
8060
  }
7960
8061
 
7961
8062
  // $FlowFixMe
@@ -7965,19 +8066,17 @@ class WebRTCPhone extends Emitter {
7965
8066
  // Downgrade
7966
8067
  if (constraints && !isUpgrade) {
7967
8068
  // No reinvite needed
7968
- return this._downgradeToAudio(callSession);
8069
+ this._downgradeToAudio(callSession);
8070
+ return false;
7969
8071
  }
7970
8072
 
7971
8073
  if (isUpgrade) {
7972
8074
  const shouldReinvite = await this._upgradeToVideo(callSession, constraints, conference);
7973
8075
  if (!shouldReinvite) {
7974
- return;
8076
+ return false;
7975
8077
  }
7976
8078
  }
7977
8079
 
7978
- // Force reinvite in SDH
7979
- sipSession.sessionDescriptionHandler.localMediaStreamConstraints = null;
7980
-
7981
8080
  return this.client.reinvite(sipSession, constraints, conference, audioOnly);
7982
8081
  }
7983
8082
 
@@ -7986,7 +8085,7 @@ class WebRTCPhone extends Emitter {
7986
8085
  }
7987
8086
 
7988
8087
  startHeartbeat() {
7989
- logger$7.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
8088
+ logger$8.info('WebRTC phone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
7990
8089
  if (!this.client || this.client.hasHeartbeat()) {
7991
8090
  return;
7992
8091
  }
@@ -7995,7 +8094,7 @@ class WebRTCPhone extends Emitter {
7995
8094
  }
7996
8095
 
7997
8096
  stopHeartbeat() {
7998
- logger$7.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
8097
+ logger$8.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
7999
8098
  if (!this.client) {
8000
8099
  return;
8001
8100
  }
@@ -8012,7 +8111,7 @@ class WebRTCPhone extends Emitter {
8012
8111
  }
8013
8112
 
8014
8113
  reconnect() {
8015
- logger$7.info('WebRTC phone - reconnect', { client: !!this.client });
8114
+ logger$8.info('WebRTC phone - reconnect', { client: !!this.client });
8016
8115
  if (!this.client) {
8017
8116
  return;
8018
8117
  }
@@ -8050,7 +8149,7 @@ class WebRTCPhone extends Emitter {
8050
8149
  _downgradeToAudio(callSession ) {
8051
8150
  const sipSession = this.findSipSession(callSession);
8052
8151
  if (!sipSession) {
8053
- return;
8152
+ return false;
8054
8153
  }
8055
8154
 
8056
8155
  // Release local video stream when downgrading to audio
@@ -8163,7 +8262,7 @@ class WebRTCPhone extends Emitter {
8163
8262
  // Monkey patch to know when canceled with the CANCEL message
8164
8263
  const onCancel = sipSession._onCancel.bind(sipSession);
8165
8264
  sipSession._onCancel = (message ) => {
8166
- logger$7.trace('on sip session canceled', { callId: message.callId });
8265
+ logger$8.trace('on sip session canceled', { callId: message.callId });
8167
8266
 
8168
8267
  onCancel(message);
8169
8268
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
@@ -8188,13 +8287,13 @@ class WebRTCPhone extends Emitter {
8188
8287
  this.audioOutputVolume,
8189
8288
  );
8190
8289
  case SessionState.Terminating:
8191
- logger$7.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8290
+ logger$8.info('WebRTC phone - call terminating', { sipId: sipSession.id });
8192
8291
 
8193
8292
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
8194
8293
 
8195
8294
  break;
8196
8295
  case SessionState.Terminated:
8197
- logger$7.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8296
+ logger$8.info('WebRTC phone - call terminated', { sipId: sipSession.id });
8198
8297
 
8199
8298
  this._onCallTerminated(sipSession);
8200
8299
 
@@ -8230,7 +8329,7 @@ class WebRTCPhone extends Emitter {
8230
8329
  }
8231
8330
 
8232
8331
  async startScreenSharing(constraints , callSession ) {
8233
- logger$7.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8332
+ logger$8.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
8234
8333
 
8235
8334
  const screenShareStream = await this._getStreamFromConstraints(constraints);
8236
8335
  if (!screenShareStream) {
@@ -8252,6 +8351,10 @@ class WebRTCPhone extends Emitter {
8252
8351
  localStream.removeTrack(videoTrack);
8253
8352
  }
8254
8353
 
8354
+ if (localStream) {
8355
+ localStream.addTrack(screenTrack);
8356
+ }
8357
+
8255
8358
  if (sender) {
8256
8359
  sender.replaceTrack(screenTrack);
8257
8360
  }
@@ -8266,7 +8369,8 @@ class WebRTCPhone extends Emitter {
8266
8369
  return;
8267
8370
  }
8268
8371
 
8269
- logger$7.info('WebRTC phone - stop screen sharing');
8372
+ logger$8.info('WebRTC phone - stop screen sharing');
8373
+ let reinvited = false;
8270
8374
 
8271
8375
  try {
8272
8376
  if (this.currentScreenShare.stream) {
@@ -8281,7 +8385,8 @@ class WebRTCPhone extends Emitter {
8281
8385
  // When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
8282
8386
  // We have to downgrade to audio.
8283
8387
  const screenshareStopped = this.currentScreenShare.sender && this.currentScreenShare.hadVideo;
8284
- await this.sendReinvite(targetCallSession, { audio: false, video: screenshareStopped }, conference);
8388
+ const constraints = { audio: false, video: screenshareStopped };
8389
+ reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
8285
8390
  }
8286
8391
  } catch (e) {
8287
8392
  console.warn(e);
@@ -8295,6 +8400,8 @@ class WebRTCPhone extends Emitter {
8295
8400
  );
8296
8401
 
8297
8402
  this.currentScreenShare = null;
8403
+
8404
+ return reinvited;
8298
8405
  }
8299
8406
 
8300
8407
  async _getStreamFromConstraints(constraints , conference = false) {
@@ -8332,7 +8439,7 @@ class WebRTCPhone extends Emitter {
8332
8439
  }
8333
8440
 
8334
8441
  _onCallAccepted(sipSession , cameraEnabled ) {
8335
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8442
+ logger$8.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
8336
8443
 
8337
8444
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
8338
8445
  this.currentSipSession = sipSession;
@@ -8350,11 +8457,15 @@ class WebRTCPhone extends Emitter {
8350
8457
  }
8351
8458
 
8352
8459
  changeAudioDevice(id ) {
8353
- logger$7.info('WebRTC phone - change audio device', { deviceId: id });
8460
+ logger$8.info('WebRTC phone - change audio device', { deviceId: id });
8354
8461
  this.audioOutputDeviceId = id;
8355
8462
  this.client.changeAudioOutputDevice(id);
8356
8463
  }
8357
8464
 
8465
+ createAudioElementFor(sessionId ) {
8466
+ return this.client.createAudioElementFor(sessionId);
8467
+ }
8468
+
8358
8469
  changeRingDevice(id ) {
8359
8470
  this.audioRingDeviceId = id;
8360
8471
  }
@@ -8371,25 +8482,25 @@ class WebRTCPhone extends Emitter {
8371
8482
  }
8372
8483
 
8373
8484
  changeAudioInputDevice(id ) {
8374
- logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
8485
+ logger$8.info('WebRTC phone - changeAudio input device', { deviceId: id });
8375
8486
 
8376
8487
  return this.client.changeAudioInputDevice(id, this.currentSipSession);
8377
8488
  }
8378
8489
 
8379
8490
  changeVideoInputDevice(id ) {
8380
- logger$7.info('WebRTC phone - change video input device', { deviceId: id });
8491
+ logger$8.info('WebRTC phone - change video input device', { deviceId: id });
8381
8492
 
8382
8493
  return this.client.changeVideoInputDevice(id, this.currentSipSession);
8383
8494
  }
8384
8495
 
8385
8496
  changeSessionVideoInputDevice(id ) {
8386
- logger$7.info('WebRTC phone - change session video input device', { deviceId: id });
8497
+ logger$8.info('WebRTC phone - change session video input device', { deviceId: id });
8387
8498
 
8388
8499
  return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
8389
8500
  }
8390
8501
 
8391
8502
  _onCallTerminated(sipSession ) {
8392
- logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8503
+ logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
8393
8504
 
8394
8505
  const callSession = this._createCallSession(sipSession);
8395
8506
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
@@ -8423,7 +8534,7 @@ class WebRTCPhone extends Emitter {
8423
8534
  const hasIncomingCallSession = this.hasIncomingCallSession();
8424
8535
 
8425
8536
  // Re-trigger incoming call event for remaining incoming calls
8426
- logger$7.info('WebRTC phone - check to re-trigger incoming call', {
8537
+ logger$8.info('WebRTC phone - check to re-trigger incoming call', {
8427
8538
  sipId: sipSession.id,
8428
8539
  shouldRetrigger,
8429
8540
  hasIncomingCallSession,
@@ -8512,37 +8623,37 @@ class WebRTCPhone extends Emitter {
8512
8623
 
8513
8624
  // Deprecated
8514
8625
  getLocalStreamForCall(callSession ) {
8515
- logger$7.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8626
+ logger$8.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
8516
8627
 
8517
8628
  return this.getLocalStream(callSession);
8518
8629
  }
8519
8630
 
8520
8631
  // Deprecated
8521
8632
  getRemoteStreamForCall(callSession ) {
8522
- logger$7.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8633
+ logger$8.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
8523
8634
 
8524
8635
  return this.getRemoteVideoStream(callSession);
8525
8636
  }
8526
8637
 
8527
8638
  getRemoteStreamsForCall(callSession ) {
8528
- logger$7.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8639
+ logger$8.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
8529
8640
 
8530
8641
  return this.getRemoteStream(callSession);
8531
8642
  }
8532
8643
 
8533
8644
  accept(callSession , cameraEnabled ) {
8534
- logger$7.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8645
+ logger$8.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
8535
8646
  if (this.currentSipSession) {
8536
8647
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
8537
8648
  }
8538
8649
 
8539
8650
  if (!callSession) {
8540
- logger$7.warn('no CallSession to accept.');
8651
+ logger$8.warn('no CallSession to accept.');
8541
8652
  return Promise.resolve(null);
8542
8653
  }
8543
8654
 
8544
8655
  if (callSession.getId() in this.acceptedSessions) {
8545
- logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8656
+ logger$8.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
8546
8657
  return Promise.resolve(callSession.sipCallId);
8547
8658
  }
8548
8659
 
@@ -8554,24 +8665,24 @@ class WebRTCPhone extends Emitter {
8554
8665
  const sipSession = this.client.getSipSession(callSession.getId());
8555
8666
  if (sipSession) {
8556
8667
  if (sipSession.state === SessionState.Terminated || sipSession.state === SessionState.Terminating) {
8557
- logger$7.warn('Trying to answer a terminated sipSession.');
8668
+ logger$8.warn('Trying to answer a terminated sipSession.');
8558
8669
 
8559
8670
  return Promise.resolve(null);
8560
8671
  }
8561
8672
 
8562
- logger$7.info('accept call, session found', { sipId: sipSession.id });
8673
+ logger$8.info('accept call, session found', { sipId: sipSession.id });
8563
8674
 
8564
8675
  // $FlowFixMe
8565
8676
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
8566
8677
  return callSession.sipCallId;
8567
8678
  }).catch(e => {
8568
- logger$7.error(e);
8679
+ logger$8.error(e);
8569
8680
  this.endCurrentCall(callSession);
8570
8681
  throw e;
8571
8682
  });
8572
8683
  }
8573
8684
 
8574
- logger$7.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8685
+ logger$8.warn('no CallSession found to accept.', { id: callSession ? callSession.getId() : 'n/a' });
8575
8686
 
8576
8687
  return Promise.resolve(null);
8577
8688
  }
@@ -8581,7 +8692,7 @@ class WebRTCPhone extends Emitter {
8581
8692
  }
8582
8693
 
8583
8694
  async reject(callSession ) {
8584
- logger$7.info('reject WebRTC called', { id: callSession.getId() });
8695
+ logger$8.info('reject WebRTC called', { id: callSession.getId() });
8585
8696
 
8586
8697
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call rejected locally');
8587
8698
  if (!callSession || callSession.getId() in this.rejectedSessions) {
@@ -8593,14 +8704,14 @@ class WebRTCPhone extends Emitter {
8593
8704
 
8594
8705
  const sipSession = this.findSipSession(callSession);
8595
8706
  if (sipSession) {
8596
- logger$7.info('WebRTC rejecting', { sipId: sipSession.id });
8707
+ logger$8.info('WebRTC rejecting', { sipId: sipSession.id });
8597
8708
 
8598
8709
  this.client.hangup(sipSession);
8599
8710
  }
8600
8711
  }
8601
8712
 
8602
8713
  async ignore(callSession ) {
8603
- logger$7.info('WebRTC ignore', { id: callSession.getId() });
8714
+ logger$8.info('WebRTC ignore', { id: callSession.getId() });
8604
8715
 
8605
8716
  // kill the ring
8606
8717
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'ignoring call');
@@ -8609,7 +8720,7 @@ class WebRTCPhone extends Emitter {
8609
8720
  }
8610
8721
 
8611
8722
  hold(callSession , withEvent = true, isConference = false) {
8612
- logger$7.info('WebRTC hold', { id: callSession.getId() });
8723
+ logger$8.info('WebRTC hold', { id: callSession.getId() });
8613
8724
 
8614
8725
  const sipSession = this.findSipSession(callSession);
8615
8726
 
@@ -8620,7 +8731,7 @@ class WebRTCPhone extends Emitter {
8620
8731
 
8621
8732
  // @Deprecated
8622
8733
  unhold(callSession , withEvent = true, isConference = false) {
8623
- logger$7.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8734
+ logger$8.info('WebRTC unhold', { id: callSession ? callSession.getId() : null });
8624
8735
 
8625
8736
  console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
8626
8737
 
@@ -8635,7 +8746,7 @@ class WebRTCPhone extends Emitter {
8635
8746
  const sipSession = this.findSipSession(callSession);
8636
8747
 
8637
8748
  if (sipSession) {
8638
- logger$7.info('WebRTC atxfer', { sipId: sipSession.id });
8749
+ logger$8.info('WebRTC atxfer', { sipId: sipSession.id });
8639
8750
 
8640
8751
  return this.client.atxfer(sipSession);
8641
8752
  }
@@ -8650,7 +8761,7 @@ class WebRTCPhone extends Emitter {
8650
8761
  if (!sipSession) {
8651
8762
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
8652
8763
  }
8653
- logger$7.info('WebRTC hold sip session', { sipId: sipSession.id });
8764
+ logger$8.info('WebRTC hold sip session', { sipId: sipSession.id });
8654
8765
 
8655
8766
  const promise = this.client.hold(sipSession, isConference);
8656
8767
  if (withEvent) {
@@ -8669,7 +8780,7 @@ class WebRTCPhone extends Emitter {
8669
8780
  if (!sipSession) {
8670
8781
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
8671
8782
  }
8672
- logger$7.info('WebRTC unhold', { sipId: sipSession.id });
8783
+ logger$8.info('WebRTC unhold', { sipId: sipSession.id });
8673
8784
 
8674
8785
  const promise = this.client.unhold(sipSession, isConference);
8675
8786
  if (withEvent) {
@@ -8680,18 +8791,18 @@ class WebRTCPhone extends Emitter {
8680
8791
  }
8681
8792
 
8682
8793
  resume(callSession , isConference = false) {
8683
- logger$7.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8794
+ logger$8.info('WebRTC resume called', { id: callSession ? callSession.getId() : null });
8684
8795
 
8685
8796
  const sipSession = this.findSipSession(callSession);
8686
8797
  if (!sipSession) {
8687
8798
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
8688
8799
  }
8689
8800
 
8690
- logger$7.info('WebRTC resuming', { sipId: sipSession.id });
8801
+ logger$8.info('WebRTC resuming', { sipId: sipSession.id });
8691
8802
 
8692
8803
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
8693
8804
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
8694
- logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8805
+ logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
8695
8806
  this.holdSipSession(this.currentSipSession, callSession);
8696
8807
  }
8697
8808
 
@@ -8706,14 +8817,14 @@ class WebRTCPhone extends Emitter {
8706
8817
  }
8707
8818
 
8708
8819
  mute(callSession , withEvent = true) {
8709
- logger$7.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8820
+ logger$8.info('WebRTC mute called', { id: callSession ? callSession.getId() : null });
8710
8821
 
8711
8822
  const sipSession = this.findSipSession(callSession);
8712
8823
  if (!sipSession) {
8713
8824
  return;
8714
8825
  }
8715
8826
 
8716
- logger$7.info('WebRTC muting', { sipId: sipSession.id });
8827
+ logger$8.info('WebRTC muting', { sipId: sipSession.id });
8717
8828
  this.client.mute(sipSession);
8718
8829
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: true });
8719
8830
 
@@ -8727,14 +8838,14 @@ class WebRTCPhone extends Emitter {
8727
8838
  }
8728
8839
 
8729
8840
  unmute(callSession , withEvent = true) {
8730
- logger$7.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8841
+ logger$8.info('WebRTC unmute called', { id: callSession ? callSession.getId() : null });
8731
8842
 
8732
8843
  const sipSession = this.findSipSession(callSession);
8733
8844
  if (!sipSession) {
8734
8845
  return;
8735
8846
  }
8736
8847
 
8737
- logger$7.info('WebRTC unmuting', { sipId: sipSession.id });
8848
+ logger$8.info('WebRTC unmuting', { sipId: sipSession.id });
8738
8849
  this.client.unmute(sipSession);
8739
8850
  const newCallSession = this._createCallSession(sipSession, callSession, { muted: false });
8740
8851
 
@@ -8761,7 +8872,7 @@ class WebRTCPhone extends Emitter {
8761
8872
  if (!sipSession) {
8762
8873
  return;
8763
8874
  }
8764
- logger$7.info('WebRTC turn camera on', { sipId: sipSession.id });
8875
+ logger$8.info('WebRTC turn camera on', { sipId: sipSession.id });
8765
8876
 
8766
8877
  this.client.toggleCameraOn(sipSession);
8767
8878
 
@@ -8773,7 +8884,7 @@ class WebRTCPhone extends Emitter {
8773
8884
  if (!sipSession) {
8774
8885
  return;
8775
8886
  }
8776
- logger$7.info('WebRTC turn camera off', { sipId: sipSession.id });
8887
+ logger$8.info('WebRTC turn camera off', { sipId: sipSession.id });
8777
8888
 
8778
8889
  this.client.toggleCameraOff(sipSession);
8779
8890
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -8785,7 +8896,7 @@ class WebRTCPhone extends Emitter {
8785
8896
  return;
8786
8897
  }
8787
8898
 
8788
- logger$7.info('WebRTC send key', { sipId: sipSession.id, tone });
8899
+ logger$8.info('WebRTC send key', { sipId: sipSession.id, tone });
8789
8900
  this.client.sendDTMF(sipSession, tone);
8790
8901
  }
8791
8902
 
@@ -8793,7 +8904,7 @@ class WebRTCPhone extends Emitter {
8793
8904
  // @TODO: line is not used here
8794
8905
  async makeCall(number , line , cameraEnabled ,
8795
8906
  audioOnly = false, conference = false) {
8796
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
8907
+ logger$8.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
8797
8908
  if (!number) {
8798
8909
  return Promise.resolve(null);
8799
8910
  }
@@ -8803,7 +8914,7 @@ class WebRTCPhone extends Emitter {
8803
8914
  }
8804
8915
  if (this.currentSipSession) {
8805
8916
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
8806
- logger$7.warn('Unable to hold current session when making another call', e);
8917
+ logger$8.warn('Unable to hold current session when making another call', e);
8807
8918
  });
8808
8919
  }
8809
8920
 
@@ -8813,7 +8924,7 @@ class WebRTCPhone extends Emitter {
8813
8924
  this._bindEvents(sipSession);
8814
8925
  } catch (error) {
8815
8926
  console.warn(error);
8816
- logger$7.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
8927
+ logger$8.warn('make WebRTC call, error', { message: error.message, stack: error.stack });
8817
8928
  return Promise.resolve(null);
8818
8929
  }
8819
8930
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
@@ -8841,7 +8952,7 @@ class WebRTCPhone extends Emitter {
8841
8952
  return;
8842
8953
  }
8843
8954
 
8844
- logger$7.info('WebRTC transfer', { sipId: sipSession.id, target });
8955
+ logger$8.info('WebRTC transfer', { sipId: sipSession.id, target });
8845
8956
 
8846
8957
  this.client.transfer(sipSession, target);
8847
8958
  }
@@ -8850,7 +8961,7 @@ class WebRTCPhone extends Emitter {
8850
8961
  const sipSession = this.client.getSipSession(source.sipCallId);
8851
8962
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
8852
8963
 
8853
- logger$7.info('WebRTC indirect transfer', {
8964
+ logger$8.info('WebRTC indirect transfer', {
8854
8965
  sipId: sipSession ? sipSession.id : null,
8855
8966
  target: sipSessionTarget ? sipSessionTarget.id : null,
8856
8967
  });
@@ -8878,7 +8989,7 @@ class WebRTCPhone extends Emitter {
8878
8989
  return false;
8879
8990
  }
8880
8991
 
8881
- logger$7.info('WebRTC hangup', { sipId: sipSession.id });
8992
+ logger$8.info('WebRTC hangup', { sipId: sipSession.id });
8882
8993
 
8883
8994
  const sipSessionId = this.getSipSessionId(sipSession);
8884
8995
 
@@ -8923,7 +9034,7 @@ class WebRTCPhone extends Emitter {
8923
9034
  }
8924
9035
 
8925
9036
  async close() {
8926
- logger$7.info('WebRTC close');
9037
+ logger$8.info('WebRTC close');
8927
9038
 
8928
9039
  try {
8929
9040
  await Promise.race([
@@ -8931,7 +9042,7 @@ class WebRTCPhone extends Emitter {
8931
9042
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000)),
8932
9043
  ]);
8933
9044
  } catch (e) {
8934
- logger$7.error('WebRTC close, unregister error', e);
9045
+ logger$8.error('WebRTC close, unregister error', e);
8935
9046
  }
8936
9047
 
8937
9048
  this.client.close();
@@ -8949,12 +9060,12 @@ class WebRTCPhone extends Emitter {
8949
9060
  }
8950
9061
 
8951
9062
  enableRinging() {
8952
- logger$7.info('WebRTC enable ringing');
9063
+ logger$8.info('WebRTC enable ringing');
8953
9064
  this.ringingEnabled = true;
8954
9065
  }
8955
9066
 
8956
9067
  disableRinging() {
8957
- logger$7.info('WebRTC disable ringing');
9068
+ logger$8.info('WebRTC disable ringing');
8958
9069
  this.ringingEnabled = false;
8959
9070
  }
8960
9071
 
@@ -8994,7 +9105,7 @@ class WebRTCPhone extends Emitter {
8994
9105
 
8995
9106
  // Deprecated
8996
9107
  getLocalMediaStream(callSession ) {
8997
- logger$7.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
9108
+ logger$8.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
8998
9109
  return this.getLocalStream(callSession);
8999
9110
  }
9000
9111
 
@@ -9002,6 +9113,10 @@ class WebRTCPhone extends Emitter {
9002
9113
  return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
9003
9114
  }
9004
9115
 
9116
+ hasALocalVideoTrack(callSession ) {
9117
+ return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
9118
+ }
9119
+
9005
9120
  getRemoteStream(callSession ) {
9006
9121
  return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
9007
9122
  }
@@ -9024,7 +9139,7 @@ class WebRTCPhone extends Emitter {
9024
9139
  this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
9025
9140
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
9026
9141
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
9027
- logger$7.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9142
+ logger$8.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
9028
9143
 
9029
9144
  const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
9030
9145
  this.incomingSessions.push(callSession.getId());
@@ -9047,7 +9162,7 @@ class WebRTCPhone extends Emitter {
9047
9162
  });
9048
9163
 
9049
9164
  this.client.on(this.client.ON_REINVITE, (...args) => {
9050
- logger$7.info('WebRTC on reinvite', {
9165
+ logger$8.info('WebRTC on reinvite', {
9051
9166
  sessionId: args[0].id,
9052
9167
  inviteId: args[1].id,
9053
9168
  updatedCalleeName: args[2],
@@ -9067,7 +9182,7 @@ class WebRTCPhone extends Emitter {
9067
9182
  });
9068
9183
 
9069
9184
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
9070
- logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
9185
+ logger$8.info('WebRTC call accepted', { sipId: sipSession.id });
9071
9186
 
9072
9187
  this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
9073
9188
 
@@ -9078,17 +9193,17 @@ class WebRTCPhone extends Emitter {
9078
9193
  this.client.on('ended', () => {});
9079
9194
 
9080
9195
  this.client.on(this.client.ON_ERROR, e => {
9081
- logger$7.error('WebRTC error', e);
9196
+ logger$8.error('WebRTC error', e);
9082
9197
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9083
9198
  });
9084
9199
 
9085
9200
  this.client.on(this.client.UNREGISTERED, () => {
9086
- logger$7.info('WebRTC unregistered');
9201
+ logger$8.info('WebRTC unregistered');
9087
9202
  this.eventEmitter.emit(ON_UNREGISTERED);
9088
9203
  });
9089
9204
 
9090
9205
  this.client.on(this.client.REGISTERED, () => {
9091
- logger$7.info('WebRTC registered', {
9206
+ logger$8.info('WebRTC registered', {
9092
9207
  shouldSendReinvite: this.shouldSendReinvite,
9093
9208
  state: this.currentSipSession ? this.currentSipSession.state : null,
9094
9209
  currentSipSession: !!this.currentSipSession,
@@ -9104,19 +9219,19 @@ class WebRTCPhone extends Emitter {
9104
9219
  try {
9105
9220
  this.sendReinvite(this.currentCallSession);
9106
9221
  } catch (e) {
9107
- logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9222
+ logger$8.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9108
9223
  }
9109
9224
  }
9110
9225
  });
9111
9226
 
9112
9227
  this.client.on(this.client.CONNECTED, () => {
9113
- logger$7.info('WebRTC client connected');
9228
+ logger$8.info('WebRTC client connected');
9114
9229
 
9115
9230
  this.stopHeartbeat();
9116
9231
  });
9117
9232
 
9118
9233
  this.client.on(this.client.DISCONNECTED, () => {
9119
- logger$7.info('WebRTC client disconnected');
9234
+ logger$8.info('WebRTC client disconnected');
9120
9235
 
9121
9236
  this.eventEmitter.emit(ON_UNREGISTERED);
9122
9237
 
@@ -9351,7 +9466,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
9351
9466
  class InvalidSubscription extends Error {}
9352
9467
  class InvalidAuthorization extends Error {}
9353
9468
 
9354
- const logger$6 = IssueReporter$1.loggerFor('simple-auth');
9469
+ const logger$7 = IssueReporter$1.loggerFor('simple-auth');
9355
9470
 
9356
9471
  class Auth {
9357
9472
 
@@ -9386,7 +9501,7 @@ class Auth {
9386
9501
  setApiClientId(this.clientId);
9387
9502
  setRefreshExpiration(this.expiration);
9388
9503
  setOnRefreshToken((token , session ) => {
9389
- logger$6.info('on refresh token done', { token });
9504
+ logger$7.info('on refresh token done', { token });
9390
9505
  setApiToken(token);
9391
9506
  Wazo.Websocket.updateToken(token);
9392
9507
 
@@ -9662,6 +9777,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
9662
9777
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
9663
9778
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
9664
9779
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
9780
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
9781
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
9665
9782
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
9666
9783
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
9667
9784
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -9703,7 +9820,7 @@ const BLACKLIST_EVENTS = [
9703
9820
  ];
9704
9821
 
9705
9822
  const HEARTBEAT_ENGINE_VERSION = '20.09';
9706
- const logger$5 = IssueReporter$1.loggerFor('wazo-ws');
9823
+ const logger$6 = IssueReporter$1.loggerFor('wazo-ws');
9707
9824
  const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
9708
9825
 
9709
9826
  class WebSocketClient extends Emitter {
@@ -9752,19 +9869,19 @@ class WebSocketClient extends Emitter {
9752
9869
  }
9753
9870
 
9754
9871
  connect() {
9755
- logger$5.info('connect method started', { host: this.host, token: this.token });
9872
+ logger$6.info('connect method started', { host: this.host, token: this.token });
9756
9873
  this.socket = new ReconnectingWebSocket(this._getUrl.bind(this), [], this.options);
9757
9874
  if (this.options.binaryType) {
9758
9875
  this.socket.binaryType = this.options.binaryType;
9759
9876
  }
9760
9877
 
9761
9878
  this.socket.onopen = () => {
9762
- logger$5.info('on Wazo WS open', { method: 'connect', host: this.host });
9879
+ logger$6.info('on Wazo WS open', { method: 'connect', host: this.host });
9763
9880
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_OPEN);
9764
9881
  };
9765
9882
 
9766
9883
  this.socket.onerror = event => {
9767
- logger$5.error('on Wazo WS error', event.target);
9884
+ logger$6.error('on Wazo WS error', event.target);
9768
9885
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_ERROR, event);
9769
9886
  };
9770
9887
 
@@ -9794,7 +9911,7 @@ class WebSocketClient extends Emitter {
9794
9911
 
9795
9912
  this.socket.onclose = event => {
9796
9913
  // Can't be converted to JSON (circular structure)
9797
- logger$5.info('on Wazo WS close', {
9914
+ logger$6.info('on Wazo WS close', {
9798
9915
  reason: event.reason,
9799
9916
  code: event.code,
9800
9917
  readyState: event.target.readyState,
@@ -9812,12 +9929,12 @@ class WebSocketClient extends Emitter {
9812
9929
  };
9813
9930
 
9814
9931
  this.socket.onerror = event => {
9815
- logger$5.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
9932
+ logger$6.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
9816
9933
  };
9817
9934
  }
9818
9935
 
9819
9936
  close(force = false) {
9820
- logger$5.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
9937
+ logger$6.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
9821
9938
 
9822
9939
  if (!this.socket) {
9823
9940
  return;
@@ -9835,7 +9952,7 @@ class WebSocketClient extends Emitter {
9835
9952
 
9836
9953
  updateToken(token ) {
9837
9954
  this.token = token;
9838
- logger$5.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
9955
+ logger$6.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
9839
9956
 
9840
9957
  if (this.socket) {
9841
9958
  // If still connected, send the token to the WS
@@ -9853,7 +9970,7 @@ class WebSocketClient extends Emitter {
9853
9970
  }
9854
9971
 
9855
9972
  startHeartbeat() {
9856
- logger$5.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
9973
+ logger$6.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
9857
9974
 
9858
9975
  if (!this.socket) {
9859
9976
  this.heartbeat.stop();
@@ -9867,7 +9984,7 @@ class WebSocketClient extends Emitter {
9867
9984
  }
9868
9985
 
9869
9986
  stopHeartbeat() {
9870
- logger$5.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
9987
+ logger$6.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
9871
9988
 
9872
9989
  this.heartbeat.stop();
9873
9990
  }
@@ -9897,7 +10014,7 @@ class WebSocketClient extends Emitter {
9897
10014
  }
9898
10015
 
9899
10016
  reconnect(reason ) {
9900
- logger$5.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
10017
+ logger$6.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
9901
10018
  if (!this.socket) {
9902
10019
  return;
9903
10020
  }
@@ -9953,7 +10070,7 @@ class WebSocketClient extends Emitter {
9953
10070
  this.close();
9954
10071
  }
9955
10072
  const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
9956
- logger$5.log('Wazo WS url computed to reconnect', { url });
10073
+ logger$6.log('Wazo WS url computed to reconnect', { url });
9957
10074
 
9958
10075
  return url;
9959
10076
  }
@@ -9961,12 +10078,12 @@ class WebSocketClient extends Emitter {
9961
10078
  _onHeartbeat(message ) {
9962
10079
  if (message.payload === 'pong') {
9963
10080
  this.heartbeat.onHeartbeat();
9964
- logger$5.log('on heartbeat received from Wazo WS');
10081
+ logger$6.log('on heartbeat received from Wazo WS');
9965
10082
  }
9966
10083
  }
9967
10084
 
9968
10085
  async _onHeartbeatTimeout() {
9969
- logger$5.log('heartbeat timed out', { host: this.host, token: this.token });
10086
+ logger$6.log('heartbeat timed out', { host: this.host, token: this.token });
9970
10087
 
9971
10088
  this.close();
9972
10089
  this.eventEmitter.emit(SOCKET_EVENTS$1.ON_CLOSE, new Error('Websocket ping failure.'));
@@ -10008,6 +10125,8 @@ WebSocketClient.eventLists = [
10008
10125
  CHATD_USER_ROOM_CREATED,
10009
10126
  CONFERENCE_USER_PARTICIPANT_JOINED,
10010
10127
  CONFERENCE_USER_PARTICIPANT_LEFT,
10128
+ MEETING_USER_PARTICIPANT_JOINED,
10129
+ MEETING_USER_PARTICIPANT_LEFT,
10011
10130
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10012
10131
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10013
10132
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -10078,6 +10197,8 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10078
10197
  CONFERENCE_USER_PARTICIPANT_LEFT: CONFERENCE_USER_PARTICIPANT_LEFT,
10079
10198
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED: CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
10080
10199
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED: CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
10200
+ MEETING_USER_PARTICIPANT_JOINED: MEETING_USER_PARTICIPANT_JOINED,
10201
+ MEETING_USER_PARTICIPANT_LEFT: MEETING_USER_PARTICIPANT_LEFT,
10081
10202
  SWITCHBOARD_QUEUED_CALLS_UPDATED: SWITCHBOARD_QUEUED_CALLS_UPDATED,
10082
10203
  SWITCHBOARD_QUEUED_CALL_ANSWERED: SWITCHBOARD_QUEUED_CALL_ANSWERED,
10083
10204
  SWITCHBOARD_HELD_CALLS_UPDATED: SWITCHBOARD_HELD_CALLS_UPDATED,
@@ -10119,7 +10240,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
10119
10240
  const { SOCKET_EVENTS, ...OTHER_EVENTS } = WebSocketClient$1;
10120
10241
  const ALL_EVENTS = [...Object.values(SOCKET_EVENTS), ...Object.values(OTHER_EVENTS)];
10121
10242
 
10122
- const logger$4 = IssueReporter$1.loggerFor('simple-ws-client');
10243
+ const logger$5 = IssueReporter$1.loggerFor('simple-ws-client');
10123
10244
 
10124
10245
  class Websocket extends Emitter {
10125
10246
 
@@ -10143,7 +10264,7 @@ class Websocket extends Emitter {
10143
10264
  }
10144
10265
 
10145
10266
  open(host , session ) {
10146
- logger$4.info('open simple WebSocket', { host, token: session.token });
10267
+ logger$5.info('open simple WebSocket', { host, token: session.token });
10147
10268
  this.ws = new WebSocketClient(
10148
10269
  {
10149
10270
  host,
@@ -10171,7 +10292,7 @@ class Websocket extends Emitter {
10171
10292
  }
10172
10293
 
10173
10294
  updateToken(token ) {
10174
- logger$4.info('update token via simple Websocket', { token, ws: !!this.ws });
10295
+ logger$5.info('update token via simple Websocket', { token, ws: !!this.ws });
10175
10296
 
10176
10297
  if (!this.ws) {
10177
10298
  return;
@@ -10199,7 +10320,7 @@ var Websocket$1 = global.wazoWebsocketInstance;
10199
10320
 
10200
10321
  //
10201
10322
 
10202
- const logger$3 = IssueReporter$1.loggerFor('room');
10323
+ const logger$4 = IssueReporter$1.loggerFor('room');
10203
10324
 
10204
10325
  class Participant extends Emitter {
10205
10326
 
@@ -10233,6 +10354,7 @@ class Participant extends Emitter {
10233
10354
 
10234
10355
 
10235
10356
  /**
10357
+ * @param room Room The room where the participant is
10236
10358
  * @param rawParticipant string Participant sent via the Wazo WS
10237
10359
  * @param extra Object extra status of the participant
10238
10360
  */
@@ -10320,7 +10442,7 @@ class Participant extends Emitter {
10320
10442
  }
10321
10443
 
10322
10444
  onTalking(isTalking ) {
10323
- logger$3.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10445
+ logger$4.info('on participant talking', { name: this.name, isTalking, callId: this.callId });
10324
10446
  this.isTalking = isTalking;
10325
10447
  // you may notice we're not broadcasting: since all participants are getting this info
10326
10448
  // directly from asterisk, there's no need to do so
@@ -10423,7 +10545,7 @@ class Participant extends Emitter {
10423
10545
  }
10424
10546
 
10425
10547
  updateStatus(status , broadcast = true) {
10426
- logger$3.info('updating participant status', { name: this.name, status });
10548
+ logger$4.info('updating participant status', { name: this.name, status });
10427
10549
 
10428
10550
  if (typeof status.audioMuted !== 'undefined' && status.audioMuted !== this.audioMuted) {
10429
10551
  if (status.audioMuted) {
@@ -10460,13 +10582,18 @@ class Participant extends Emitter {
10460
10582
  // Poor man's object comparison
10461
10583
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
10462
10584
  this.extra = { ...this.extra, ...status.extra };
10585
+
10586
+ if (this.extra.contact && !(this.extra.contact instanceof Contact)) {
10587
+ this.extra.contact = new Contact(this.extra.contact);
10588
+ }
10589
+
10463
10590
  this.triggerUpdate(this.ON_EXTRA_CHANGE, broadcast);
10464
10591
  }
10465
10592
  }
10466
10593
 
10467
10594
  broadcastStatus(inboundStatus = null) {
10468
10595
  const status = inboundStatus || this.getStatus();
10469
- logger$3.info('broadcasting participant status', { callId: this.callId, status });
10596
+ logger$4.info('broadcasting participant status', { callId: this.callId, status });
10470
10597
 
10471
10598
  this.room.sendSignal({
10472
10599
  type: SIGNAL_TYPE_PARTICIPANT_UPDATE,
@@ -10487,18 +10614,24 @@ class RemoteParticipant extends Participant {
10487
10614
  }
10488
10615
  }
10489
10616
 
10490
- /* global document */
10617
+ //
10618
+
10619
+ class LocalParticipant extends Participant {
10620
+ }
10621
+
10622
+ //
10491
10623
 
10492
10624
  const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
10493
10625
  const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
10494
10626
 
10495
- const logger$2 = IssueReporter$1.loggerFor('sdk-room');
10627
+ const logger$3 = IssueReporter$1.loggerFor('sdk-room');
10496
10628
 
10497
10629
  class Room$1 extends Emitter {
10498
10630
 
10499
10631
 
10500
10632
 
10501
10633
 
10634
+
10502
10635
 
10503
10636
 
10504
10637
 
@@ -10520,6 +10653,8 @@ class Room$1 extends Emitter {
10520
10653
 
10521
10654
 
10522
10655
 
10656
+
10657
+
10523
10658
 
10524
10659
 
10525
10660
 
@@ -10537,6 +10672,7 @@ class Room$1 extends Emitter {
10537
10672
  * @param extension string
10538
10673
  * @param sourceId number
10539
10674
  * @param callId string
10675
+ * @param meetingUuid string
10540
10676
  * @param extra Object
10541
10677
  */
10542
10678
  constructor(
@@ -10544,15 +10680,17 @@ class Room$1 extends Emitter {
10544
10680
  extension ,
10545
10681
  sourceId ,
10546
10682
  callId ,
10683
+ meetingUuid ,
10547
10684
  extra = {},
10548
10685
  ) {
10549
10686
  super();
10550
- logger$2.info('room initialized', { callId, extension, sourceId });
10687
+ logger$3.info('room initialized', { callId, extension, sourceId, meetingUuid });
10551
10688
 
10552
10689
  // Represents the room callSession
10553
10690
  this.callSession = callSession;
10554
10691
  this.extension = extension;
10555
10692
  this.sourceId = sourceId;
10693
+ this.meetingUuid = meetingUuid;
10556
10694
  this.callId = callId;
10557
10695
  this.participants = [];
10558
10696
  this.connected = false;
@@ -10572,6 +10710,8 @@ class Room$1 extends Emitter {
10572
10710
  // Sugar syntax for `room.EVENT_NAME`
10573
10711
  this.CONFERENCE_USER_PARTICIPANT_JOINED = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_JOINED;
10574
10712
  this.CONFERENCE_USER_PARTICIPANT_LEFT = Wazo.Websocket.CONFERENCE_USER_PARTICIPANT_LEFT;
10713
+ this.MEETING_USER_PARTICIPANT_JOINED = Wazo.Websocket.MEETING_USER_PARTICIPANT_JOINED;
10714
+ this.MEETING_USER_PARTICIPANT_LEFT = Wazo.Websocket.MEETING_USER_PARTICIPANT_LEFT;
10575
10715
  this.ON_SHARE_SCREEN_ENDED = Wazo.Phone.ON_SHARE_SCREEN_ENDED;
10576
10716
  this.ON_MESSAGE = Wazo.Phone.ON_MESSAGE;
10577
10717
  this.ON_CHAT = Wazo.Phone.ON_CHAT;
@@ -10606,10 +10746,11 @@ class Room$1 extends Emitter {
10606
10746
  * @param audioOnly boolean
10607
10747
  * @param extra Object
10608
10748
  * @param room ?Room
10749
+ * @param meeting ?Meeting
10609
10750
  * @returns {Promise<Room>}
10610
10751
  */
10611
- static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
10612
- logger$2.info('connecting to room', { extension, audioOnly, room: !!room });
10752
+ static async connect({ extension, constraints, audioOnly = false, extra, room, meeting } ) {
10753
+ logger$3.info('connecting to room', { extension, audioOnly, room: !!room });
10613
10754
 
10614
10755
  if (!room) {
10615
10756
  await Wazo.Phone.connect();
@@ -10622,7 +10763,7 @@ class Room$1 extends Emitter {
10622
10763
 
10623
10764
  // Call_created is triggered before call_accepted, so we have to listen for it here.
10624
10765
  Wazo.Websocket.once(Wazo.Websocket.CALL_CREATED, ({ data }) => {
10625
- logger$2.info('room call received via WS', { callId: data.call_id });
10766
+ logger$3.info('room call received via WS', { callId: data.call_id });
10626
10767
  if (room) {
10627
10768
  room.setCallId(data.call_id);
10628
10769
  }
@@ -10643,34 +10784,44 @@ class Room$1 extends Emitter {
10643
10784
  room.setCallId(room.callSession.call.id);
10644
10785
  }
10645
10786
 
10646
- // Fetch conference source
10647
- const sources = await getApiClient().dird.fetchConferenceSource('default');
10648
- // Retrieve conference sources
10649
- const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10650
- // Retrieve conference
10651
- const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10787
+ if (!meeting) {
10788
+ // Fetch conference source
10789
+ const sources = await getApiClient().dird.fetchConferenceSource('default');
10790
+ // Retrieve conference sources
10791
+ const contacts = await getApiClient().dird.fetchConferenceContacts(sources.items[0]);
10792
+ // Retrieve conference
10793
+ const conference = contacts.find(contact => contact.numbers.find(number => number.number === extension));
10652
10794
 
10653
- logger$2.info('connected to room', {
10654
- sourceId: conference ? conference.sourceId : null,
10655
- name: conference ? conference.name : null,
10656
- });
10795
+ logger$3.info('connected to room', {
10796
+ sourceId: conference ? conference.sourceId : null,
10797
+ name: conference ? conference.name : null,
10798
+ });
10657
10799
 
10658
- if (conference) {
10659
- room.setSourceId(conference.sourceId);
10660
- room.setName(conference.name);
10800
+ if (conference) {
10801
+ room.setSourceId(conference.sourceId);
10802
+ room.setName(conference.name);
10803
+ }
10804
+ } else if (meeting) {
10805
+ logger$3.info('Already connected to meeting', {
10806
+ uuid: meeting.uuid,
10807
+ name: meeting.name,
10808
+ });
10809
+
10810
+ room.setMeetingUuid(meeting.uuid);
10811
+ room.setName(meeting.name);
10661
10812
  }
10662
10813
 
10663
10814
  return room;
10664
10815
  }
10665
10816
 
10666
10817
  static disconnect() {
10667
- logger$2.info('static disconnection to room');
10818
+ logger$3.info('static disconnection to room');
10668
10819
 
10669
10820
  Wazo.Phone.disconnect();
10670
10821
  }
10671
10822
 
10672
10823
  async disconnect() {
10673
- logger$2.info('disconnection to room called');
10824
+ logger$3.info('disconnection to room called');
10674
10825
 
10675
10826
  await Wazo.Phone.hangup(this.callSession);
10676
10827
  this.callSession = null;
@@ -10685,20 +10836,24 @@ class Room$1 extends Emitter {
10685
10836
  Wazo.Phone.phone.off(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10686
10837
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10687
10838
  Wazo.Websocket.off(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10688
-
10689
- if (this.roomAudioElement && document.body) {
10690
- document.body.removeChild(this.roomAudioElement);
10691
- }
10839
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10840
+ Wazo.Websocket.off(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10692
10841
  }
10693
10842
 
10694
10843
  setSourceId(sourceId ) {
10695
- logger$2.info('set room source id', { sourceId });
10844
+ logger$3.info('set room source id', { sourceId });
10696
10845
 
10697
10846
  this.sourceId = sourceId;
10698
10847
  }
10699
10848
 
10849
+ setMeetingUuid(meetingUuid ) {
10850
+ logger$3.info('set meeting uuid', { meetingUuid });
10851
+
10852
+ this.meetingUuid = meetingUuid;
10853
+ }
10854
+
10700
10855
  setCallId(callId ) {
10701
- logger$2.info('set room call id', { callId });
10856
+ logger$3.info('set room call id', { callId });
10702
10857
 
10703
10858
  if (callId) {
10704
10859
  this.callId = callId;
@@ -10706,7 +10861,7 @@ class Room$1 extends Emitter {
10706
10861
  }
10707
10862
 
10708
10863
  setName(name ) {
10709
- logger$2.info('set room name', { name });
10864
+ logger$3.info('set room name', { name });
10710
10865
 
10711
10866
  this.name = name;
10712
10867
  }
@@ -10725,7 +10880,7 @@ class Room$1 extends Emitter {
10725
10880
  }
10726
10881
 
10727
10882
  async startScreenSharing(constraints ) {
10728
- logger$2.info('start room screen sharing', { constraints });
10883
+ logger$3.info('start room screen sharing', { constraints });
10729
10884
 
10730
10885
  const screensharingStream = await Wazo.Phone.startScreenSharing(constraints, this.callSession);
10731
10886
  if (!screensharingStream) {
@@ -10738,18 +10893,26 @@ class Room$1 extends Emitter {
10738
10893
  return screensharingStream;
10739
10894
  }
10740
10895
 
10741
- stopScreenSharing(restoreLocalStream = true) {
10742
- logger$2.info('stop room screen sharing');
10896
+ async stopScreenSharing(restoreLocalStream = true) {
10897
+ logger$3.info('stop room screen sharing');
10743
10898
 
10744
- Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
10899
+ const reinvited = await Wazo.Phone.stopScreenSharing(this.callSession, restoreLocalStream);
10745
10900
 
10746
10901
  if (this.localParticipant) {
10747
10902
  this.localParticipant.onStopScreensharing();
10748
10903
  }
10904
+
10905
+ if (!reinvited && this.localParticipant) {
10906
+ // When we had video and we made a screenshare we don't reinvite when stopping the screensahre
10907
+ // So not REINVITE even is fired, we have to restore the video stream manually
10908
+ const localVideoStream = Wazo.Phone.getLocalVideoStream(this.callSession);
10909
+ // $FlowFixMe
10910
+ this._associateStreamTo(localVideoStream, this.localParticipant);
10911
+ }
10749
10912
  }
10750
10913
 
10751
10914
  turnCameraOff() {
10752
- logger$2.info('turn room camera off');
10915
+ logger$3.info('turn room camera off');
10753
10916
 
10754
10917
  Wazo.Phone.turnCameraOff(this.callSession);
10755
10918
 
@@ -10759,7 +10922,7 @@ class Room$1 extends Emitter {
10759
10922
  }
10760
10923
 
10761
10924
  turnCameraOn() {
10762
- logger$2.info('turn room camera on');
10925
+ logger$3.info('turn room camera on');
10763
10926
 
10764
10927
  Wazo.Phone.turnCameraOn(this.callSession);
10765
10928
 
@@ -10769,7 +10932,7 @@ class Room$1 extends Emitter {
10769
10932
  }
10770
10933
 
10771
10934
  mute() {
10772
- logger$2.info('mute room');
10935
+ logger$3.info('mute room');
10773
10936
 
10774
10937
  Wazo.Phone.mute(this.callSession);
10775
10938
 
@@ -10777,7 +10940,7 @@ class Room$1 extends Emitter {
10777
10940
  }
10778
10941
 
10779
10942
  unmute() {
10780
- logger$2.info('unmute room');
10943
+ logger$3.info('unmute room');
10781
10944
 
10782
10945
  Wazo.Phone.unmute(this.callSession);
10783
10946
 
@@ -10797,7 +10960,7 @@ class Room$1 extends Emitter {
10797
10960
  }
10798
10961
 
10799
10962
  hold() {
10800
- logger$2.info('hold room');
10963
+ logger$3.info('hold room');
10801
10964
 
10802
10965
  Wazo.Phone.hold(this.callSession, true);
10803
10966
 
@@ -10807,7 +10970,7 @@ class Room$1 extends Emitter {
10807
10970
  }
10808
10971
 
10809
10972
  resume() {
10810
- logger$2.info('resume room');
10973
+ logger$3.info('resume room');
10811
10974
 
10812
10975
  Wazo.Phone.resume(this.callSession, true);
10813
10976
 
@@ -10817,13 +10980,13 @@ class Room$1 extends Emitter {
10817
10980
  }
10818
10981
 
10819
10982
  sendDTMF(tone ) {
10820
- logger$2.info('send room DTMF', { tone });
10983
+ logger$3.info('send room DTMF', { tone });
10821
10984
 
10822
10985
  Wazo.Phone.sendDTMF(tone, this.callSession);
10823
10986
  }
10824
10987
 
10825
10988
  async sendReinvite(newConstraints = null) {
10826
- logger$2.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
10989
+ logger$3.info('send room reinvite', { callId: this.callSession ? this.callSession.getId() : null, newConstraints });
10827
10990
  const wasScreensharing = this.localParticipant && this.localParticipant.screensharing;
10828
10991
 
10829
10992
  Wazo.Phone.on(Wazo.Phone.ON_SHARE_SCREEN_STARTED, () => {
@@ -10848,6 +11011,22 @@ class Room$1 extends Emitter {
10848
11011
  return response;
10849
11012
  }
10850
11013
 
11014
+ hasALocalVideoTrack() {
11015
+ return Wazo.Phone.hasALocalVideoTrack(this.callSession);
11016
+ }
11017
+
11018
+ getLocalStream() {
11019
+ return Wazo.Phone.getLocalStream(this.callSession);
11020
+ }
11021
+
11022
+ getRemoteStream() {
11023
+ return Wazo.Phone.getRemoteStream(this.callSession);
11024
+ }
11025
+
11026
+ getRemoteVideoStream() {
11027
+ return Wazo.Phone.getRemoteVideoStream(this.callSession);
11028
+ }
11029
+
10851
11030
  _bindEvents() {
10852
11031
  if (!Wazo.Phone.phone || !Wazo.Phone.phone.currentSipSession) {
10853
11032
  return;
@@ -10866,35 +11045,18 @@ class Room$1 extends Emitter {
10866
11045
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
10867
11046
 
10868
11047
  this.on(this.ON_AUDIO_STREAM, stream => {
10869
- logger$2.info('on room audio stream');
11048
+ logger$3.info('on room audio stream');
10870
11049
 
10871
11050
  this.audioStream = stream;
10872
- if (document.createElement) {
10873
- // $FlowFixMe
10874
- let roomAudioElement = document.getElementById('audio-room');
10875
- if (!this.roomAudioElement) {
10876
- roomAudioElement = document.createElement('audio');
10877
- // $FlowFixMe
10878
- document.body.appendChild(roomAudioElement);
10879
- }
10880
- if (!roomAudioElement) {
10881
- return;
10882
- }
10883
- this.roomAudioElement = roomAudioElement;
11051
+ if (!this.roomAudioElement) {
11052
+ const sessionId = Wazo.Phone.phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11053
+ this.roomAudioElement = Wazo.Phone.phone.createAudioElementFor(sessionId);
10884
11054
  this.roomAudioElement.srcObject = stream;
10885
- this.roomAudioElement.autoplay = true;
10886
- this.roomAudioElement.id = 'audio-room';
10887
-
10888
- // $FlowFixMe
10889
- if (this.roomAudioElement.setSinkId) {
10890
- // $FlowFixMe
10891
- this.roomAudioElement.setSinkId(Wazo.Phone.getOutputDevice());
10892
- }
10893
11055
  }
10894
11056
  });
10895
11057
 
10896
11058
  this.on(this.ON_VIDEO_STREAM, (stream, streamId, event, sipSession) => {
10897
- logger$2.info('on room video stream', { streamId });
11059
+ logger$3.info('on room video stream', { streamId });
10898
11060
 
10899
11061
  this._mapMsid(sipSession.body.body);
10900
11062
 
@@ -10909,7 +11071,7 @@ class Room$1 extends Emitter {
10909
11071
  });
10910
11072
 
10911
11073
  this.on(this.ON_REMOVE_STREAM, stream => {
10912
- logger$2.info('on room remove stream');
11074
+ logger$3.info('on room remove stream');
10913
11075
 
10914
11076
  const participant = this.participants.find(someParticipant =>
10915
11077
  someParticipant.streams.find(someStream => someStream && someStream.id === stream.id));
@@ -10964,6 +11126,9 @@ class Room$1 extends Emitter {
10964
11126
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
10965
11127
  Wazo.Websocket.on(this.CONFERENCE_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
10966
11128
 
11129
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_JOINED, this._boundOnParticipantJoined);
11130
+ Wazo.Websocket.on(this.MEETING_USER_PARTICIPANT_LEFT, this._boundOnParticipantLeft);
11131
+
10967
11132
  // Phone events
10968
11133
  Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
10969
11134
  Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
@@ -10974,15 +11139,15 @@ class Room$1 extends Emitter {
10974
11139
  Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
10975
11140
  }
10976
11141
 
10977
- _onMessage(message ) {
11142
+ _onMessage(message ) {
10978
11143
  if (message.method !== 'MESSAGE') {
10979
- return;
11144
+ return null;
10980
11145
  }
10981
11146
  let body;
10982
11147
  try {
10983
11148
  body = JSON.parse(message.body);
10984
11149
  } catch (e) {
10985
- return;
11150
+ return null;
10986
11151
  }
10987
11152
 
10988
11153
  switch (body.type) {
@@ -11001,6 +11166,8 @@ class Room$1 extends Emitter {
11001
11166
  }
11002
11167
 
11003
11168
  this.eventEmitter.emit(this.ON_MESSAGE, body);
11169
+
11170
+ return body;
11004
11171
  }
11005
11172
 
11006
11173
  _onChat(content ) {
@@ -11036,7 +11203,7 @@ class Room$1 extends Emitter {
11036
11203
  const requester = this._getParticipantFromCallId(origin.callId);
11037
11204
  if (requester) {
11038
11205
  // @FIXME?: when need to trigger an update on join-in; this is a bit of a hack
11039
- logger$2.info('trigger room requester status', { origin });
11206
+ logger$3.info('trigger room requester status', { origin });
11040
11207
  requester.triggerUpdate('REQUESTER_UPDATE');
11041
11208
  }
11042
11209
  break;
@@ -11065,25 +11232,26 @@ class Room$1 extends Emitter {
11065
11232
  const session = Wazo.Auth.getSession();
11066
11233
  let participants = [];
11067
11234
 
11068
- // @TODO: we could use a better function name here
11069
- const isJoining = part => {
11070
- this.__associateStreams(part);
11071
- // @VALIDATE: no need to publicize ourselves, no?
11072
- if (part instanceof RemoteParticipant) {
11073
- this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, part);
11074
- }
11075
- };
11076
-
11077
11235
  // When we join the room, we can call `getConferenceParticipantsAsUser`, not before.
11078
11236
  if (participant.user_uuid === session.uuid) {
11079
- logger$2.info('room current user joined');
11237
+ logger$3.info('room current user joined');
11080
11238
 
11081
11239
  // Retrieve participants via an API calls
11082
11240
  const conferenceId = this.sourceId || payload.data.conference_id;
11083
- const response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11084
- logger$2.info('fetching conference participants', { conferenceId });
11241
+ let response;
11242
+ try {
11243
+ if (this.meetingUuid) {
11244
+ logger$3.info('fetching meeting participants', { meetingUuid: this.meetingUuid });
11245
+ response = await getApiClient().calld.getMeetingParticipantsAsUser(this.meetingUuid);
11246
+ } else {
11247
+ logger$3.info('fetching conference participants', { conferenceId });
11248
+ response = await getApiClient().calld.getConferenceParticipantsAsUser(conferenceId);
11249
+ }
11250
+ } catch (e) {
11251
+ logger$3.error('room participants fetching, error', e);
11252
+ }
11085
11253
  if (response) {
11086
- logger$2.info('conference participants fetched', { nb: response.items.length });
11254
+ logger$3.info('conference participants fetched', { nb: response.items.length });
11087
11255
  participants = response.items.map(item => {
11088
11256
  const isMe = item.call_id === this.callId;
11089
11257
 
@@ -11096,25 +11264,10 @@ class Room$1 extends Emitter {
11096
11264
 
11097
11265
  const localParticipant = participants.find(someParticipant => someParticipant instanceof Wazo.LocalParticipant);
11098
11266
  if (!this.localParticipant && localParticipant) {
11099
- this.localParticipant = localParticipant;
11100
-
11101
- const localVideoStream = this._getLocalVideoStream();
11102
- if (localVideoStream) {
11103
- this._saveLocalVideoStream(localVideoStream);
11104
- }
11105
-
11106
- this.connected = true;
11107
-
11108
- // we're in the room, now let's request everyone's status
11109
- if (this.localParticipant) {
11110
- this.sendSignal({
11111
- type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11112
- origin: this.localParticipant.getStatus(),
11113
- });
11114
- }
11267
+ this._onLocalParticipantJoined(localParticipant);
11115
11268
  }
11116
11269
 
11117
- participants.forEach(someParticipant => isJoining(someParticipant));
11270
+ participants.forEach(someParticipant => this._isParticipantJoining(someParticipant));
11118
11271
  this.eventEmitter.emit(this.ON_JOINED, localParticipant, participants);
11119
11272
  }
11120
11273
 
@@ -11125,16 +11278,45 @@ class Room$1 extends Emitter {
11125
11278
  ? new Wazo.RemoteParticipant(this, participant)
11126
11279
  : null;
11127
11280
 
11128
- logger$2.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11281
+ logger$3.info('other room user joined', { callId: participant.call_id, remoteParticipant: !!remoteParticipant });
11129
11282
 
11130
11283
  if (remoteParticipant) {
11131
11284
  this.participants.push(remoteParticipant);
11132
- isJoining(remoteParticipant);
11285
+ this._isParticipantJoining(remoteParticipant);
11133
11286
  }
11134
11287
 
11135
11288
  return remoteParticipant;
11136
11289
  }
11137
11290
 
11291
+ _onLocalParticipantJoined(localParticipant ) {
11292
+ this.localParticipant = localParticipant;
11293
+
11294
+ const localVideoStream = this._getLocalVideoStream();
11295
+ if (localVideoStream) {
11296
+ this._saveLocalVideoStream(localVideoStream);
11297
+ }
11298
+
11299
+ this.connected = true;
11300
+
11301
+ localParticipant.broadcastStatus();
11302
+
11303
+ // we're in the room, now let's request everyone's status
11304
+ if (this.localParticipant) {
11305
+ this.sendSignal({
11306
+ type: SIGNAL_TYPE_PARTICIPANT_REQUEST,
11307
+ origin: this.localParticipant.getStatus(),
11308
+ });
11309
+ }
11310
+ }
11311
+
11312
+ _isParticipantJoining(participant ) {
11313
+ this.__associateStreams(participant);
11314
+ // @VALIDATE: no need to publicize ourselves, no?
11315
+ if (participant instanceof RemoteParticipant) {
11316
+ this.eventEmitter.emit(this.CONFERENCE_USER_PARTICIPANT_JOINED, participant);
11317
+ }
11318
+ }
11319
+
11138
11320
  _saveLocalVideoStream(stream ) {
11139
11321
  const { localParticipant } = this;
11140
11322
 
@@ -11180,9 +11362,11 @@ class Room$1 extends Emitter {
11180
11362
  _onParticipantTrackUpdate(oldParticipant , update ) {
11181
11363
  const newParticipant = oldParticipant;
11182
11364
 
11183
- const { trackId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11365
+ const { trackId, streamId } = this._callIdStreamIdMap[newParticipant.callId] || {};
11184
11366
  const pc = Wazo.Phone.phone.currentSipSession.sessionDescriptionHandler.peerConnection;
11185
- const stream = pc.getRemoteStreams().find(someStream => someStream.getTracks().some(track => track.id === trackId));
11367
+ // Can't use `getReceivers` here because on FF we make the mapping based on the streamId
11368
+ const stream = pc.getRemoteStreams().find(someStream =>
11369
+ someStream.id === streamId || someStream.getTracks().some(track => track.id === trackId));
11186
11370
 
11187
11371
  if (update === 'downgrade') {
11188
11372
  newParticipant.streams = [];
@@ -11212,15 +11396,42 @@ class Room$1 extends Emitter {
11212
11396
  return;
11213
11397
  }
11214
11398
 
11215
- if (this._unassociatedVideoStreams[trackId]) {
11399
+ const streamId = this._getStreamIdFrTrackId(trackId);
11400
+ const key = this._getUnassociatedMapIdFromTrackIdOrStreamId(trackId, streamId);
11401
+ const stream = this._unassociatedVideoStreams[key];
11402
+
11403
+ if (stream) {
11216
11404
  // Try to associate stream
11217
- this._associateStreamTo(this._unassociatedVideoStreams[trackId], participant);
11405
+ this._associateStreamTo(stream, participant);
11218
11406
 
11219
- delete this._unassociatedVideoStreams[trackId];
11407
+ delete this._unassociatedVideoStreams[key];
11220
11408
  delete this._unassociatedParticipants[participant.callId];
11221
11409
  }
11222
11410
  }
11223
11411
 
11412
+ _getUnassociatedMapIdFromTrackIdOrStreamId(trackId , streamId ) {
11413
+ // Find by trackId
11414
+ if (trackId in this._unassociatedVideoStreams) {
11415
+ return trackId;
11416
+ }
11417
+
11418
+ // Find by streamId
11419
+ if (streamId && streamId in this._unassociatedVideoStreams) {
11420
+ return streamId;
11421
+ }
11422
+
11423
+ // Find in all the streams by streamId (used on FF where we can't map by trackId)
11424
+ const idx = Object.values(this._unassociatedVideoStreams).findIndex((stream ) =>
11425
+ stream && stream.id === streamId);
11426
+ return idx === -1 ? null : Object.keys(this._unassociatedVideoStreams)[idx];
11427
+ }
11428
+
11429
+ _getStreamIdFrTrackId(trackId ) {
11430
+ const mapping = Object.values(this._callIdStreamIdMap).find((map ) => map.trackId === trackId);
11431
+
11432
+ return mapping ? mapping.streamId : null;
11433
+ }
11434
+
11224
11435
  _associateStreamTo(rawStream , participant ) {
11225
11436
  const stream = new Wazo.Stream(rawStream, participant);
11226
11437
  participant.streams.push(stream);
@@ -11244,7 +11455,141 @@ class Room$1 extends Emitter {
11244
11455
 
11245
11456
  //
11246
11457
 
11247
- class LocalParticipant extends Participant {
11458
+ const logger$2 = IssueReporter$1.loggerFor('sdk-sip-room');
11459
+
11460
+ class SipRoom extends Room$1 {
11461
+
11462
+ static async connect({ extension, constraints, audioOnly = false, extra, room } ) {
11463
+ logger$2.info('connecting to sip room', { extension, audioOnly, room: !!room });
11464
+
11465
+ if (!room) {
11466
+ await Wazo.Phone.connect();
11467
+
11468
+ const withCamera = constraints && !!constraints.video;
11469
+
11470
+ const callSession = await Wazo.Phone.call(extension, withCamera, null, audioOnly, true);
11471
+ // eslint-disable-next-line no-param-reassign
11472
+ room = new SipRoom(callSession, extension, null, null, extra);
11473
+ }
11474
+
11475
+ if (room && room.callSession && room.callSession.call) {
11476
+ room.setCallId(room.callSession.call.id);
11477
+ }
11478
+
11479
+ logger$2.info('connected to room', {
11480
+ extension: room.extension,
11481
+ });
11482
+
11483
+ return room;
11484
+ }
11485
+
11486
+ mute() {
11487
+ logger$2.info('mute sip room');
11488
+
11489
+ Wazo.Phone.mute(this.callSession, false);
11490
+
11491
+ this.sendMuteStatus();
11492
+ }
11493
+
11494
+ unmute() {
11495
+ logger$2.info('unmute sip room');
11496
+
11497
+ Wazo.Phone.unmute(this.callSession, false);
11498
+
11499
+ this.sendUnMuteStatus();
11500
+ }
11501
+
11502
+ getLocalGuestName() {
11503
+ return Wazo.Phone.phone.client.userAgent.options.displayName;
11504
+ }
11505
+
11506
+ // Overridden to not listen to websocket messages
11507
+ _transferEvents() {
11508
+ // Phone events
11509
+ Wazo.Phone.on(this.ON_MESSAGE, this._boundOnMessage);
11510
+ Wazo.Phone.on(this.ON_CHAT, this._boundOnChat);
11511
+ Wazo.Phone.on(this.ON_SIGNAL, this._boundOnSignal);
11512
+ Wazo.Phone.on(this.ON_VIDEO_INPUT_CHANGE, this._boundSaveLocalVideoStream);
11513
+
11514
+ [this.ON_AUDIO_STREAM, this.ON_VIDEO_STREAM, this.ON_REMOVE_STREAM].forEach(event =>
11515
+ Wazo.Phone.on(event, (...args) => this.eventEmitter.emit.apply(this.eventEmitter, [event, ...args])));
11516
+ }
11517
+
11518
+ _onMessage(message ) {
11519
+ // eslint-disable-next-line no-underscore-dangle
11520
+ const body = super._onMessage(message);
11521
+ if (!body) {
11522
+ return;
11523
+ }
11524
+
11525
+ const getChannel = () => body.channels[0];
11526
+
11527
+ switch (body.type) {
11528
+ case 'ConfbridgeWelcome':
11529
+ body.channels.forEach(channel => {
11530
+ this._onParticipantJoined(channel);
11531
+ });
11532
+
11533
+ break;
11534
+ case 'ConfbridgeJoin': {
11535
+ const channel = getChannel();
11536
+ this._onParticipantJoined(channel);
11537
+ break;
11538
+ }
11539
+ case 'ConfbridgeLeave': {
11540
+ const channel = getChannel();
11541
+ this._onParticipantLeft({
11542
+ data: {
11543
+ call_id: channel.id,
11544
+ },
11545
+ });
11546
+ break;
11547
+ }
11548
+ }
11549
+ }
11550
+
11551
+ async _onParticipantJoined(channel ) {
11552
+ const isLocal = channel.channelvars.WAZO_SIP_CALL_ID === this._getCurrentSipCallIs();
11553
+ const callId = channel.id;
11554
+ const ParticipantClass = isLocal ? Wazo.LocalParticipant : Wazo.RemoteParticipant;
11555
+ const name = channel.caller ? channel.caller.name : null;
11556
+ const extra = isLocal ? { guestName: this.getLocalGuestName() } : {};
11557
+ const participant = new ParticipantClass(this, {
11558
+ caller_id_name: name,
11559
+ call_id: callId,
11560
+ }, extra);
11561
+
11562
+ const participantIdx = this.participants.findIndex(other => other.callId === participant.callId);
11563
+ if (participantIdx !== -1 && name) {
11564
+ this.participants[participantIdx].name = name;
11565
+ return;
11566
+ }
11567
+
11568
+ if (isLocal) {
11569
+ // Should be updated by the Wazo WS but we don't have it for now
11570
+ if (this.callSession) {
11571
+ this.callSession.ringing = false;
11572
+ }
11573
+
11574
+ this._onLocalParticipantJoined(participant);
11575
+
11576
+ // Give some time for the stream to be updated
11577
+ setTimeout(() => {
11578
+ this.eventEmitter.emit(this.ON_JOINED, participant, this.participants);
11579
+ }, 1000);
11580
+ }
11581
+
11582
+ this.participants.push(participant);
11583
+
11584
+ this._isParticipantJoining(participant);
11585
+
11586
+ return participant;
11587
+ }
11588
+
11589
+ _getCurrentSipCallIs() {
11590
+ return Wazo.Phone.getSipSessionId(Wazo.Phone.phone.currentSipSession);
11591
+ }
11592
+
11248
11593
  }
11249
11594
 
11250
11595
  /* global document */
@@ -11297,9 +11642,7 @@ class Stream {
11297
11642
  return false;
11298
11643
  }
11299
11644
 
11300
- // With canvas track (used to fake upgrade in conference), we don't have a width
11301
- return this.htmlStream.getTracks().find(track => track.kind === 'video'
11302
- && track.readyState !== 'ended' && 'width' in track.getSettings());
11645
+ return this.htmlStream.getTracks().some(track => track.kind === 'video' && track.readyState !== 'ended');
11303
11646
  }
11304
11647
 
11305
11648
  get id() {
@@ -12200,6 +12543,7 @@ const Wazo = {
12200
12543
  Phone: Phone$1,
12201
12544
  Websocket: Websocket$1,
12202
12545
  Room: Room$1,
12546
+ SipRoom,
12203
12547
  RemoteParticipant,
12204
12548
  LocalParticipant,
12205
12549
  Stream,
@@ -12236,6 +12580,7 @@ const Wazo = {
12236
12580
  IndirectTransfer,
12237
12581
  SwitchboardCall,
12238
12582
  WebRTCPhone,
12583
+ Meeting,
12239
12584
  },
12240
12585
 
12241
12586
  // Api
@@ -12422,13 +12767,18 @@ class Phone extends Emitter {
12422
12767
  return adHocConference.start();
12423
12768
  }
12424
12769
 
12425
- mute(callSession ) {
12426
- this.muteViaAPI(callSession);
12770
+ mute(callSession , withApi = true) {
12771
+ if (withApi) {
12772
+ this.muteViaAPI(callSession);
12773
+ }
12774
+
12427
12775
  return this.phone && this.phone.mute(callSession);
12428
12776
  }
12429
12777
 
12430
- unmute(callSession ) {
12431
- this.unmuteViaAPI(callSession);
12778
+ unmute(callSession , withApi = true) {
12779
+ if (withApi) {
12780
+ this.unmuteViaAPI(callSession);
12781
+ }
12432
12782
 
12433
12783
  return this.phone && this.phone.unmute(callSession);
12434
12784
  }
@@ -12534,6 +12884,10 @@ class Phone extends Emitter {
12534
12884
  return this.phone && this.phone.hasLocalVideo(callSession);
12535
12885
  }
12536
12886
 
12887
+ hasALocalVideoTrack(callSession ) {
12888
+ return this.phone && this.phone.hasALocalVideoTrack(callSession);
12889
+ }
12890
+
12537
12891
  // @Deprecated
12538
12892
  getLocalMediaStream(callSession ) {
12539
12893
  logger.warn('Phone.getLocalMediaStream is deprecated, use Phone.getLocalStream instead');