@stream-io/video-client 0.0.2-alpha.2 → 0.0.2-alpha.20
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 +97 -0
- package/dist/index.browser.es.js +226 -88
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +226 -88
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +226 -88
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +47 -23
- package/dist/src/StreamVideoClient.d.ts +1 -0
- package/dist/src/events/callEventHandlers.d.ts +12 -0
- package/dist/src/gen/coordinator/index.d.ts +60 -76
- package/dist/src/helpers/sound-detector.d.ts +10 -1
- package/dist/src/rtc/flows/join.d.ts +1 -0
- package/dist/src/store/CallState.d.ts +22 -1
- package/dist/src/store/stateStore.d.ts +7 -0
- package/dist/src/types.d.ts +7 -1
- package/package.json +1 -1
- package/src/Call.ts +147 -80
- package/src/StreamVideoClient.ts +76 -41
- package/src/events/__tests__/call-permissions.test.ts +4 -8
- package/src/events/__tests__/call.test.ts +127 -15
- package/src/events/__tests__/sessions.test.ts +0 -2
- package/src/events/call-permissions.ts +3 -11
- package/src/events/call.ts +31 -8
- package/src/events/callEventHandlers.ts +17 -7
- package/src/events/sessions.ts +2 -12
- package/src/gen/coordinator/index.ts +60 -74
- package/src/helpers/sound-detector.ts +13 -9
- package/src/rtc/flows/join.ts +7 -1
- package/src/rtc/publisher.ts +7 -6
- package/src/store/CallState.ts +31 -0
- package/src/store/stateStore.ts +10 -0
- package/src/types.ts +8 -0
package/dist/index.browser.es.js
CHANGED
|
@@ -5733,14 +5733,13 @@ class Publisher {
|
|
|
5733
5733
|
};
|
|
5734
5734
|
this.updateVideoPublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
|
|
5735
5735
|
var _a;
|
|
5736
|
-
console.log('
|
|
5736
|
+
console.log('Update publish quality, requested rids by SFU:', enabledRids);
|
|
5737
5737
|
const videoSender = (_a = this.transceiverRegistry[TrackType.VIDEO]) === null || _a === void 0 ? void 0 : _a.sender;
|
|
5738
5738
|
if (!videoSender)
|
|
5739
5739
|
return;
|
|
5740
5740
|
const params = videoSender.getParameters();
|
|
5741
5741
|
let changed = false;
|
|
5742
5742
|
params.encodings.forEach((enc) => {
|
|
5743
|
-
console.log(enc.rid, enc.active);
|
|
5744
5743
|
// flip 'active' flag only when necessary
|
|
5745
5744
|
const shouldEnable = enabledRids.includes(enc.rid);
|
|
5746
5745
|
if (shouldEnable !== enc.active) {
|
|
@@ -5753,6 +5752,10 @@ class Publisher {
|
|
|
5753
5752
|
console.warn('No suitable video encoding quality found');
|
|
5754
5753
|
}
|
|
5755
5754
|
yield videoSender.setParameters(params);
|
|
5755
|
+
console.log(`Update publish quality, enabled rids: ${params.encodings
|
|
5756
|
+
.filter((e) => e.active)
|
|
5757
|
+
.map((e) => e.rid)
|
|
5758
|
+
.join(', ')}`);
|
|
5756
5759
|
}
|
|
5757
5760
|
});
|
|
5758
5761
|
this.getCodecPreferences = (trackType, preferredCodec) => {
|
|
@@ -6615,6 +6618,12 @@ class CallState {
|
|
|
6615
6618
|
* @internal
|
|
6616
6619
|
*/
|
|
6617
6620
|
this.membersSubject = new BehaviorSubject([]);
|
|
6621
|
+
/**
|
|
6622
|
+
* The list of capabilities of the current user.
|
|
6623
|
+
*
|
|
6624
|
+
* @private
|
|
6625
|
+
*/
|
|
6626
|
+
this.ownCapabilitiesSubject = new BehaviorSubject([]);
|
|
6618
6627
|
/**
|
|
6619
6628
|
* The calling state.
|
|
6620
6629
|
*
|
|
@@ -6797,6 +6806,15 @@ class CallState {
|
|
|
6797
6806
|
this.setMembers = (members) => {
|
|
6798
6807
|
this.setCurrentValue(this.membersSubject, members);
|
|
6799
6808
|
};
|
|
6809
|
+
/**
|
|
6810
|
+
* Sets the own capabilities.
|
|
6811
|
+
*
|
|
6812
|
+
* @internal
|
|
6813
|
+
* @param capabilities the capabilities to set.
|
|
6814
|
+
*/
|
|
6815
|
+
this.setOwnCapabilities = (capabilities) => {
|
|
6816
|
+
return this.setCurrentValue(this.ownCapabilitiesSubject, capabilities);
|
|
6817
|
+
};
|
|
6800
6818
|
/**
|
|
6801
6819
|
* Will try to find the participant with the given sessionId in the current call.
|
|
6802
6820
|
*
|
|
@@ -6886,6 +6904,7 @@ class CallState {
|
|
|
6886
6904
|
this.callRecordingList$ = this.callRecordingListSubject.asObservable();
|
|
6887
6905
|
this.metadata$ = this.metadataSubject.asObservable();
|
|
6888
6906
|
this.members$ = this.membersSubject.asObservable();
|
|
6907
|
+
this.ownCapabilities$ = this.ownCapabilitiesSubject.asObservable();
|
|
6889
6908
|
this.callingState$ = this.callingStateSubject.asObservable();
|
|
6890
6909
|
}
|
|
6891
6910
|
/**
|
|
@@ -6981,6 +7000,12 @@ class CallState {
|
|
|
6981
7000
|
get members() {
|
|
6982
7001
|
return this.getCurrentValue(this.members$);
|
|
6983
7002
|
}
|
|
7003
|
+
/**
|
|
7004
|
+
* The capabilities of the current user for the current call.
|
|
7005
|
+
*/
|
|
7006
|
+
get ownCapabilities() {
|
|
7007
|
+
return this.getCurrentValue(this.ownCapabilities$);
|
|
7008
|
+
}
|
|
6984
7009
|
}
|
|
6985
7010
|
|
|
6986
7011
|
class StreamVideoWriteableStateStore {
|
|
@@ -7044,6 +7069,15 @@ class StreamVideoWriteableStateStore {
|
|
|
7044
7069
|
this.unregisterCall = (call) => {
|
|
7045
7070
|
return this.setCalls((calls) => calls.filter((c) => c !== call));
|
|
7046
7071
|
};
|
|
7072
|
+
/**
|
|
7073
|
+
* Finds a {@link Call} object in the list of {@link Call} objects created/tracked by this client.
|
|
7074
|
+
*
|
|
7075
|
+
* @param type the type of call to find.
|
|
7076
|
+
* @param id the id of the call to find.
|
|
7077
|
+
*/
|
|
7078
|
+
this.findCall = (type, id) => {
|
|
7079
|
+
return this.calls.find((c) => c.type === type && c.id === id);
|
|
7080
|
+
};
|
|
7047
7081
|
this.connectedUserSubject.subscribe((user) => __awaiter(this, void 0, void 0, function* () {
|
|
7048
7082
|
// leave all calls when the user disconnects.
|
|
7049
7083
|
if (!user) {
|
|
@@ -7163,16 +7197,39 @@ const watchCallAccepted = (call) => {
|
|
|
7163
7197
|
* Once the event is received, the call is left.
|
|
7164
7198
|
*/
|
|
7165
7199
|
const watchCallRejected = (call) => {
|
|
7166
|
-
let totalRejections = 0;
|
|
7167
7200
|
return function onCallRejected(event) {
|
|
7168
7201
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7169
7202
|
if (event.type !== 'call.rejected')
|
|
7170
7203
|
return;
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7204
|
+
// We want to discard the event if it's from the current user
|
|
7205
|
+
if (event.user.id === call.currentUserId)
|
|
7206
|
+
return;
|
|
7207
|
+
const { call: eventCall } = event;
|
|
7208
|
+
const { session: callSession } = eventCall;
|
|
7209
|
+
if (!callSession) {
|
|
7210
|
+
console.log('No call session provided. Ignoring call.rejected event.');
|
|
7211
|
+
return;
|
|
7212
|
+
}
|
|
7213
|
+
const rejectedBy = callSession.rejected_by;
|
|
7214
|
+
const { members, callingState } = call.state;
|
|
7215
|
+
if (callingState !== CallingState.RINGING) {
|
|
7216
|
+
console.log('Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.');
|
|
7217
|
+
return;
|
|
7218
|
+
}
|
|
7219
|
+
if (call.isCreatedByMe) {
|
|
7220
|
+
const everyoneElseRejected = members
|
|
7221
|
+
.filter((m) => m.user_id !== call.currentUserId)
|
|
7222
|
+
.every((m) => rejectedBy[m.user_id]);
|
|
7223
|
+
if (everyoneElseRejected) {
|
|
7224
|
+
console.log('everyone rejected, leaving the call');
|
|
7225
|
+
yield call.leave();
|
|
7226
|
+
}
|
|
7227
|
+
}
|
|
7228
|
+
else {
|
|
7229
|
+
if (rejectedBy[eventCall.created_by.id]) {
|
|
7230
|
+
console.log('call creator rejected, leaving call');
|
|
7231
|
+
yield call.leave();
|
|
7232
|
+
}
|
|
7176
7233
|
}
|
|
7177
7234
|
});
|
|
7178
7235
|
};
|
|
@@ -7225,7 +7282,7 @@ const watchCallPermissionsUpdated = (state) => {
|
|
|
7225
7282
|
return;
|
|
7226
7283
|
const { localParticipant } = state;
|
|
7227
7284
|
if (event.user.id === (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
|
|
7228
|
-
state.
|
|
7285
|
+
state.setOwnCapabilities(event.own_capabilities);
|
|
7229
7286
|
}
|
|
7230
7287
|
};
|
|
7231
7288
|
};
|
|
@@ -7236,7 +7293,6 @@ const watchCallPermissionsUpdated = (state) => {
|
|
|
7236
7293
|
*/
|
|
7237
7294
|
const watchCallGrantsUpdated = (state) => {
|
|
7238
7295
|
return function onCallGrantsUpdated(event) {
|
|
7239
|
-
var _a;
|
|
7240
7296
|
if (event.eventPayload.oneofKind !== 'callGrantsUpdated')
|
|
7241
7297
|
return;
|
|
7242
7298
|
const { currentGrants } = event.eventPayload.callGrantsUpdated;
|
|
@@ -7247,15 +7303,13 @@ const watchCallGrantsUpdated = (state) => {
|
|
|
7247
7303
|
[OwnCapability.SEND_VIDEO]: canPublishVideo,
|
|
7248
7304
|
[OwnCapability.SCREENSHARE]: canScreenshare,
|
|
7249
7305
|
};
|
|
7250
|
-
const nextCapabilities =
|
|
7306
|
+
const nextCapabilities = state.ownCapabilities.filter((capability) => update[capability] !== false);
|
|
7251
7307
|
Object.entries(update).forEach(([capability, value]) => {
|
|
7252
7308
|
if (value && !nextCapabilities.includes(capability)) {
|
|
7253
7309
|
nextCapabilities.push(capability);
|
|
7254
7310
|
}
|
|
7255
7311
|
});
|
|
7256
|
-
state.
|
|
7257
|
-
return Object.assign(Object.assign({}, metadata), { own_capabilities: nextCapabilities });
|
|
7258
|
-
});
|
|
7312
|
+
state.setOwnCapabilities(nextCapabilities);
|
|
7259
7313
|
}
|
|
7260
7314
|
};
|
|
7261
7315
|
};
|
|
@@ -7548,10 +7602,7 @@ const watchCallSessionStarted = (state) => {
|
|
|
7548
7602
|
return function onCallSessionStarted(event) {
|
|
7549
7603
|
if (event.type !== 'call.session_started')
|
|
7550
7604
|
return;
|
|
7551
|
-
|
|
7552
|
-
state.setMetadata((metadata) => (Object.assign(Object.assign({}, call), {
|
|
7553
|
-
// FIXME OL: temporary, until the backend sends the own_capabilities
|
|
7554
|
-
own_capabilities: (metadata === null || metadata === void 0 ? void 0 : metadata.own_capabilities) || [] })));
|
|
7605
|
+
state.setMetadata(event.call);
|
|
7555
7606
|
};
|
|
7556
7607
|
};
|
|
7557
7608
|
/**
|
|
@@ -7563,10 +7614,7 @@ const watchCallSessionEnded = (state) => {
|
|
|
7563
7614
|
return function onCallSessionEnded(event) {
|
|
7564
7615
|
if (event.type !== 'call.session_ended')
|
|
7565
7616
|
return;
|
|
7566
|
-
|
|
7567
|
-
state.setMetadata((metadata) => (Object.assign(Object.assign({}, call), {
|
|
7568
|
-
// FIXME OL: temporary, until the backend sends the own_capabilities
|
|
7569
|
-
own_capabilities: (metadata === null || metadata === void 0 ? void 0 : metadata.own_capabilities) || [] })));
|
|
7617
|
+
state.setMetadata(event.call);
|
|
7570
7618
|
};
|
|
7571
7619
|
};
|
|
7572
7620
|
/**
|
|
@@ -7643,6 +7691,13 @@ const watchUnblockedUser = (state) => (event) => {
|
|
|
7643
7691
|
});
|
|
7644
7692
|
};
|
|
7645
7693
|
|
|
7694
|
+
/**
|
|
7695
|
+
* Registers the default event handlers for a call during its lifecycle.
|
|
7696
|
+
*
|
|
7697
|
+
* @param call the call to register event handlers for.
|
|
7698
|
+
* @param state the call state.
|
|
7699
|
+
* @param dispatcher the dispatcher.
|
|
7700
|
+
*/
|
|
7646
7701
|
const registerEventHandlers = (call, state, dispatcher) => {
|
|
7647
7702
|
const coordinatorEvents = {
|
|
7648
7703
|
'call.blocked_user': watchBlockedUser(state),
|
|
@@ -7665,8 +7720,6 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
7665
7720
|
'call.session_participant_left': watchCallSessionParticipantLeft(state),
|
|
7666
7721
|
'call.unblocked_user': watchUnblockedUser(state),
|
|
7667
7722
|
'call.updated': watchCallUpdated(state),
|
|
7668
|
-
'call.notification': (event) => console.log(`Received ${event.type} event`, event),
|
|
7669
|
-
'call.ring': (event) => console.log(`Received ${event.type} event`, event),
|
|
7670
7723
|
};
|
|
7671
7724
|
const eventHandlers = [
|
|
7672
7725
|
watchChangePublishQuality(dispatcher, call),
|
|
@@ -7692,6 +7745,11 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
7692
7745
|
eventHandlers.forEach((unsubscribe) => unsubscribe());
|
|
7693
7746
|
};
|
|
7694
7747
|
};
|
|
7748
|
+
/**
|
|
7749
|
+
* Registers event handlers for a call that is of ringing type.
|
|
7750
|
+
*
|
|
7751
|
+
* @param call the call to register event handlers for.
|
|
7752
|
+
*/
|
|
7695
7753
|
const registerRingingCallEventHandlers = (call) => {
|
|
7696
7754
|
const coordinatorRingEvents = {
|
|
7697
7755
|
'call.accepted': watchCallAccepted(call),
|
|
@@ -7718,13 +7776,14 @@ const registerRingingCallEventHandlers = (call) => {
|
|
|
7718
7776
|
const join = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7719
7777
|
yield httpClient.connectionIdPromise;
|
|
7720
7778
|
const joinCallResponse = yield doJoin(httpClient, type, id, data);
|
|
7721
|
-
const { call, credentials, members } = joinCallResponse;
|
|
7779
|
+
const { call, credentials, members, own_capabilities } = joinCallResponse;
|
|
7722
7780
|
return {
|
|
7723
7781
|
connectionConfig: toRtcConfiguration(credentials.ice_servers),
|
|
7724
7782
|
sfuServer: credentials.server,
|
|
7725
7783
|
token: credentials.token,
|
|
7726
7784
|
metadata: call,
|
|
7727
7785
|
members,
|
|
7786
|
+
ownCapabilities: own_capabilities,
|
|
7728
7787
|
};
|
|
7729
7788
|
});
|
|
7730
7789
|
const doJoin = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -7741,9 +7800,12 @@ const doJoin = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0,
|
|
|
7741
7800
|
});
|
|
7742
7801
|
const getLocationHint = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
7743
7802
|
const hintURL = `https://hint.stream-io-video.com/`;
|
|
7803
|
+
const abortController = new AbortController();
|
|
7804
|
+
const timeoutId = setTimeout(() => abortController.abort(), 1000);
|
|
7744
7805
|
try {
|
|
7745
7806
|
const response = yield fetch(hintURL, {
|
|
7746
7807
|
method: 'HEAD',
|
|
7808
|
+
signal: abortController.signal,
|
|
7747
7809
|
});
|
|
7748
7810
|
const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
|
|
7749
7811
|
return awsPop.substring(0, 3); // AMS1-P2 -> AMS
|
|
@@ -7752,6 +7814,9 @@ const getLocationHint = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
7752
7814
|
console.error(`Failed to get location hint from ${hintURL}`, e);
|
|
7753
7815
|
return 'ERR';
|
|
7754
7816
|
}
|
|
7817
|
+
finally {
|
|
7818
|
+
clearTimeout(timeoutId);
|
|
7819
|
+
}
|
|
7755
7820
|
});
|
|
7756
7821
|
const toRtcConfiguration = (config) => {
|
|
7757
7822
|
if (!config || config.length === 0)
|
|
@@ -8254,7 +8319,7 @@ class Call {
|
|
|
8254
8319
|
* Use the [`StreamVideoClient.call`](./StreamVideoClient.md/#call)
|
|
8255
8320
|
* method to construct a `Call` instance.
|
|
8256
8321
|
*/
|
|
8257
|
-
constructor({ type, id, streamClient, metadata, members, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
|
|
8322
|
+
constructor({ type, id, streamClient, metadata, members, ownCapabilities, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
|
|
8258
8323
|
/**
|
|
8259
8324
|
* ViewportTracker instance
|
|
8260
8325
|
*/
|
|
@@ -8298,13 +8363,11 @@ class Call {
|
|
|
8298
8363
|
if (this.isCreatedByMe && !hasOtherParticipants) {
|
|
8299
8364
|
// Signals other users that I have cancelled my call to them
|
|
8300
8365
|
// before they accepted it.
|
|
8301
|
-
|
|
8302
|
-
yield this.endCall();
|
|
8366
|
+
yield this.reject();
|
|
8303
8367
|
}
|
|
8304
8368
|
else if (reject && callingState === CallingState.RINGING) {
|
|
8305
8369
|
// Signals other users that I have rejected the incoming call.
|
|
8306
|
-
|
|
8307
|
-
yield this.sendEvent({ type: 'call.rejected' });
|
|
8370
|
+
yield this.reject();
|
|
8308
8371
|
}
|
|
8309
8372
|
}
|
|
8310
8373
|
(_a = this.statsReporter) === null || _a === void 0 ? void 0 : _a.stop();
|
|
@@ -8336,11 +8399,19 @@ class Call {
|
|
|
8336
8399
|
});
|
|
8337
8400
|
/**
|
|
8338
8401
|
* Loads the information about the call.
|
|
8402
|
+
*
|
|
8403
|
+
* @param params.ring if set to true, a `call.ring` event will be sent to the call members.
|
|
8404
|
+
* @param params.notify if set to true, a `call.notification` event will be sent to the call members.
|
|
8405
|
+
* @param params.members_limit the members limit.
|
|
8339
8406
|
*/
|
|
8340
8407
|
this.get = (params) => __awaiter(this, void 0, void 0, function* () {
|
|
8341
8408
|
const response = yield this.streamClient.get(this.streamClientBasePath, params);
|
|
8409
|
+
if ((params === null || params === void 0 ? void 0 : params.ring) && !this.ringing) {
|
|
8410
|
+
this.ringingSubject.next(true);
|
|
8411
|
+
}
|
|
8342
8412
|
this.state.setMetadata(response.call);
|
|
8343
8413
|
this.state.setMembers(response.members);
|
|
8414
|
+
this.state.setOwnCapabilities(response.own_capabilities);
|
|
8344
8415
|
if (this.streamClient._hasConnectionID()) {
|
|
8345
8416
|
this.watching = true;
|
|
8346
8417
|
this.clientStore.registerCall(this);
|
|
@@ -8354,20 +8425,52 @@ class Call {
|
|
|
8354
8425
|
*/
|
|
8355
8426
|
this.getOrCreate = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
8356
8427
|
const response = yield this.streamClient.post(this.streamClientBasePath, data);
|
|
8428
|
+
if ((data === null || data === void 0 ? void 0 : data.ring) && !this.ringing) {
|
|
8429
|
+
this.ringingSubject.next(true);
|
|
8430
|
+
}
|
|
8357
8431
|
this.state.setMetadata(response.call);
|
|
8358
8432
|
this.state.setMembers(response.members);
|
|
8433
|
+
this.state.setOwnCapabilities(response.own_capabilities);
|
|
8359
8434
|
if (this.streamClient._hasConnectionID()) {
|
|
8360
8435
|
this.watching = true;
|
|
8361
8436
|
this.clientStore.registerCall(this);
|
|
8362
8437
|
}
|
|
8363
8438
|
return response;
|
|
8364
8439
|
});
|
|
8440
|
+
/**
|
|
8441
|
+
* A shortcut for {@link Call.get} with `ring` parameter set to `true`.
|
|
8442
|
+
* Will send a `call.ring` event to the call members.
|
|
8443
|
+
*/
|
|
8365
8444
|
this.ring = () => __awaiter(this, void 0, void 0, function* () {
|
|
8366
8445
|
return yield this.get({ ring: true });
|
|
8367
8446
|
});
|
|
8447
|
+
/**
|
|
8448
|
+
* A shortcut for {@link Call.get} with `notify` parameter set to `true`.
|
|
8449
|
+
* Will send a `call.notification` event to the call members.
|
|
8450
|
+
*/
|
|
8368
8451
|
this.notify = () => __awaiter(this, void 0, void 0, function* () {
|
|
8369
8452
|
return yield this.get({ notify: true });
|
|
8370
8453
|
});
|
|
8454
|
+
/**
|
|
8455
|
+
* Marks the incoming call as accepted.
|
|
8456
|
+
*
|
|
8457
|
+
* This method should be used only for "ringing" call flows.
|
|
8458
|
+
* {@link Call.join} invokes this method automatically for you when joining a call.
|
|
8459
|
+
* Unless you are implementing a custom "ringing" flow, you should not use this method.
|
|
8460
|
+
*/
|
|
8461
|
+
this.accept = () => __awaiter(this, void 0, void 0, function* () {
|
|
8462
|
+
return this.streamClient.post(`${this.streamClientBasePath}/accept`);
|
|
8463
|
+
});
|
|
8464
|
+
/**
|
|
8465
|
+
* Marks the incoming call as rejected.
|
|
8466
|
+
*
|
|
8467
|
+
* This method should be used only for "ringing" call flows.
|
|
8468
|
+
* {@link Call.leave} invokes this method automatically for you when you leave or reject this call.
|
|
8469
|
+
* Unless you are implementing a custom "ringing" flow, you should not use this method.
|
|
8470
|
+
*/
|
|
8471
|
+
this.reject = () => __awaiter(this, void 0, void 0, function* () {
|
|
8472
|
+
return this.streamClient.post(`${this.streamClientBasePath}/reject`);
|
|
8473
|
+
});
|
|
8371
8474
|
/**
|
|
8372
8475
|
* Will start to watch for call related WebSocket events and initiate a call session with the server.
|
|
8373
8476
|
*
|
|
@@ -8380,6 +8483,13 @@ class Call {
|
|
|
8380
8483
|
}
|
|
8381
8484
|
const previousCallingState = this.state.callingState;
|
|
8382
8485
|
this.state.setCallingState(CallingState.JOINING);
|
|
8486
|
+
if ((data === null || data === void 0 ? void 0 : data.ring) && !this.ringing) {
|
|
8487
|
+
this.ringingSubject.next(true);
|
|
8488
|
+
}
|
|
8489
|
+
if (this.ringing && !this.isCreatedByMe) {
|
|
8490
|
+
// signals other users that I have accepted the incoming call.
|
|
8491
|
+
yield this.accept();
|
|
8492
|
+
}
|
|
8383
8493
|
let sfuServer;
|
|
8384
8494
|
let sfuToken;
|
|
8385
8495
|
let connectionConfig;
|
|
@@ -8387,6 +8497,7 @@ class Call {
|
|
|
8387
8497
|
const call = yield join(this.streamClient, this.type, this.id, data);
|
|
8388
8498
|
this.state.setMetadata(call.metadata);
|
|
8389
8499
|
this.state.setMembers(call.members);
|
|
8500
|
+
this.state.setOwnCapabilities(call.ownCapabilities);
|
|
8390
8501
|
connectionConfig = call.connectionConfig;
|
|
8391
8502
|
sfuServer = call.sfuServer;
|
|
8392
8503
|
sfuToken = call.token;
|
|
@@ -8576,15 +8687,6 @@ class Call {
|
|
|
8576
8687
|
}
|
|
8577
8688
|
}
|
|
8578
8689
|
});
|
|
8579
|
-
/**
|
|
8580
|
-
* Will update the call members.
|
|
8581
|
-
*
|
|
8582
|
-
* @param data the request data.
|
|
8583
|
-
*/
|
|
8584
|
-
this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
8585
|
-
// FIXME: OL: implement kick-users
|
|
8586
|
-
return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
|
|
8587
|
-
});
|
|
8588
8690
|
/**
|
|
8589
8691
|
* Starts publishing the given video stream to the call.
|
|
8590
8692
|
* The stream will be stopped if the user changes an input device, or if the user leaves the call.
|
|
@@ -9037,7 +9139,12 @@ class Call {
|
|
|
9037
9139
|
* @param updates the updates to apply to the call.
|
|
9038
9140
|
*/
|
|
9039
9141
|
this.update = (updates) => __awaiter(this, void 0, void 0, function* () {
|
|
9040
|
-
|
|
9142
|
+
const response = yield this.streamClient.patch(`${this.streamClientBasePath}`, updates);
|
|
9143
|
+
const { call, members, own_capabilities } = response;
|
|
9144
|
+
this.state.setMetadata(call);
|
|
9145
|
+
this.state.setMembers(members);
|
|
9146
|
+
this.state.setOwnCapabilities(own_capabilities);
|
|
9147
|
+
return response;
|
|
9041
9148
|
});
|
|
9042
9149
|
/**
|
|
9043
9150
|
* Ends the call. Once the call is ended, it cannot be re-joined.
|
|
@@ -9064,7 +9171,17 @@ class Call {
|
|
|
9064
9171
|
this.queryMembers = (request) => {
|
|
9065
9172
|
return this.streamClient.post('/call/members', Object.assign(Object.assign({}, request), { id: this.id, type: this.type }));
|
|
9066
9173
|
};
|
|
9174
|
+
/**
|
|
9175
|
+
* Will update the call members.
|
|
9176
|
+
*
|
|
9177
|
+
* @param data the request data.
|
|
9178
|
+
*/
|
|
9179
|
+
this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
9180
|
+
return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
|
|
9181
|
+
});
|
|
9067
9182
|
this.scheduleAutoDrop = () => {
|
|
9183
|
+
if (this.dropTimeout)
|
|
9184
|
+
clearTimeout(this.dropTimeout);
|
|
9068
9185
|
const subscription = this.state.metadata$
|
|
9069
9186
|
.pipe(pairwise(), tap(([prevMeta, currentMeta]) => {
|
|
9070
9187
|
if (!(currentMeta && this.clientStore.connectedUser))
|
|
@@ -9076,8 +9193,8 @@ class Call {
|
|
|
9076
9193
|
currentMeta.settings.ring.auto_cancel_timeout_ms,
|
|
9077
9194
|
]
|
|
9078
9195
|
: [
|
|
9079
|
-
prevMeta === null || prevMeta === void 0 ? void 0 : prevMeta.settings.ring.
|
|
9080
|
-
currentMeta.settings.ring.
|
|
9196
|
+
prevMeta === null || prevMeta === void 0 ? void 0 : prevMeta.settings.ring.incoming_call_timeout_ms,
|
|
9197
|
+
currentMeta.settings.ring.incoming_call_timeout_ms,
|
|
9081
9198
|
];
|
|
9082
9199
|
if (typeof timeoutMs === 'undefined' || timeoutMs === prevTimeoutMs)
|
|
9083
9200
|
return;
|
|
@@ -9091,25 +9208,23 @@ class Call {
|
|
|
9091
9208
|
});
|
|
9092
9209
|
};
|
|
9093
9210
|
/**
|
|
9094
|
-
*
|
|
9095
|
-
* Updates the call state with
|
|
9211
|
+
* Retrieves the list of recordings for the current call or call session.
|
|
9212
|
+
* Updates the call state with the returned array of CallRecording objects.
|
|
9213
|
+
*
|
|
9214
|
+
* If `callSessionId` is provided, it will return the recordings for that call session.
|
|
9215
|
+
* Otherwise, all recordings for the current call will be returned.
|
|
9216
|
+
*
|
|
9217
|
+
* @param callSessionId the call session id to retrieve recordings for.
|
|
9096
9218
|
*/
|
|
9097
|
-
this.queryRecordings = () => __awaiter(this, void 0, void 0, function* () {
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9219
|
+
this.queryRecordings = (callSessionId) => __awaiter(this, void 0, void 0, function* () {
|
|
9220
|
+
let endpoint = this.streamClientBasePath;
|
|
9221
|
+
if (callSessionId) {
|
|
9222
|
+
endpoint = `${endpoint}/${callSessionId}`;
|
|
9223
|
+
}
|
|
9224
|
+
const response = yield this.streamClient.get(`${endpoint}/recordings`);
|
|
9101
9225
|
this.state.setCallRecordingsList(response.recordings);
|
|
9102
9226
|
return response;
|
|
9103
9227
|
});
|
|
9104
|
-
/**
|
|
9105
|
-
* Returns a list of Edge Serves for current call.
|
|
9106
|
-
*
|
|
9107
|
-
* @deprecated merged with `call.join`.
|
|
9108
|
-
* @param data the data.
|
|
9109
|
-
*/
|
|
9110
|
-
this.getEdgeServer = (data) => {
|
|
9111
|
-
return this.streamClient.post(`${this.streamClientBasePath}/get_edge_server`, data);
|
|
9112
|
-
};
|
|
9113
9228
|
/**
|
|
9114
9229
|
* Sends an event to all call participants.
|
|
9115
9230
|
*
|
|
@@ -9118,12 +9233,6 @@ class Call {
|
|
|
9118
9233
|
this.sendEvent = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
9119
9234
|
return this.streamClient.post(`${this.streamClientBasePath}/event`, event);
|
|
9120
9235
|
});
|
|
9121
|
-
this.accept = () => __awaiter(this, void 0, void 0, function* () {
|
|
9122
|
-
return this.streamClient.post(`${this.streamClientBasePath}/accept`);
|
|
9123
|
-
});
|
|
9124
|
-
this.reject = () => __awaiter(this, void 0, void 0, function* () {
|
|
9125
|
-
return this.streamClient.post(`${this.streamClientBasePath}/reject`);
|
|
9126
|
-
});
|
|
9127
9236
|
this.type = type;
|
|
9128
9237
|
this.id = id;
|
|
9129
9238
|
this.cid = `${type}:${id}`;
|
|
@@ -9139,6 +9248,7 @@ class Call {
|
|
|
9139
9248
|
}
|
|
9140
9249
|
this.state.setMetadata(metadata);
|
|
9141
9250
|
this.state.setMembers(members || []);
|
|
9251
|
+
this.state.setOwnCapabilities(ownCapabilities || []);
|
|
9142
9252
|
this.state.setCallingState(ringing ? CallingState.RINGING : CallingState.IDLE);
|
|
9143
9253
|
this.leaveCallHooks.push(registerEventHandlers(this, this.state, this.dispatcher));
|
|
9144
9254
|
this.registerEffects();
|
|
@@ -9150,23 +9260,13 @@ class Call {
|
|
|
9150
9260
|
createSubscription(this.state.metadata$, (metadata) => {
|
|
9151
9261
|
if (!metadata)
|
|
9152
9262
|
return;
|
|
9153
|
-
this.permissionsContext.setPermissions(metadata.own_capabilities);
|
|
9154
9263
|
this.permissionsContext.setCallSettings(metadata.settings);
|
|
9155
9264
|
}),
|
|
9156
|
-
//
|
|
9157
|
-
createSubscription(this.state.
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
if (currentUserId &&
|
|
9162
|
-
metadata.blocked_user_ids.includes(currentUserId)) {
|
|
9163
|
-
yield this.leave();
|
|
9164
|
-
}
|
|
9165
|
-
})),
|
|
9166
|
-
// handle the case when the user permissions are revoked.
|
|
9167
|
-
createSubscription(this.state.metadata$, (metadata) => {
|
|
9168
|
-
if (!metadata)
|
|
9169
|
-
return;
|
|
9265
|
+
// handle the case when the user permissions are modified.
|
|
9266
|
+
createSubscription(this.state.ownCapabilities$, (ownCapabilities) => {
|
|
9267
|
+
// update the permission context.
|
|
9268
|
+
this.permissionsContext.setPermissions(ownCapabilities);
|
|
9269
|
+
// check if the user still has publishing permissions and stop publishing if not.
|
|
9170
9270
|
const permissionToTrackType = {
|
|
9171
9271
|
[OwnCapability.SEND_AUDIO]: TrackType.AUDIO,
|
|
9172
9272
|
[OwnCapability.SEND_VIDEO]: TrackType.VIDEO,
|
|
@@ -9181,6 +9281,16 @@ class Call {
|
|
|
9181
9281
|
}
|
|
9182
9282
|
});
|
|
9183
9283
|
}),
|
|
9284
|
+
// handles the case when the user is blocked by the call owner.
|
|
9285
|
+
createSubscription(this.state.metadata$, (metadata) => __awaiter(this, void 0, void 0, function* () {
|
|
9286
|
+
if (!metadata)
|
|
9287
|
+
return;
|
|
9288
|
+
const currentUserId = this.currentUserId;
|
|
9289
|
+
if (currentUserId &&
|
|
9290
|
+
metadata.blocked_user_ids.includes(currentUserId)) {
|
|
9291
|
+
yield this.leave();
|
|
9292
|
+
}
|
|
9293
|
+
})),
|
|
9184
9294
|
// watch for auto drop cancellation
|
|
9185
9295
|
createSubscription(this.state.callingState$, (callingState) => {
|
|
9186
9296
|
if (!this.ringing)
|
|
@@ -10870,7 +10980,7 @@ class StreamClient {
|
|
|
10870
10980
|
}
|
|
10871
10981
|
getUserAgent() {
|
|
10872
10982
|
return (this.userAgent ||
|
|
10873
|
-
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.2-alpha.
|
|
10983
|
+
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.2-alpha.19"}`);
|
|
10874
10984
|
}
|
|
10875
10985
|
setUserAgent(userAgent) {
|
|
10876
10986
|
this.userAgent = userAgent;
|
|
@@ -10916,6 +11026,7 @@ class StreamVideoClient {
|
|
|
10916
11026
|
* @param opts the options for the client.
|
|
10917
11027
|
*/
|
|
10918
11028
|
constructor(apiKey, opts) {
|
|
11029
|
+
this.eventHandlersToUnregister = [];
|
|
10919
11030
|
/**
|
|
10920
11031
|
* Connects the given user to the client.
|
|
10921
11032
|
* Only one user can connect at a time, if you want to change users, call `disconnectUser` before connecting a new user.
|
|
@@ -10928,8 +11039,8 @@ class StreamVideoClient {
|
|
|
10928
11039
|
const connectUserResponse = yield this.streamClient.connectUser(
|
|
10929
11040
|
// @ts-expect-error
|
|
10930
11041
|
user, tokenOrProvider);
|
|
10931
|
-
|
|
10932
|
-
this.on('connection.changed', (e) => {
|
|
11042
|
+
this.writeableStateStore.setConnectedUser(user);
|
|
11043
|
+
this.eventHandlersToUnregister.push(this.on('connection.changed', (e) => {
|
|
10933
11044
|
const event = e;
|
|
10934
11045
|
if (event.online) {
|
|
10935
11046
|
const callsToReWatch = this.writeableStateStore.calls
|
|
@@ -10947,9 +11058,8 @@ class StreamVideoClient {
|
|
|
10947
11058
|
});
|
|
10948
11059
|
}
|
|
10949
11060
|
}
|
|
10950
|
-
});
|
|
10951
|
-
|
|
10952
|
-
this.on('call.created', (event) => {
|
|
11061
|
+
}));
|
|
11062
|
+
this.eventHandlersToUnregister.push(this.on('call.created', (event) => {
|
|
10953
11063
|
if (event.type !== 'call.created')
|
|
10954
11064
|
return;
|
|
10955
11065
|
const { call, members } = event;
|
|
@@ -10963,11 +11073,36 @@ class StreamVideoClient {
|
|
|
10963
11073
|
id: call.id,
|
|
10964
11074
|
metadata: call,
|
|
10965
11075
|
members,
|
|
10966
|
-
ringing: false,
|
|
10967
11076
|
clientStore: this.writeableStateStore,
|
|
10968
11077
|
}));
|
|
10969
|
-
});
|
|
10970
|
-
this.
|
|
11078
|
+
}));
|
|
11079
|
+
this.eventHandlersToUnregister.push(this.on('call.ring', (event) => __awaiter(this, void 0, void 0, function* () {
|
|
11080
|
+
if (event.type !== 'call.ring')
|
|
11081
|
+
return;
|
|
11082
|
+
const { call, members } = event;
|
|
11083
|
+
if (user.id === call.created_by.id) {
|
|
11084
|
+
console.warn('Received `call.ring` sent by the current user');
|
|
11085
|
+
return;
|
|
11086
|
+
}
|
|
11087
|
+
// The call might already be tracked by the client,
|
|
11088
|
+
// if `call.created` was received before `call.ring`.
|
|
11089
|
+
// In that case, we just reuse the already tracked call.
|
|
11090
|
+
let theCall = this.writeableStateStore.findCall(call.type, call.id);
|
|
11091
|
+
if (!theCall) {
|
|
11092
|
+
// otherwise, we create a new call
|
|
11093
|
+
theCall = new Call({
|
|
11094
|
+
streamClient: this.streamClient,
|
|
11095
|
+
type: call.type,
|
|
11096
|
+
id: call.id,
|
|
11097
|
+
members,
|
|
11098
|
+
clientStore: this.writeableStateStore,
|
|
11099
|
+
ringing: true,
|
|
11100
|
+
});
|
|
11101
|
+
}
|
|
11102
|
+
// we fetch the latest metadata for the call from the server
|
|
11103
|
+
yield theCall.get({ ring: true });
|
|
11104
|
+
this.writeableStateStore.registerCall(theCall);
|
|
11105
|
+
})));
|
|
10971
11106
|
return connectUserResponse;
|
|
10972
11107
|
});
|
|
10973
11108
|
/**
|
|
@@ -10990,6 +11125,8 @@ class StreamVideoClient {
|
|
|
10990
11125
|
*/
|
|
10991
11126
|
this.disconnectUser = (timeout) => __awaiter(this, void 0, void 0, function* () {
|
|
10992
11127
|
yield this.streamClient.disconnectUser(timeout);
|
|
11128
|
+
this.eventHandlersToUnregister.forEach((unregister) => unregister());
|
|
11129
|
+
this.eventHandlersToUnregister = [];
|
|
10993
11130
|
this.writeableStateStore.setConnectedUser(undefined);
|
|
10994
11131
|
});
|
|
10995
11132
|
/**
|
|
@@ -11051,6 +11188,7 @@ class StreamVideoClient {
|
|
|
11051
11188
|
type: c.call.type,
|
|
11052
11189
|
metadata: c.call,
|
|
11053
11190
|
members: c.members,
|
|
11191
|
+
ownCapabilities: c.own_capabilities,
|
|
11054
11192
|
watching: data.watch,
|
|
11055
11193
|
clientStore: this.writeableStateStore,
|
|
11056
11194
|
});
|
|
@@ -11400,7 +11538,7 @@ const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options =
|
|
|
11400
11538
|
const percentage = averagedDataValue > audioLevelThreshold
|
|
11401
11539
|
? 100
|
|
11402
11540
|
: Math.round((averagedDataValue / audioLevelThreshold) * 100);
|
|
11403
|
-
onSoundDetectedStateChanged(isSoundDetected, percentage);
|
|
11541
|
+
onSoundDetectedStateChanged({ isSoundDetected, audioLevel: percentage });
|
|
11404
11542
|
}, detectionFrequencyInMs);
|
|
11405
11543
|
return function stop() {
|
|
11406
11544
|
return __awaiter(this, void 0, void 0, function* () {
|