@stream-io/video-client 1.61.0 → 2.0.0-beta.1
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.
- package/CHANGELOG.md +10 -10
- package/dist/index.browser.es.js +358 -611
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +357 -611
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +358 -611
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +3 -3
- package/dist/src/StreamVideoClient.d.ts +15 -21
- package/dist/src/store/CallState.d.ts +108 -266
- package/dist/src/store/ClientState.d.ts +62 -0
- package/dist/src/store/index.d.ts +1 -1
- package/dist/src/store/subjects.d.ts +15 -0
- package/dist/src/store/types.d.ts +22 -0
- package/dist/src/types.d.ts +3 -3
- package/package.json +2 -2
- package/src/Call.ts +14 -18
- package/src/StreamVideoClient.ts +40 -47
- package/src/__tests__/Call.autodrop.test.ts +4 -4
- package/src/__tests__/Call.getRingState.test.ts +2 -2
- package/src/__tests__/Call.lifecycle.test.ts +8 -8
- package/src/__tests__/Call.publishing.test.ts +2 -2
- package/src/__tests__/Call.ringSettled.test.ts +4 -4
- package/src/__tests__/Call.ringingLifecycle.test.ts +2 -2
- package/src/__tests__/StreamVideoClient.disconnect.test.ts +62 -0
- package/src/devices/__tests__/CameraManager.test.ts +2 -2
- package/src/devices/__tests__/DeviceManager.test.ts +2 -2
- package/src/devices/__tests__/DeviceManagerFilters.test.ts +2 -2
- package/src/devices/__tests__/MicrophoneManager.test.ts +2 -2
- package/src/devices/__tests__/MicrophoneManagerRN.test.ts +2 -2
- package/src/devices/__tests__/ScreenShareManager.test.ts +3 -3
- package/src/devices/__tests__/SpeakerManager.test.ts +4 -4
- package/src/events/__tests__/call.test.ts +3 -3
- package/src/helpers/__tests__/AudioBindingsWatchdog.test.ts +2 -2
- package/src/helpers/__tests__/DynascaleManager.test.ts +2 -2
- package/src/helpers/__tests__/ViewportTracker.test.ts +2 -2
- package/src/ringing/__tests__/RingStatePoller.test.ts +7 -7
- package/src/ringing/__tests__/RingTimeout.test.ts +4 -4
- package/src/ringing/__tests__/reconcileRingState.test.ts +3 -3
- package/src/rtc/__tests__/Call.reconnect.test.ts +5 -5
- package/src/store/CallState.ts +281 -551
- package/src/store/ClientState.ts +101 -0
- package/src/store/__tests__/CallState.test.ts +1 -1
- package/src/store/__tests__/ClientState.test.ts +35 -0
- package/src/store/__tests__/rxUtils.test.ts +67 -1
- package/src/store/index.ts +1 -1
- package/src/store/rxUtils.ts +8 -4
- package/src/store/subjects.ts +30 -0
- package/src/store/types.ts +45 -0
- package/src/types.ts +3 -3
- package/dist/src/store/stateStore.d.ts +0 -84
- package/src/store/stateStore.ts +0 -156
package/dist/index.cjs.js
CHANGED
|
@@ -5101,7 +5101,7 @@ const toIceCandidate = (iceTrickle) => {
|
|
|
5101
5101
|
}
|
|
5102
5102
|
};
|
|
5103
5103
|
|
|
5104
|
-
const version = "
|
|
5104
|
+
const version = "2.0.0-beta.1";
|
|
5105
5105
|
const [major, minor, patch] = version.split('.');
|
|
5106
5106
|
let sdkInfo = {
|
|
5107
5107
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -5481,11 +5481,14 @@ const isFunctionPatch = (update) => typeof update === 'function';
|
|
|
5481
5481
|
* @param observable$ the observable to get the value from.
|
|
5482
5482
|
*/
|
|
5483
5483
|
const getCurrentValue = (observable$) => {
|
|
5484
|
+
if (observable$ instanceof rxjs.BehaviorSubject) {
|
|
5485
|
+
return observable$.getValue();
|
|
5486
|
+
}
|
|
5484
5487
|
let value;
|
|
5485
5488
|
let err = undefined;
|
|
5486
|
-
|
|
5489
|
+
observable$
|
|
5487
5490
|
.subscribe({
|
|
5488
|
-
next: (
|
|
5491
|
+
next: (v) => {
|
|
5489
5492
|
value = v;
|
|
5490
5493
|
},
|
|
5491
5494
|
error: (e) => {
|
|
@@ -5634,38 +5637,39 @@ exports.CallingState = void 0;
|
|
|
5634
5637
|
CallingState["OFFLINE"] = "offline";
|
|
5635
5638
|
})(exports.CallingState || (exports.CallingState = {}));
|
|
5636
5639
|
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
/**
|
|
5665
|
-
* The currently connected user.
|
|
5666
|
-
*/
|
|
5640
|
+
function subject(initialValue) {
|
|
5641
|
+
return new rxjs.BehaviorSubject(initialValue);
|
|
5642
|
+
}
|
|
5643
|
+
/**
|
|
5644
|
+
* Creates an Observable from the given subject by piping it to the
|
|
5645
|
+
* `distinctUntilChanged()` operator.
|
|
5646
|
+
*/
|
|
5647
|
+
const duc = (source, comparator) => source.pipe(rxjs.distinctUntilChanged(comparator));
|
|
5648
|
+
/**
|
|
5649
|
+
* Multicasts the given Observable, replaying the latest computed value to
|
|
5650
|
+
* every new subscriber instead of re-running the pipeline for each of them.
|
|
5651
|
+
*/
|
|
5652
|
+
const shared = (source) => source.pipe(rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5653
|
+
|
|
5654
|
+
/**
|
|
5655
|
+
* Holds the state of the client, and the calls it created or tracks.
|
|
5656
|
+
* You can subscribe to the exposed observables to get notified about changes.
|
|
5657
|
+
*/
|
|
5658
|
+
class ClientState {
|
|
5659
|
+
logger = videoLoggerSystem.getLogger('ClientState');
|
|
5660
|
+
connectedUserSubject = subject();
|
|
5661
|
+
callsSubject = subject([]);
|
|
5662
|
+
/** Data describing a user successfully connected over WS to the coordinator. */
|
|
5663
|
+
connectedUser$ = this.connectedUserSubject.asObservable();
|
|
5664
|
+
/** A list of {@link Call} objects created/tracked by this client. */
|
|
5665
|
+
calls$ = this.callsSubject.asObservable();
|
|
5666
|
+
/** The currently connected user. */
|
|
5667
5667
|
get connectedUser() {
|
|
5668
|
-
return this.connectedUserSubject
|
|
5668
|
+
return getCurrentValue(this.connectedUserSubject);
|
|
5669
|
+
}
|
|
5670
|
+
/** A list of {@link Call} objects created/tracked by this client. */
|
|
5671
|
+
get calls() {
|
|
5672
|
+
return getCurrentValue(this.callsSubject);
|
|
5669
5673
|
}
|
|
5670
5674
|
/**
|
|
5671
5675
|
* Sets the currently connected user.
|
|
@@ -5676,22 +5680,19 @@ class StreamVideoWriteableStateStore {
|
|
|
5676
5680
|
setConnectedUser = (user) => {
|
|
5677
5681
|
return setCurrentValue(this.connectedUserSubject, user);
|
|
5678
5682
|
};
|
|
5679
|
-
/**
|
|
5680
|
-
* A list of {@link Call} objects created/tracked by this client.
|
|
5681
|
-
*/
|
|
5682
|
-
get calls() {
|
|
5683
|
-
return getCurrentValue(this.callsSubject);
|
|
5684
|
-
}
|
|
5685
5683
|
/**
|
|
5686
5684
|
* Sets the list of {@link Call} objects created/tracked by this client.
|
|
5687
|
-
*
|
|
5685
|
+
*
|
|
5686
|
+
* @internal
|
|
5687
|
+
* @param calls the calls to set.
|
|
5688
5688
|
*/
|
|
5689
5689
|
setCalls = (calls) => {
|
|
5690
5690
|
return setCurrentValue(this.callsSubject, calls);
|
|
5691
5691
|
};
|
|
5692
5692
|
/**
|
|
5693
|
-
* Adds a {@link Call} object to the list of
|
|
5693
|
+
* Adds a {@link Call} object to the list of calls tracked by this client.
|
|
5694
5694
|
*
|
|
5695
|
+
* @internal
|
|
5695
5696
|
* @param call the call to add.
|
|
5696
5697
|
*/
|
|
5697
5698
|
registerCall = (call) => {
|
|
@@ -5702,6 +5703,7 @@ class StreamVideoWriteableStateStore {
|
|
|
5702
5703
|
/**
|
|
5703
5704
|
* Registers a {@link Call} object if it doesn't exist, otherwise updates it.
|
|
5704
5705
|
*
|
|
5706
|
+
* @internal
|
|
5705
5707
|
* @param call the call to register or update.
|
|
5706
5708
|
*/
|
|
5707
5709
|
registerOrUpdateCall = (call) => {
|
|
@@ -5713,17 +5715,17 @@ class StreamVideoWriteableStateStore {
|
|
|
5713
5715
|
}
|
|
5714
5716
|
};
|
|
5715
5717
|
/**
|
|
5716
|
-
* Removes a {@link Call} object from the list of
|
|
5718
|
+
* Removes a {@link Call} object from the list of calls tracked by this client.
|
|
5717
5719
|
*
|
|
5718
|
-
* @
|
|
5720
|
+
* @internal
|
|
5721
|
+
* @param call the call to remove.
|
|
5719
5722
|
*/
|
|
5720
5723
|
unregisterCall = (call) => {
|
|
5721
|
-
|
|
5722
|
-
logger.trace(`Unregistering call: ${call.cid}`);
|
|
5724
|
+
this.logger.trace(`Unregistering call: ${call.cid}`);
|
|
5723
5725
|
return this.setCalls((calls) => calls.filter((c) => c !== call));
|
|
5724
5726
|
};
|
|
5725
5727
|
/**
|
|
5726
|
-
* Finds a {@link Call} object in the list of
|
|
5728
|
+
* Finds a {@link Call} object in the list of calls tracked by this client.
|
|
5727
5729
|
*
|
|
5728
5730
|
* @param type the type of call to find.
|
|
5729
5731
|
* @param id the id of the call to find.
|
|
@@ -5732,38 +5734,6 @@ class StreamVideoWriteableStateStore {
|
|
|
5732
5734
|
return this.calls.find((c) => c.type === type && c.id === id);
|
|
5733
5735
|
};
|
|
5734
5736
|
}
|
|
5735
|
-
/**
|
|
5736
|
-
* A reactive store that exposes state variables in a reactive manner.
|
|
5737
|
-
* You can subscribe to changes of the different state variables.
|
|
5738
|
-
* This central store contains all the state variables related to [`StreamVideoClient`](./StreamVideClient.md) and [`Call`](./Call.md).
|
|
5739
|
-
*/
|
|
5740
|
-
class StreamVideoReadOnlyStateStore {
|
|
5741
|
-
/**
|
|
5742
|
-
* Data describing a user successfully connected over WS to coordinator server.
|
|
5743
|
-
*/
|
|
5744
|
-
connectedUser$;
|
|
5745
|
-
/**
|
|
5746
|
-
* A list of {@link Call} objects created/tracked by this client.
|
|
5747
|
-
*/
|
|
5748
|
-
calls$;
|
|
5749
|
-
constructor(store) {
|
|
5750
|
-
// convert and expose subjects as observables
|
|
5751
|
-
this.connectedUser$ = store.connectedUserSubject.asObservable();
|
|
5752
|
-
this.calls$ = store.callsSubject.asObservable();
|
|
5753
|
-
}
|
|
5754
|
-
/**
|
|
5755
|
-
* The current user connected over WS to the backend.
|
|
5756
|
-
*/
|
|
5757
|
-
get connectedUser() {
|
|
5758
|
-
return getCurrentValue(this.connectedUser$);
|
|
5759
|
-
}
|
|
5760
|
-
/**
|
|
5761
|
-
* A list of {@link Call} objects created/tracked by this client.
|
|
5762
|
-
*/
|
|
5763
|
-
get calls() {
|
|
5764
|
-
return getCurrentValue(this.calls$);
|
|
5765
|
-
}
|
|
5766
|
-
}
|
|
5767
5737
|
|
|
5768
5738
|
/**
|
|
5769
5739
|
* Creates a new combined {@link Comparator<T>} which sorts items by the given comparators.
|
|
@@ -6096,9 +6066,7 @@ const paginatedLayoutSortPreset = combineComparators(pinned, ifInvisibleOrUnknow
|
|
|
6096
6066
|
*/
|
|
6097
6067
|
const livestreamOrAudioRoomSortPreset = combineComparators(publishing, ifInvisibleOrUnknownBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)), role('admin', 'host', 'speaker'));
|
|
6098
6068
|
|
|
6099
|
-
/**
|
|
6100
|
-
* Returns the default egress object - when no egress data is available.
|
|
6101
|
-
*/
|
|
6069
|
+
/** Returns the default egress object - when no egress data is available. */
|
|
6102
6070
|
const defaultEgress = {
|
|
6103
6071
|
broadcasting: false,
|
|
6104
6072
|
hls: { playlist_url: '', status: '' },
|
|
@@ -6109,93 +6077,120 @@ const defaultEgress = {
|
|
|
6109
6077
|
* @react You don't have to use this class directly, as we are exposing the state through Hooks.
|
|
6110
6078
|
*/
|
|
6111
6079
|
class CallState {
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
// We keep these tracks around until we can associate them with a participant.
|
|
6145
|
-
orphanedTracks = [];
|
|
6080
|
+
logger = videoLoggerSystem.getLogger('CallState');
|
|
6081
|
+
/** A list of comparators that are used to sort the participants. */
|
|
6082
|
+
sortParticipantsBy = defaultSortPreset;
|
|
6083
|
+
backstageSubject = subject(true);
|
|
6084
|
+
blockedUserIdsSubject = subject([]);
|
|
6085
|
+
createdAtSubject = subject(new Date());
|
|
6086
|
+
endedAtSubject = subject();
|
|
6087
|
+
startsAtSubject = subject();
|
|
6088
|
+
updatedAtSubject = subject(new Date());
|
|
6089
|
+
createdBySubject = subject();
|
|
6090
|
+
customSubject = subject({});
|
|
6091
|
+
egressSubject = subject();
|
|
6092
|
+
ingressSubject = subject();
|
|
6093
|
+
recordingSubject = subject(false);
|
|
6094
|
+
individualRecordingSubject = subject(false);
|
|
6095
|
+
rawRecordingSubject = subject(false);
|
|
6096
|
+
sessionSubject = subject();
|
|
6097
|
+
settingsSubject = subject();
|
|
6098
|
+
transcribingSubject = subject(false);
|
|
6099
|
+
captioningSubject = subject(false);
|
|
6100
|
+
e2eeEnabledSubject = subject(false);
|
|
6101
|
+
endedBySubject = subject();
|
|
6102
|
+
thumbnailsSubject = subject();
|
|
6103
|
+
membersSubject = subject([]);
|
|
6104
|
+
ownCapabilitiesSubject = subject([]);
|
|
6105
|
+
callingStateSubject = subject(exports.CallingState.UNKNOWN);
|
|
6106
|
+
startedAtSubject = subject();
|
|
6107
|
+
participantCountSubject = subject(0);
|
|
6108
|
+
anonymousParticipantCountSubject = subject(0);
|
|
6109
|
+
participantsSubject = subject([]);
|
|
6110
|
+
callStatsReportSubject = subject();
|
|
6111
|
+
closedCaptionsSubject = subject([]);
|
|
6146
6112
|
callGrantsSubject = new rxjs.ReplaySubject(1);
|
|
6147
|
-
|
|
6113
|
+
/** The backstage state. */
|
|
6114
|
+
backstage$ = duc(this.backstageSubject);
|
|
6115
|
+
/** Will provide the list of blocked user IDs. */
|
|
6116
|
+
blockedUserIds$ = duc(this.blockedUserIdsSubject, isShallowArrayEqual);
|
|
6117
|
+
/** Will provide the time when this call has been created. */
|
|
6118
|
+
createdAt$ = this.createdAtSubject.asObservable();
|
|
6119
|
+
/** Will provide the time when this call has been ended. */
|
|
6120
|
+
endedAt$ = this.endedAtSubject.asObservable();
|
|
6121
|
+
/** Will provide the time when this call has been scheduled to start. */
|
|
6122
|
+
startsAt$ = this.startsAtSubject.asObservable();
|
|
6123
|
+
/** Will provide the time when this call has been updated. */
|
|
6124
|
+
updatedAt$ = this.updatedAtSubject.asObservable();
|
|
6125
|
+
/** Will provide the user who created this call. */
|
|
6126
|
+
createdBy$ = this.createdBySubject.asObservable();
|
|
6127
|
+
/** Will provide the custom data of this call. */
|
|
6128
|
+
custom$ = this.customSubject.asObservable();
|
|
6129
|
+
/** Will provide the egress data of this call. */
|
|
6130
|
+
egress$ = this.egressSubject.asObservable();
|
|
6131
|
+
/** Will provide the ingress data of this call. */
|
|
6132
|
+
ingress$ = this.ingressSubject.asObservable();
|
|
6133
|
+
/** Will provide the recording state of this call. */
|
|
6134
|
+
recording$ = duc(this.recordingSubject);
|
|
6135
|
+
/** Will provide the recording state of this call. */
|
|
6136
|
+
individualRecording$ = duc(this.individualRecordingSubject);
|
|
6137
|
+
/** Will provide the recording state of this call. */
|
|
6138
|
+
rawRecording$ = duc(this.rawRecordingSubject);
|
|
6139
|
+
/** Will provide the session data of this call. */
|
|
6140
|
+
session$ = this.sessionSubject.asObservable();
|
|
6141
|
+
/** Will provide the settings of this call. */
|
|
6142
|
+
settings$ = this.settingsSubject.asObservable();
|
|
6143
|
+
/** Will provide the transcribing state of this call. */
|
|
6144
|
+
transcribing$ = duc(this.transcribingSubject);
|
|
6145
|
+
/** Will provide the closed captioning state of this call. */
|
|
6146
|
+
captioning$ = duc(this.captioningSubject);
|
|
6147
|
+
/**
|
|
6148
|
+
* Whether end-to-end encryption is active for this call, as reported by the
|
|
6149
|
+
* SFU in the join response.
|
|
6150
|
+
*/
|
|
6151
|
+
e2eeEnabled$ = duc(this.e2eeEnabledSubject);
|
|
6152
|
+
/** Will provide the user who ended this call. */
|
|
6153
|
+
endedBy$ = this.endedBySubject.asObservable();
|
|
6154
|
+
/** Will provide the thumbnails of this call. */
|
|
6155
|
+
thumbnails$ = this.thumbnailsSubject.asObservable();
|
|
6156
|
+
/** The list of members in the current call. */
|
|
6157
|
+
members$ = this.membersSubject.asObservable();
|
|
6158
|
+
/** The calling state. */
|
|
6159
|
+
callingState$ = duc(this.callingStateSubject);
|
|
6148
6160
|
/**
|
|
6149
6161
|
* The time the call session actually started.
|
|
6150
6162
|
* Useful for displaying the call duration.
|
|
6151
6163
|
*/
|
|
6152
|
-
startedAt
|
|
6164
|
+
startedAt$ = this.startedAtSubject.asObservable();
|
|
6153
6165
|
/**
|
|
6154
6166
|
* The server-side counted number of participants connected to the current call.
|
|
6155
6167
|
* This number includes the anonymous participants as well.
|
|
6156
6168
|
*/
|
|
6157
|
-
participantCount
|
|
6169
|
+
participantCount$ = duc(this.participantCountSubject);
|
|
6158
6170
|
/**
|
|
6159
6171
|
* The server-side counted number of anonymous participants connected to the current call.
|
|
6160
6172
|
* This number excludes the regular participants.
|
|
6161
6173
|
*/
|
|
6162
|
-
anonymousParticipantCount
|
|
6174
|
+
anonymousParticipantCount$ = duc(this.anonymousParticipantCountSubject);
|
|
6163
6175
|
/**
|
|
6164
6176
|
* All participants of the current call (this includes the current user and other participants as well),
|
|
6165
6177
|
* unsorted. This observable only updates when participants join or leave the call.
|
|
6166
6178
|
*/
|
|
6167
|
-
rawParticipants
|
|
6168
|
-
/**
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
* Pinned participants of the current call.
|
|
6183
|
-
*/
|
|
6184
|
-
pinnedParticipants$;
|
|
6185
|
-
/**
|
|
6186
|
-
* The currently elected dominant speaker in the current call.
|
|
6187
|
-
*/
|
|
6188
|
-
dominantSpeaker$;
|
|
6189
|
-
/**
|
|
6190
|
-
* Emits true whenever there is an active screen sharing session within
|
|
6191
|
-
* the current call. Useful for displaying a "screen sharing" indicator and
|
|
6192
|
-
* switching the layout to a screen sharing layout.
|
|
6193
|
-
*
|
|
6194
|
-
* The actual screen sharing track isn't exposed here, but can be retrieved
|
|
6195
|
-
* from the list of call participants. We also don't want to be limiting
|
|
6196
|
-
* to the number of share screen tracks are displayed in a call.
|
|
6197
|
-
*/
|
|
6198
|
-
hasOngoingScreenShare$;
|
|
6179
|
+
rawParticipants$ = shared(this.participantsSubject.asObservable());
|
|
6180
|
+
/** All participants of the current call sorted according to the current `sortByParticipantsBy` setting. */
|
|
6181
|
+
participants$ = shared(this.participantsSubject.asObservable().pipe(
|
|
6182
|
+
// maintain stable-sort by mutating the participants stored in the original subject
|
|
6183
|
+
rxjs.map((ps) => ps.sort(this.sortParticipantsBy))));
|
|
6184
|
+
/** The local participant of the current call. */
|
|
6185
|
+
localParticipant$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.find((p) => p.isLocalParticipant))));
|
|
6186
|
+
/** Remote participants of the current call (all except the local participant). */
|
|
6187
|
+
remoteParticipants$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.filter((p) => !p.isLocalParticipant))));
|
|
6188
|
+
/** Pinned participants of the current call. */
|
|
6189
|
+
pinnedParticipants$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.filter((p) => !!p.pin))));
|
|
6190
|
+
/** The currently elected dominant speaker in the current call. */
|
|
6191
|
+
dominantSpeaker$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.find((p) => p.isDominantSpeaker))));
|
|
6192
|
+
/** Emits true whenever there is an active screen sharing session within the current call. */
|
|
6193
|
+
hasOngoingScreenShare$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.some((p) => hasScreenShare(p))), rxjs.distinctUntilChanged()));
|
|
6199
6194
|
/**
|
|
6200
6195
|
* The latest stats report of the current call.
|
|
6201
6196
|
* When stats gathering is enabled, this observable will emit a new value
|
|
@@ -6204,232 +6199,66 @@ class CallState {
|
|
|
6204
6199
|
* Consumers of this observable can implement their own batching logic
|
|
6205
6200
|
* in case they want to show historical stats data.
|
|
6206
6201
|
*/
|
|
6207
|
-
callStatsReport
|
|
6208
|
-
/**
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
/**
|
|
6245
|
-
* Will provide the user who created this call.
|
|
6246
|
-
*/
|
|
6247
|
-
createdBy$;
|
|
6248
|
-
/**
|
|
6249
|
-
* Will provide the custom data of this call.
|
|
6250
|
-
*/
|
|
6251
|
-
custom$;
|
|
6252
|
-
/**
|
|
6253
|
-
* Will provide the egress data of this call.
|
|
6254
|
-
*/
|
|
6255
|
-
egress$;
|
|
6256
|
-
/**
|
|
6257
|
-
* Will provide the ingress data of this call.
|
|
6258
|
-
*/
|
|
6259
|
-
ingress$;
|
|
6260
|
-
/**
|
|
6261
|
-
* Will provide the recording state of this call.
|
|
6262
|
-
*/
|
|
6263
|
-
recording$;
|
|
6264
|
-
/**
|
|
6265
|
-
* Will provide the recording state of this call.
|
|
6266
|
-
*/
|
|
6267
|
-
individualRecording$;
|
|
6268
|
-
/**
|
|
6269
|
-
* Will provide the recording state of this call.
|
|
6270
|
-
*/
|
|
6271
|
-
rawRecording$;
|
|
6272
|
-
/**
|
|
6273
|
-
* Will provide the session data of this call.
|
|
6274
|
-
*/
|
|
6275
|
-
session$;
|
|
6276
|
-
/**
|
|
6277
|
-
* Will provide the settings of this call.
|
|
6278
|
-
*/
|
|
6279
|
-
settings$;
|
|
6280
|
-
/**
|
|
6281
|
-
* Will provide the transcribing state of this call.
|
|
6282
|
-
*/
|
|
6283
|
-
transcribing$;
|
|
6284
|
-
/**
|
|
6285
|
-
* Will provide the closed captioning state of this call.
|
|
6286
|
-
*/
|
|
6287
|
-
captioning$;
|
|
6288
|
-
/**
|
|
6289
|
-
* Whether end-to-end encryption is active for this call, as reported by the
|
|
6290
|
-
* SFU in the join response.
|
|
6291
|
-
*/
|
|
6292
|
-
e2eeEnabled$;
|
|
6293
|
-
/**
|
|
6294
|
-
* Will provide the user who ended this call.
|
|
6295
|
-
*/
|
|
6296
|
-
endedBy$;
|
|
6297
|
-
/**
|
|
6298
|
-
* Will provide the thumbnails of this call.
|
|
6299
|
-
*/
|
|
6300
|
-
thumbnails$;
|
|
6301
|
-
/**
|
|
6302
|
-
* The queue of closed captions.
|
|
6303
|
-
*/
|
|
6304
|
-
closedCaptions$;
|
|
6305
|
-
logger = videoLoggerSystem.getLogger('CallState');
|
|
6306
|
-
/**
|
|
6307
|
-
* A list of comparators that are used to sort the participants.
|
|
6308
|
-
*/
|
|
6309
|
-
sortParticipantsBy = defaultSortPreset;
|
|
6310
|
-
/**
|
|
6311
|
-
* The closed captions configuration.
|
|
6312
|
-
*/
|
|
6202
|
+
callStatsReport$ = this.callStatsReportSubject.asObservable();
|
|
6203
|
+
/** The queue of closed captions. */
|
|
6204
|
+
closedCaptions$ = this.closedCaptionsSubject.asObservable();
|
|
6205
|
+
/** The list of capabilities of the current user. */
|
|
6206
|
+
ownCapabilities$ = shared(rxjs.combineLatest([
|
|
6207
|
+
this.ownCapabilitiesSubject,
|
|
6208
|
+
this.callGrantsSubject.pipe(rxjs.startWith(undefined)),
|
|
6209
|
+
]).pipe(rxjs.map(([capabilities, grants]) => {
|
|
6210
|
+
if (!grants)
|
|
6211
|
+
return capabilities;
|
|
6212
|
+
const { canPublishAudio, canPublishVideo, canScreenshare } = grants;
|
|
6213
|
+
const update = {
|
|
6214
|
+
[OwnCapability.SEND_AUDIO]: canPublishAudio,
|
|
6215
|
+
[OwnCapability.SEND_VIDEO]: canPublishVideo,
|
|
6216
|
+
[OwnCapability.SCREENSHARE]: canScreenshare,
|
|
6217
|
+
};
|
|
6218
|
+
const nextCapabilities = [...capabilities];
|
|
6219
|
+
for (const _capability in update) {
|
|
6220
|
+
const capability = _capability;
|
|
6221
|
+
const allowed = update[capability];
|
|
6222
|
+
// grants take precedence over capabilities, reconstruct the capabilities
|
|
6223
|
+
if (allowed && !nextCapabilities.includes(capability)) {
|
|
6224
|
+
nextCapabilities.push(capability);
|
|
6225
|
+
}
|
|
6226
|
+
else if (!allowed && nextCapabilities.includes(capability)) {
|
|
6227
|
+
const index = nextCapabilities.indexOf(capability);
|
|
6228
|
+
nextCapabilities.splice(index, 1);
|
|
6229
|
+
}
|
|
6230
|
+
}
|
|
6231
|
+
return nextCapabilities;
|
|
6232
|
+
}), rxjs.distinctUntilChanged(isShallowArrayEqual)));
|
|
6233
|
+
// These are tracks that were delivered to the Subscriber's onTrack event
|
|
6234
|
+
// that we couldn't associate with a participant yet.
|
|
6235
|
+
// This happens when the participantJoined event hasn't been received yet.
|
|
6236
|
+
// We keep these tracks around until we can associate them with a participant.
|
|
6237
|
+
orphanedTracks = [];
|
|
6238
|
+
/** The closed captions configuration. */
|
|
6313
6239
|
closedCaptionsSettings;
|
|
6314
6240
|
closedCaptionsTasks = new Map();
|
|
6315
6241
|
eventHandlers;
|
|
6316
|
-
/**
|
|
6317
|
-
* Creates a new instance of the CallState class.
|
|
6318
|
-
*
|
|
6319
|
-
*/
|
|
6242
|
+
/** Creates a new instance of the CallState class. */
|
|
6320
6243
|
constructor() {
|
|
6321
|
-
this.rawParticipants$ = this.participantsSubject
|
|
6322
|
-
.asObservable()
|
|
6323
|
-
.pipe(rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6324
|
-
this.participants$ = this.participantsSubject.asObservable().pipe(
|
|
6325
|
-
// maintain stable-sort by mutating the participants stored
|
|
6326
|
-
// in the original subject
|
|
6327
|
-
rxjs.map((ps) => ps.sort(this.sortParticipantsBy)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6328
|
-
this.localParticipant$ = this.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.isLocalParticipant)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6329
|
-
this.remoteParticipants$ = this.participants$.pipe(rxjs.map((participants) => participants.filter((p) => !p.isLocalParticipant)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6330
|
-
this.pinnedParticipants$ = this.participants$.pipe(rxjs.map((participants) => participants.filter((p) => !!p.pin)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6331
|
-
this.dominantSpeaker$ = this.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.isDominantSpeaker)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6332
|
-
this.hasOngoingScreenShare$ = this.participants$.pipe(rxjs.map((participants) => participants.some((p) => hasScreenShare(p))), rxjs.distinctUntilChanged(), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6333
|
-
// dates
|
|
6334
|
-
this.createdAt$ = this.createdAtSubject.asObservable();
|
|
6335
|
-
this.endedAt$ = this.endedAtSubject.asObservable();
|
|
6336
|
-
this.startsAt$ = this.startsAtSubject.asObservable();
|
|
6337
|
-
this.startedAt$ = this.startedAtSubject.asObservable();
|
|
6338
|
-
this.updatedAt$ = this.updatedAtSubject.asObservable();
|
|
6339
|
-
this.callStatsReport$ = this.callStatsReportSubject.asObservable();
|
|
6340
|
-
this.members$ = this.membersSubject.asObservable();
|
|
6341
|
-
// complex objects should work as streams of data
|
|
6342
|
-
this.createdBy$ = this.createdBySubject.asObservable();
|
|
6343
|
-
this.custom$ = this.customSubject.asObservable();
|
|
6344
|
-
this.egress$ = this.egressSubject.asObservable();
|
|
6345
|
-
this.ingress$ = this.ingressSubject.asObservable();
|
|
6346
|
-
this.session$ = this.sessionSubject.asObservable();
|
|
6347
|
-
this.settings$ = this.settingsSubject.asObservable();
|
|
6348
|
-
this.endedBy$ = this.endedBySubject.asObservable();
|
|
6349
|
-
this.thumbnails$ = this.thumbnailsSubject.asObservable();
|
|
6350
|
-
this.closedCaptions$ = this.closedCaptionsSubject.asObservable();
|
|
6351
|
-
/**
|
|
6352
|
-
* Creates an Observable from the given subject by piping to the
|
|
6353
|
-
* `distinctUntilChanged()` operator.
|
|
6354
|
-
*/
|
|
6355
|
-
const duc = (subject, comparator) => subject.pipe(rxjs.distinctUntilChanged(comparator));
|
|
6356
|
-
// primitive values should only emit once the value they hold changes
|
|
6357
|
-
this.anonymousParticipantCount$ = duc(this.anonymousParticipantCountSubject);
|
|
6358
|
-
this.blockedUserIds$ = duc(this.blockedUserIdsSubject, isShallowArrayEqual);
|
|
6359
|
-
this.backstage$ = duc(this.backstageSubject);
|
|
6360
|
-
this.callingState$ = duc(this.callingStateSubject);
|
|
6361
|
-
this.ownCapabilities$ = rxjs.combineLatest([
|
|
6362
|
-
this.ownCapabilitiesSubject,
|
|
6363
|
-
this.callGrantsSubject.pipe(rxjs.startWith(undefined)),
|
|
6364
|
-
]).pipe(rxjs.map(([capabilities, grants]) => {
|
|
6365
|
-
if (!grants)
|
|
6366
|
-
return capabilities;
|
|
6367
|
-
const { canPublishAudio, canPublishVideo, canScreenshare } = grants;
|
|
6368
|
-
const update = {
|
|
6369
|
-
[OwnCapability.SEND_AUDIO]: canPublishAudio,
|
|
6370
|
-
[OwnCapability.SEND_VIDEO]: canPublishVideo,
|
|
6371
|
-
[OwnCapability.SCREENSHARE]: canScreenshare,
|
|
6372
|
-
};
|
|
6373
|
-
const nextCapabilities = [...capabilities];
|
|
6374
|
-
for (const _capability in update) {
|
|
6375
|
-
const capability = _capability;
|
|
6376
|
-
const allowed = update[capability];
|
|
6377
|
-
// grants take precedence over capabilities, reconstruct the capabilities
|
|
6378
|
-
if (allowed && !nextCapabilities.includes(capability)) {
|
|
6379
|
-
nextCapabilities.push(capability);
|
|
6380
|
-
}
|
|
6381
|
-
else if (!allowed && nextCapabilities.includes(capability)) {
|
|
6382
|
-
const index = nextCapabilities.indexOf(capability);
|
|
6383
|
-
nextCapabilities.splice(index, 1);
|
|
6384
|
-
}
|
|
6385
|
-
}
|
|
6386
|
-
return nextCapabilities;
|
|
6387
|
-
}), rxjs.distinctUntilChanged(isShallowArrayEqual), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
6388
|
-
this.participantCount$ = duc(this.participantCountSubject);
|
|
6389
|
-
this.recording$ = duc(this.recordingSubject);
|
|
6390
|
-
this.individualRecording$ = duc(this.individualRecordingSubject);
|
|
6391
|
-
this.rawRecording$ = duc(this.rawRecordingSubject);
|
|
6392
|
-
this.transcribing$ = duc(this.transcribingSubject);
|
|
6393
|
-
this.captioning$ = duc(this.captioningSubject);
|
|
6394
|
-
this.e2eeEnabled$ = duc(this.e2eeEnabledSubject);
|
|
6395
6244
|
this.eventHandlers = {
|
|
6396
|
-
// these events are not updating the call state:
|
|
6397
|
-
'call.frame_recording_ready': undefined,
|
|
6398
|
-
'call.kicked_user': undefined,
|
|
6399
|
-
'call.moderation_blur': undefined,
|
|
6400
|
-
'call.moderation_warning': undefined,
|
|
6401
|
-
'call.permission_request': undefined,
|
|
6402
|
-
'call.recording_ready': undefined,
|
|
6403
|
-
'call.rtmp_broadcast_failed': undefined,
|
|
6404
|
-
'call.rtmp_broadcast_started': undefined,
|
|
6405
|
-
'call.rtmp_broadcast_stopped': undefined,
|
|
6406
|
-
'call.stats_report_ready': undefined,
|
|
6407
|
-
'call.transcription_ready': undefined,
|
|
6408
|
-
'call.user_feedback_submitted': undefined,
|
|
6409
|
-
'call.user_muted': undefined,
|
|
6410
|
-
'connection.error': undefined,
|
|
6411
|
-
'connection.ok': undefined,
|
|
6412
|
-
'health.check': undefined,
|
|
6413
|
-
'user.updated': undefined,
|
|
6414
|
-
custom: undefined,
|
|
6415
|
-
// events that update call state:
|
|
6416
6245
|
'call.accepted': (e) => this.updateFromCallResponse(e.call),
|
|
6417
6246
|
'call.blocked_user': this.blockUser,
|
|
6418
6247
|
'call.closed_caption': this.updateFromClosedCaptions,
|
|
6419
6248
|
'call.closed_captions_failed': () => {
|
|
6420
|
-
|
|
6249
|
+
setCurrentValue(this.captioningSubject, false);
|
|
6421
6250
|
},
|
|
6422
6251
|
'call.closed_captions_started': () => {
|
|
6423
|
-
|
|
6252
|
+
setCurrentValue(this.captioningSubject, true);
|
|
6424
6253
|
},
|
|
6425
6254
|
'call.closed_captions_stopped': () => {
|
|
6426
|
-
|
|
6255
|
+
setCurrentValue(this.captioningSubject, false);
|
|
6427
6256
|
},
|
|
6428
6257
|
'call.created': (e) => this.updateFromCallResponse(e.call),
|
|
6429
6258
|
'call.deleted': (e) => this.updateFromCallResponse(e.call),
|
|
6430
6259
|
'call.ended': (e) => {
|
|
6431
6260
|
this.updateFromCallResponse(e.call);
|
|
6432
|
-
|
|
6261
|
+
setCurrentValue(this.endedBySubject, e.user);
|
|
6433
6262
|
},
|
|
6434
6263
|
'call.frame_recording_failed': (e) => {
|
|
6435
6264
|
this.updateFromCallResponse(e.call);
|
|
@@ -6474,21 +6303,19 @@ class CallState {
|
|
|
6474
6303
|
'call.session_participant_left': this.updateFromSessionParticipantLeft,
|
|
6475
6304
|
'call.session_started': (e) => this.updateFromCallResponse(e.call),
|
|
6476
6305
|
'call.transcription_started': () => {
|
|
6477
|
-
|
|
6306
|
+
setCurrentValue(this.transcribingSubject, true);
|
|
6478
6307
|
},
|
|
6479
6308
|
'call.transcription_stopped': () => {
|
|
6480
|
-
|
|
6309
|
+
setCurrentValue(this.transcribingSubject, false);
|
|
6481
6310
|
},
|
|
6482
6311
|
'call.transcription_failed': () => {
|
|
6483
|
-
|
|
6312
|
+
setCurrentValue(this.transcribingSubject, false);
|
|
6484
6313
|
},
|
|
6485
6314
|
'call.unblocked_user': this.unblockUser,
|
|
6486
6315
|
'call.updated': (e) => this.updateFromCallResponse(e.call),
|
|
6487
6316
|
};
|
|
6488
6317
|
}
|
|
6489
|
-
/**
|
|
6490
|
-
* Runs the cleanup tasks.
|
|
6491
|
-
*/
|
|
6318
|
+
/** Runs the cleanup tasks. */
|
|
6492
6319
|
dispose = () => {
|
|
6493
6320
|
for (const [ccKey, taskId] of this.closedCaptionsTasks.entries()) {
|
|
6494
6321
|
clearTimeout(taskId);
|
|
@@ -6505,39 +6332,18 @@ class CallState {
|
|
|
6505
6332
|
setSortParticipantsBy = (comparator) => {
|
|
6506
6333
|
this.sortParticipantsBy = comparator;
|
|
6507
6334
|
// trigger re-sorting of participants
|
|
6508
|
-
|
|
6335
|
+
setCurrentValue(this.participantsSubject, (ps) => ps);
|
|
6509
6336
|
};
|
|
6510
|
-
/**
|
|
6511
|
-
* Returns the comparator currently used to sort the participants.
|
|
6512
|
-
*/
|
|
6337
|
+
/** Returns the comparator currently used to sort the participants. */
|
|
6513
6338
|
getSortParticipantsBy = () => {
|
|
6514
6339
|
return this.sortParticipantsBy;
|
|
6515
6340
|
};
|
|
6516
|
-
/**
|
|
6517
|
-
* Gets the current value of an observable, or undefined if the observable has
|
|
6518
|
-
* not emitted a value yet.
|
|
6519
|
-
*
|
|
6520
|
-
* @param observable$ the observable to get the value from.
|
|
6521
|
-
*/
|
|
6522
|
-
getCurrentValue = getCurrentValue;
|
|
6523
|
-
/**
|
|
6524
|
-
* Updates the value of the provided Subject.
|
|
6525
|
-
* An `update` can either be a new value or a function which takes
|
|
6526
|
-
* the current value and returns a new value.
|
|
6527
|
-
*
|
|
6528
|
-
* @internal
|
|
6529
|
-
*
|
|
6530
|
-
* @param subject the subject to update.
|
|
6531
|
-
* @param update the update to apply to the subject.
|
|
6532
|
-
* @return the updated value.
|
|
6533
|
-
*/
|
|
6534
|
-
setCurrentValue = setCurrentValue;
|
|
6535
6341
|
/**
|
|
6536
6342
|
* The server-side counted number of participants connected to the current call.
|
|
6537
6343
|
* This number includes the anonymous participants as well.
|
|
6538
6344
|
*/
|
|
6539
6345
|
get participantCount() {
|
|
6540
|
-
return
|
|
6346
|
+
return getCurrentValue(this.participantCountSubject);
|
|
6541
6347
|
}
|
|
6542
6348
|
/**
|
|
6543
6349
|
* Sets the number of participants in the current call.
|
|
@@ -6546,14 +6352,14 @@ class CallState {
|
|
|
6546
6352
|
* @param count the number of participants.
|
|
6547
6353
|
*/
|
|
6548
6354
|
setParticipantCount = (count) => {
|
|
6549
|
-
return
|
|
6355
|
+
return setCurrentValue(this.participantCountSubject, count);
|
|
6550
6356
|
};
|
|
6551
6357
|
/**
|
|
6552
6358
|
* The time the call session actually started.
|
|
6553
6359
|
* Useful for displaying the call duration.
|
|
6554
6360
|
*/
|
|
6555
6361
|
get startedAt() {
|
|
6556
|
-
return
|
|
6362
|
+
return getCurrentValue(this.startedAtSubject);
|
|
6557
6363
|
}
|
|
6558
6364
|
/**
|
|
6559
6365
|
* Sets the time the call session actually started.
|
|
@@ -6562,13 +6368,11 @@ class CallState {
|
|
|
6562
6368
|
* @param startedAt the time the call session actually started.
|
|
6563
6369
|
*/
|
|
6564
6370
|
setStartedAt = (startedAt) => {
|
|
6565
|
-
return
|
|
6371
|
+
return setCurrentValue(this.startedAtSubject, startedAt);
|
|
6566
6372
|
};
|
|
6567
|
-
/**
|
|
6568
|
-
* Returns whether closed captions are enabled in the current call.
|
|
6569
|
-
*/
|
|
6373
|
+
/** Returns whether closed captions are enabled in the current call. */
|
|
6570
6374
|
get captioning() {
|
|
6571
|
-
return
|
|
6375
|
+
return getCurrentValue(this.captioningSubject);
|
|
6572
6376
|
}
|
|
6573
6377
|
/**
|
|
6574
6378
|
* Sets the closed captioning state of the current call.
|
|
@@ -6584,7 +6388,7 @@ class CallState {
|
|
|
6584
6388
|
* This number includes the anonymous participants as well.
|
|
6585
6389
|
*/
|
|
6586
6390
|
get anonymousParticipantCount() {
|
|
6587
|
-
return
|
|
6391
|
+
return getCurrentValue(this.anonymousParticipantCountSubject);
|
|
6588
6392
|
}
|
|
6589
6393
|
/**
|
|
6590
6394
|
* Sets the number of anonymous participants in the current call.
|
|
@@ -6593,19 +6397,15 @@ class CallState {
|
|
|
6593
6397
|
* @param count the number of anonymous participants.
|
|
6594
6398
|
*/
|
|
6595
6399
|
setAnonymousParticipantCount = (count) => {
|
|
6596
|
-
return
|
|
6400
|
+
return setCurrentValue(this.anonymousParticipantCountSubject, count);
|
|
6597
6401
|
};
|
|
6598
|
-
/**
|
|
6599
|
-
* The list of participants in the current call.
|
|
6600
|
-
*/
|
|
6402
|
+
/** The list of participants in the current call. */
|
|
6601
6403
|
get participants() {
|
|
6602
|
-
return
|
|
6404
|
+
return getCurrentValue(this.participants$);
|
|
6603
6405
|
}
|
|
6604
|
-
/**
|
|
6605
|
-
* The stable list of participants in the current call, unsorted.
|
|
6606
|
-
*/
|
|
6406
|
+
/** The stable list of participants in the current call, unsorted. */
|
|
6607
6407
|
get rawParticipants() {
|
|
6608
|
-
return
|
|
6408
|
+
return getCurrentValue(this.rawParticipants$);
|
|
6609
6409
|
}
|
|
6610
6410
|
/**
|
|
6611
6411
|
* Returns the current participants array directly from the BehaviorSubject.
|
|
@@ -6626,43 +6426,31 @@ class CallState {
|
|
|
6626
6426
|
* @param participants the list of participants.
|
|
6627
6427
|
*/
|
|
6628
6428
|
setParticipants = (participants) => {
|
|
6629
|
-
return
|
|
6429
|
+
return setCurrentValue(this.participantsSubject, participants);
|
|
6630
6430
|
};
|
|
6631
|
-
/**
|
|
6632
|
-
* The local participant in the current call.
|
|
6633
|
-
*/
|
|
6431
|
+
/** The local participant in the current call. */
|
|
6634
6432
|
get localParticipant() {
|
|
6635
|
-
return
|
|
6433
|
+
return getCurrentValue(this.localParticipant$);
|
|
6636
6434
|
}
|
|
6637
|
-
/**
|
|
6638
|
-
* The list of remote participants in the current call.
|
|
6639
|
-
*/
|
|
6435
|
+
/** The list of remote participants in the current call. */
|
|
6640
6436
|
get remoteParticipants() {
|
|
6641
|
-
return
|
|
6437
|
+
return getCurrentValue(this.remoteParticipants$);
|
|
6642
6438
|
}
|
|
6643
|
-
/**
|
|
6644
|
-
* The dominant speaker in the current call.
|
|
6645
|
-
*/
|
|
6439
|
+
/** The dominant speaker in the current call. */
|
|
6646
6440
|
get dominantSpeaker() {
|
|
6647
|
-
return
|
|
6441
|
+
return getCurrentValue(this.dominantSpeaker$);
|
|
6648
6442
|
}
|
|
6649
|
-
/**
|
|
6650
|
-
* The list of pinned participants in the current call.
|
|
6651
|
-
*/
|
|
6443
|
+
/** The list of pinned participants in the current call. */
|
|
6652
6444
|
get pinnedParticipants() {
|
|
6653
|
-
return
|
|
6445
|
+
return getCurrentValue(this.pinnedParticipants$);
|
|
6654
6446
|
}
|
|
6655
|
-
/**
|
|
6656
|
-
* Tell if there is an ongoing screen share in this call.
|
|
6657
|
-
*/
|
|
6447
|
+
/** Tell if there is an ongoing screen share in this call. */
|
|
6658
6448
|
get hasOngoingScreenShare() {
|
|
6659
|
-
return
|
|
6449
|
+
return getCurrentValue(this.hasOngoingScreenShare$);
|
|
6660
6450
|
}
|
|
6661
|
-
/**
|
|
6662
|
-
* The calling state.
|
|
6663
|
-
*/
|
|
6451
|
+
/** The calling state. */
|
|
6664
6452
|
get callingState() {
|
|
6665
|
-
return
|
|
6453
|
+
return getCurrentValue(this.callingStateSubject);
|
|
6666
6454
|
}
|
|
6667
6455
|
/**
|
|
6668
6456
|
* Sets the calling state.
|
|
@@ -6671,13 +6459,11 @@ class CallState {
|
|
|
6671
6459
|
* @param state the new calling state.
|
|
6672
6460
|
*/
|
|
6673
6461
|
setCallingState = (state) => {
|
|
6674
|
-
return
|
|
6462
|
+
return setCurrentValue(this.callingStateSubject, state);
|
|
6675
6463
|
};
|
|
6676
|
-
/**
|
|
6677
|
-
* The call stats report.
|
|
6678
|
-
*/
|
|
6464
|
+
/** The call stats report. */
|
|
6679
6465
|
get callStatsReport() {
|
|
6680
|
-
return
|
|
6466
|
+
return getCurrentValue(this.callStatsReportSubject);
|
|
6681
6467
|
}
|
|
6682
6468
|
/**
|
|
6683
6469
|
* Returns whether the call stats report is being observed or not.
|
|
@@ -6693,13 +6479,11 @@ class CallState {
|
|
|
6693
6479
|
* @param report the report to set.
|
|
6694
6480
|
*/
|
|
6695
6481
|
setCallStatsReport = (report) => {
|
|
6696
|
-
return
|
|
6482
|
+
return setCurrentValue(this.callStatsReportSubject, report);
|
|
6697
6483
|
};
|
|
6698
|
-
/**
|
|
6699
|
-
* The members of the current call.
|
|
6700
|
-
*/
|
|
6484
|
+
/** The members of the current call. */
|
|
6701
6485
|
get members() {
|
|
6702
|
-
return
|
|
6486
|
+
return getCurrentValue(this.membersSubject);
|
|
6703
6487
|
}
|
|
6704
6488
|
/**
|
|
6705
6489
|
* Sets the members of the current call.
|
|
@@ -6708,13 +6492,11 @@ class CallState {
|
|
|
6708
6492
|
* @param members the members to set.
|
|
6709
6493
|
*/
|
|
6710
6494
|
setMembers = (members) => {
|
|
6711
|
-
|
|
6495
|
+
setCurrentValue(this.membersSubject, members);
|
|
6712
6496
|
};
|
|
6713
|
-
/**
|
|
6714
|
-
* The capabilities of the current user for the current call.
|
|
6715
|
-
*/
|
|
6497
|
+
/** The capabilities of the current user for the current call. */
|
|
6716
6498
|
get ownCapabilities() {
|
|
6717
|
-
return
|
|
6499
|
+
return getCurrentValue(this.ownCapabilities$);
|
|
6718
6500
|
}
|
|
6719
6501
|
/**
|
|
6720
6502
|
* Sets the own capabilities.
|
|
@@ -6723,7 +6505,7 @@ class CallState {
|
|
|
6723
6505
|
* @param capabilities the capabilities to set.
|
|
6724
6506
|
*/
|
|
6725
6507
|
setOwnCapabilities = (capabilities) => {
|
|
6726
|
-
return
|
|
6508
|
+
return setCurrentValue(this.ownCapabilitiesSubject, capabilities);
|
|
6727
6509
|
};
|
|
6728
6510
|
/**
|
|
6729
6511
|
* Sets the call grants (used for own capabilities).
|
|
@@ -6732,141 +6514,105 @@ class CallState {
|
|
|
6732
6514
|
* @param grants the grants to set.
|
|
6733
6515
|
*/
|
|
6734
6516
|
setCallGrants = (grants) => {
|
|
6735
|
-
return
|
|
6517
|
+
return setCurrentValue(this.callGrantsSubject, grants);
|
|
6736
6518
|
};
|
|
6737
|
-
/**
|
|
6738
|
-
* The backstage state.
|
|
6739
|
-
*/
|
|
6519
|
+
/** The backstage state. */
|
|
6740
6520
|
get backstage() {
|
|
6741
|
-
return
|
|
6521
|
+
return getCurrentValue(this.backstageSubject);
|
|
6742
6522
|
}
|
|
6743
6523
|
/**
|
|
6744
6524
|
* Sets the backstage state.
|
|
6745
6525
|
* @param backstage the backstage state.
|
|
6746
6526
|
*/
|
|
6747
6527
|
setBackstage = (backstage) => {
|
|
6748
|
-
return
|
|
6528
|
+
return setCurrentValue(this.backstageSubject, backstage);
|
|
6749
6529
|
};
|
|
6750
|
-
/**
|
|
6751
|
-
* Will provide the list of blocked user IDs.
|
|
6752
|
-
*/
|
|
6530
|
+
/** Will provide the list of blocked user IDs. */
|
|
6753
6531
|
get blockedUserIds() {
|
|
6754
|
-
return
|
|
6532
|
+
return getCurrentValue(this.blockedUserIdsSubject);
|
|
6755
6533
|
}
|
|
6756
|
-
/**
|
|
6757
|
-
* Will provide the time when this call has been created.
|
|
6758
|
-
*/
|
|
6534
|
+
/** Will provide the time when this call has been created. */
|
|
6759
6535
|
get createdAt() {
|
|
6760
|
-
return
|
|
6536
|
+
return getCurrentValue(this.createdAtSubject);
|
|
6761
6537
|
}
|
|
6762
|
-
/**
|
|
6763
|
-
* Will provide the time when this call has been ended.
|
|
6764
|
-
*/
|
|
6538
|
+
/** Will provide the time when this call has been ended. */
|
|
6765
6539
|
get endedAt() {
|
|
6766
|
-
return
|
|
6540
|
+
return getCurrentValue(this.endedAtSubject);
|
|
6767
6541
|
}
|
|
6768
6542
|
/**
|
|
6769
6543
|
* Sets the time when this call has been ended.
|
|
6770
6544
|
* @param endedAt the time when this call has been ended.
|
|
6771
6545
|
*/
|
|
6772
6546
|
setEndedAt = (endedAt) => {
|
|
6773
|
-
return
|
|
6547
|
+
return setCurrentValue(this.endedAtSubject, endedAt);
|
|
6774
6548
|
};
|
|
6775
|
-
/**
|
|
6776
|
-
* Will provide the time when this call has been scheduled to start.
|
|
6777
|
-
*/
|
|
6549
|
+
/** Will provide the time when this call has been scheduled to start. */
|
|
6778
6550
|
get startsAt() {
|
|
6779
|
-
return
|
|
6551
|
+
return getCurrentValue(this.startsAtSubject);
|
|
6780
6552
|
}
|
|
6781
|
-
/**
|
|
6782
|
-
* Will provide the time when this call has been updated.
|
|
6783
|
-
*/
|
|
6553
|
+
/** Will provide the time when this call has been updated. */
|
|
6784
6554
|
get updatedAt() {
|
|
6785
|
-
return
|
|
6555
|
+
return getCurrentValue(this.updatedAtSubject);
|
|
6786
6556
|
}
|
|
6787
|
-
/**
|
|
6788
|
-
* Will provide the user who created this call.
|
|
6789
|
-
*/
|
|
6557
|
+
/** Will provide the user who created this call. */
|
|
6790
6558
|
get createdBy() {
|
|
6791
|
-
return
|
|
6559
|
+
return getCurrentValue(this.createdBySubject);
|
|
6792
6560
|
}
|
|
6793
|
-
/**
|
|
6794
|
-
* Will provide the custom data of this call.
|
|
6795
|
-
*/
|
|
6561
|
+
/** Will provide the custom data of this call. */
|
|
6796
6562
|
get custom() {
|
|
6797
|
-
return
|
|
6563
|
+
return getCurrentValue(this.customSubject);
|
|
6798
6564
|
}
|
|
6799
6565
|
/**
|
|
6800
6566
|
* Will provide the egress data of this call.
|
|
6801
6567
|
*/
|
|
6802
6568
|
get egress() {
|
|
6803
|
-
return
|
|
6569
|
+
return getCurrentValue(this.egressSubject);
|
|
6804
6570
|
}
|
|
6805
|
-
/**
|
|
6806
|
-
* Will provide the ingress data of this call.
|
|
6807
|
-
*/
|
|
6571
|
+
/** Will provide the ingress data of this call. */
|
|
6808
6572
|
get ingress() {
|
|
6809
|
-
return
|
|
6573
|
+
return getCurrentValue(this.ingressSubject);
|
|
6810
6574
|
}
|
|
6811
|
-
/**
|
|
6812
|
-
* Will provide the composite recording state of this call.
|
|
6813
|
-
*/
|
|
6575
|
+
/** Will provide the composite recording state of this call. */
|
|
6814
6576
|
get recording() {
|
|
6815
|
-
return
|
|
6577
|
+
return getCurrentValue(this.recordingSubject);
|
|
6816
6578
|
}
|
|
6817
|
-
/**
|
|
6818
|
-
* Will provide the individual recording state of this call.
|
|
6819
|
-
*/
|
|
6579
|
+
/** Will provide the individual recording state of this call. */
|
|
6820
6580
|
get individualRecording() {
|
|
6821
|
-
return
|
|
6581
|
+
return getCurrentValue(this.individualRecordingSubject);
|
|
6822
6582
|
}
|
|
6823
|
-
/**
|
|
6824
|
-
* Will provide the raw recording state of this call.
|
|
6825
|
-
*/
|
|
6583
|
+
/** Will provide the raw recording state of this call. */
|
|
6826
6584
|
get rawRecording() {
|
|
6827
|
-
return
|
|
6585
|
+
return getCurrentValue(this.rawRecordingSubject);
|
|
6828
6586
|
}
|
|
6829
|
-
/**
|
|
6830
|
-
* Will provide the session data of this call.
|
|
6831
|
-
*/
|
|
6587
|
+
/** Will provide the session data of this call. */
|
|
6832
6588
|
get session() {
|
|
6833
|
-
return
|
|
6589
|
+
return getCurrentValue(this.sessionSubject);
|
|
6834
6590
|
}
|
|
6835
|
-
/**
|
|
6836
|
-
* Will provide the settings of this call.
|
|
6837
|
-
*/
|
|
6591
|
+
/** Will provide the settings of this call. */
|
|
6838
6592
|
get settings() {
|
|
6839
|
-
return
|
|
6593
|
+
return getCurrentValue(this.settingsSubject);
|
|
6840
6594
|
}
|
|
6841
|
-
/**
|
|
6842
|
-
* Will provide the transcribing state of this call.
|
|
6843
|
-
*/
|
|
6595
|
+
/** Will provide the transcribing state of this call. */
|
|
6844
6596
|
get transcribing() {
|
|
6845
|
-
return
|
|
6597
|
+
return getCurrentValue(this.transcribingSubject);
|
|
6846
6598
|
}
|
|
6847
|
-
/**
|
|
6848
|
-
* Whether end-to-end encryption is active for this call.
|
|
6849
|
-
*/
|
|
6599
|
+
/** Whether end-to-end encryption is active for this call. */
|
|
6850
6600
|
get e2eeEnabled() {
|
|
6851
|
-
return
|
|
6601
|
+
return getCurrentValue(this.e2eeEnabledSubject);
|
|
6852
6602
|
}
|
|
6853
|
-
/**
|
|
6854
|
-
* Will provide the user who ended this call.
|
|
6855
|
-
*/
|
|
6603
|
+
/** Will provide the user who ended this call. */
|
|
6856
6604
|
get endedBy() {
|
|
6857
|
-
return
|
|
6605
|
+
return getCurrentValue(this.endedBySubject);
|
|
6858
6606
|
}
|
|
6859
6607
|
/**
|
|
6860
6608
|
* Will provide the thumbnails of this call, if enabled in the call settings.
|
|
6861
6609
|
*/
|
|
6862
6610
|
get thumbnails() {
|
|
6863
|
-
return
|
|
6611
|
+
return getCurrentValue(this.thumbnailsSubject);
|
|
6864
6612
|
}
|
|
6865
|
-
/**
|
|
6866
|
-
* Returns the current queue of closed captions.
|
|
6867
|
-
*/
|
|
6613
|
+
/** Returns the current queue of closed captions. */
|
|
6868
6614
|
get closedCaptions() {
|
|
6869
|
-
return
|
|
6615
|
+
return getCurrentValue(this.closedCaptionsSubject);
|
|
6870
6616
|
}
|
|
6871
6617
|
/**
|
|
6872
6618
|
* Will try to find the participant with the given sessionId in the current call.
|
|
@@ -6877,9 +6623,7 @@ class CallState {
|
|
|
6877
6623
|
findParticipantBySessionId = (sessionId) => {
|
|
6878
6624
|
return this.participants.find((p) => p.sessionId === sessionId);
|
|
6879
6625
|
};
|
|
6880
|
-
/**
|
|
6881
|
-
* Returns a new lookup table of participants indexed by their session ID.
|
|
6882
|
-
*/
|
|
6626
|
+
/** Returns a new lookup table of participants indexed by their session ID. */
|
|
6883
6627
|
getParticipantLookupBySessionId = () => {
|
|
6884
6628
|
return this.participants.reduce((lookupTable, participant) => {
|
|
6885
6629
|
lookupTable[participant.sessionId] = participant;
|
|
@@ -7114,25 +6858,25 @@ class CallState {
|
|
|
7114
6858
|
*/
|
|
7115
6859
|
updateFromCallResponse = (call) => {
|
|
7116
6860
|
this.setBackstage(call.backstage);
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
6861
|
+
setCurrentValue(this.blockedUserIdsSubject, call.blocked_user_ids);
|
|
6862
|
+
setCurrentValue(this.createdAtSubject, new Date(call.created_at));
|
|
6863
|
+
setCurrentValue(this.updatedAtSubject, new Date(call.updated_at));
|
|
6864
|
+
setCurrentValue(this.startsAtSubject, call.starts_at ? new Date(call.starts_at) : undefined);
|
|
7121
6865
|
this.setEndedAt(call.ended_at ? new Date(call.ended_at) : undefined);
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
6866
|
+
setCurrentValue(this.createdBySubject, call.created_by);
|
|
6867
|
+
setCurrentValue(this.customSubject, call.custom);
|
|
6868
|
+
setCurrentValue(this.egressSubject, call.egress);
|
|
6869
|
+
setCurrentValue(this.ingressSubject, call.ingress);
|
|
7126
6870
|
const { individual_recording, composite_recording, raw_recording } = call.egress;
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
const s =
|
|
6871
|
+
setCurrentValue(this.recordingSubject, call.recording || composite_recording?.status === 'running');
|
|
6872
|
+
setCurrentValue(this.individualRecordingSubject, individual_recording?.status === 'running');
|
|
6873
|
+
setCurrentValue(this.rawRecordingSubject, raw_recording?.status === 'running');
|
|
6874
|
+
const s = setCurrentValue(this.sessionSubject, call.session);
|
|
7131
6875
|
this.updateParticipantCountFromSession(s);
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
6876
|
+
setCurrentValue(this.settingsSubject, call.settings);
|
|
6877
|
+
setCurrentValue(this.transcribingSubject, call.transcribing);
|
|
6878
|
+
setCurrentValue(this.captioningSubject, call.captioning);
|
|
6879
|
+
setCurrentValue(this.thumbnailsSubject, call.thumbnails);
|
|
7136
6880
|
};
|
|
7137
6881
|
/**
|
|
7138
6882
|
* Merges a polled ring state into the current session. Only the ring fields
|
|
@@ -7143,7 +6887,7 @@ class CallState {
|
|
|
7143
6887
|
* @param ringState the ring state as returned by the coordinator.
|
|
7144
6888
|
*/
|
|
7145
6889
|
updateFromRingState = (ringState) => {
|
|
7146
|
-
|
|
6890
|
+
setCurrentValue(this.sessionSubject, (session) => {
|
|
7147
6891
|
if (!session || session.id !== ringState.session_id)
|
|
7148
6892
|
return session;
|
|
7149
6893
|
return {
|
|
@@ -7194,21 +6938,21 @@ class CallState {
|
|
|
7194
6938
|
this.setAnonymousParticipantCount(participantCount?.anonymous || 0);
|
|
7195
6939
|
this.setStartedAt(startedAt ? Timestamp.toDate(startedAt) : new Date());
|
|
7196
6940
|
this.setServerSidePins(pins);
|
|
7197
|
-
|
|
6941
|
+
setCurrentValue(this.e2eeEnabledSubject, e2EeEnabled);
|
|
7198
6942
|
};
|
|
7199
6943
|
updateFromMemberRemoved = (event) => {
|
|
7200
6944
|
this.updateFromCallResponse(event.call);
|
|
7201
|
-
|
|
6945
|
+
setCurrentValue(this.membersSubject, (members) => members.filter((m) => event.members.indexOf(m.user_id) === -1));
|
|
7202
6946
|
};
|
|
7203
6947
|
updateFromMemberAdded = (event) => {
|
|
7204
6948
|
this.updateFromCallResponse(event.call);
|
|
7205
|
-
|
|
6949
|
+
setCurrentValue(this.membersSubject, (members) => [
|
|
7206
6950
|
...members,
|
|
7207
6951
|
...event.members,
|
|
7208
6952
|
]);
|
|
7209
6953
|
};
|
|
7210
6954
|
updateFromHLSBroadcastStopped = () => {
|
|
7211
|
-
|
|
6955
|
+
setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
|
|
7212
6956
|
...egress,
|
|
7213
6957
|
broadcasting: false,
|
|
7214
6958
|
hls: {
|
|
@@ -7218,7 +6962,7 @@ class CallState {
|
|
|
7218
6962
|
}));
|
|
7219
6963
|
};
|
|
7220
6964
|
updateFromHLSBroadcastingFailed = () => {
|
|
7221
|
-
|
|
6965
|
+
setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
|
|
7222
6966
|
...egress,
|
|
7223
6967
|
broadcasting: false,
|
|
7224
6968
|
hls: {
|
|
@@ -7230,13 +6974,13 @@ class CallState {
|
|
|
7230
6974
|
updateFromRecordingEvent = (type, running) => {
|
|
7231
6975
|
// handle the legacy format, where `type` is absent in the emitted events
|
|
7232
6976
|
if (type === undefined || type === 'composite') {
|
|
7233
|
-
|
|
6977
|
+
setCurrentValue(this.recordingSubject, running);
|
|
7234
6978
|
}
|
|
7235
6979
|
else if (type === 'individual') {
|
|
7236
|
-
|
|
6980
|
+
setCurrentValue(this.individualRecordingSubject, running);
|
|
7237
6981
|
}
|
|
7238
6982
|
else if (type === 'raw') {
|
|
7239
|
-
|
|
6983
|
+
setCurrentValue(this.rawRecordingSubject, running);
|
|
7240
6984
|
}
|
|
7241
6985
|
else {
|
|
7242
6986
|
ensureExhausted(type, 'Unknown recording type');
|
|
@@ -7253,7 +6997,7 @@ class CallState {
|
|
|
7253
6997
|
this.setAnonymousParticipantCount(session.anonymous_participant_count || 0);
|
|
7254
6998
|
};
|
|
7255
6999
|
updateFromSessionParticipantCountUpdate = (event) => {
|
|
7256
|
-
const s =
|
|
7000
|
+
const s = setCurrentValue(this.sessionSubject, (session) => {
|
|
7257
7001
|
if (!session)
|
|
7258
7002
|
return session;
|
|
7259
7003
|
return {
|
|
@@ -7265,7 +7009,7 @@ class CallState {
|
|
|
7265
7009
|
this.updateParticipantCountFromSession(s);
|
|
7266
7010
|
};
|
|
7267
7011
|
updateFromSessionParticipantLeft = (event) => {
|
|
7268
|
-
const s =
|
|
7012
|
+
const s = setCurrentValue(this.sessionSubject, (session) => {
|
|
7269
7013
|
if (!session)
|
|
7270
7014
|
return session;
|
|
7271
7015
|
const { participants, participants_count_by_role } = session;
|
|
@@ -7282,7 +7026,7 @@ class CallState {
|
|
|
7282
7026
|
this.updateParticipantCountFromSession(s);
|
|
7283
7027
|
};
|
|
7284
7028
|
updateFromSessionParticipantJoined = (event) => {
|
|
7285
|
-
const s =
|
|
7029
|
+
const s = setCurrentValue(this.sessionSubject, (session) => {
|
|
7286
7030
|
if (!session)
|
|
7287
7031
|
return session;
|
|
7288
7032
|
const { participants, participants_count_by_role } = session;
|
|
@@ -7319,7 +7063,7 @@ class CallState {
|
|
|
7319
7063
|
};
|
|
7320
7064
|
updateMembers = (event) => {
|
|
7321
7065
|
this.updateFromCallResponse(event.call);
|
|
7322
|
-
|
|
7066
|
+
setCurrentValue(this.membersSubject, (members) => members.map((member) => {
|
|
7323
7067
|
const memberUpdate = event.members.find((m) => m.user_id === member.user_id);
|
|
7324
7068
|
return memberUpdate ? memberUpdate : member;
|
|
7325
7069
|
}));
|
|
@@ -7344,14 +7088,14 @@ class CallState {
|
|
|
7344
7088
|
});
|
|
7345
7089
|
};
|
|
7346
7090
|
unblockUser = (event) => {
|
|
7347
|
-
|
|
7091
|
+
setCurrentValue(this.blockedUserIdsSubject, (current) => {
|
|
7348
7092
|
if (!current)
|
|
7349
7093
|
return current;
|
|
7350
7094
|
return current.filter((id) => id !== event.user.id);
|
|
7351
7095
|
});
|
|
7352
7096
|
};
|
|
7353
7097
|
blockUser = (event) => {
|
|
7354
|
-
|
|
7098
|
+
setCurrentValue(this.blockedUserIdsSubject, (current) => [
|
|
7355
7099
|
...(current || []),
|
|
7356
7100
|
event.user.id,
|
|
7357
7101
|
]);
|
|
@@ -7362,7 +7106,7 @@ class CallState {
|
|
|
7362
7106
|
}
|
|
7363
7107
|
};
|
|
7364
7108
|
updateFromClosedCaptions = (event) => {
|
|
7365
|
-
|
|
7109
|
+
setCurrentValue(this.closedCaptionsSubject, (queue) => {
|
|
7366
7110
|
const { closed_caption } = event;
|
|
7367
7111
|
const keyOf = (c) => `${c.speaker_id}/${c.start_time}`;
|
|
7368
7112
|
const currentKey = keyOf(closed_caption);
|
|
@@ -7374,7 +7118,7 @@ class CallState {
|
|
|
7374
7118
|
// schedule the removal of the closed caption after the retention time
|
|
7375
7119
|
if (visibilityDurationMs > 0) {
|
|
7376
7120
|
const taskId = setTimeout(() => {
|
|
7377
|
-
|
|
7121
|
+
setCurrentValue(this.closedCaptionsSubject, (captions) => captions.filter((caption) => caption !== closed_caption));
|
|
7378
7122
|
this.closedCaptionsTasks.delete(currentKey);
|
|
7379
7123
|
}, visibilityDurationMs);
|
|
7380
7124
|
this.closedCaptionsTasks.set(currentKey, taskId);
|
|
@@ -15596,7 +15340,7 @@ class Call {
|
|
|
15596
15340
|
lastStatsOptions;
|
|
15597
15341
|
ringTimeout;
|
|
15598
15342
|
ringStatePoller;
|
|
15599
|
-
|
|
15343
|
+
clientState;
|
|
15600
15344
|
streamClient;
|
|
15601
15345
|
clientEventReporter;
|
|
15602
15346
|
sfuClient;
|
|
@@ -15663,7 +15407,7 @@ class Call {
|
|
|
15663
15407
|
* Use the [`StreamVideoClient.call`](./StreamVideoClient.md/#call)
|
|
15664
15408
|
* method to construct a `Call` instance.
|
|
15665
15409
|
*/
|
|
15666
|
-
constructor({ type, id, streamClient, clientEventReporter, members, ownCapabilities, sortParticipantsBy,
|
|
15410
|
+
constructor({ type, id, streamClient, clientEventReporter, members, ownCapabilities, sortParticipantsBy, clientState, ringing = false, watching = false, }) {
|
|
15667
15411
|
this.type = type;
|
|
15668
15412
|
this.id = id;
|
|
15669
15413
|
this.cid = `${type}:${id}`;
|
|
@@ -15671,7 +15415,7 @@ class Call {
|
|
|
15671
15415
|
this.watching = watching;
|
|
15672
15416
|
this.streamClient = streamClient;
|
|
15673
15417
|
this.clientEventReporter = clientEventReporter;
|
|
15674
|
-
this.
|
|
15418
|
+
this.clientState = clientState;
|
|
15675
15419
|
this.streamClientBasePath = `/call/${this.type}/${this.id}`;
|
|
15676
15420
|
this.logger = videoLoggerSystem.getLogger('Call');
|
|
15677
15421
|
const callTypeConfig = CallTypes.get(type);
|
|
@@ -15790,7 +15534,7 @@ class Call {
|
|
|
15790
15534
|
};
|
|
15791
15535
|
handleRingingCall = () => {
|
|
15792
15536
|
const callSession = this.state.session;
|
|
15793
|
-
const receiver_id = this.
|
|
15537
|
+
const receiver_id = this.clientState.connectedUser?.id;
|
|
15794
15538
|
const ended_at = callSession?.ended_at;
|
|
15795
15539
|
const created_by_id = this.state.createdBy?.id;
|
|
15796
15540
|
if (this.currentUserId && created_by_id === this.currentUserId) {
|
|
@@ -16019,7 +15763,7 @@ class Call {
|
|
|
16019
15763
|
this.ringingSubject.next(false);
|
|
16020
15764
|
this.cancelAutoDrop();
|
|
16021
15765
|
this.cancelRingStatePolling();
|
|
16022
|
-
this.
|
|
15766
|
+
this.clientState.unregisterCall(this);
|
|
16023
15767
|
globalThis.streamRNVideoSDK?.callManager.stop({
|
|
16024
15768
|
isRingingTypeCall: this.ringing,
|
|
16025
15769
|
shouldStopCallManager: this.callManagerStarted,
|
|
@@ -16078,7 +15822,7 @@ class Call {
|
|
|
16078
15822
|
* Retrieves the current user ID.
|
|
16079
15823
|
*/
|
|
16080
15824
|
get currentUserId() {
|
|
16081
|
-
return this.
|
|
15825
|
+
return this.clientState.connectedUser?.id;
|
|
16082
15826
|
}
|
|
16083
15827
|
/**
|
|
16084
15828
|
* A flag indicating whether self-subscription is enabled for the call.
|
|
@@ -16139,8 +15883,8 @@ class Call {
|
|
|
16139
15883
|
this.ringingSubject.next(true);
|
|
16140
15884
|
// we remove the instance from the calls list to enable the following filter in useCalls hook
|
|
16141
15885
|
// const calls = useCalls().filter((c) => c.ringing);
|
|
16142
|
-
const calls = this.
|
|
16143
|
-
this.
|
|
15886
|
+
const calls = this.clientState.calls.filter((c) => c.cid !== this.cid);
|
|
15887
|
+
this.clientState.setCalls([this, ...calls]);
|
|
16144
15888
|
await this.applyDeviceConfig(settings, { publish: false });
|
|
16145
15889
|
};
|
|
16146
15890
|
/**
|
|
@@ -16174,7 +15918,7 @@ class Call {
|
|
|
16174
15918
|
}
|
|
16175
15919
|
if (this.streamClient._hasConnectionID()) {
|
|
16176
15920
|
this.watching = true;
|
|
16177
|
-
this.
|
|
15921
|
+
this.clientState.registerOrUpdateCall(this);
|
|
16178
15922
|
}
|
|
16179
15923
|
await this.applyDeviceConfig(response.call.settings, { publish: false });
|
|
16180
15924
|
return response;
|
|
@@ -16193,7 +15937,7 @@ class Call {
|
|
|
16193
15937
|
}
|
|
16194
15938
|
if (this.streamClient._hasConnectionID()) {
|
|
16195
15939
|
this.watching = true;
|
|
16196
|
-
this.
|
|
15940
|
+
this.clientState.registerOrUpdateCall(this);
|
|
16197
15941
|
}
|
|
16198
15942
|
await this.applyDeviceConfig(response.call.settings, { publish: false });
|
|
16199
15943
|
return response;
|
|
@@ -16314,7 +16058,7 @@ class Call {
|
|
|
16314
16058
|
}
|
|
16315
16059
|
if (callingX) {
|
|
16316
16060
|
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
16317
|
-
await callingX.joinCall(this, this.
|
|
16061
|
+
await callingX.joinCall(this, this.clientState.calls, supersededByLeave);
|
|
16318
16062
|
if (supersededByLeave()) {
|
|
16319
16063
|
this.logger.debug('Join superseded by leave; not setting up');
|
|
16320
16064
|
return;
|
|
@@ -16844,7 +16588,7 @@ class Call {
|
|
|
16844
16588
|
}
|
|
16845
16589
|
if (this.streamClient._hasConnectionID()) {
|
|
16846
16590
|
this.watching = true;
|
|
16847
|
-
this.
|
|
16591
|
+
this.clientState.registerOrUpdateCall(this);
|
|
16848
16592
|
}
|
|
16849
16593
|
return joinResponse;
|
|
16850
16594
|
};
|
|
@@ -17532,7 +17276,7 @@ class Call {
|
|
|
17532
17276
|
});
|
|
17533
17277
|
};
|
|
17534
17278
|
/**
|
|
17535
|
-
* Will enhance the reported stats with additional participant-specific information (`callStatsReport$` state
|
|
17279
|
+
* Will enhance the reported stats with additional participant-specific information (the `callStatsReport$` state variable).
|
|
17536
17280
|
* This is usually helpful when detailed stats for a specific participant are needed.
|
|
17537
17281
|
*
|
|
17538
17282
|
* @param sessionId the sessionId to start reporting for.
|
|
@@ -19651,11 +19395,11 @@ class StreamClient {
|
|
|
19651
19395
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
19652
19396
|
};
|
|
19653
19397
|
getSdkVersion = () => this.options.clientAppIdentifier?.sdkVersion ||
|
|
19654
|
-
"
|
|
19398
|
+
"2.0.0-beta.1";
|
|
19655
19399
|
getUserAgent = () => {
|
|
19656
19400
|
if (!this.cachedUserAgent) {
|
|
19657
19401
|
const { clientAppIdentifier = {} } = this.options;
|
|
19658
|
-
const { sdkName = 'js', sdkVersion = "
|
|
19402
|
+
const { sdkName = 'js', sdkVersion = "2.0.0-beta.1", ...extras } = clientAppIdentifier;
|
|
19659
19403
|
this.cachedUserAgent = [
|
|
19660
19404
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
19661
19405
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|
|
@@ -20411,16 +20155,11 @@ const mapWsJoinError = (err) => {
|
|
|
20411
20155
|
*/
|
|
20412
20156
|
class StreamVideoClient {
|
|
20413
20157
|
/**
|
|
20414
|
-
*
|
|
20158
|
+
* The reactive state of this client.
|
|
20415
20159
|
* You can subscribe to changes of the different state variables.
|
|
20416
|
-
* Our library is built in a way that all state changes are exposed in this store,
|
|
20417
|
-
* o all UI changes in your application should be handled by subscribing to these variables.
|
|
20418
|
-
*
|
|
20419
|
-
* @deprecated use the `client.state` getter.
|
|
20420
20160
|
*/
|
|
20421
|
-
|
|
20161
|
+
state = new ClientState();
|
|
20422
20162
|
logger;
|
|
20423
|
-
writeableStateStore;
|
|
20424
20163
|
streamClient;
|
|
20425
20164
|
clientEventReporter;
|
|
20426
20165
|
effectsRegistered = false;
|
|
@@ -20445,8 +20184,6 @@ class StreamVideoClient {
|
|
|
20445
20184
|
streamClient: this.streamClient,
|
|
20446
20185
|
enabled: clientOptions?.clientEventsReportingEnabled ?? true,
|
|
20447
20186
|
});
|
|
20448
|
-
this.writeableStateStore = new StreamVideoWriteableStateStore();
|
|
20449
|
-
this.readOnlyStateStore = new StreamVideoReadOnlyStateStore(this.writeableStateStore);
|
|
20450
20187
|
if (typeof apiKeyOrArgs !== 'string' && apiKeyOrArgs.user) {
|
|
20451
20188
|
const user = apiKeyOrArgs.user;
|
|
20452
20189
|
if (user.type === 'anonymous')
|
|
@@ -20483,19 +20220,13 @@ class StreamVideoClient {
|
|
|
20483
20220
|
}
|
|
20484
20221
|
StreamVideoClient._instances.set(instanceKey, this);
|
|
20485
20222
|
};
|
|
20486
|
-
/**
|
|
20487
|
-
* Return the reactive state store, use this if you want to be notified about changes to the client state
|
|
20488
|
-
*/
|
|
20489
|
-
get state() {
|
|
20490
|
-
return this.readOnlyStateStore;
|
|
20491
|
-
}
|
|
20492
20223
|
registerEffects = () => {
|
|
20493
20224
|
if (this.effectsRegistered)
|
|
20494
20225
|
return;
|
|
20495
20226
|
this.eventHandlersToUnregister.push(this.on('call.created', (event) => this.initCallFromEvent(event)), this.on('call.ring', (event) => this.initCallFromEvent(event)), this.on('connection.changed', (event) => {
|
|
20496
20227
|
if (!event.online)
|
|
20497
20228
|
return;
|
|
20498
|
-
const callsToReWatch = this.
|
|
20229
|
+
const callsToReWatch = this.state.calls
|
|
20499
20230
|
.filter((call) => call.watching)
|
|
20500
20231
|
.map((call) => call.cid);
|
|
20501
20232
|
if (callsToReWatch.length <= 0)
|
|
@@ -20515,7 +20246,7 @@ class StreamVideoClient {
|
|
|
20515
20246
|
const concurrencyTag = getCallInitConcurrencyTag(e.call_cid);
|
|
20516
20247
|
await withoutConcurrency(concurrencyTag, async () => {
|
|
20517
20248
|
const ringing = e.type === 'call.ring';
|
|
20518
|
-
let call = this.
|
|
20249
|
+
let call = this.state.findCall(e.call.type, e.call.id);
|
|
20519
20250
|
if (call) {
|
|
20520
20251
|
if (ringing) {
|
|
20521
20252
|
if (this.shouldRejectCall(call.cid)) {
|
|
@@ -20541,7 +20272,7 @@ class StreamVideoClient {
|
|
|
20541
20272
|
type: e.call.type,
|
|
20542
20273
|
id: e.call.id,
|
|
20543
20274
|
members: e.members,
|
|
20544
|
-
|
|
20275
|
+
clientState: this.state,
|
|
20545
20276
|
ringing,
|
|
20546
20277
|
});
|
|
20547
20278
|
if (ringing) {
|
|
@@ -20557,7 +20288,7 @@ class StreamVideoClient {
|
|
|
20557
20288
|
}
|
|
20558
20289
|
else {
|
|
20559
20290
|
call.state.updateFromCallResponse(e.call);
|
|
20560
|
-
this.
|
|
20291
|
+
this.state.registerCall(call);
|
|
20561
20292
|
this.logger.info(`New call created and registered: ${call.cid}`);
|
|
20562
20293
|
}
|
|
20563
20294
|
});
|
|
@@ -20588,7 +20319,7 @@ class StreamVideoClient {
|
|
|
20588
20319
|
filter_conditions: { cid: { $in: callsToReWatch } },
|
|
20589
20320
|
});
|
|
20590
20321
|
for (const c of response.calls) {
|
|
20591
|
-
const call = this.
|
|
20322
|
+
const call = this.state.findCall(c.call.type, c.call.id);
|
|
20592
20323
|
if (call) {
|
|
20593
20324
|
call.updateFromCallStateResponse(c);
|
|
20594
20325
|
}
|
|
@@ -20609,8 +20340,6 @@ class StreamVideoClient {
|
|
|
20609
20340
|
};
|
|
20610
20341
|
/**
|
|
20611
20342
|
* Connects the given user to the client.
|
|
20612
|
-
* Only one user can connect at a time, if you want to change users, call `disconnectUser` before connecting a new user.
|
|
20613
|
-
* If the connection is successful, the connected user [state variable](#readonlystatestore) will be updated accordingly.
|
|
20614
20343
|
*
|
|
20615
20344
|
* @param user the user to connect.
|
|
20616
20345
|
* @param tokenOrProvider a token or a function that returns a token.
|
|
@@ -20654,24 +20383,40 @@ class StreamVideoClient {
|
|
|
20654
20383
|
});
|
|
20655
20384
|
// connectUserResponse will be void if connectUser called twice for the same user
|
|
20656
20385
|
if (connectUserResponse?.me) {
|
|
20657
|
-
this.
|
|
20386
|
+
this.state.setConnectedUser(connectUserResponse.me);
|
|
20658
20387
|
}
|
|
20659
20388
|
this.registerEffects();
|
|
20660
20389
|
return connectUserResponse;
|
|
20661
20390
|
};
|
|
20391
|
+
/**
|
|
20392
|
+
* Leaves every call this client still tracks. Runs while the coordinator
|
|
20393
|
+
* connection is alive, so that the leave requests each call sends reach the
|
|
20394
|
+
* backend.
|
|
20395
|
+
*/
|
|
20396
|
+
leaveAllCalls = async () => {
|
|
20397
|
+
for (const call of this.state.calls) {
|
|
20398
|
+
if (call.state.callingState === exports.CallingState.LEFT)
|
|
20399
|
+
continue;
|
|
20400
|
+
this.logger.info(`User disconnected, leaving call: ${call.cid}`);
|
|
20401
|
+
await call
|
|
20402
|
+
.leave({ message: 'client.disconnectUser() called' })
|
|
20403
|
+
.catch((err) => {
|
|
20404
|
+
this.logger.error(`Error leaving call: ${call.cid}`, err);
|
|
20405
|
+
});
|
|
20406
|
+
}
|
|
20407
|
+
};
|
|
20662
20408
|
/**
|
|
20663
20409
|
* Disconnects the currently connected user from the client.
|
|
20664
|
-
*
|
|
20665
|
-
* If the connection is successfully disconnected, the connected user [state variable](#readonlystatestore) will be updated accordingly
|
|
20410
|
+
* Leaves every call the user is still in, and updates `client.state`accordingly.
|
|
20666
20411
|
*
|
|
20667
20412
|
* @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming successful disconnection.
|
|
20668
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
|
|
20669
20413
|
*/
|
|
20670
20414
|
disconnectUser = async (timeout) => {
|
|
20671
20415
|
await withoutConcurrency(this.connectionConcurrencyTag, async () => {
|
|
20672
20416
|
const { user, key } = this.streamClient;
|
|
20673
20417
|
if (!user)
|
|
20674
20418
|
return;
|
|
20419
|
+
await this.leaveAllCalls();
|
|
20675
20420
|
await this.streamClient.disconnectUser(timeout);
|
|
20676
20421
|
if (user.id) {
|
|
20677
20422
|
StreamVideoClient._instances.delete(getInstanceKey(key, user));
|
|
@@ -20679,13 +20424,15 @@ class StreamVideoClient {
|
|
|
20679
20424
|
this.eventHandlersToUnregister.forEach((unregister) => unregister());
|
|
20680
20425
|
this.eventHandlersToUnregister = [];
|
|
20681
20426
|
this.effectsRegistered = false;
|
|
20682
|
-
this.
|
|
20427
|
+
this.state.setConnectedUser(undefined);
|
|
20683
20428
|
});
|
|
20684
20429
|
};
|
|
20685
20430
|
/**
|
|
20686
20431
|
* You can subscribe to WebSocket events provided by the API.
|
|
20687
20432
|
* To remove a subscription, call the `off` method or, execute the returned unsubscribe function.
|
|
20688
|
-
* Please note that subscribing to WebSocket events is an advanced use-case,
|
|
20433
|
+
* Please note that subscribing to WebSocket events is an advanced use-case,
|
|
20434
|
+
* for most use-cases it should be enough to watch for changes in the reactive
|
|
20435
|
+
* `client.state`.
|
|
20689
20436
|
*
|
|
20690
20437
|
* @param eventName the event name or 'all'.
|
|
20691
20438
|
* @param callback the callback which will be called when the event is emitted.
|
|
@@ -20712,7 +20459,7 @@ class StreamVideoClient {
|
|
|
20712
20459
|
*/
|
|
20713
20460
|
call = (type, id, options = {}) => {
|
|
20714
20461
|
const call = options.reuseInstance
|
|
20715
|
-
? this.
|
|
20462
|
+
? this.state.findCall(type, id)
|
|
20716
20463
|
: undefined;
|
|
20717
20464
|
return (call ??
|
|
20718
20465
|
new Call({
|
|
@@ -20720,7 +20467,7 @@ class StreamVideoClient {
|
|
|
20720
20467
|
clientEventReporter: this.clientEventReporter,
|
|
20721
20468
|
id: id,
|
|
20722
20469
|
type: type,
|
|
20723
|
-
|
|
20470
|
+
clientState: this.state,
|
|
20724
20471
|
}));
|
|
20725
20472
|
};
|
|
20726
20473
|
/**
|
|
@@ -20750,7 +20497,7 @@ class StreamVideoClient {
|
|
|
20750
20497
|
members: c.members,
|
|
20751
20498
|
ownCapabilities: c.own_capabilities,
|
|
20752
20499
|
watching: data.watch,
|
|
20753
|
-
|
|
20500
|
+
clientState: this.state,
|
|
20754
20501
|
});
|
|
20755
20502
|
call.state.updateFromCallResponse(c.call);
|
|
20756
20503
|
await call.applyDeviceConfig(c.call.settings, {
|
|
@@ -20759,7 +20506,7 @@ class StreamVideoClient {
|
|
|
20759
20506
|
});
|
|
20760
20507
|
if (data.watch) {
|
|
20761
20508
|
await call.setup();
|
|
20762
|
-
this.
|
|
20509
|
+
this.state.registerCall(call);
|
|
20763
20510
|
}
|
|
20764
20511
|
calls.push(call);
|
|
20765
20512
|
}
|
|
@@ -20858,7 +20605,7 @@ class StreamVideoClient {
|
|
|
20858
20605
|
clientEventReporter: this.clientEventReporter,
|
|
20859
20606
|
type: callType,
|
|
20860
20607
|
id: callId,
|
|
20861
|
-
|
|
20608
|
+
clientState: this.state,
|
|
20862
20609
|
ringing: true,
|
|
20863
20610
|
});
|
|
20864
20611
|
await call.get();
|
|
@@ -21476,6 +21223,7 @@ exports.CallType = CallType;
|
|
|
21476
21223
|
exports.CallTypes = CallTypes;
|
|
21477
21224
|
exports.CameraManager = CameraManager;
|
|
21478
21225
|
exports.CameraManagerState = CameraManagerState;
|
|
21226
|
+
exports.ClientState = ClientState;
|
|
21479
21227
|
exports.CreateDeviceRequestPushProviderEnum = CreateDeviceRequestPushProviderEnum;
|
|
21480
21228
|
exports.DEFAULT_LOOPBACK_RECORDING_DURATION_MS = DEFAULT_LOOPBACK_RECORDING_DURATION_MS;
|
|
21481
21229
|
exports.DeviceManager = DeviceManager;
|
|
@@ -21525,8 +21273,6 @@ exports.StartClosedCaptionsRequestLanguageEnum = StartClosedCaptionsRequestLangu
|
|
|
21525
21273
|
exports.StartTranscriptionRequestLanguageEnum = StartTranscriptionRequestLanguageEnum;
|
|
21526
21274
|
exports.StreamSfuClient = StreamSfuClient;
|
|
21527
21275
|
exports.StreamVideoClient = StreamVideoClient;
|
|
21528
|
-
exports.StreamVideoReadOnlyStateStore = StreamVideoReadOnlyStateStore;
|
|
21529
|
-
exports.StreamVideoWriteableStateStore = StreamVideoWriteableStateStore;
|
|
21530
21276
|
exports.TranscriptionSettingsRequestClosedCaptionModeEnum = TranscriptionSettingsRequestClosedCaptionModeEnum;
|
|
21531
21277
|
exports.TranscriptionSettingsRequestLanguageEnum = TranscriptionSettingsRequestLanguageEnum;
|
|
21532
21278
|
exports.TranscriptionSettingsRequestModeEnum = TranscriptionSettingsRequestModeEnum;
|