@stream-io/video-client 0.2.2 → 0.3.0
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 +18 -0
- package/dist/index.browser.es.js +325 -421
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +325 -421
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +325 -421
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +8 -10
- package/dist/src/StreamVideoClient.d.ts +3 -1
- package/dist/src/events/call-permissions.d.ts +0 -5
- package/dist/src/events/call.d.ts +0 -6
- package/dist/src/events/index.d.ts +0 -6
- package/dist/src/gen/coordinator/index.d.ts +25 -0
- package/dist/src/rtc/Dispatcher.d.ts +2 -2
- package/dist/src/rtc/Publisher.d.ts +0 -1
- package/dist/src/store/CallState.d.ts +164 -89
- package/dist/src/types.d.ts +1 -7
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +37 -44
- package/src/StreamVideoClient.ts +14 -17
- package/src/events/__tests__/call-permissions.test.ts +1 -61
- package/src/events/__tests__/call.test.ts +5 -50
- package/src/events/call-permissions.ts +0 -14
- package/src/events/call.ts +5 -16
- package/src/events/callEventHandlers.ts +2 -57
- package/src/events/index.ts +0 -6
- package/src/gen/coordinator/index.ts +25 -0
- package/src/rtc/Dispatcher.ts +2 -2
- package/src/rtc/Publisher.ts +4 -6
- package/src/store/CallState.ts +475 -119
- package/src/store/__tests__/CallState.test.ts +447 -1
- package/src/types.ts +0 -8
- package/dist/src/events/__tests__/backstage.test.d.ts +0 -1
- package/dist/src/events/__tests__/members.test.d.ts +0 -1
- package/dist/src/events/__tests__/recording.test.d.ts +0 -1
- package/dist/src/events/__tests__/sessions.test.d.ts +0 -1
- package/dist/src/events/backstage.d.ts +0 -6
- package/dist/src/events/members.d.ts +0 -18
- package/dist/src/events/moderation.d.ts +0 -14
- package/dist/src/events/reactions.d.ts +0 -8
- package/dist/src/events/recording.d.ts +0 -18
- package/dist/src/events/sessions.d.ts +0 -26
- package/src/events/__tests__/backstage.test.ts +0 -15
- package/src/events/__tests__/members.test.ts +0 -135
- package/src/events/__tests__/recording.test.ts +0 -65
- package/src/events/__tests__/sessions.test.ts +0 -135
- package/src/events/backstage.ts +0 -15
- package/src/events/members.ts +0 -62
- package/src/events/moderation.ts +0 -35
- package/src/events/reactions.ts +0 -30
- package/src/events/recording.ts +0 -64
- package/src/events/sessions.ts +0 -102
package/src/store/CallState.ts
CHANGED
|
@@ -11,10 +11,26 @@ import {
|
|
|
11
11
|
} from '../types';
|
|
12
12
|
import { CallStatsReport } from '../stats/types';
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
BlockedUserEvent,
|
|
15
|
+
CallBroadcastingStartedEvent,
|
|
16
|
+
CallIngressResponse,
|
|
17
|
+
CallMemberAddedEvent,
|
|
18
|
+
CallMemberRemovedEvent,
|
|
19
|
+
CallMemberUpdatedEvent,
|
|
20
|
+
CallMemberUpdatedPermissionEvent,
|
|
21
|
+
CallReactionEvent,
|
|
15
22
|
CallResponse,
|
|
23
|
+
CallSessionParticipantJoinedEvent,
|
|
24
|
+
CallSessionParticipantLeftEvent,
|
|
25
|
+
CallSessionResponse,
|
|
26
|
+
CallSettingsResponse,
|
|
27
|
+
EgressResponse,
|
|
16
28
|
MemberResponse,
|
|
17
29
|
OwnCapability,
|
|
30
|
+
UnblockedUserEvent,
|
|
31
|
+
UpdatedCallPermissionsEvent,
|
|
32
|
+
UserResponse,
|
|
33
|
+
VideoEvent,
|
|
18
34
|
} from '../gen/coordinator';
|
|
19
35
|
import { Pin, TrackType } from '../gen/video/sfu/models/models';
|
|
20
36
|
import { Comparator } from '../sorting';
|
|
@@ -82,89 +98,48 @@ export enum CallingState {
|
|
|
82
98
|
* @react You don't have to use this class directly, as we are exposing the state through Hooks.
|
|
83
99
|
*/
|
|
84
100
|
export class CallState {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
private
|
|
101
|
+
private backstageSubject = new BehaviorSubject<boolean>(false);
|
|
102
|
+
private blockedUserIdsSubject = new BehaviorSubject<string[]>([]);
|
|
103
|
+
private createdAtSubject = new BehaviorSubject<Date>(new Date());
|
|
104
|
+
private endedAtSubject = new BehaviorSubject<Date | undefined>(undefined);
|
|
105
|
+
private startsAtSubject = new BehaviorSubject<Date | undefined>(undefined);
|
|
106
|
+
private updatedAtSubject = new BehaviorSubject<Date>(new Date());
|
|
107
|
+
private createdBySubject = new BehaviorSubject<UserResponse | undefined>(
|
|
108
|
+
undefined,
|
|
109
|
+
);
|
|
110
|
+
private customSubject = new BehaviorSubject<Record<string, any>>({});
|
|
111
|
+
private egressSubject = new BehaviorSubject<EgressResponse | undefined>(
|
|
112
|
+
undefined,
|
|
113
|
+
);
|
|
114
|
+
private ingressSubject = new BehaviorSubject<CallIngressResponse | undefined>(
|
|
115
|
+
undefined,
|
|
116
|
+
);
|
|
117
|
+
private recordingSubject = new BehaviorSubject<boolean>(false);
|
|
118
|
+
private sessionSubject = new BehaviorSubject<CallSessionResponse | undefined>(
|
|
119
|
+
undefined,
|
|
120
|
+
);
|
|
121
|
+
private settingsSubject = new BehaviorSubject<
|
|
122
|
+
CallSettingsResponse | undefined
|
|
123
|
+
>(undefined);
|
|
124
|
+
private transcribingSubject = new BehaviorSubject<boolean>(false);
|
|
125
|
+
private endedBySubject = new BehaviorSubject<UserResponse | undefined>(
|
|
91
126
|
undefined,
|
|
92
127
|
);
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* The list of members of the current call.
|
|
96
|
-
*
|
|
97
|
-
* @internal
|
|
98
|
-
*/
|
|
99
128
|
private membersSubject = new BehaviorSubject<MemberResponse[]>([]);
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* The list of capabilities of the current user.
|
|
103
|
-
*
|
|
104
|
-
* @private
|
|
105
|
-
*/
|
|
106
129
|
private ownCapabilitiesSubject = new BehaviorSubject<OwnCapability[]>([]);
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* The calling state.
|
|
110
|
-
*
|
|
111
|
-
* @internal
|
|
112
|
-
*/
|
|
113
130
|
private callingStateSubject = new BehaviorSubject<CallingState>(
|
|
114
131
|
CallingState.UNKNOWN,
|
|
115
132
|
);
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* The time the call session actually started.
|
|
119
|
-
*
|
|
120
|
-
* @internal
|
|
121
|
-
*/
|
|
122
133
|
private startedAtSubject = new BehaviorSubject<Date | undefined>(undefined);
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* The server-side counted number of participants connected to the current call.
|
|
126
|
-
* This number includes the anonymous participants as well.
|
|
127
|
-
*
|
|
128
|
-
* @internal
|
|
129
|
-
*/
|
|
130
134
|
private participantCountSubject = new BehaviorSubject<number>(0);
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* The server-side counted number of anonymous participants connected to the current call.
|
|
134
|
-
* This number excludes the regular participants.
|
|
135
|
-
*
|
|
136
|
-
* @internal
|
|
137
|
-
*/
|
|
138
135
|
private anonymousParticipantCountSubject = new BehaviorSubject<number>(0);
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* All participants of the current call (including the logged-in user).
|
|
142
|
-
*
|
|
143
|
-
* @internal
|
|
144
|
-
*/
|
|
145
136
|
private participantsSubject = new BehaviorSubject<
|
|
146
137
|
(StreamVideoParticipant | StreamVideoLocalParticipant)[]
|
|
147
138
|
>([]);
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* The latest stats report of the current call.
|
|
151
|
-
* When stats gathering is enabled, this observable will emit a new value
|
|
152
|
-
* at a regular (configurable) interval.
|
|
153
|
-
*
|
|
154
|
-
* Consumers of this observable can implement their own batching logic
|
|
155
|
-
* in case they want to show historical stat data.
|
|
156
|
-
*
|
|
157
|
-
* @internal
|
|
158
|
-
*/
|
|
159
139
|
private callStatsReportSubject = new BehaviorSubject<
|
|
160
140
|
CallStatsReport | undefined
|
|
161
141
|
>(undefined);
|
|
162
142
|
|
|
163
|
-
/**
|
|
164
|
-
* Emits a list of details about recordings performed for the current call.
|
|
165
|
-
*/
|
|
166
|
-
private callRecordingListSubject = new BehaviorSubject<CallRecording[]>([]);
|
|
167
|
-
|
|
168
143
|
// Derived state
|
|
169
144
|
|
|
170
145
|
/**
|
|
@@ -233,16 +208,6 @@ export class CallState {
|
|
|
233
208
|
*/
|
|
234
209
|
callStatsReport$: Observable<CallStatsReport | undefined>;
|
|
235
210
|
|
|
236
|
-
/**
|
|
237
|
-
* Emits a list of details about recordings performed for the current call
|
|
238
|
-
*/
|
|
239
|
-
callRecordingList$: Observable<CallRecording[]>;
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* The raw call metadata object, as defined on the backend.
|
|
243
|
-
*/
|
|
244
|
-
metadata$: Observable<CallResponse | undefined>;
|
|
245
|
-
|
|
246
211
|
/**
|
|
247
212
|
* The list of members in the current call.
|
|
248
213
|
*/
|
|
@@ -258,6 +223,81 @@ export class CallState {
|
|
|
258
223
|
*/
|
|
259
224
|
callingState$: Observable<CallingState>;
|
|
260
225
|
|
|
226
|
+
/**
|
|
227
|
+
* The backstage state.
|
|
228
|
+
*/
|
|
229
|
+
backstage$: Observable<boolean>;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Will provide the list of blocked user IDs.
|
|
233
|
+
*/
|
|
234
|
+
blockedUserIds$: Observable<string[]>;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Will provide the time when this call has been created.
|
|
238
|
+
*/
|
|
239
|
+
createdAt$: Observable<Date>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Will provide the time when this call has been ended.
|
|
243
|
+
*/
|
|
244
|
+
endedAt$: Observable<Date | undefined>;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Will provide the time when this call has been scheduled to start.
|
|
248
|
+
*/
|
|
249
|
+
startsAt$: Observable<Date | undefined>;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Will provide the time when this call has been updated.
|
|
253
|
+
*/
|
|
254
|
+
updatedAt$: Observable<Date>;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Will provide the user who created this call.
|
|
258
|
+
*/
|
|
259
|
+
createdBy$: Observable<UserResponse | undefined>;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Will provide the custom data of this call.
|
|
263
|
+
*/
|
|
264
|
+
custom$: Observable<Record<string, any>>;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Will provide the egress data of this call.
|
|
268
|
+
*/
|
|
269
|
+
egress$: Observable<EgressResponse | undefined>;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Will provide the ingress data of this call.
|
|
273
|
+
*/
|
|
274
|
+
ingress$: Observable<CallIngressResponse | undefined>;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Will provide the recording state of this call.
|
|
278
|
+
*/
|
|
279
|
+
recording$: Observable<boolean>;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Will provide the session data of this call.
|
|
283
|
+
*/
|
|
284
|
+
session$: Observable<CallSessionResponse | undefined>;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Will provide the settings of this call.
|
|
288
|
+
*/
|
|
289
|
+
settings$: Observable<CallSettingsResponse | undefined>;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Will provide the transcribing state of this call.
|
|
293
|
+
*/
|
|
294
|
+
transcribing$: Observable<boolean>;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Will provide the user who ended this call.
|
|
298
|
+
*/
|
|
299
|
+
endedBy$: Observable<UserResponse | undefined>;
|
|
300
|
+
|
|
261
301
|
readonly logger: Logger;
|
|
262
302
|
|
|
263
303
|
/**
|
|
@@ -268,12 +308,18 @@ export class CallState {
|
|
|
268
308
|
private sortParticipantsBy: Comparator<StreamVideoParticipant> =
|
|
269
309
|
SortingPreset.defaultSortPreset;
|
|
270
310
|
|
|
311
|
+
private readonly eventHandlers: {
|
|
312
|
+
[EventType in VideoEvent['type']]:
|
|
313
|
+
| ((event: Extract<VideoEvent, { type: EventType }>) => void)
|
|
314
|
+
| undefined;
|
|
315
|
+
};
|
|
316
|
+
|
|
271
317
|
/**
|
|
272
318
|
* Creates a new instance of the CallState class.
|
|
273
319
|
*
|
|
274
320
|
*/
|
|
275
321
|
constructor() {
|
|
276
|
-
this.logger = getLogger(['
|
|
322
|
+
this.logger = getLogger(['CallState']);
|
|
277
323
|
this.participants$ = this.participantsSubject.pipe(
|
|
278
324
|
map((ps) => ps.sort(this.sortParticipantsBy)),
|
|
279
325
|
);
|
|
@@ -295,11 +341,11 @@ export class CallState {
|
|
|
295
341
|
);
|
|
296
342
|
|
|
297
343
|
this.hasOngoingScreenShare$ = this.participants$.pipe(
|
|
298
|
-
map((participants) =>
|
|
299
|
-
|
|
344
|
+
map((participants) =>
|
|
345
|
+
participants.some((p) =>
|
|
300
346
|
p.publishedTracks.includes(TrackType.SCREEN_SHARE),
|
|
301
|
-
)
|
|
302
|
-
|
|
347
|
+
),
|
|
348
|
+
),
|
|
303
349
|
distinctUntilChanged(),
|
|
304
350
|
);
|
|
305
351
|
|
|
@@ -309,11 +355,67 @@ export class CallState {
|
|
|
309
355
|
this.anonymousParticipantCountSubject.asObservable();
|
|
310
356
|
|
|
311
357
|
this.callStatsReport$ = this.callStatsReportSubject.asObservable();
|
|
312
|
-
this.callRecordingList$ = this.callRecordingListSubject.asObservable();
|
|
313
|
-
this.metadata$ = this.metadataSubject.asObservable();
|
|
314
358
|
this.members$ = this.membersSubject.asObservable();
|
|
315
359
|
this.ownCapabilities$ = this.ownCapabilitiesSubject.asObservable();
|
|
316
360
|
this.callingState$ = this.callingStateSubject.asObservable();
|
|
361
|
+
|
|
362
|
+
this.backstage$ = this.backstageSubject.asObservable();
|
|
363
|
+
this.blockedUserIds$ = this.blockedUserIdsSubject.asObservable();
|
|
364
|
+
this.createdAt$ = this.createdAtSubject.asObservable();
|
|
365
|
+
this.endedAt$ = this.endedAtSubject.asObservable();
|
|
366
|
+
this.startsAt$ = this.startsAtSubject.asObservable();
|
|
367
|
+
this.updatedAt$ = this.updatedAtSubject.asObservable();
|
|
368
|
+
this.createdBy$ = this.createdBySubject.asObservable();
|
|
369
|
+
this.custom$ = this.customSubject.asObservable();
|
|
370
|
+
this.egress$ = this.egressSubject.asObservable();
|
|
371
|
+
this.ingress$ = this.ingressSubject.asObservable();
|
|
372
|
+
this.recording$ = this.recordingSubject.asObservable();
|
|
373
|
+
this.session$ = this.sessionSubject.asObservable();
|
|
374
|
+
this.settings$ = this.settingsSubject.asObservable();
|
|
375
|
+
this.transcribing$ = this.transcribingSubject.asObservable();
|
|
376
|
+
this.endedBy$ = this.endedBySubject.asObservable();
|
|
377
|
+
|
|
378
|
+
this.eventHandlers = {
|
|
379
|
+
// these events are not updating the call state:
|
|
380
|
+
'call.permission_request': undefined,
|
|
381
|
+
'call.user_muted': undefined,
|
|
382
|
+
'connection.error': undefined,
|
|
383
|
+
'connection.ok': undefined,
|
|
384
|
+
'health.check': undefined,
|
|
385
|
+
custom: undefined,
|
|
386
|
+
|
|
387
|
+
// events that update call state:
|
|
388
|
+
'call.accepted': (e) => this.updateFromCallResponse(e.call),
|
|
389
|
+
'call.created': (e) => this.updateFromCallResponse(e.call),
|
|
390
|
+
'call.notification': (e) => this.updateFromCallResponse(e.call),
|
|
391
|
+
'call.rejected': (e) => this.updateFromCallResponse(e.call),
|
|
392
|
+
'call.ring': (e) => this.updateFromCallResponse(e.call),
|
|
393
|
+
'call.live_started': (e) => this.updateFromCallResponse(e.call),
|
|
394
|
+
'call.updated': (e) => this.updateFromCallResponse(e.call),
|
|
395
|
+
'call.session_started': (e) => this.updateFromCallResponse(e.call),
|
|
396
|
+
'call.session_ended': (e) => this.updateFromCallResponse(e.call),
|
|
397
|
+
'call.ended': (e) => {
|
|
398
|
+
this.updateFromCallResponse(e.call);
|
|
399
|
+
this.setCurrentValue(this.endedBySubject, e.user);
|
|
400
|
+
},
|
|
401
|
+
'call.recording_started': () =>
|
|
402
|
+
this.setCurrentValue(this.recordingSubject, true),
|
|
403
|
+
'call.recording_stopped': () =>
|
|
404
|
+
this.setCurrentValue(this.recordingSubject, false),
|
|
405
|
+
'call.broadcasting_started': this.updateFromBroadcastStarted,
|
|
406
|
+
'call.broadcasting_stopped': this.updateFromBroadcastStopped,
|
|
407
|
+
'call.session_participant_joined':
|
|
408
|
+
this.updateFromSessionParticipantJoined,
|
|
409
|
+
'call.session_participant_left': this.updateFromSessionParticipantLeft,
|
|
410
|
+
'call.blocked_user': this.blockUser,
|
|
411
|
+
'call.unblocked_user': this.unblockUser,
|
|
412
|
+
'call.permissions_updated': this.updateOwnCapabilities,
|
|
413
|
+
'call.member_added': this.updateFromMemberAdded,
|
|
414
|
+
'call.member_removed': this.updateFromMemberRemoved,
|
|
415
|
+
'call.member_updated': this.updateMembers,
|
|
416
|
+
'call.member_updated_permission': this.updateMembers,
|
|
417
|
+
'call.reaction_new': this.updateParticipantReaction,
|
|
418
|
+
};
|
|
317
419
|
}
|
|
318
420
|
|
|
319
421
|
/**
|
|
@@ -473,23 +575,6 @@ export class CallState {
|
|
|
473
575
|
return this.setCurrentValue(this.callingStateSubject, state);
|
|
474
576
|
};
|
|
475
577
|
|
|
476
|
-
/**
|
|
477
|
-
* The list of call recordings.
|
|
478
|
-
*/
|
|
479
|
-
get callRecordingsList() {
|
|
480
|
-
return this.getCurrentValue(this.callRecordingList$);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* Sets the list of call recordings.
|
|
485
|
-
*
|
|
486
|
-
* @internal
|
|
487
|
-
* @param recordings the list of call recordings.
|
|
488
|
-
*/
|
|
489
|
-
setCallRecordingsList = (recordings: Patch<CallRecording[]>) => {
|
|
490
|
-
return this.setCurrentValue(this.callRecordingListSubject, recordings);
|
|
491
|
-
};
|
|
492
|
-
|
|
493
578
|
/**
|
|
494
579
|
* The call stats report.
|
|
495
580
|
*/
|
|
@@ -507,24 +592,6 @@ export class CallState {
|
|
|
507
592
|
return this.setCurrentValue(this.callStatsReportSubject, report);
|
|
508
593
|
};
|
|
509
594
|
|
|
510
|
-
/**
|
|
511
|
-
* The metadata of the current call.
|
|
512
|
-
*/
|
|
513
|
-
get metadata() {
|
|
514
|
-
return this.getCurrentValue(this.metadata$);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
/**
|
|
518
|
-
* Sets the metadata of the current call.
|
|
519
|
-
*
|
|
520
|
-
* @internal
|
|
521
|
-
*
|
|
522
|
-
* @param metadata the metadata to set.
|
|
523
|
-
*/
|
|
524
|
-
setMetadata = (metadata: Patch<CallResponse | undefined>) => {
|
|
525
|
-
return this.setCurrentValue(this.metadataSubject, metadata);
|
|
526
|
-
};
|
|
527
|
-
|
|
528
595
|
/**
|
|
529
596
|
* The members of the current call.
|
|
530
597
|
*/
|
|
@@ -559,6 +626,111 @@ export class CallState {
|
|
|
559
626
|
return this.setCurrentValue(this.ownCapabilitiesSubject, capabilities);
|
|
560
627
|
};
|
|
561
628
|
|
|
629
|
+
/**
|
|
630
|
+
* The backstage state.
|
|
631
|
+
*/
|
|
632
|
+
get backstage() {
|
|
633
|
+
return this.getCurrentValue(this.backstage$);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Will provide the list of blocked user IDs.
|
|
638
|
+
*/
|
|
639
|
+
get blockedUserIds() {
|
|
640
|
+
return this.getCurrentValue(this.blockedUserIds$);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Will provide the time when this call has been created.
|
|
645
|
+
*/
|
|
646
|
+
get createdAt() {
|
|
647
|
+
return this.getCurrentValue(this.createdAt$);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Will provide the time when this call has been ended.
|
|
652
|
+
*/
|
|
653
|
+
get endedAt() {
|
|
654
|
+
return this.getCurrentValue(this.endedAt$);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Will provide the time when this call has been scheduled to start.
|
|
659
|
+
*/
|
|
660
|
+
get startsAt() {
|
|
661
|
+
return this.getCurrentValue(this.startsAt$);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Will provide the time when this call has been updated.
|
|
666
|
+
*/
|
|
667
|
+
get updatedAt() {
|
|
668
|
+
return this.getCurrentValue(this.updatedAt$);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Will provide the user who created this call.
|
|
673
|
+
*/
|
|
674
|
+
get createdBy() {
|
|
675
|
+
return this.getCurrentValue(this.createdBy$);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Will provide the custom data of this call.
|
|
680
|
+
*/
|
|
681
|
+
get custom() {
|
|
682
|
+
return this.getCurrentValue(this.custom$);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Will provide the egress data of this call.
|
|
687
|
+
*/
|
|
688
|
+
get egress() {
|
|
689
|
+
return this.getCurrentValue(this.egress$);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Will provide the ingress data of this call.
|
|
694
|
+
*/
|
|
695
|
+
get ingress() {
|
|
696
|
+
return this.getCurrentValue(this.ingress$);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Will provide the recording state of this call.
|
|
701
|
+
*/
|
|
702
|
+
get recording() {
|
|
703
|
+
return this.getCurrentValue(this.recording$);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Will provide the session data of this call.
|
|
708
|
+
*/
|
|
709
|
+
get session() {
|
|
710
|
+
return this.getCurrentValue(this.session$);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Will provide the settings of this call.
|
|
715
|
+
*/
|
|
716
|
+
get settings() {
|
|
717
|
+
return this.getCurrentValue(this.settings$);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Will provide the transcribing state of this call.
|
|
722
|
+
*/
|
|
723
|
+
get transcribing() {
|
|
724
|
+
return this.getCurrentValue(this.transcribing$);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Will provide the user who ended this call.
|
|
729
|
+
*/
|
|
730
|
+
get endedBy() {
|
|
731
|
+
return this.getCurrentValue(this.endedBy$);
|
|
732
|
+
}
|
|
733
|
+
|
|
562
734
|
/**
|
|
563
735
|
* Will try to find the participant with the given sessionId in the current call.
|
|
564
736
|
*
|
|
@@ -679,6 +851,20 @@ export class CallState {
|
|
|
679
851
|
);
|
|
680
852
|
};
|
|
681
853
|
|
|
854
|
+
/**
|
|
855
|
+
* Updates the call state with the data received from the server.
|
|
856
|
+
*
|
|
857
|
+
* @internal
|
|
858
|
+
*
|
|
859
|
+
* @param event the video event that our backend sent us.
|
|
860
|
+
*/
|
|
861
|
+
updateFromEvent = (event: VideoEvent) => {
|
|
862
|
+
const update = this.eventHandlers[event.type];
|
|
863
|
+
if (update) {
|
|
864
|
+
update(event as any);
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
|
|
682
868
|
/**
|
|
683
869
|
* Updates the participant pinned state with server side pinning data.
|
|
684
870
|
*
|
|
@@ -719,4 +905,174 @@ export class CallState {
|
|
|
719
905
|
}),
|
|
720
906
|
);
|
|
721
907
|
};
|
|
908
|
+
|
|
909
|
+
/**
|
|
910
|
+
* Updates the call state with the data received from the server.
|
|
911
|
+
*
|
|
912
|
+
* @internal
|
|
913
|
+
*
|
|
914
|
+
* @param call the call response from the server.
|
|
915
|
+
*/
|
|
916
|
+
updateFromCallResponse = (call: CallResponse) => {
|
|
917
|
+
this.setCurrentValue(this.backstageSubject, call.backstage);
|
|
918
|
+
this.setCurrentValue(this.blockedUserIdsSubject, call.blocked_user_ids);
|
|
919
|
+
this.setCurrentValue(this.createdAtSubject, new Date(call.created_at));
|
|
920
|
+
this.setCurrentValue(this.updatedAtSubject, new Date(call.updated_at));
|
|
921
|
+
this.setCurrentValue(
|
|
922
|
+
this.startsAtSubject,
|
|
923
|
+
call.starts_at ? new Date(call.starts_at) : undefined,
|
|
924
|
+
);
|
|
925
|
+
this.setCurrentValue(
|
|
926
|
+
this.endedAtSubject,
|
|
927
|
+
call.ended_at ? new Date(call.ended_at) : undefined,
|
|
928
|
+
);
|
|
929
|
+
this.setCurrentValue(this.createdBySubject, call.created_by);
|
|
930
|
+
this.setCurrentValue(this.customSubject, call.custom);
|
|
931
|
+
this.setCurrentValue(this.egressSubject, call.egress);
|
|
932
|
+
this.setCurrentValue(this.ingressSubject, call.ingress);
|
|
933
|
+
this.setCurrentValue(this.recordingSubject, call.recording);
|
|
934
|
+
this.setCurrentValue(this.sessionSubject, call.session);
|
|
935
|
+
this.setCurrentValue(this.settingsSubject, call.settings);
|
|
936
|
+
this.setCurrentValue(this.transcribingSubject, call.transcribing);
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
private updateFromMemberRemoved = (event: CallMemberRemovedEvent) => {
|
|
940
|
+
this.setCurrentValue(this.membersSubject, (members) =>
|
|
941
|
+
members.filter((m) => event.members.indexOf(m.user_id) === -1),
|
|
942
|
+
);
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
private updateFromMemberAdded = (event: CallMemberAddedEvent) => {
|
|
946
|
+
this.setCurrentValue(this.membersSubject, (members) => [
|
|
947
|
+
...members,
|
|
948
|
+
...event.members,
|
|
949
|
+
]);
|
|
950
|
+
};
|
|
951
|
+
|
|
952
|
+
private updateFromBroadcastStopped = () => {
|
|
953
|
+
this.setCurrentValue(this.egressSubject, (egress) => ({
|
|
954
|
+
...egress!,
|
|
955
|
+
broadcasting: false,
|
|
956
|
+
}));
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
private updateFromBroadcastStarted = (
|
|
960
|
+
event: CallBroadcastingStartedEvent,
|
|
961
|
+
) => {
|
|
962
|
+
this.setCurrentValue(this.egressSubject, (egress) => ({
|
|
963
|
+
...egress!,
|
|
964
|
+
broadcasting: true,
|
|
965
|
+
hls: {
|
|
966
|
+
...egress!.hls,
|
|
967
|
+
playlist_url: event.hls_playlist_url,
|
|
968
|
+
},
|
|
969
|
+
}));
|
|
970
|
+
};
|
|
971
|
+
|
|
972
|
+
private updateFromSessionParticipantLeft = (
|
|
973
|
+
event: CallSessionParticipantLeftEvent,
|
|
974
|
+
) => {
|
|
975
|
+
this.setCurrentValue(this.sessionSubject, (session) => {
|
|
976
|
+
if (!session) {
|
|
977
|
+
this.logger(
|
|
978
|
+
'warn',
|
|
979
|
+
`Received call.session_participant_left event but no session is available.`,
|
|
980
|
+
event,
|
|
981
|
+
);
|
|
982
|
+
return session;
|
|
983
|
+
}
|
|
984
|
+
const { participants, participants_count_by_role } = session;
|
|
985
|
+
const { user, user_session_id } = event.participant;
|
|
986
|
+
return {
|
|
987
|
+
...session,
|
|
988
|
+
participants: participants.filter(
|
|
989
|
+
(p) => p.user_session_id !== user_session_id,
|
|
990
|
+
),
|
|
991
|
+
participants_count_by_role: {
|
|
992
|
+
...participants_count_by_role,
|
|
993
|
+
[user.role]: Math.max(
|
|
994
|
+
0,
|
|
995
|
+
(participants_count_by_role[user.role] || 0) - 1,
|
|
996
|
+
),
|
|
997
|
+
},
|
|
998
|
+
};
|
|
999
|
+
});
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
private updateFromSessionParticipantJoined = (
|
|
1003
|
+
event: CallSessionParticipantJoinedEvent,
|
|
1004
|
+
) => {
|
|
1005
|
+
this.setCurrentValue(this.sessionSubject, (session) => {
|
|
1006
|
+
if (!session) {
|
|
1007
|
+
this.logger(
|
|
1008
|
+
'warn',
|
|
1009
|
+
`Received call.session_participant_joined event but no session is available.`,
|
|
1010
|
+
event,
|
|
1011
|
+
);
|
|
1012
|
+
return session;
|
|
1013
|
+
}
|
|
1014
|
+
const { participants, participants_count_by_role } = session;
|
|
1015
|
+
const { user } = event.participant;
|
|
1016
|
+
return {
|
|
1017
|
+
...session,
|
|
1018
|
+
participants: [...participants, event.participant],
|
|
1019
|
+
participants_count_by_role: {
|
|
1020
|
+
...participants_count_by_role,
|
|
1021
|
+
[user.role]: (participants_count_by_role[user.role] || 0) + 1,
|
|
1022
|
+
},
|
|
1023
|
+
};
|
|
1024
|
+
});
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
private updateMembers = (
|
|
1028
|
+
event: CallMemberUpdatedEvent | CallMemberUpdatedPermissionEvent,
|
|
1029
|
+
) => {
|
|
1030
|
+
this.setCurrentValue(this.membersSubject, (members) =>
|
|
1031
|
+
members.map((member) => {
|
|
1032
|
+
const memberUpdate = event.members.find(
|
|
1033
|
+
(m) => m.user_id === member.user_id,
|
|
1034
|
+
);
|
|
1035
|
+
return memberUpdate ? memberUpdate : member;
|
|
1036
|
+
}),
|
|
1037
|
+
);
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
private updateParticipantReaction = (event: CallReactionEvent) => {
|
|
1041
|
+
const { user, custom, type, emoji_code } = event.reaction;
|
|
1042
|
+
this.setParticipants((participants) => {
|
|
1043
|
+
return participants.map((p) => {
|
|
1044
|
+
// skip if the reaction is not for this participant
|
|
1045
|
+
if (p.userId !== user.id) return p;
|
|
1046
|
+
// update the participant with the new reaction
|
|
1047
|
+
return {
|
|
1048
|
+
...p,
|
|
1049
|
+
reaction: {
|
|
1050
|
+
type,
|
|
1051
|
+
emoji_code,
|
|
1052
|
+
custom,
|
|
1053
|
+
},
|
|
1054
|
+
};
|
|
1055
|
+
});
|
|
1056
|
+
});
|
|
1057
|
+
};
|
|
1058
|
+
|
|
1059
|
+
private unblockUser = (event: UnblockedUserEvent) => {
|
|
1060
|
+
this.setCurrentValue(this.blockedUserIdsSubject, (current) => {
|
|
1061
|
+
if (!current) return current;
|
|
1062
|
+
return current.filter((id) => id !== event.user.id);
|
|
1063
|
+
});
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
private blockUser = (event: BlockedUserEvent) => {
|
|
1067
|
+
this.setCurrentValue(this.blockedUserIdsSubject, (current) => [
|
|
1068
|
+
...(current || []),
|
|
1069
|
+
event.user.id,
|
|
1070
|
+
]);
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
private updateOwnCapabilities = (event: UpdatedCallPermissionsEvent) => {
|
|
1074
|
+
if (event.user.id === this.localParticipant?.userId) {
|
|
1075
|
+
this.setCurrentValue(this.ownCapabilitiesSubject, event.own_capabilities);
|
|
1076
|
+
}
|
|
1077
|
+
};
|
|
722
1078
|
}
|