@stream-io/video-client 0.0.2-alpha.2 → 0.0.2-alpha.21
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 +106 -0
- package/dist/index.browser.es.js +230 -89
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +230 -89
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +230 -89
- 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 +40 -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 +7 -12
- 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.cjs.js
CHANGED
|
@@ -5737,14 +5737,13 @@ class Publisher {
|
|
|
5737
5737
|
};
|
|
5738
5738
|
this.updateVideoPublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
|
|
5739
5739
|
var _a;
|
|
5740
|
-
console.log('
|
|
5740
|
+
console.log('Update publish quality, requested rids by SFU:', enabledRids);
|
|
5741
5741
|
const videoSender = (_a = this.transceiverRegistry[TrackType.VIDEO]) === null || _a === void 0 ? void 0 : _a.sender;
|
|
5742
5742
|
if (!videoSender)
|
|
5743
5743
|
return;
|
|
5744
5744
|
const params = videoSender.getParameters();
|
|
5745
5745
|
let changed = false;
|
|
5746
5746
|
params.encodings.forEach((enc) => {
|
|
5747
|
-
console.log(enc.rid, enc.active);
|
|
5748
5747
|
// flip 'active' flag only when necessary
|
|
5749
5748
|
const shouldEnable = enabledRids.includes(enc.rid);
|
|
5750
5749
|
if (shouldEnable !== enc.active) {
|
|
@@ -5757,6 +5756,10 @@ class Publisher {
|
|
|
5757
5756
|
console.warn('No suitable video encoding quality found');
|
|
5758
5757
|
}
|
|
5759
5758
|
yield videoSender.setParameters(params);
|
|
5759
|
+
console.log(`Update publish quality, enabled rids: ${params.encodings
|
|
5760
|
+
.filter((e) => e.active)
|
|
5761
|
+
.map((e) => e.rid)
|
|
5762
|
+
.join(', ')}`);
|
|
5760
5763
|
}
|
|
5761
5764
|
});
|
|
5762
5765
|
this.getCodecPreferences = (trackType, preferredCodec) => {
|
|
@@ -6619,6 +6622,12 @@ class CallState {
|
|
|
6619
6622
|
* @internal
|
|
6620
6623
|
*/
|
|
6621
6624
|
this.membersSubject = new rxjs.BehaviorSubject([]);
|
|
6625
|
+
/**
|
|
6626
|
+
* The list of capabilities of the current user.
|
|
6627
|
+
*
|
|
6628
|
+
* @private
|
|
6629
|
+
*/
|
|
6630
|
+
this.ownCapabilitiesSubject = new rxjs.BehaviorSubject([]);
|
|
6622
6631
|
/**
|
|
6623
6632
|
* The calling state.
|
|
6624
6633
|
*
|
|
@@ -6801,6 +6810,15 @@ class CallState {
|
|
|
6801
6810
|
this.setMembers = (members) => {
|
|
6802
6811
|
this.setCurrentValue(this.membersSubject, members);
|
|
6803
6812
|
};
|
|
6813
|
+
/**
|
|
6814
|
+
* Sets the own capabilities.
|
|
6815
|
+
*
|
|
6816
|
+
* @internal
|
|
6817
|
+
* @param capabilities the capabilities to set.
|
|
6818
|
+
*/
|
|
6819
|
+
this.setOwnCapabilities = (capabilities) => {
|
|
6820
|
+
return this.setCurrentValue(this.ownCapabilitiesSubject, capabilities);
|
|
6821
|
+
};
|
|
6804
6822
|
/**
|
|
6805
6823
|
* Will try to find the participant with the given sessionId in the current call.
|
|
6806
6824
|
*
|
|
@@ -6890,6 +6908,7 @@ class CallState {
|
|
|
6890
6908
|
this.callRecordingList$ = this.callRecordingListSubject.asObservable();
|
|
6891
6909
|
this.metadata$ = this.metadataSubject.asObservable();
|
|
6892
6910
|
this.members$ = this.membersSubject.asObservable();
|
|
6911
|
+
this.ownCapabilities$ = this.ownCapabilitiesSubject.asObservable();
|
|
6893
6912
|
this.callingState$ = this.callingStateSubject.asObservable();
|
|
6894
6913
|
}
|
|
6895
6914
|
/**
|
|
@@ -6985,6 +7004,12 @@ class CallState {
|
|
|
6985
7004
|
get members() {
|
|
6986
7005
|
return this.getCurrentValue(this.members$);
|
|
6987
7006
|
}
|
|
7007
|
+
/**
|
|
7008
|
+
* The capabilities of the current user for the current call.
|
|
7009
|
+
*/
|
|
7010
|
+
get ownCapabilities() {
|
|
7011
|
+
return this.getCurrentValue(this.ownCapabilities$);
|
|
7012
|
+
}
|
|
6988
7013
|
}
|
|
6989
7014
|
|
|
6990
7015
|
class StreamVideoWriteableStateStore {
|
|
@@ -7048,6 +7073,15 @@ class StreamVideoWriteableStateStore {
|
|
|
7048
7073
|
this.unregisterCall = (call) => {
|
|
7049
7074
|
return this.setCalls((calls) => calls.filter((c) => c !== call));
|
|
7050
7075
|
};
|
|
7076
|
+
/**
|
|
7077
|
+
* Finds a {@link Call} object in the list of {@link Call} objects created/tracked by this client.
|
|
7078
|
+
*
|
|
7079
|
+
* @param type the type of call to find.
|
|
7080
|
+
* @param id the id of the call to find.
|
|
7081
|
+
*/
|
|
7082
|
+
this.findCall = (type, id) => {
|
|
7083
|
+
return this.calls.find((c) => c.type === type && c.id === id);
|
|
7084
|
+
};
|
|
7051
7085
|
this.connectedUserSubject.subscribe((user) => __awaiter(this, void 0, void 0, function* () {
|
|
7052
7086
|
// leave all calls when the user disconnects.
|
|
7053
7087
|
if (!user) {
|
|
@@ -7167,16 +7201,39 @@ const watchCallAccepted = (call) => {
|
|
|
7167
7201
|
* Once the event is received, the call is left.
|
|
7168
7202
|
*/
|
|
7169
7203
|
const watchCallRejected = (call) => {
|
|
7170
|
-
let totalRejections = 0;
|
|
7171
7204
|
return function onCallRejected(event) {
|
|
7172
7205
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7173
7206
|
if (event.type !== 'call.rejected')
|
|
7174
7207
|
return;
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7208
|
+
// We want to discard the event if it's from the current user
|
|
7209
|
+
if (event.user.id === call.currentUserId)
|
|
7210
|
+
return;
|
|
7211
|
+
const { call: eventCall } = event;
|
|
7212
|
+
const { session: callSession } = eventCall;
|
|
7213
|
+
if (!callSession) {
|
|
7214
|
+
console.log('No call session provided. Ignoring call.rejected event.');
|
|
7215
|
+
return;
|
|
7216
|
+
}
|
|
7217
|
+
const rejectedBy = callSession.rejected_by;
|
|
7218
|
+
const { members, callingState } = call.state;
|
|
7219
|
+
if (callingState !== exports.CallingState.RINGING) {
|
|
7220
|
+
console.log('Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.');
|
|
7221
|
+
return;
|
|
7222
|
+
}
|
|
7223
|
+
if (call.isCreatedByMe) {
|
|
7224
|
+
const everyoneElseRejected = members
|
|
7225
|
+
.filter((m) => m.user_id !== call.currentUserId)
|
|
7226
|
+
.every((m) => rejectedBy[m.user_id]);
|
|
7227
|
+
if (everyoneElseRejected) {
|
|
7228
|
+
console.log('everyone rejected, leaving the call');
|
|
7229
|
+
yield call.leave();
|
|
7230
|
+
}
|
|
7231
|
+
}
|
|
7232
|
+
else {
|
|
7233
|
+
if (rejectedBy[eventCall.created_by.id]) {
|
|
7234
|
+
console.log('call creator rejected, leaving call');
|
|
7235
|
+
yield call.leave();
|
|
7236
|
+
}
|
|
7180
7237
|
}
|
|
7181
7238
|
});
|
|
7182
7239
|
};
|
|
@@ -7217,7 +7274,10 @@ const watchCallPermissionRequest = (state) => {
|
|
|
7217
7274
|
return function onCallPermissionRequest(event) {
|
|
7218
7275
|
if (event.type !== 'call.permission_request')
|
|
7219
7276
|
return;
|
|
7220
|
-
state
|
|
7277
|
+
const { localParticipant } = state;
|
|
7278
|
+
if (event.user.id !== (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
|
|
7279
|
+
state.setCallPermissionRequest(event);
|
|
7280
|
+
}
|
|
7221
7281
|
};
|
|
7222
7282
|
};
|
|
7223
7283
|
/**
|
|
@@ -7229,7 +7289,7 @@ const watchCallPermissionsUpdated = (state) => {
|
|
|
7229
7289
|
return;
|
|
7230
7290
|
const { localParticipant } = state;
|
|
7231
7291
|
if (event.user.id === (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
|
|
7232
|
-
state.
|
|
7292
|
+
state.setOwnCapabilities(event.own_capabilities);
|
|
7233
7293
|
}
|
|
7234
7294
|
};
|
|
7235
7295
|
};
|
|
@@ -7240,7 +7300,6 @@ const watchCallPermissionsUpdated = (state) => {
|
|
|
7240
7300
|
*/
|
|
7241
7301
|
const watchCallGrantsUpdated = (state) => {
|
|
7242
7302
|
return function onCallGrantsUpdated(event) {
|
|
7243
|
-
var _a;
|
|
7244
7303
|
if (event.eventPayload.oneofKind !== 'callGrantsUpdated')
|
|
7245
7304
|
return;
|
|
7246
7305
|
const { currentGrants } = event.eventPayload.callGrantsUpdated;
|
|
@@ -7251,15 +7310,13 @@ const watchCallGrantsUpdated = (state) => {
|
|
|
7251
7310
|
[OwnCapability.SEND_VIDEO]: canPublishVideo,
|
|
7252
7311
|
[OwnCapability.SCREENSHARE]: canScreenshare,
|
|
7253
7312
|
};
|
|
7254
|
-
const nextCapabilities =
|
|
7313
|
+
const nextCapabilities = state.ownCapabilities.filter((capability) => update[capability] !== false);
|
|
7255
7314
|
Object.entries(update).forEach(([capability, value]) => {
|
|
7256
7315
|
if (value && !nextCapabilities.includes(capability)) {
|
|
7257
7316
|
nextCapabilities.push(capability);
|
|
7258
7317
|
}
|
|
7259
7318
|
});
|
|
7260
|
-
state.
|
|
7261
|
-
return Object.assign(Object.assign({}, metadata), { own_capabilities: nextCapabilities });
|
|
7262
|
-
});
|
|
7319
|
+
state.setOwnCapabilities(nextCapabilities);
|
|
7263
7320
|
}
|
|
7264
7321
|
};
|
|
7265
7322
|
};
|
|
@@ -7552,10 +7609,7 @@ const watchCallSessionStarted = (state) => {
|
|
|
7552
7609
|
return function onCallSessionStarted(event) {
|
|
7553
7610
|
if (event.type !== 'call.session_started')
|
|
7554
7611
|
return;
|
|
7555
|
-
|
|
7556
|
-
state.setMetadata((metadata) => (Object.assign(Object.assign({}, call), {
|
|
7557
|
-
// FIXME OL: temporary, until the backend sends the own_capabilities
|
|
7558
|
-
own_capabilities: (metadata === null || metadata === void 0 ? void 0 : metadata.own_capabilities) || [] })));
|
|
7612
|
+
state.setMetadata(event.call);
|
|
7559
7613
|
};
|
|
7560
7614
|
};
|
|
7561
7615
|
/**
|
|
@@ -7567,10 +7621,7 @@ const watchCallSessionEnded = (state) => {
|
|
|
7567
7621
|
return function onCallSessionEnded(event) {
|
|
7568
7622
|
if (event.type !== 'call.session_ended')
|
|
7569
7623
|
return;
|
|
7570
|
-
|
|
7571
|
-
state.setMetadata((metadata) => (Object.assign(Object.assign({}, call), {
|
|
7572
|
-
// FIXME OL: temporary, until the backend sends the own_capabilities
|
|
7573
|
-
own_capabilities: (metadata === null || metadata === void 0 ? void 0 : metadata.own_capabilities) || [] })));
|
|
7624
|
+
state.setMetadata(event.call);
|
|
7574
7625
|
};
|
|
7575
7626
|
};
|
|
7576
7627
|
/**
|
|
@@ -7647,6 +7698,13 @@ const watchUnblockedUser = (state) => (event) => {
|
|
|
7647
7698
|
});
|
|
7648
7699
|
};
|
|
7649
7700
|
|
|
7701
|
+
/**
|
|
7702
|
+
* Registers the default event handlers for a call during its lifecycle.
|
|
7703
|
+
*
|
|
7704
|
+
* @param call the call to register event handlers for.
|
|
7705
|
+
* @param state the call state.
|
|
7706
|
+
* @param dispatcher the dispatcher.
|
|
7707
|
+
*/
|
|
7650
7708
|
const registerEventHandlers = (call, state, dispatcher) => {
|
|
7651
7709
|
const coordinatorEvents = {
|
|
7652
7710
|
'call.blocked_user': watchBlockedUser(state),
|
|
@@ -7669,8 +7727,6 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
7669
7727
|
'call.session_participant_left': watchCallSessionParticipantLeft(state),
|
|
7670
7728
|
'call.unblocked_user': watchUnblockedUser(state),
|
|
7671
7729
|
'call.updated': watchCallUpdated(state),
|
|
7672
|
-
'call.notification': (event) => console.log(`Received ${event.type} event`, event),
|
|
7673
|
-
'call.ring': (event) => console.log(`Received ${event.type} event`, event),
|
|
7674
7730
|
};
|
|
7675
7731
|
const eventHandlers = [
|
|
7676
7732
|
watchChangePublishQuality(dispatcher, call),
|
|
@@ -7696,6 +7752,11 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
7696
7752
|
eventHandlers.forEach((unsubscribe) => unsubscribe());
|
|
7697
7753
|
};
|
|
7698
7754
|
};
|
|
7755
|
+
/**
|
|
7756
|
+
* Registers event handlers for a call that is of ringing type.
|
|
7757
|
+
*
|
|
7758
|
+
* @param call the call to register event handlers for.
|
|
7759
|
+
*/
|
|
7699
7760
|
const registerRingingCallEventHandlers = (call) => {
|
|
7700
7761
|
const coordinatorRingEvents = {
|
|
7701
7762
|
'call.accepted': watchCallAccepted(call),
|
|
@@ -7722,13 +7783,14 @@ const registerRingingCallEventHandlers = (call) => {
|
|
|
7722
7783
|
const join = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7723
7784
|
yield httpClient.connectionIdPromise;
|
|
7724
7785
|
const joinCallResponse = yield doJoin(httpClient, type, id, data);
|
|
7725
|
-
const { call, credentials, members } = joinCallResponse;
|
|
7786
|
+
const { call, credentials, members, own_capabilities } = joinCallResponse;
|
|
7726
7787
|
return {
|
|
7727
7788
|
connectionConfig: toRtcConfiguration(credentials.ice_servers),
|
|
7728
7789
|
sfuServer: credentials.server,
|
|
7729
7790
|
token: credentials.token,
|
|
7730
7791
|
metadata: call,
|
|
7731
7792
|
members,
|
|
7793
|
+
ownCapabilities: own_capabilities,
|
|
7732
7794
|
};
|
|
7733
7795
|
});
|
|
7734
7796
|
const doJoin = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -7745,9 +7807,12 @@ const doJoin = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0,
|
|
|
7745
7807
|
});
|
|
7746
7808
|
const getLocationHint = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
7747
7809
|
const hintURL = `https://hint.stream-io-video.com/`;
|
|
7810
|
+
const abortController = new AbortController();
|
|
7811
|
+
const timeoutId = setTimeout(() => abortController.abort(), 1000);
|
|
7748
7812
|
try {
|
|
7749
7813
|
const response = yield fetch(hintURL, {
|
|
7750
7814
|
method: 'HEAD',
|
|
7815
|
+
signal: abortController.signal,
|
|
7751
7816
|
});
|
|
7752
7817
|
const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
|
|
7753
7818
|
return awsPop.substring(0, 3); // AMS1-P2 -> AMS
|
|
@@ -7756,6 +7821,9 @@ const getLocationHint = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
7756
7821
|
console.error(`Failed to get location hint from ${hintURL}`, e);
|
|
7757
7822
|
return 'ERR';
|
|
7758
7823
|
}
|
|
7824
|
+
finally {
|
|
7825
|
+
clearTimeout(timeoutId);
|
|
7826
|
+
}
|
|
7759
7827
|
});
|
|
7760
7828
|
const toRtcConfiguration = (config) => {
|
|
7761
7829
|
if (!config || config.length === 0)
|
|
@@ -8258,7 +8326,7 @@ class Call {
|
|
|
8258
8326
|
* Use the [`StreamVideoClient.call`](./StreamVideoClient.md/#call)
|
|
8259
8327
|
* method to construct a `Call` instance.
|
|
8260
8328
|
*/
|
|
8261
|
-
constructor({ type, id, streamClient, metadata, members, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
|
|
8329
|
+
constructor({ type, id, streamClient, metadata, members, ownCapabilities, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
|
|
8262
8330
|
/**
|
|
8263
8331
|
* ViewportTracker instance
|
|
8264
8332
|
*/
|
|
@@ -8302,13 +8370,11 @@ class Call {
|
|
|
8302
8370
|
if (this.isCreatedByMe && !hasOtherParticipants) {
|
|
8303
8371
|
// Signals other users that I have cancelled my call to them
|
|
8304
8372
|
// before they accepted it.
|
|
8305
|
-
|
|
8306
|
-
yield this.endCall();
|
|
8373
|
+
yield this.reject();
|
|
8307
8374
|
}
|
|
8308
8375
|
else if (reject && callingState === exports.CallingState.RINGING) {
|
|
8309
8376
|
// Signals other users that I have rejected the incoming call.
|
|
8310
|
-
|
|
8311
|
-
yield this.sendEvent({ type: 'call.rejected' });
|
|
8377
|
+
yield this.reject();
|
|
8312
8378
|
}
|
|
8313
8379
|
}
|
|
8314
8380
|
(_a = this.statsReporter) === null || _a === void 0 ? void 0 : _a.stop();
|
|
@@ -8340,11 +8406,19 @@ class Call {
|
|
|
8340
8406
|
});
|
|
8341
8407
|
/**
|
|
8342
8408
|
* Loads the information about the call.
|
|
8409
|
+
*
|
|
8410
|
+
* @param params.ring if set to true, a `call.ring` event will be sent to the call members.
|
|
8411
|
+
* @param params.notify if set to true, a `call.notification` event will be sent to the call members.
|
|
8412
|
+
* @param params.members_limit the members limit.
|
|
8343
8413
|
*/
|
|
8344
8414
|
this.get = (params) => __awaiter(this, void 0, void 0, function* () {
|
|
8345
8415
|
const response = yield this.streamClient.get(this.streamClientBasePath, params);
|
|
8416
|
+
if ((params === null || params === void 0 ? void 0 : params.ring) && !this.ringing) {
|
|
8417
|
+
this.ringingSubject.next(true);
|
|
8418
|
+
}
|
|
8346
8419
|
this.state.setMetadata(response.call);
|
|
8347
8420
|
this.state.setMembers(response.members);
|
|
8421
|
+
this.state.setOwnCapabilities(response.own_capabilities);
|
|
8348
8422
|
if (this.streamClient._hasConnectionID()) {
|
|
8349
8423
|
this.watching = true;
|
|
8350
8424
|
this.clientStore.registerCall(this);
|
|
@@ -8358,20 +8432,52 @@ class Call {
|
|
|
8358
8432
|
*/
|
|
8359
8433
|
this.getOrCreate = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
8360
8434
|
const response = yield this.streamClient.post(this.streamClientBasePath, data);
|
|
8435
|
+
if ((data === null || data === void 0 ? void 0 : data.ring) && !this.ringing) {
|
|
8436
|
+
this.ringingSubject.next(true);
|
|
8437
|
+
}
|
|
8361
8438
|
this.state.setMetadata(response.call);
|
|
8362
8439
|
this.state.setMembers(response.members);
|
|
8440
|
+
this.state.setOwnCapabilities(response.own_capabilities);
|
|
8363
8441
|
if (this.streamClient._hasConnectionID()) {
|
|
8364
8442
|
this.watching = true;
|
|
8365
8443
|
this.clientStore.registerCall(this);
|
|
8366
8444
|
}
|
|
8367
8445
|
return response;
|
|
8368
8446
|
});
|
|
8447
|
+
/**
|
|
8448
|
+
* A shortcut for {@link Call.get} with `ring` parameter set to `true`.
|
|
8449
|
+
* Will send a `call.ring` event to the call members.
|
|
8450
|
+
*/
|
|
8369
8451
|
this.ring = () => __awaiter(this, void 0, void 0, function* () {
|
|
8370
8452
|
return yield this.get({ ring: true });
|
|
8371
8453
|
});
|
|
8454
|
+
/**
|
|
8455
|
+
* A shortcut for {@link Call.get} with `notify` parameter set to `true`.
|
|
8456
|
+
* Will send a `call.notification` event to the call members.
|
|
8457
|
+
*/
|
|
8372
8458
|
this.notify = () => __awaiter(this, void 0, void 0, function* () {
|
|
8373
8459
|
return yield this.get({ notify: true });
|
|
8374
8460
|
});
|
|
8461
|
+
/**
|
|
8462
|
+
* Marks the incoming call as accepted.
|
|
8463
|
+
*
|
|
8464
|
+
* This method should be used only for "ringing" call flows.
|
|
8465
|
+
* {@link Call.join} invokes this method automatically for you when joining a call.
|
|
8466
|
+
* Unless you are implementing a custom "ringing" flow, you should not use this method.
|
|
8467
|
+
*/
|
|
8468
|
+
this.accept = () => __awaiter(this, void 0, void 0, function* () {
|
|
8469
|
+
return this.streamClient.post(`${this.streamClientBasePath}/accept`);
|
|
8470
|
+
});
|
|
8471
|
+
/**
|
|
8472
|
+
* Marks the incoming call as rejected.
|
|
8473
|
+
*
|
|
8474
|
+
* This method should be used only for "ringing" call flows.
|
|
8475
|
+
* {@link Call.leave} invokes this method automatically for you when you leave or reject this call.
|
|
8476
|
+
* Unless you are implementing a custom "ringing" flow, you should not use this method.
|
|
8477
|
+
*/
|
|
8478
|
+
this.reject = () => __awaiter(this, void 0, void 0, function* () {
|
|
8479
|
+
return this.streamClient.post(`${this.streamClientBasePath}/reject`);
|
|
8480
|
+
});
|
|
8375
8481
|
/**
|
|
8376
8482
|
* Will start to watch for call related WebSocket events and initiate a call session with the server.
|
|
8377
8483
|
*
|
|
@@ -8384,6 +8490,13 @@ class Call {
|
|
|
8384
8490
|
}
|
|
8385
8491
|
const previousCallingState = this.state.callingState;
|
|
8386
8492
|
this.state.setCallingState(exports.CallingState.JOINING);
|
|
8493
|
+
if ((data === null || data === void 0 ? void 0 : data.ring) && !this.ringing) {
|
|
8494
|
+
this.ringingSubject.next(true);
|
|
8495
|
+
}
|
|
8496
|
+
if (this.ringing && !this.isCreatedByMe) {
|
|
8497
|
+
// signals other users that I have accepted the incoming call.
|
|
8498
|
+
yield this.accept();
|
|
8499
|
+
}
|
|
8387
8500
|
let sfuServer;
|
|
8388
8501
|
let sfuToken;
|
|
8389
8502
|
let connectionConfig;
|
|
@@ -8391,6 +8504,7 @@ class Call {
|
|
|
8391
8504
|
const call = yield join(this.streamClient, this.type, this.id, data);
|
|
8392
8505
|
this.state.setMetadata(call.metadata);
|
|
8393
8506
|
this.state.setMembers(call.members);
|
|
8507
|
+
this.state.setOwnCapabilities(call.ownCapabilities);
|
|
8394
8508
|
connectionConfig = call.connectionConfig;
|
|
8395
8509
|
sfuServer = call.sfuServer;
|
|
8396
8510
|
sfuToken = call.token;
|
|
@@ -8580,15 +8694,6 @@ class Call {
|
|
|
8580
8694
|
}
|
|
8581
8695
|
}
|
|
8582
8696
|
});
|
|
8583
|
-
/**
|
|
8584
|
-
* Will update the call members.
|
|
8585
|
-
*
|
|
8586
|
-
* @param data the request data.
|
|
8587
|
-
*/
|
|
8588
|
-
this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
8589
|
-
// FIXME: OL: implement kick-users
|
|
8590
|
-
return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
|
|
8591
|
-
});
|
|
8592
8697
|
/**
|
|
8593
8698
|
* Starts publishing the given video stream to the call.
|
|
8594
8699
|
* The stream will be stopped if the user changes an input device, or if the user leaves the call.
|
|
@@ -9041,7 +9146,12 @@ class Call {
|
|
|
9041
9146
|
* @param updates the updates to apply to the call.
|
|
9042
9147
|
*/
|
|
9043
9148
|
this.update = (updates) => __awaiter(this, void 0, void 0, function* () {
|
|
9044
|
-
|
|
9149
|
+
const response = yield this.streamClient.patch(`${this.streamClientBasePath}`, updates);
|
|
9150
|
+
const { call, members, own_capabilities } = response;
|
|
9151
|
+
this.state.setMetadata(call);
|
|
9152
|
+
this.state.setMembers(members);
|
|
9153
|
+
this.state.setOwnCapabilities(own_capabilities);
|
|
9154
|
+
return response;
|
|
9045
9155
|
});
|
|
9046
9156
|
/**
|
|
9047
9157
|
* Ends the call. Once the call is ended, it cannot be re-joined.
|
|
@@ -9068,7 +9178,17 @@ class Call {
|
|
|
9068
9178
|
this.queryMembers = (request) => {
|
|
9069
9179
|
return this.streamClient.post('/call/members', Object.assign(Object.assign({}, request), { id: this.id, type: this.type }));
|
|
9070
9180
|
};
|
|
9181
|
+
/**
|
|
9182
|
+
* Will update the call members.
|
|
9183
|
+
*
|
|
9184
|
+
* @param data the request data.
|
|
9185
|
+
*/
|
|
9186
|
+
this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
9187
|
+
return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
|
|
9188
|
+
});
|
|
9071
9189
|
this.scheduleAutoDrop = () => {
|
|
9190
|
+
if (this.dropTimeout)
|
|
9191
|
+
clearTimeout(this.dropTimeout);
|
|
9072
9192
|
const subscription = this.state.metadata$
|
|
9073
9193
|
.pipe(rxjs.pairwise(), rxjs.tap(([prevMeta, currentMeta]) => {
|
|
9074
9194
|
if (!(currentMeta && this.clientStore.connectedUser))
|
|
@@ -9080,8 +9200,8 @@ class Call {
|
|
|
9080
9200
|
currentMeta.settings.ring.auto_cancel_timeout_ms,
|
|
9081
9201
|
]
|
|
9082
9202
|
: [
|
|
9083
|
-
prevMeta === null || prevMeta === void 0 ? void 0 : prevMeta.settings.ring.
|
|
9084
|
-
currentMeta.settings.ring.
|
|
9203
|
+
prevMeta === null || prevMeta === void 0 ? void 0 : prevMeta.settings.ring.incoming_call_timeout_ms,
|
|
9204
|
+
currentMeta.settings.ring.incoming_call_timeout_ms,
|
|
9085
9205
|
];
|
|
9086
9206
|
if (typeof timeoutMs === 'undefined' || timeoutMs === prevTimeoutMs)
|
|
9087
9207
|
return;
|
|
@@ -9095,25 +9215,23 @@ class Call {
|
|
|
9095
9215
|
});
|
|
9096
9216
|
};
|
|
9097
9217
|
/**
|
|
9098
|
-
*
|
|
9099
|
-
* Updates the call state with
|
|
9218
|
+
* Retrieves the list of recordings for the current call or call session.
|
|
9219
|
+
* Updates the call state with the returned array of CallRecording objects.
|
|
9220
|
+
*
|
|
9221
|
+
* If `callSessionId` is provided, it will return the recordings for that call session.
|
|
9222
|
+
* Otherwise, all recordings for the current call will be returned.
|
|
9223
|
+
*
|
|
9224
|
+
* @param callSessionId the call session id to retrieve recordings for.
|
|
9100
9225
|
*/
|
|
9101
|
-
this.queryRecordings = () => __awaiter(this, void 0, void 0, function* () {
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9226
|
+
this.queryRecordings = (callSessionId) => __awaiter(this, void 0, void 0, function* () {
|
|
9227
|
+
let endpoint = this.streamClientBasePath;
|
|
9228
|
+
if (callSessionId) {
|
|
9229
|
+
endpoint = `${endpoint}/${callSessionId}`;
|
|
9230
|
+
}
|
|
9231
|
+
const response = yield this.streamClient.get(`${endpoint}/recordings`);
|
|
9105
9232
|
this.state.setCallRecordingsList(response.recordings);
|
|
9106
9233
|
return response;
|
|
9107
9234
|
});
|
|
9108
|
-
/**
|
|
9109
|
-
* Returns a list of Edge Serves for current call.
|
|
9110
|
-
*
|
|
9111
|
-
* @deprecated merged with `call.join`.
|
|
9112
|
-
* @param data the data.
|
|
9113
|
-
*/
|
|
9114
|
-
this.getEdgeServer = (data) => {
|
|
9115
|
-
return this.streamClient.post(`${this.streamClientBasePath}/get_edge_server`, data);
|
|
9116
|
-
};
|
|
9117
9235
|
/**
|
|
9118
9236
|
* Sends an event to all call participants.
|
|
9119
9237
|
*
|
|
@@ -9122,12 +9240,6 @@ class Call {
|
|
|
9122
9240
|
this.sendEvent = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
9123
9241
|
return this.streamClient.post(`${this.streamClientBasePath}/event`, event);
|
|
9124
9242
|
});
|
|
9125
|
-
this.accept = () => __awaiter(this, void 0, void 0, function* () {
|
|
9126
|
-
return this.streamClient.post(`${this.streamClientBasePath}/accept`);
|
|
9127
|
-
});
|
|
9128
|
-
this.reject = () => __awaiter(this, void 0, void 0, function* () {
|
|
9129
|
-
return this.streamClient.post(`${this.streamClientBasePath}/reject`);
|
|
9130
|
-
});
|
|
9131
9243
|
this.type = type;
|
|
9132
9244
|
this.id = id;
|
|
9133
9245
|
this.cid = `${type}:${id}`;
|
|
@@ -9143,6 +9255,7 @@ class Call {
|
|
|
9143
9255
|
}
|
|
9144
9256
|
this.state.setMetadata(metadata);
|
|
9145
9257
|
this.state.setMembers(members || []);
|
|
9258
|
+
this.state.setOwnCapabilities(ownCapabilities || []);
|
|
9146
9259
|
this.state.setCallingState(ringing ? exports.CallingState.RINGING : exports.CallingState.IDLE);
|
|
9147
9260
|
this.leaveCallHooks.push(registerEventHandlers(this, this.state, this.dispatcher));
|
|
9148
9261
|
this.registerEffects();
|
|
@@ -9154,23 +9267,13 @@ class Call {
|
|
|
9154
9267
|
createSubscription(this.state.metadata$, (metadata) => {
|
|
9155
9268
|
if (!metadata)
|
|
9156
9269
|
return;
|
|
9157
|
-
this.permissionsContext.setPermissions(metadata.own_capabilities);
|
|
9158
9270
|
this.permissionsContext.setCallSettings(metadata.settings);
|
|
9159
9271
|
}),
|
|
9160
|
-
//
|
|
9161
|
-
createSubscription(this.state.
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
if (currentUserId &&
|
|
9166
|
-
metadata.blocked_user_ids.includes(currentUserId)) {
|
|
9167
|
-
yield this.leave();
|
|
9168
|
-
}
|
|
9169
|
-
})),
|
|
9170
|
-
// handle the case when the user permissions are revoked.
|
|
9171
|
-
createSubscription(this.state.metadata$, (metadata) => {
|
|
9172
|
-
if (!metadata)
|
|
9173
|
-
return;
|
|
9272
|
+
// handle the case when the user permissions are modified.
|
|
9273
|
+
createSubscription(this.state.ownCapabilities$, (ownCapabilities) => {
|
|
9274
|
+
// update the permission context.
|
|
9275
|
+
this.permissionsContext.setPermissions(ownCapabilities);
|
|
9276
|
+
// check if the user still has publishing permissions and stop publishing if not.
|
|
9174
9277
|
const permissionToTrackType = {
|
|
9175
9278
|
[OwnCapability.SEND_AUDIO]: TrackType.AUDIO,
|
|
9176
9279
|
[OwnCapability.SEND_VIDEO]: TrackType.VIDEO,
|
|
@@ -9185,6 +9288,16 @@ class Call {
|
|
|
9185
9288
|
}
|
|
9186
9289
|
});
|
|
9187
9290
|
}),
|
|
9291
|
+
// handles the case when the user is blocked by the call owner.
|
|
9292
|
+
createSubscription(this.state.metadata$, (metadata) => __awaiter(this, void 0, void 0, function* () {
|
|
9293
|
+
if (!metadata)
|
|
9294
|
+
return;
|
|
9295
|
+
const currentUserId = this.currentUserId;
|
|
9296
|
+
if (currentUserId &&
|
|
9297
|
+
metadata.blocked_user_ids.includes(currentUserId)) {
|
|
9298
|
+
yield this.leave();
|
|
9299
|
+
}
|
|
9300
|
+
})),
|
|
9188
9301
|
// watch for auto drop cancellation
|
|
9189
9302
|
createSubscription(this.state.callingState$, (callingState) => {
|
|
9190
9303
|
if (!this.ringing)
|
|
@@ -10875,7 +10988,7 @@ class StreamClient {
|
|
|
10875
10988
|
}
|
|
10876
10989
|
getUserAgent() {
|
|
10877
10990
|
return (this.userAgent ||
|
|
10878
|
-
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.2-alpha.
|
|
10991
|
+
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.2-alpha.20"}`);
|
|
10879
10992
|
}
|
|
10880
10993
|
setUserAgent(userAgent) {
|
|
10881
10994
|
this.userAgent = userAgent;
|
|
@@ -10921,6 +11034,7 @@ class StreamVideoClient {
|
|
|
10921
11034
|
* @param opts the options for the client.
|
|
10922
11035
|
*/
|
|
10923
11036
|
constructor(apiKey, opts) {
|
|
11037
|
+
this.eventHandlersToUnregister = [];
|
|
10924
11038
|
/**
|
|
10925
11039
|
* Connects the given user to the client.
|
|
10926
11040
|
* Only one user can connect at a time, if you want to change users, call `disconnectUser` before connecting a new user.
|
|
@@ -10933,8 +11047,8 @@ class StreamVideoClient {
|
|
|
10933
11047
|
const connectUserResponse = yield this.streamClient.connectUser(
|
|
10934
11048
|
// @ts-expect-error
|
|
10935
11049
|
user, tokenOrProvider);
|
|
10936
|
-
|
|
10937
|
-
this.on('connection.changed', (e) => {
|
|
11050
|
+
this.writeableStateStore.setConnectedUser(user);
|
|
11051
|
+
this.eventHandlersToUnregister.push(this.on('connection.changed', (e) => {
|
|
10938
11052
|
const event = e;
|
|
10939
11053
|
if (event.online) {
|
|
10940
11054
|
const callsToReWatch = this.writeableStateStore.calls
|
|
@@ -10952,9 +11066,8 @@ class StreamVideoClient {
|
|
|
10952
11066
|
});
|
|
10953
11067
|
}
|
|
10954
11068
|
}
|
|
10955
|
-
});
|
|
10956
|
-
|
|
10957
|
-
this.on('call.created', (event) => {
|
|
11069
|
+
}));
|
|
11070
|
+
this.eventHandlersToUnregister.push(this.on('call.created', (event) => {
|
|
10958
11071
|
if (event.type !== 'call.created')
|
|
10959
11072
|
return;
|
|
10960
11073
|
const { call, members } = event;
|
|
@@ -10968,11 +11081,36 @@ class StreamVideoClient {
|
|
|
10968
11081
|
id: call.id,
|
|
10969
11082
|
metadata: call,
|
|
10970
11083
|
members,
|
|
10971
|
-
ringing: false,
|
|
10972
11084
|
clientStore: this.writeableStateStore,
|
|
10973
11085
|
}));
|
|
10974
|
-
});
|
|
10975
|
-
this.
|
|
11086
|
+
}));
|
|
11087
|
+
this.eventHandlersToUnregister.push(this.on('call.ring', (event) => __awaiter(this, void 0, void 0, function* () {
|
|
11088
|
+
if (event.type !== 'call.ring')
|
|
11089
|
+
return;
|
|
11090
|
+
const { call, members } = event;
|
|
11091
|
+
if (user.id === call.created_by.id) {
|
|
11092
|
+
console.warn('Received `call.ring` sent by the current user');
|
|
11093
|
+
return;
|
|
11094
|
+
}
|
|
11095
|
+
// The call might already be tracked by the client,
|
|
11096
|
+
// if `call.created` was received before `call.ring`.
|
|
11097
|
+
// In that case, we just reuse the already tracked call.
|
|
11098
|
+
let theCall = this.writeableStateStore.findCall(call.type, call.id);
|
|
11099
|
+
if (!theCall) {
|
|
11100
|
+
// otherwise, we create a new call
|
|
11101
|
+
theCall = new Call({
|
|
11102
|
+
streamClient: this.streamClient,
|
|
11103
|
+
type: call.type,
|
|
11104
|
+
id: call.id,
|
|
11105
|
+
members,
|
|
11106
|
+
clientStore: this.writeableStateStore,
|
|
11107
|
+
ringing: true,
|
|
11108
|
+
});
|
|
11109
|
+
}
|
|
11110
|
+
// we fetch the latest metadata for the call from the server
|
|
11111
|
+
yield theCall.get({ ring: true });
|
|
11112
|
+
this.writeableStateStore.registerCall(theCall);
|
|
11113
|
+
})));
|
|
10976
11114
|
return connectUserResponse;
|
|
10977
11115
|
});
|
|
10978
11116
|
/**
|
|
@@ -10995,6 +11133,8 @@ class StreamVideoClient {
|
|
|
10995
11133
|
*/
|
|
10996
11134
|
this.disconnectUser = (timeout) => __awaiter(this, void 0, void 0, function* () {
|
|
10997
11135
|
yield this.streamClient.disconnectUser(timeout);
|
|
11136
|
+
this.eventHandlersToUnregister.forEach((unregister) => unregister());
|
|
11137
|
+
this.eventHandlersToUnregister = [];
|
|
10998
11138
|
this.writeableStateStore.setConnectedUser(undefined);
|
|
10999
11139
|
});
|
|
11000
11140
|
/**
|
|
@@ -11056,6 +11196,7 @@ class StreamVideoClient {
|
|
|
11056
11196
|
type: c.call.type,
|
|
11057
11197
|
metadata: c.call,
|
|
11058
11198
|
members: c.members,
|
|
11199
|
+
ownCapabilities: c.own_capabilities,
|
|
11059
11200
|
watching: data.watch,
|
|
11060
11201
|
clientStore: this.writeableStateStore,
|
|
11061
11202
|
});
|
|
@@ -11405,7 +11546,7 @@ const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options =
|
|
|
11405
11546
|
const percentage = averagedDataValue > audioLevelThreshold
|
|
11406
11547
|
? 100
|
|
11407
11548
|
: Math.round((averagedDataValue / audioLevelThreshold) * 100);
|
|
11408
|
-
onSoundDetectedStateChanged(isSoundDetected, percentage);
|
|
11549
|
+
onSoundDetectedStateChanged({ isSoundDetected, audioLevel: percentage });
|
|
11409
11550
|
}, detectionFrequencyInMs);
|
|
11410
11551
|
return function stop() {
|
|
11411
11552
|
return __awaiter(this, void 0, void 0, function* () {
|