@stream-io/video-client 0.0.1-alpha.91 → 0.0.1-alpha.93

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 (38) hide show
  1. package/dist/index.browser.es.js +481 -414
  2. package/dist/index.browser.es.js.map +1 -1
  3. package/dist/index.cjs.js +481 -414
  4. package/dist/index.cjs.js.map +1 -1
  5. package/dist/index.es.js +481 -414
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/src/coordinator/connection/client.d.ts +4 -4
  8. package/dist/src/coordinator/connection/types.d.ts +6 -8
  9. package/dist/src/events/call-permissions.d.ts +3 -4
  10. package/dist/src/events/call.d.ts +6 -8
  11. package/dist/src/events/moderation.d.ts +3 -3
  12. package/dist/src/events/reactions.d.ts +3 -3
  13. package/dist/src/events/recording.d.ts +3 -3
  14. package/dist/src/gen/coordinator/index.d.ts +51 -51
  15. package/dist/src/permissions/PermissionsContext.d.ts +38 -0
  16. package/dist/src/permissions/index.d.ts +1 -0
  17. package/dist/src/rtc/Call.d.ts +78 -4
  18. package/dist/src/rtc/callEventHandlers.d.ts +1 -1
  19. package/dist/src/rtc/types.d.ts +0 -8
  20. package/dist/src/store/rxUtils.d.ts +7 -0
  21. package/generate-openapi.sh +3 -4
  22. package/openapitools.json +1 -1
  23. package/package.json +1 -1
  24. package/src/StreamVideoClient.ts +25 -40
  25. package/src/coordinator/connection/client.ts +11 -11
  26. package/src/coordinator/connection/types.ts +7 -49
  27. package/src/events/call-permissions.ts +10 -66
  28. package/src/events/call.ts +15 -67
  29. package/src/events/moderation.ts +5 -34
  30. package/src/events/reactions.ts +5 -16
  31. package/src/events/recording.ts +5 -27
  32. package/src/gen/coordinator/index.ts +51 -51
  33. package/src/permissions/PermissionsContext.ts +63 -0
  34. package/src/permissions/index.ts +1 -0
  35. package/src/rtc/Call.ts +178 -61
  36. package/src/rtc/callEventHandlers.ts +39 -16
  37. package/src/rtc/types.ts +1 -10
  38. package/src/store/rxUtils.ts +16 -0
@@ -12,93 +12,93 @@ import { fromByteArray } from 'base64-js';
12
12
  * @export
13
13
  */
14
14
  const DeviceFieldsRequestPushProviderEnum = {
15
- firebase: 'firebase',
16
- apn: 'apn',
17
- huawei: 'huawei',
18
- xiaomi: 'xiaomi',
15
+ FIREBASE: 'firebase',
16
+ APN: 'apn',
17
+ HUAWEI: 'huawei',
18
+ XIAOMI: 'xiaomi',
19
19
  };
20
20
  /**
21
21
  * All possibility of string to use
22
22
  * @export
23
23
  */
24
24
  const OwnCapability = {
25
- block_users: 'block-users',
26
- create_call: 'create-call',
27
- create_reaction: 'create-reaction',
28
- end_call: 'end-call',
29
- join_backstage: 'join-backstage',
30
- join_call: 'join-call',
31
- join_ended_call: 'join-ended-call',
32
- mute_users: 'mute-users',
33
- read_call: 'read-call',
34
- remove_call_member: 'remove-call-member',
35
- screenshare: 'screenshare',
36
- send_audio: 'send-audio',
37
- send_video: 'send-video',
38
- start_broadcast_call: 'start-broadcast-call',
39
- start_record_call: 'start-record-call',
40
- start_transcription_call: 'start-transcription-call',
41
- stop_broadcast_call: 'stop-broadcast-call',
42
- stop_record_call: 'stop-record-call',
43
- stop_transcription_call: 'stop-transcription-call',
44
- update_call: 'update-call',
45
- update_call_member: 'update-call-member',
46
- update_call_permissions: 'update-call-permissions',
47
- update_call_settings: 'update-call-settings',
25
+ BLOCK_USERS: 'block-users',
26
+ CREATE_CALL: 'create-call',
27
+ CREATE_REACTION: 'create-reaction',
28
+ END_CALL: 'end-call',
29
+ JOIN_BACKSTAGE: 'join-backstage',
30
+ JOIN_CALL: 'join-call',
31
+ JOIN_ENDED_CALL: 'join-ended-call',
32
+ MUTE_USERS: 'mute-users',
33
+ READ_CALL: 'read-call',
34
+ REMOVE_CALL_MEMBER: 'remove-call-member',
35
+ SCREENSHARE: 'screenshare',
36
+ SEND_AUDIO: 'send-audio',
37
+ SEND_VIDEO: 'send-video',
38
+ START_BROADCAST_CALL: 'start-broadcast-call',
39
+ START_RECORD_CALL: 'start-record-call',
40
+ START_TRANSCRIPTION_CALL: 'start-transcription-call',
41
+ STOP_BROADCAST_CALL: 'stop-broadcast-call',
42
+ STOP_RECORD_CALL: 'stop-record-call',
43
+ STOP_TRANSCRIPTION_CALL: 'stop-transcription-call',
44
+ UPDATE_CALL: 'update-call',
45
+ UPDATE_CALL_MEMBER: 'update-call-member',
46
+ UPDATE_CALL_PERMISSIONS: 'update-call-permissions',
47
+ UPDATE_CALL_SETTINGS: 'update-call-settings',
48
48
  };
49
49
  /**
50
50
  * @export
51
51
  */
52
52
  const RecordSettingsModeEnum = {
53
- available: 'available',
54
- disabled: 'disabled',
55
- auto_on: 'auto-on',
53
+ AVAILABLE: 'available',
54
+ DISABLED: 'disabled',
55
+ AUTO_ON: 'auto-on',
56
56
  };
57
57
  /**
58
58
  * @export
59
59
  */
60
60
  const RecordSettingsQualityEnum = {
61
- audio_only: 'audio-only',
62
- _360p: '360p',
63
- _480p: '480p',
64
- _720p: '720p',
65
- _1080p: '1080p',
66
- _1440p: '1440p',
61
+ AUDIO_ONLY: 'audio-only',
62
+ _360P: '360p',
63
+ _480P: '480p',
64
+ _720P: '720p',
65
+ _1080P: '1080p',
66
+ _1440P: '1440p',
67
67
  };
68
68
  /**
69
69
  * @export
70
70
  */
71
71
  const RecordSettingsRequestModeEnum = {
72
- available: 'available',
73
- disabled: 'disabled',
74
- auto_on: 'auto-on',
72
+ AVAILABLE: 'available',
73
+ DISABLED: 'disabled',
74
+ AUTO_ON: 'auto-on',
75
75
  };
76
76
  /**
77
77
  * @export
78
78
  */
79
79
  const RecordSettingsRequestQualityEnum = {
80
- audio_only: 'audio-only',
81
- _360p: '360p',
82
- _480p: '480p',
83
- _720p: '720p',
84
- _1080p: '1080p',
85
- _1440p: '1440p',
80
+ AUDIO_ONLY: 'audio-only',
81
+ _360P: '360p',
82
+ _480P: '480p',
83
+ _720P: '720p',
84
+ _1080P: '1080p',
85
+ _1440P: '1440p',
86
86
  };
87
87
  /**
88
88
  * @export
89
89
  */
90
90
  const TranscriptionSettingsModeEnum = {
91
- available: 'available',
92
- disabled: 'disabled',
93
- auto_on: 'auto-on',
91
+ AVAILABLE: 'available',
92
+ DISABLED: 'disabled',
93
+ AUTO_ON: 'auto-on',
94
94
  };
95
95
  /**
96
96
  * @export
97
97
  */
98
98
  const TranscriptionSettingsRequestModeEnum = {
99
- available: 'available',
100
- disabled: 'disabled',
101
- auto_on: 'auto-on',
99
+ AVAILABLE: 'available',
100
+ DISABLED: 'disabled',
101
+ AUTO_ON: 'auto-on',
102
102
  };
103
103
 
104
104
  class ErrorFromResponse extends Error {
@@ -4653,6 +4653,127 @@ class Publisher {
4653
4653
  }
4654
4654
  }
4655
4655
 
4656
+ /**
4657
+ * Event handler that watched the delivery of CallAcceptedEvent
4658
+ * Updates the state store and notifies its subscribers that
4659
+ * the given user will be joining the call.
4660
+ */
4661
+ const watchCallAccepted = (store) => {
4662
+ return function onCallAccepted(event) {
4663
+ if (event.type !== 'call.accepted')
4664
+ return;
4665
+ const { call_cid } = event;
4666
+ const acceptedIncomingCall = store.incomingCalls.find((incomingCall) => incomingCall.cid === call_cid);
4667
+ if (acceptedIncomingCall) {
4668
+ console.warn('Received CallAcceptedEvent for an incoming call');
4669
+ return;
4670
+ }
4671
+ const acceptedOutgoingCall = store.outgoingCalls.find((outgoingCall) => outgoingCall.cid === call_cid);
4672
+ const activeCall = store.activeCall;
4673
+ // FIXME OL: we should revisit this logic, it is hard to follow
4674
+ const acceptedActiveCall = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.cid) !== undefined && activeCall.cid === call_cid
4675
+ ? activeCall
4676
+ : undefined;
4677
+ if (!acceptedOutgoingCall && !acceptedActiveCall) {
4678
+ console.warn(`CallAcceptedEvent received for a non-existent outgoing call (CID: ${call_cid}`);
4679
+ return;
4680
+ }
4681
+ // once in active call, it is unnecessary to keep track of accepted call events
4682
+ if (call_cid === (acceptedActiveCall === null || acceptedActiveCall === void 0 ? void 0 : acceptedActiveCall.cid)) {
4683
+ return;
4684
+ }
4685
+ // do not set a new accepted call while in an active call? It would lead to joining a new active call.
4686
+ // todo: solve the situation of 2nd outgoing call being accepted in the UI SDK
4687
+ store.setAcceptedCall(event);
4688
+ };
4689
+ };
4690
+ /**
4691
+ * Event handler that watches delivery of CallRejected Websocket event.
4692
+ * Updates the state store and notifies its subscribers that
4693
+ * the given user will not be joining the call.
4694
+ */
4695
+ const watchCallRejected = (store) => {
4696
+ return function onCallRejected(event) {
4697
+ if (event.type !== 'call.rejected')
4698
+ return;
4699
+ const { call_cid } = event;
4700
+ const rejectedIncomingCall = store.incomingCalls.find((incomingCall) => incomingCall.cid === call_cid);
4701
+ if (rejectedIncomingCall) {
4702
+ console.warn('Received CallRejectedEvent for an incoming call');
4703
+ return;
4704
+ }
4705
+ const rejectedOutgoingCall = store.outgoingCalls.find((outgoingCall) => outgoingCall.cid === call_cid);
4706
+ const activeCall = store.activeCall;
4707
+ const rejectedActiveCall = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.cid) !== undefined && activeCall.cid === call_cid
4708
+ ? activeCall
4709
+ : undefined;
4710
+ if (!rejectedOutgoingCall && !rejectedActiveCall) {
4711
+ console.warn(`CallRejectedEvent received for a non-existent outgoing call (CID: ${call_cid}`);
4712
+ return;
4713
+ }
4714
+ // FIXME: we should remove the call from pending once every callee has rejected, but for now we support only 1:1 ring calls
4715
+ store.setPendingCalls((pendingCalls) => pendingCalls.filter((pendingCall) => pendingCall.cid !== call_cid));
4716
+ };
4717
+ };
4718
+ /**
4719
+ * Event handler that watches the delivery of CallEndedEvent
4720
+ * Updates the state store and notifies its subscribers that
4721
+ * the call is now considered terminated.
4722
+ */
4723
+ const watchCallCancelled = (store) => {
4724
+ return function onCallCancelled(event) {
4725
+ if (event.type !== 'call.ended')
4726
+ return;
4727
+ const { call_cid } = event;
4728
+ const cancelledIncomingCall = store.incomingCalls.find((incomingCall) => incomingCall.cid === call_cid);
4729
+ const activeCall = store.activeCall;
4730
+ const cancelledActiveCall = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.cid) !== undefined && activeCall.cid === call_cid
4731
+ ? activeCall
4732
+ : undefined;
4733
+ if (!cancelledIncomingCall && !cancelledActiveCall) {
4734
+ console.warn(`CallEndedEvent received for a non-existent incoming call (CID: ${call_cid}`);
4735
+ return;
4736
+ }
4737
+ store.setPendingCalls((pendingCalls) => pendingCalls.filter((pendingCall) => pendingCall.cid !== call_cid));
4738
+ };
4739
+ };
4740
+ /**
4741
+ * An event handler which listens to `call.updated` events
4742
+ * and updates the given call state accordingly.
4743
+ */
4744
+ const watchCallUpdated = (state) => {
4745
+ return function onCallUpdated(event) {
4746
+ if (event.type !== 'call.updated')
4747
+ return;
4748
+ state.setMetadata(event.call);
4749
+ };
4750
+ };
4751
+
4752
+ /**
4753
+ * Event handler that watches for `call.permission_request` events
4754
+ * Updates the state store using the `callPermissionRequest$` stream
4755
+ */
4756
+ const watchCallPermissionRequest = (state) => {
4757
+ return function onCallPermissionRequest(event) {
4758
+ if (event.type !== 'call.permission_request')
4759
+ return;
4760
+ state.setCallPermissionRequest(event);
4761
+ };
4762
+ };
4763
+ /**
4764
+ * Event handler that watches for `call.permissions_updated` events
4765
+ */
4766
+ const watchCallPermissionsUpdated = (state) => {
4767
+ return function onCallPermissionsUpdated(event) {
4768
+ if (event.type !== 'call.permissions_updated')
4769
+ return;
4770
+ const { localParticipant } = state;
4771
+ if (event.user.id === (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
4772
+ state.setMetadata((metadata) => (Object.assign(Object.assign({}, metadata), { own_capabilities: event.own_capabilities })));
4773
+ }
4774
+ };
4775
+ };
4776
+
4656
4777
  /**
4657
4778
  * An event responder which handles the `changePublishQuality` event.
4658
4779
  */
@@ -4750,6 +4871,57 @@ const watchTrackUnpublished = (dispatcher, state) => {
4750
4871
  };
4751
4872
  const unique = (v, i, arr) => arr.indexOf(v) === i;
4752
4873
 
4874
+ /**
4875
+ * Watches the delivery of CallReactionEvent.
4876
+ *
4877
+ * @param state the state store to update.
4878
+ */
4879
+ const watchNewReactions = (state) => {
4880
+ return function onNewReactions(event) {
4881
+ if (event.type !== 'call.reaction_new')
4882
+ return;
4883
+ const { reaction } = event;
4884
+ const { user, custom, type, emoji_code } = reaction;
4885
+ state.setParticipants((participants) => {
4886
+ return participants.map((p) => {
4887
+ // skip if the reaction is not for this participant
4888
+ if (p.userId !== user.id)
4889
+ return p;
4890
+ // skip if the reaction is not for this session
4891
+ if (custom.sessionId && p.sessionId !== custom.sessionId)
4892
+ return p;
4893
+ // update the participant with the new reaction
4894
+ return Object.assign(Object.assign({}, p), { reaction: {
4895
+ type,
4896
+ emoji_code,
4897
+ custom,
4898
+ } });
4899
+ });
4900
+ });
4901
+ };
4902
+ };
4903
+
4904
+ /**
4905
+ * Watches for `call.recording_started` events.
4906
+ */
4907
+ const watchCallRecordingStarted = (state) => {
4908
+ return function onCallRecordingStarted(event) {
4909
+ if (event.type !== 'call.recording_started')
4910
+ return;
4911
+ state.setCallRecordingInProgress(true);
4912
+ };
4913
+ };
4914
+ /**
4915
+ * Watches for `call.recording_stopped` events.
4916
+ */
4917
+ const watchCallRecordingStopped = (state) => {
4918
+ return function onCallRecordingStopped(event) {
4919
+ if (event.type !== 'call.recording_stopped')
4920
+ return;
4921
+ state.setCallRecordingInProgress(false);
4922
+ };
4923
+ };
4924
+
4753
4925
  /**
4754
4926
  * Watches for `dominantSpeakerChanged` events.
4755
4927
  */
@@ -4792,15 +4964,52 @@ const watchAudioLevelChanged = (dispatcher, state) => {
4792
4964
  });
4793
4965
  };
4794
4966
 
4795
- const registerEventHandlers = (call, store, dispatcher) => {
4796
- watchChangePublishQuality(dispatcher, call);
4797
- watchConnectionQualityChanged(dispatcher, store);
4798
- watchParticipantJoined(dispatcher, store);
4799
- watchParticipantLeft(dispatcher, store);
4800
- watchTrackPublished(dispatcher, store);
4801
- watchTrackUnpublished(dispatcher, store);
4802
- watchAudioLevelChanged(dispatcher, store);
4803
- watchDominantSpeakerChanged(dispatcher, store);
4967
+ /**
4968
+ * Event handler that watches for `call.blocked_user` events,
4969
+ * updates the call store `blocked_user_ids` property by adding
4970
+ * `event.user_id` to the list
4971
+ */
4972
+ const watchBlockedUser = (state) => (event) => {
4973
+ if (event.type !== 'call.blocked_user')
4974
+ return;
4975
+ state.setMetadata((metadata) => (Object.assign(Object.assign({}, metadata), { blocked_user_ids: [...metadata.blocked_user_ids, event.user.id] })));
4976
+ };
4977
+ /**
4978
+ * Event handler that watches for `call.unblocked_user` events,
4979
+ * updates the call store `blocked_user_ids` property by
4980
+ * removing `event.user_id` from the list
4981
+ */
4982
+ const watchUnblockedUser = (state) => (event) => {
4983
+ if (event.type !== 'call.unblocked_user')
4984
+ return;
4985
+ state.setMetadata((metadata) => {
4986
+ const blocked_user_ids = metadata.blocked_user_ids.filter((userId) => event.user.id !== userId);
4987
+ return Object.assign(Object.assign({}, metadata), { blocked_user_ids });
4988
+ });
4989
+ };
4990
+
4991
+ const registerEventHandlers = (call, state, dispatcher) => {
4992
+ const eventHandlers = [
4993
+ watchChangePublishQuality(dispatcher, call),
4994
+ watchConnectionQualityChanged(dispatcher, state),
4995
+ watchParticipantJoined(dispatcher, state),
4996
+ watchParticipantLeft(dispatcher, state),
4997
+ watchTrackPublished(dispatcher, state),
4998
+ watchTrackUnpublished(dispatcher, state),
4999
+ watchAudioLevelChanged(dispatcher, state),
5000
+ watchDominantSpeakerChanged(dispatcher, state),
5001
+ call.on('call.updated', watchCallUpdated(state)),
5002
+ call.on('call.blocked_user', watchBlockedUser(state)),
5003
+ call.on('call.unblocked_user', watchUnblockedUser(state)),
5004
+ call.on('call.reaction_new', watchNewReactions(state)),
5005
+ call.on('call.recording_started', watchCallRecordingStarted(state)),
5006
+ call.on('call.recording_stopped', watchCallRecordingStopped(state)),
5007
+ call.on('call.permission_request', watchCallPermissionRequest(state)),
5008
+ call.on('call.permissions_updated', watchCallPermissionsUpdated(state)),
5009
+ ];
5010
+ return () => {
5011
+ eventHandlers.forEach((unsubscribe) => unsubscribe());
5012
+ };
4804
5013
  };
4805
5014
 
4806
5015
  const sfuEventKinds = {
@@ -4895,9 +5104,22 @@ const setCurrentValue = (subject, update) => {
4895
5104
  subject.next(next);
4896
5105
  return next;
4897
5106
  };
5107
+ /**
5108
+ * Creates a subscription and returns a function to unsubscribe.
5109
+ *
5110
+ * @param observable the observable to subscribe to.
5111
+ * @param handler the handler to call when the observable emits a value.
5112
+ */
5113
+ const createSubscription = (observable, handler) => {
5114
+ const subscription = observable.subscribe(handler);
5115
+ return () => {
5116
+ subscription.unsubscribe();
5117
+ };
5118
+ };
4898
5119
 
4899
5120
  var rxUtils = /*#__PURE__*/Object.freeze({
4900
5121
  __proto__: null,
5122
+ createSubscription: createSubscription,
4901
5123
  getCurrentValue: getCurrentValue,
4902
5124
  setCurrentValue: setCurrentValue
4903
5125
  });
@@ -6052,6 +6274,65 @@ class ViewportTracker {
6052
6274
  }
6053
6275
  }
6054
6276
 
6277
+ /**
6278
+ * Stores the permissions for the current user and exposes
6279
+ * a few helper methods which make it easier to work with permissions.
6280
+ *
6281
+ * This is an internal class meant to be used in combination with
6282
+ * a {@link Call} instance.
6283
+ *
6284
+ * @internal
6285
+ */
6286
+ class PermissionsContext {
6287
+ constructor() {
6288
+ this.permissions = [];
6289
+ /**
6290
+ * Sets the permissions for the current user.
6291
+ *
6292
+ * @param permissions the permissions to set.
6293
+ */
6294
+ this.setPermissions = (permissions) => {
6295
+ this.permissions = permissions;
6296
+ };
6297
+ /**
6298
+ * Sets the settings for the bound call.
6299
+ * @param settings
6300
+ */
6301
+ this.setCallSettings = (settings) => {
6302
+ this.settings = settings;
6303
+ };
6304
+ /**
6305
+ * Checks if the current user has a specific permission.
6306
+ *
6307
+ * @param permission the permission to check for.
6308
+ */
6309
+ this.hasPermission = (permission) => {
6310
+ return this.permissions.includes(permission);
6311
+ };
6312
+ /**
6313
+ * Checks if the current user can request a specific permission
6314
+ * within the call.
6315
+ *
6316
+ * @param permission the permission to check for.
6317
+ */
6318
+ this.canRequest = (permission) => {
6319
+ if (!this.settings)
6320
+ return false;
6321
+ const { audio, video, screensharing } = this.settings;
6322
+ switch (permission) {
6323
+ case OwnCapability.SEND_AUDIO:
6324
+ return audio.access_request_enabled;
6325
+ case OwnCapability.SEND_VIDEO:
6326
+ return video.access_request_enabled;
6327
+ case OwnCapability.SCREENSHARE:
6328
+ return screensharing.access_request_enabled;
6329
+ default:
6330
+ return false;
6331
+ }
6332
+ };
6333
+ }
6334
+ }
6335
+
6055
6336
  /**
6056
6337
  * Represents a call type.
6057
6338
  */
@@ -6162,6 +6443,10 @@ class Call {
6162
6443
  * ViewportTracker instance
6163
6444
  */
6164
6445
  this.viewportTracker = new ViewportTracker();
6446
+ /**
6447
+ * The permissions context of this call.
6448
+ */
6449
+ this.permissionsContext = new PermissionsContext();
6165
6450
  /**
6166
6451
  * The event dispatcher instance dedicated to this Call instance.
6167
6452
  * @private
@@ -6176,15 +6461,7 @@ class Call {
6176
6461
  * @private
6177
6462
  */
6178
6463
  this.leaveCallHooks = [];
6179
- /**
6180
- * Remove subscription for WebSocket events that were created by the `on` method.
6181
- * @param eventName
6182
- * @param fn
6183
- * @returns
6184
- */
6185
- this.off = (eventName, fn) => {
6186
- return this.dispatcher.off(eventName, fn);
6187
- };
6464
+ this.streamClientEventHandlers = new Map();
6188
6465
  /**
6189
6466
  * Leave the call and stop the media streams that were published by the call.
6190
6467
  */
@@ -6245,6 +6522,7 @@ class Call {
6245
6522
  const call = yield join(this.streamClient, this.type, this.id, data);
6246
6523
  this.state.setMetadata(call.metadata);
6247
6524
  this.state.setMembers(call.members);
6525
+ // TODO OL: do we need to handle JOIN_CALL permission here?
6248
6526
  // FIXME OL: convert to a derived state
6249
6527
  this.state.setCallRecordingInProgress(call.metadata.recording);
6250
6528
  // FIXME OL: remove once cascading is implemented
@@ -6373,12 +6651,7 @@ class Call {
6373
6651
  // fails to respond in time
6374
6652
  const { callState } = yield this.waitForJoinResponse();
6375
6653
  const currentParticipants = (callState === null || callState === void 0 ? void 0 : callState.participants) || [];
6376
- const ownCapabilities = {
6377
- ownCapabilities: call.metadata.own_capabilities,
6378
- };
6379
- this.state.setParticipants(currentParticipants.map((participant) => (Object.assign(Object.assign(Object.assign({}, participant), { isLoggedInUser: participant.sessionId === sfuClient.sessionId, viewportVisibilityState: VisibilityState.UNKNOWN }), (participant.sessionId === sfuClient.sessionId
6380
- ? ownCapabilities
6381
- : {})))));
6654
+ this.state.setParticipants(currentParticipants.map((participant) => (Object.assign(Object.assign({}, participant), { isLoggedInUser: participant.sessionId === sfuClient.sessionId, viewportVisibilityState: VisibilityState.UNKNOWN }))));
6382
6655
  this.clientStore.setActiveCall(this);
6383
6656
  this.reconnectAttempts = 0; // reset the reconnect attempts counter
6384
6657
  this.state.setCallingState(CallingState.JOINED);
@@ -6397,8 +6670,13 @@ class Call {
6397
6670
  }
6398
6671
  }
6399
6672
  });
6673
+ /**
6674
+ * Will update the call members.
6675
+ *
6676
+ * @param data the request data.
6677
+ */
6400
6678
  this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
6401
- return yield this.streamClient.post(`${this.streamClientBasePath}/members`, data);
6679
+ return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
6402
6680
  });
6403
6681
  /**
6404
6682
  * Starts publishing the given video stream to the call.
@@ -6751,38 +7029,72 @@ class Call {
6751
7029
  .subscribe(() => resolve());
6752
7030
  });
6753
7031
  };
7032
+ /**
7033
+ * Sends a reaction to the other call participants.
7034
+ *
7035
+ * @param reaction the reaction to send.
7036
+ */
6754
7037
  this.sendReaction = (reaction) => __awaiter(this, void 0, void 0, function* () {
6755
7038
  return this.streamClient.post(`${this.streamClientBasePath}/reaction`, reaction);
6756
7039
  });
7040
+ /**
7041
+ * Blocks the user with the given `userId`.
7042
+ *
7043
+ * @param userId the id of the user to block.
7044
+ */
6757
7045
  this.blockUser = (userId) => __awaiter(this, void 0, void 0, function* () {
6758
7046
  return this.streamClient.post(`${this.streamClientBasePath}/block`, {
6759
7047
  user_id: userId,
6760
7048
  });
6761
7049
  });
7050
+ /**
7051
+ * Unblocks the user with the given `userId`.
7052
+ *
7053
+ * @param userId the id of the user to unblock.
7054
+ */
6762
7055
  this.unblockUser = (userId) => __awaiter(this, void 0, void 0, function* () {
6763
7056
  return this.streamClient.post(`${this.streamClientBasePath}/unblock`, {
6764
7057
  user_id: userId,
6765
7058
  });
6766
7059
  });
6767
- this.muteUser = (userId, type, sessionId) => {
7060
+ /**
7061
+ * Mutes the user with the given `userId`.
7062
+ *
7063
+ * @param userId the id of the user to mute.
7064
+ * @param type the type of the mute operation.
7065
+ */
7066
+ this.muteUser = (userId, type) => {
7067
+ // FIXME OL: handle muting self.
6768
7068
  return this.streamClient.post(`${this.streamClientBasePath}/mute_users`, {
6769
- user_ids: [userId],
7069
+ user_ids: Array.isArray(userId) ? userId : [userId],
6770
7070
  [type]: true,
6771
- // session_ids: [sessionId],
6772
7071
  });
6773
7072
  };
7073
+ /**
7074
+ * Will mute all users in the call.
7075
+ *
7076
+ * @param type the type of the mute operation.
7077
+ */
6774
7078
  this.muteAllUsers = (type) => {
6775
7079
  return this.streamClient.post(`${this.streamClientBasePath}/mute_users`, {
6776
7080
  mute_all_users: true,
6777
7081
  [type]: true,
6778
7082
  });
6779
7083
  };
7084
+ /**
7085
+ * Loads the information about the call.
7086
+ */
6780
7087
  this.get = () => __awaiter(this, void 0, void 0, function* () {
6781
7088
  const response = yield this.streamClient.get(this.streamClientBasePath);
6782
7089
  this.state.setMetadata(response.call);
6783
7090
  this.state.setMembers(response.members);
6784
7091
  return response;
6785
7092
  });
7093
+ /**
7094
+ * Loads the information about the call and creates it if it doesn't exist.
7095
+ *
7096
+ * @param data the data to create the call with.
7097
+ */
6786
7098
  this.getOrCreate = (data) => __awaiter(this, void 0, void 0, function* () {
6787
7099
  const response = yield this.streamClient.post(this.streamClientBasePath, data);
6788
7100
  if ((data === null || data === void 0 ? void 0 : data.ring) && !this.dropTimeout) {
@@ -6804,28 +7116,23 @@ class Call {
6804
7116
  * Starts recording the call
6805
7117
  */
6806
7118
  this.startRecording = () => __awaiter(this, void 0, void 0, function* () {
6807
- try {
6808
- return yield this.streamClient.post(`${this.streamClientBasePath}/start_recording`, {});
6809
- }
6810
- catch (error) {
6811
- console.log(`Failed to start recording`, error);
6812
- }
7119
+ return this.streamClient.post(`${this.streamClientBasePath}/start_recording`, {});
6813
7120
  });
6814
7121
  /**
6815
7122
  * Stops recording the call
6816
7123
  */
6817
7124
  this.stopRecording = () => __awaiter(this, void 0, void 0, function* () {
6818
- try {
6819
- return yield this.streamClient.post(`${this.streamClientBasePath}/stop_recording`, {});
6820
- }
6821
- catch (error) {
6822
- console.log(`Failed to stop recording`, error);
6823
- }
7125
+ return this.streamClient.post(`${this.streamClientBasePath}/stop_recording`, {});
6824
7126
  });
6825
7127
  /**
6826
7128
  * Sends a `call.permission_request` event to all users connected to the call. The call settings object contains infomration about which permissions can be requested during a call (for example a user might be allowed to request permission to publish audio, but not video).
6827
7129
  */
6828
7130
  this.requestPermissions = (data) => __awaiter(this, void 0, void 0, function* () {
7131
+ const { permissions } = data;
7132
+ const canRequestPermissions = permissions.every((permission) => this.permissionsContext.canRequest(permission));
7133
+ if (!canRequestPermissions) {
7134
+ throw new Error(`You are not allowed to request permissions: ${permissions.join(', ')}`);
7135
+ }
6829
7136
  return this.streamClient.post(`${this.streamClientBasePath}/request_permission`, data);
6830
7137
  });
6831
7138
  /**
@@ -6841,12 +7148,24 @@ class Call {
6841
7148
  this.updateUserPermissions = (data) => __awaiter(this, void 0, void 0, function* () {
6842
7149
  return this.streamClient.post(`${this.streamClientBasePath}/user_permissions`, data);
6843
7150
  });
7151
+ /**
7152
+ * Starts the livestreaming of the call.
7153
+ */
6844
7154
  this.goLive = () => __awaiter(this, void 0, void 0, function* () {
6845
7155
  return this.streamClient.post(`${this.streamClientBasePath}/go_live`, {});
6846
7156
  });
7157
+ /**
7158
+ * Stops the livestreaming of the call.
7159
+ */
6847
7160
  this.stopLive = () => __awaiter(this, void 0, void 0, function* () {
6848
7161
  return this.streamClient.post(`${this.streamClientBasePath}/stop_live`, {});
6849
7162
  });
7163
+ /**
7164
+ * Updates the call settings or custom data.
7165
+ *
7166
+ * @param custom the custom data to update.
7167
+ * @param settings the call settings to update.
7168
+ */
6850
7169
  this.update = (custom, settings) => __awaiter(this, void 0, void 0, function* () {
6851
7170
  const payload = {
6852
7171
  custom: custom,
@@ -6854,6 +7173,9 @@ class Call {
6854
7173
  };
6855
7174
  return this.streamClient.patch(`${this.streamClientBasePath}`, payload);
6856
7175
  });
7176
+ /**
7177
+ * Ends the call. Once the call is ended, it cannot be re-joined.
7178
+ */
6857
7179
  this.endCall = () => __awaiter(this, void 0, void 0, function* () {
6858
7180
  return this.streamClient.post(`${this.streamClientBasePath}/mark_ended`);
6859
7181
  });
@@ -6976,9 +7298,19 @@ class Call {
6976
7298
  this.state.setCallRecordingsList(response.recordings);
6977
7299
  return response;
6978
7300
  });
7301
+ /**
7302
+ * Returns a list of Edge Serves for current call.
7303
+ *
7304
+ * @param data the data.
7305
+ */
6979
7306
  this.getEdgeServer = (data) => {
6980
7307
  return this.streamClient.post(`${this.streamClientBasePath}/get_edge_server`, data);
6981
7308
  };
7309
+ /**
7310
+ * Sends an event to all call participants.
7311
+ *
7312
+ * @param event the event to send.
7313
+ */
6982
7314
  this.sendEvent = (event) => __awaiter(this, void 0, void 0, function* () {
6983
7315
  return this.streamClient.post(`${this.streamClientBasePath}/event`, event);
6984
7316
  });
@@ -6996,13 +7328,29 @@ class Call {
6996
7328
  }
6997
7329
  this.state.setMetadata(metadata);
6998
7330
  this.state.setMembers(members || []);
6999
- registerEventHandlers(this, this.state, this.dispatcher);
7000
- this.trackSubscriptionsSubject
7001
- .pipe(debounceTime(UPDATE_SUBSCRIPTIONS_DEBOUNCE_DURATION))
7002
- .subscribe((subscriptions) => {
7003
- var _a;
7004
- (_a = this.sfuClient) === null || _a === void 0 ? void 0 : _a.updateSubscriptions(subscriptions);
7005
- });
7331
+ this.leaveCallHooks.push(registerEventHandlers(this, this.state, this.dispatcher));
7332
+ this.registerEffects();
7333
+ this.leaveCallHooks.push(createSubscription(this.trackSubscriptionsSubject.pipe(debounceTime(UPDATE_SUBSCRIPTIONS_DEBOUNCE_DURATION)), (subscriptions) => { var _a; return (_a = this.sfuClient) === null || _a === void 0 ? void 0 : _a.updateSubscriptions(subscriptions); }));
7334
+ }
7335
+ registerEffects() {
7336
+ this.leaveCallHooks.push(
7337
+ // handles updating the permissions context when the metadata changes.
7338
+ createSubscription(this.state.metadata$, (metadata) => {
7339
+ if (!metadata)
7340
+ return;
7341
+ this.permissionsContext.setPermissions(metadata.own_capabilities);
7342
+ this.permissionsContext.setCallSettings(metadata.settings);
7343
+ }),
7344
+ // handles the case when the user is blocked by the call owner.
7345
+ createSubscription(this.state.metadata$, (metadata) => {
7346
+ if (!metadata)
7347
+ return;
7348
+ const connectedUser = this.clientStore.connectedUser;
7349
+ if (connectedUser &&
7350
+ metadata.blocked_user_ids.includes(connectedUser.id)) {
7351
+ this.leave();
7352
+ }
7353
+ }));
7006
7354
  }
7007
7355
  on(eventName, fn) {
7008
7356
  if (isSfuEvent(eventName)) {
@@ -7014,320 +7362,25 @@ class Call {
7014
7362
  fn(event);
7015
7363
  }
7016
7364
  };
7365
+ this.streamClientEventHandlers.set(fn, eventHandler);
7017
7366
  return this.streamClient.on(eventName, eventHandler);
7018
7367
  }
7019
7368
  }
7020
- get data() {
7021
- return this.state.metadata;
7022
- }
7023
- }
7024
-
7025
- /**
7026
- * Event handler that watches the delivery of CallCreated Websocket event
7027
- * Updates the state store and notifies its subscribers that
7028
- * a new pending call has been initiated.
7029
- */
7030
- const watchCallCreated = (store, streamClient) => {
7031
- return function onCallCreated(event) {
7032
- if (event.type !== 'call.created') {
7033
- return;
7034
- }
7035
- const { call, members, ringing } = event;
7036
- if (!call) {
7037
- console.warn("Can't find call in CallCreatedEvent");
7038
- return;
7039
- }
7040
- const currentUser = store.connectedUser;
7041
- if ((currentUser === null || currentUser === void 0 ? void 0 : currentUser.id) === call.created_by.id) {
7042
- console.warn('Received CallCreatedEvent sent by the current user');
7043
- return;
7044
- }
7045
- store.setPendingCalls((pendingCalls) => [
7046
- ...pendingCalls,
7047
- new Call({
7048
- streamClient,
7049
- type: call.type,
7050
- id: call.id,
7051
- metadata: call,
7052
- members,
7053
- ringing,
7054
- clientStore: store,
7055
- }),
7056
- ]);
7057
- };
7058
- };
7059
- /**
7060
- * Event handler that watched the delivery of CallAcceptedEvent
7061
- * Updates the state store and notifies its subscribers that
7062
- * the given user will be joining the call.
7063
- */
7064
- const watchCallAccepted = (store) => {
7065
- return function onCallAccepted(event) {
7066
- if (event.type !== 'call.accepted') {
7067
- return;
7068
- }
7069
- const { call_cid } = event;
7070
- if (!call_cid) {
7071
- console.warn("Can't find call_cid in CallAcceptedEvent");
7072
- return;
7073
- }
7074
- const acceptedIncomingCall = store.incomingCalls.find((incomingCall) => incomingCall.cid === call_cid);
7075
- if (acceptedIncomingCall) {
7076
- console.warn('Received CallAcceptedEvent for an incoming call');
7077
- return;
7078
- }
7079
- const acceptedOutgoingCall = store.outgoingCalls.find((outgoingCall) => outgoingCall.cid === call_cid);
7080
- const activeCall = store.activeCall;
7081
- // FIXME OL: we should revisit this logic, it is hard to follow
7082
- const acceptedActiveCall = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.cid) !== undefined && activeCall.cid === call_cid
7083
- ? activeCall
7084
- : undefined;
7085
- if (!acceptedOutgoingCall && !acceptedActiveCall) {
7086
- console.warn(`CallAcceptedEvent received for a non-existent outgoing call (CID: ${call_cid}`);
7087
- return;
7088
- }
7089
- // once in active call, it is unnecessary to keep track of accepted call events
7090
- if (call_cid === (acceptedActiveCall === null || acceptedActiveCall === void 0 ? void 0 : acceptedActiveCall.cid)) {
7091
- return;
7092
- }
7093
- // do not set a new accepted call while in an active call? It would lead to joining a new active call.
7094
- // todo: solve the situation of 2nd outgoing call being accepted in the UI SDK
7095
- store.setAcceptedCall(event);
7096
- };
7097
- };
7098
- /**
7099
- * Event handler that watches delivery of CallRejected Websocket event.
7100
- * Updates the state store and notifies its subscribers that
7101
- * the given user will not be joining the call.
7102
- */
7103
- const watchCallRejected = (store) => {
7104
- return function onCallRejected(event) {
7105
- if (event.type !== 'call.rejected') {
7106
- return;
7107
- }
7108
- const { call_cid } = event;
7109
- if (!call_cid) {
7110
- console.warn("Can't find call_cid in CallRejectedEvent");
7111
- return;
7112
- }
7113
- const rejectedIncomingCall = store.incomingCalls.find((incomingCall) => incomingCall.cid === call_cid);
7114
- if (rejectedIncomingCall) {
7115
- console.warn('Received CallRejectedEvent for an incoming call');
7116
- return;
7117
- }
7118
- const rejectedOutgoingCall = store.outgoingCalls.find((outgoingCall) => outgoingCall.cid === call_cid);
7119
- const activeCall = store.activeCall;
7120
- const rejectedActiveCall = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.cid) !== undefined && activeCall.cid === call_cid
7121
- ? activeCall
7122
- : undefined;
7123
- if (!rejectedOutgoingCall && !rejectedActiveCall) {
7124
- console.warn(`CallRejectedEvent received for a non-existent outgoing call (CID: ${call_cid}`);
7125
- return;
7126
- }
7127
- // FIXME: we should remove the call from pending once every callee has rejected, but for now we support only 1:1 ring calls
7128
- store.setPendingCalls((pendingCalls) => pendingCalls.filter((pendingCall) => pendingCall.cid !== call_cid));
7129
- };
7130
- };
7131
- /**
7132
- * Event handler that watches the delivery of CallEndedEvent
7133
- * Updates the state store and notifies its subscribers that
7134
- * the call is now considered terminated.
7135
- */
7136
- const watchCallCancelled = (store) => {
7137
- return function onCallCancelled(event) {
7138
- if (event.type !== 'call.ended') {
7139
- return;
7140
- }
7141
- const { call_cid } = event;
7142
- if (!call_cid) {
7143
- console.log("Can't find call in CallEndedEvent");
7144
- return;
7145
- }
7146
- const cancelledIncomingCall = store.incomingCalls.find((incomingCall) => incomingCall.cid === call_cid);
7147
- const activeCall = store.activeCall;
7148
- const cancelledActiveCall = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.cid) !== undefined && activeCall.cid === call_cid
7149
- ? activeCall
7150
- : undefined;
7151
- if (!cancelledIncomingCall && !cancelledActiveCall) {
7152
- console.warn(`CallEndedEvent received for a non-existent incoming call (CID: ${call_cid}`);
7153
- return;
7154
- }
7155
- store.setPendingCalls((pendingCalls) => pendingCalls.filter((pendingCall) => pendingCall.cid !== call_cid));
7156
- };
7157
- };
7158
-
7159
- /**
7160
- * Event handler that watches for `call.permission_request` events
7161
- * Updates the state store using the `callPermissionRequest$` stream
7162
- */
7163
- const watchCallPermissionRequest = (store) => {
7164
- return function onCallPermissionRequest(event) {
7165
- if (event.type !== 'call.permission_request') {
7166
- return;
7167
- }
7168
- const activeCall = store.activeCall;
7169
- if (!activeCall) {
7170
- console.warn(`Ignoring "call.permission_request" as there is no active call`, event);
7171
- return;
7172
- }
7173
- if (activeCall.cid !== event.call_cid) {
7174
- console.warn(`Ignoring "call.permission_request" as it doesn't belong to the active call`, event);
7175
- return;
7176
- }
7177
- const state = activeCall.state;
7178
- const localParticipant = state.localParticipant;
7179
- if (!(localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.ownCapabilities.includes('update-call-permissions'))) {
7180
- console.warn(`Ignoring "call.permission_request" as the user doesn't have permission to handle it`);
7181
- return;
7182
- }
7183
- state.setCallPermissionRequest(event);
7184
- };
7185
- };
7186
- /**
7187
- * Event handler that watches for `call.permissions_updated` events
7188
- * It will update the `localParticipant$` or `remoteParticipants$` based on whose permissions were changed.
7189
- */
7190
- const watchCallPermissionsUpdated = (store) => {
7191
- return function onCallPermissionsUpdated(event) {
7192
- if (event.type !== 'call.permissions_updated') {
7193
- return;
7194
- }
7195
- const activeCall = store.activeCall;
7196
- if (!activeCall) {
7197
- console.warn(`Ignoring "call.permissions_updated" as there is no active call`, event);
7198
- return;
7199
- }
7200
- if (activeCall.cid !== event.call_cid) {
7201
- console.warn(`Ignoring "call.permissions_updated" as it doesn't belong to the active call`, event);
7202
- return;
7203
- }
7204
- const state = activeCall.state;
7205
- const localParticipant = state.localParticipant;
7206
- if (event.user.id === (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
7207
- state.updateParticipant(localParticipant.sessionId, {
7208
- ownCapabilities: event.own_capabilities,
7209
- });
7210
- }
7211
- // TODO: update remote participant once SFU includes that info in the participant data model
7212
- };
7213
- };
7214
-
7215
- /**
7216
- * Watches the delivery of CallReactionEvent.
7217
- *
7218
- * @param store the state store to update.
7219
- */
7220
- const watchNewReactions = (store) => {
7221
- return function onNewReactions(event) {
7222
- if (event.type !== 'call.reaction_new') {
7223
- return;
7224
- }
7225
- const { call_cid, reaction } = event;
7226
- const activeCall = store.activeCall;
7227
- if (!activeCall || activeCall.cid !== call_cid) {
7228
- console.warn('Received CallReactionEvent for an inactive or unknown call');
7229
- return;
7230
- }
7231
- const state = activeCall.state;
7232
- const { user, custom, type, emoji_code } = reaction;
7233
- state.setParticipants((participants) => {
7234
- return participants.map((p) => {
7235
- // skip if the reaction is not for this participant
7236
- if (p.userId !== user.id)
7237
- return p;
7238
- // skip if the reaction is not for this session
7239
- if (custom.sessionId && p.sessionId !== custom.sessionId)
7240
- return p;
7241
- // update the participant with the new reaction
7242
- return Object.assign(Object.assign({}, p), { reaction: {
7243
- type,
7244
- emoji_code,
7245
- custom,
7246
- } });
7247
- });
7248
- });
7249
- };
7250
- };
7251
-
7252
- /**
7253
- * Watches for `call.recording_started` events.
7254
- */
7255
- const watchCallRecordingStarted = (store) => {
7256
- return function onCallRecordingStarted(event) {
7257
- if (event.type !== 'call.recording_started') {
7258
- return;
7259
- }
7260
- const { call_cid } = event;
7261
- const activeCall = store.activeCall;
7262
- if (!activeCall || activeCall.cid !== call_cid) {
7263
- console.warn('Received CallRecordingStartedEvent for a non-active call');
7264
- return;
7265
- }
7266
- const state = activeCall.state;
7267
- state.setCallRecordingInProgress(true);
7268
- };
7269
- };
7270
- /**
7271
- * Watches for `call.recording_stopped` events.
7272
- */
7273
- const watchCallRecordingStopped = (store) => {
7274
- return function onCallRecordingStopped(event) {
7275
- if (event.type !== 'call.recording_stopped') {
7276
- return;
7369
+ off(eventName, fn) {
7370
+ if (isSfuEvent(eventName)) {
7371
+ return this.dispatcher.off(eventName, fn);
7277
7372
  }
7278
- const { call_cid } = event;
7279
- const activeCall = store.activeCall;
7280
- if (!activeCall || activeCall.cid !== call_cid) {
7281
- console.warn('Received CallRecordingStoppedEvent for a non-active call');
7282
- return;
7373
+ else {
7374
+ const registeredEventHandler = this.streamClientEventHandlers.get(fn);
7375
+ if (registeredEventHandler) {
7376
+ return this.streamClient.off(eventName, registeredEventHandler);
7377
+ }
7283
7378
  }
7284
- const state = activeCall.state;
7285
- state.setCallRecordingInProgress(false);
7286
- };
7287
- };
7288
-
7289
- /**
7290
- * Event handler that watches for `call.blocked_user` events,
7291
- * updates the call store `blocked_user_ids` property by adding
7292
- * `event.user_id` to the list
7293
- */
7294
- const watchBlockedUser = (store) => (event) => {
7295
- var _a;
7296
- if (event.type !== 'call.blocked_user') {
7297
- return;
7298
- }
7299
- const activeCall = store.activeCall;
7300
- if (!activeCall || activeCall.cid !== event.call_cid) {
7301
- console.warn(`Received "call.blocked_user" for an inactive or unknown call`, event);
7302
- return;
7303
- }
7304
- const state = activeCall.state;
7305
- // FIXME: end call
7306
- if (((_a = state.localParticipant) === null || _a === void 0 ? void 0 : _a.userId) === event.user.id) {
7307
- activeCall.leave();
7308
- }
7309
- state.setMetadata((metadata) => (Object.assign(Object.assign({}, metadata), { blocked_user_ids: [...metadata.blocked_user_ids, event.user.id] })));
7310
- };
7311
- /**
7312
- * Event handler that watches for `call.unblocked_user` events,
7313
- * updates the call store `blocked_user_ids` property by
7314
- * removing `event.user_id` from the list
7315
- */
7316
- const watchUnblockedUser = (store) => (event) => {
7317
- if (event.type !== 'call.unblocked_user') {
7318
- return;
7319
7379
  }
7320
- const activeCall = store.activeCall;
7321
- if (!activeCall || activeCall.cid !== event.call_cid) {
7322
- console.warn(`Received "call.unblocked_user" for an inactive or unknown call`, event);
7323
- return;
7380
+ get data() {
7381
+ return this.state.metadata;
7324
7382
  }
7325
- const state = activeCall.state;
7326
- state.setMetadata((metadata) => {
7327
- const blocked_user_ids = metadata.blocked_user_ids.filter((userId) => event.user.id !== userId);
7328
- return Object.assign(Object.assign({}, metadata), { blocked_user_ids });
7329
- });
7330
- };
7383
+ }
7331
7384
 
7332
7385
  var https = null;
7333
7386
 
@@ -8943,7 +8996,7 @@ class StreamClient {
8943
8996
  }
8944
8997
  getUserAgent() {
8945
8998
  return (this.userAgent ||
8946
- `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.1-alpha.90"}`);
8999
+ `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.1-alpha.92"}`);
8947
9000
  }
8948
9001
  setUserAgent(userAgent) {
8949
9002
  this.userAgent = userAgent;
@@ -9003,17 +9056,31 @@ class StreamVideoClient {
9003
9056
  yield this.streamClient.connectUser(
9004
9057
  // @ts-expect-error
9005
9058
  user, tokenOrProvider);
9006
- this.on('call.created', watchCallCreated(this.writeableStateStore, this.streamClient));
9059
+ // FIXME: OL: unregister the event listeners.
9060
+ this.on('call.created', (event) => {
9061
+ if (event.type !== 'call.created')
9062
+ return;
9063
+ const { call, members, ringing } = event;
9064
+ if (user.id === call.created_by.id) {
9065
+ console.warn('Received CallCreatedEvent sent by the current user');
9066
+ return;
9067
+ }
9068
+ this.writeableStateStore.setPendingCalls((pendingCalls) => [
9069
+ ...pendingCalls,
9070
+ new Call({
9071
+ streamClient: this.streamClient,
9072
+ type: call.type,
9073
+ id: call.id,
9074
+ metadata: call,
9075
+ members,
9076
+ ringing,
9077
+ clientStore: this.writeableStateStore,
9078
+ }),
9079
+ ]);
9080
+ });
9007
9081
  this.on('call.accepted', watchCallAccepted(this.writeableStateStore));
9008
9082
  this.on('call.rejected', watchCallRejected(this.writeableStateStore));
9009
9083
  this.on('call.ended', watchCallCancelled(this.writeableStateStore));
9010
- this.on('call.permission_request', watchCallPermissionRequest(this.writeableStateStore));
9011
- this.on('call.permissions_updated', watchCallPermissionsUpdated(this.writeableStateStore));
9012
- this.on('call.blocked_user', watchBlockedUser(this.writeableStateStore));
9013
- this.on('call.unblocked_user', watchUnblockedUser(this.writeableStateStore));
9014
- this.on('call.recording_started', watchCallRecordingStarted(this.writeableStateStore));
9015
- this.on('call.recording_stopped', watchCallRecordingStopped(this.writeableStateStore));
9016
- this.on('call.reaction_new', watchNewReactions(this.writeableStateStore));
9017
9084
  this.writeableStateStore.setConnectedUser(user);
9018
9085
  });
9019
9086
  /**