@stream-io/video-client 0.1.11 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/index.browser.es.js +254 -28
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +254 -28
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +254 -28
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +27 -6
- package/dist/src/events/internal.d.ts +6 -0
- package/dist/src/gen/coordinator/index.d.ts +133 -0
- package/dist/src/gen/video/sfu/event/events.d.ts +31 -1
- package/dist/src/gen/video/sfu/models/models.d.ts +34 -0
- package/dist/src/store/CallState.d.ts +7 -0
- package/dist/src/types.d.ts +16 -2
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +60 -10
- package/src/events/call.ts +1 -0
- package/src/events/callEventHandlers.ts +2 -0
- package/src/events/internal.ts +13 -0
- package/src/gen/coordinator/index.ts +133 -0
- package/src/gen/video/sfu/event/events.ts +131 -0
- package/src/gen/video/sfu/models/models.ts +122 -1
- package/src/rtc/Dispatcher.ts +1 -0
- package/src/rtc/flows/join.ts +2 -8
- package/src/sorting/__tests__/participant-data.ts +4 -1
- package/src/sorting/participants.ts +7 -5
- package/src/store/CallState.ts +43 -2
- package/src/store/__tests__/CallState.test.ts +133 -78
- package/src/types.ts +18 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [0.2.1](https://github.com/GetStream/stream-video-js/compare/client0.2.0...client0.2.1) (2023-08-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* enhanced call session ([#900](https://github.com/GetStream/stream-video-js/issues/900)) ([dd4f1ea](https://github.com/GetStream/stream-video-js/commit/dd4f1ea03dbab0661a8b79dd55f51b0e9477ae75))
|
|
11
|
+
|
|
12
|
+
## [0.2.0](https://github.com/GetStream/stream-video-js/compare/client0.1.11...client0.2.0) (2023-08-07)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### ⚠ BREAKING CHANGES
|
|
16
|
+
|
|
17
|
+
* Server-side participant pinning (#881)
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* Server-side participant pinning ([#881](https://github.com/GetStream/stream-video-js/issues/881)) ([72829f1](https://github.com/GetStream/stream-video-js/commit/72829f1caf5b9c719d063a7e5175b7aa7431cd71))
|
|
22
|
+
|
|
5
23
|
### [0.1.11](https://github.com/GetStream/stream-video-js/compare/client0.1.10...client0.1.11) (2023-08-04)
|
|
6
24
|
|
|
7
25
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -47,6 +47,7 @@ const OwnCapability = {
|
|
|
47
47
|
JOIN_CALL: 'join-call',
|
|
48
48
|
JOIN_ENDED_CALL: 'join-ended-call',
|
|
49
49
|
MUTE_USERS: 'mute-users',
|
|
50
|
+
PIN_FOR_EVERYONE: 'pin-for-everyone',
|
|
50
51
|
READ_CALL: 'read-call',
|
|
51
52
|
REMOVE_CALL_MEMBER: 'remove-call-member',
|
|
52
53
|
SCREENSHARE: 'screenshare',
|
|
@@ -971,10 +972,17 @@ class CallState$Type extends MessageType {
|
|
|
971
972
|
kind: 'message',
|
|
972
973
|
T: () => ParticipantCount,
|
|
973
974
|
},
|
|
975
|
+
{
|
|
976
|
+
no: 4,
|
|
977
|
+
name: 'pins',
|
|
978
|
+
kind: 'message',
|
|
979
|
+
repeat: 1 /*RepeatType.PACKED*/,
|
|
980
|
+
T: () => Pin,
|
|
981
|
+
},
|
|
974
982
|
]);
|
|
975
983
|
}
|
|
976
984
|
create(value) {
|
|
977
|
-
const message = { participants: [] };
|
|
985
|
+
const message = { participants: [], pins: [] };
|
|
978
986
|
globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
|
|
979
987
|
enumerable: false,
|
|
980
988
|
value: this,
|
|
@@ -997,6 +1005,9 @@ class CallState$Type extends MessageType {
|
|
|
997
1005
|
case /* stream.video.sfu.models.ParticipantCount participant_count */ 3:
|
|
998
1006
|
message.participantCount = ParticipantCount.internalBinaryRead(reader, reader.uint32(), options, message.participantCount);
|
|
999
1007
|
break;
|
|
1008
|
+
case /* repeated stream.video.sfu.models.Pin pins */ 4:
|
|
1009
|
+
message.pins.push(Pin.internalBinaryRead(reader, reader.uint32(), options));
|
|
1010
|
+
break;
|
|
1000
1011
|
default:
|
|
1001
1012
|
let u = options.readUnknownField;
|
|
1002
1013
|
if (u === 'throw')
|
|
@@ -1018,6 +1029,9 @@ class CallState$Type extends MessageType {
|
|
|
1018
1029
|
/* stream.video.sfu.models.ParticipantCount participant_count = 3; */
|
|
1019
1030
|
if (message.participantCount)
|
|
1020
1031
|
ParticipantCount.internalBinaryWrite(message.participantCount, writer.tag(3, WireType.LengthDelimited).fork(), options).join();
|
|
1032
|
+
/* repeated stream.video.sfu.models.Pin pins = 4; */
|
|
1033
|
+
for (let i = 0; i < message.pins.length; i++)
|
|
1034
|
+
Pin.internalBinaryWrite(message.pins[i], writer.tag(4, WireType.LengthDelimited).fork(), options).join();
|
|
1021
1035
|
let u = options.writeUnknownFields;
|
|
1022
1036
|
if (u !== false)
|
|
1023
1037
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -1086,6 +1100,63 @@ class ParticipantCount$Type extends MessageType {
|
|
|
1086
1100
|
*/
|
|
1087
1101
|
const ParticipantCount = new ParticipantCount$Type();
|
|
1088
1102
|
// @generated message type with reflection information, may provide speed optimized methods
|
|
1103
|
+
class Pin$Type extends MessageType {
|
|
1104
|
+
constructor() {
|
|
1105
|
+
super('stream.video.sfu.models.Pin', [
|
|
1106
|
+
{ no: 1, name: 'user_id', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
|
|
1107
|
+
{ no: 2, name: 'session_id', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
|
|
1108
|
+
]);
|
|
1109
|
+
}
|
|
1110
|
+
create(value) {
|
|
1111
|
+
const message = { userId: '', sessionId: '' };
|
|
1112
|
+
globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
|
|
1113
|
+
enumerable: false,
|
|
1114
|
+
value: this,
|
|
1115
|
+
});
|
|
1116
|
+
if (value !== undefined)
|
|
1117
|
+
reflectionMergePartial(this, message, value);
|
|
1118
|
+
return message;
|
|
1119
|
+
}
|
|
1120
|
+
internalBinaryRead(reader, length, options, target) {
|
|
1121
|
+
let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
|
|
1122
|
+
while (reader.pos < end) {
|
|
1123
|
+
let [fieldNo, wireType] = reader.tag();
|
|
1124
|
+
switch (fieldNo) {
|
|
1125
|
+
case /* string user_id */ 1:
|
|
1126
|
+
message.userId = reader.string();
|
|
1127
|
+
break;
|
|
1128
|
+
case /* string session_id */ 2:
|
|
1129
|
+
message.sessionId = reader.string();
|
|
1130
|
+
break;
|
|
1131
|
+
default:
|
|
1132
|
+
let u = options.readUnknownField;
|
|
1133
|
+
if (u === 'throw')
|
|
1134
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
1135
|
+
let d = reader.skip(wireType);
|
|
1136
|
+
if (u !== false)
|
|
1137
|
+
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return message;
|
|
1141
|
+
}
|
|
1142
|
+
internalBinaryWrite(message, writer, options) {
|
|
1143
|
+
/* string user_id = 1; */
|
|
1144
|
+
if (message.userId !== '')
|
|
1145
|
+
writer.tag(1, WireType.LengthDelimited).string(message.userId);
|
|
1146
|
+
/* string session_id = 2; */
|
|
1147
|
+
if (message.sessionId !== '')
|
|
1148
|
+
writer.tag(2, WireType.LengthDelimited).string(message.sessionId);
|
|
1149
|
+
let u = options.writeUnknownFields;
|
|
1150
|
+
if (u !== false)
|
|
1151
|
+
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
1152
|
+
return writer;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* @generated MessageType for protobuf message stream.video.sfu.models.Pin
|
|
1157
|
+
*/
|
|
1158
|
+
const Pin = new Pin$Type();
|
|
1159
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
1089
1160
|
class Participant$Type extends MessageType {
|
|
1090
1161
|
constructor() {
|
|
1091
1162
|
super('stream.video.sfu.models.Participant', [
|
|
@@ -2400,6 +2471,7 @@ var models = /*#__PURE__*/Object.freeze({
|
|
|
2400
2471
|
Participant: Participant,
|
|
2401
2472
|
ParticipantCount: ParticipantCount,
|
|
2402
2473
|
get PeerType () { return PeerType; },
|
|
2474
|
+
Pin: Pin,
|
|
2403
2475
|
Sdk: Sdk,
|
|
2404
2476
|
get SdkType () { return SdkType; },
|
|
2405
2477
|
StreamQuality: StreamQuality,
|
|
@@ -3491,6 +3563,13 @@ class SfuEvent$Type extends MessageType {
|
|
|
3491
3563
|
oneof: 'eventPayload',
|
|
3492
3564
|
T: () => ICERestart,
|
|
3493
3565
|
},
|
|
3566
|
+
{
|
|
3567
|
+
no: 22,
|
|
3568
|
+
name: 'pins_updated',
|
|
3569
|
+
kind: 'message',
|
|
3570
|
+
oneof: 'eventPayload',
|
|
3571
|
+
T: () => PinsChanged,
|
|
3572
|
+
},
|
|
3494
3573
|
]);
|
|
3495
3574
|
}
|
|
3496
3575
|
create(value) {
|
|
@@ -3610,6 +3689,12 @@ class SfuEvent$Type extends MessageType {
|
|
|
3610
3689
|
iceRestart: ICERestart.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.iceRestart),
|
|
3611
3690
|
};
|
|
3612
3691
|
break;
|
|
3692
|
+
case /* stream.video.sfu.event.PinsChanged pins_updated */ 22:
|
|
3693
|
+
message.eventPayload = {
|
|
3694
|
+
oneofKind: 'pinsUpdated',
|
|
3695
|
+
pinsUpdated: PinsChanged.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.pinsUpdated),
|
|
3696
|
+
};
|
|
3697
|
+
break;
|
|
3613
3698
|
default:
|
|
3614
3699
|
let u = options.readUnknownField;
|
|
3615
3700
|
if (u === 'throw')
|
|
@@ -3673,6 +3758,9 @@ class SfuEvent$Type extends MessageType {
|
|
|
3673
3758
|
/* stream.video.sfu.event.ICERestart ice_restart = 21; */
|
|
3674
3759
|
if (message.eventPayload.oneofKind === 'iceRestart')
|
|
3675
3760
|
ICERestart.internalBinaryWrite(message.eventPayload.iceRestart, writer.tag(21, WireType.LengthDelimited).fork(), options).join();
|
|
3761
|
+
/* stream.video.sfu.event.PinsChanged pins_updated = 22; */
|
|
3762
|
+
if (message.eventPayload.oneofKind === 'pinsUpdated')
|
|
3763
|
+
PinsChanged.internalBinaryWrite(message.eventPayload.pinsUpdated, writer.tag(22, WireType.LengthDelimited).fork(), options).join();
|
|
3676
3764
|
let u = options.writeUnknownFields;
|
|
3677
3765
|
if (u !== false)
|
|
3678
3766
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -3684,6 +3772,62 @@ class SfuEvent$Type extends MessageType {
|
|
|
3684
3772
|
*/
|
|
3685
3773
|
const SfuEvent = new SfuEvent$Type();
|
|
3686
3774
|
// @generated message type with reflection information, may provide speed optimized methods
|
|
3775
|
+
class PinsChanged$Type extends MessageType {
|
|
3776
|
+
constructor() {
|
|
3777
|
+
super('stream.video.sfu.event.PinsChanged', [
|
|
3778
|
+
{
|
|
3779
|
+
no: 1,
|
|
3780
|
+
name: 'pins',
|
|
3781
|
+
kind: 'message',
|
|
3782
|
+
repeat: 1 /*RepeatType.PACKED*/,
|
|
3783
|
+
T: () => Pin,
|
|
3784
|
+
},
|
|
3785
|
+
]);
|
|
3786
|
+
}
|
|
3787
|
+
create(value) {
|
|
3788
|
+
const message = { pins: [] };
|
|
3789
|
+
globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
|
|
3790
|
+
enumerable: false,
|
|
3791
|
+
value: this,
|
|
3792
|
+
});
|
|
3793
|
+
if (value !== undefined)
|
|
3794
|
+
reflectionMergePartial(this, message, value);
|
|
3795
|
+
return message;
|
|
3796
|
+
}
|
|
3797
|
+
internalBinaryRead(reader, length, options, target) {
|
|
3798
|
+
let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
|
|
3799
|
+
while (reader.pos < end) {
|
|
3800
|
+
let [fieldNo, wireType] = reader.tag();
|
|
3801
|
+
switch (fieldNo) {
|
|
3802
|
+
case /* repeated stream.video.sfu.models.Pin pins */ 1:
|
|
3803
|
+
message.pins.push(Pin.internalBinaryRead(reader, reader.uint32(), options));
|
|
3804
|
+
break;
|
|
3805
|
+
default:
|
|
3806
|
+
let u = options.readUnknownField;
|
|
3807
|
+
if (u === 'throw')
|
|
3808
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
3809
|
+
let d = reader.skip(wireType);
|
|
3810
|
+
if (u !== false)
|
|
3811
|
+
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
return message;
|
|
3815
|
+
}
|
|
3816
|
+
internalBinaryWrite(message, writer, options) {
|
|
3817
|
+
/* repeated stream.video.sfu.models.Pin pins = 1; */
|
|
3818
|
+
for (let i = 0; i < message.pins.length; i++)
|
|
3819
|
+
Pin.internalBinaryWrite(message.pins[i], writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
|
3820
|
+
let u = options.writeUnknownFields;
|
|
3821
|
+
if (u !== false)
|
|
3822
|
+
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
3823
|
+
return writer;
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
/**
|
|
3827
|
+
* @generated MessageType for protobuf message stream.video.sfu.event.PinsChanged
|
|
3828
|
+
*/
|
|
3829
|
+
const PinsChanged = new PinsChanged$Type();
|
|
3830
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
3687
3831
|
class Error$Type extends MessageType {
|
|
3688
3832
|
constructor() {
|
|
3689
3833
|
super('stream.video.sfu.event.Error', [
|
|
@@ -5546,6 +5690,7 @@ var events = /*#__PURE__*/Object.freeze({
|
|
|
5546
5690
|
Migration: Migration,
|
|
5547
5691
|
ParticipantJoined: ParticipantJoined,
|
|
5548
5692
|
ParticipantLeft: ParticipantLeft,
|
|
5693
|
+
PinsChanged: PinsChanged,
|
|
5549
5694
|
PublisherAnswer: PublisherAnswer,
|
|
5550
5695
|
SfuEvent: SfuEvent,
|
|
5551
5696
|
SfuRequest: SfuRequest,
|
|
@@ -6038,6 +6183,7 @@ const sfuEventKinds = {
|
|
|
6038
6183
|
callGrantsUpdated: undefined,
|
|
6039
6184
|
goAway: undefined,
|
|
6040
6185
|
iceRestart: undefined,
|
|
6186
|
+
pinsUpdated: undefined,
|
|
6041
6187
|
};
|
|
6042
6188
|
const isSfuEvent = (eventName) => {
|
|
6043
6189
|
return Object.prototype.hasOwnProperty.call(sfuEventKinds, eventName);
|
|
@@ -7690,15 +7836,19 @@ const publishingAudio = (a, b) => {
|
|
|
7690
7836
|
* @param b the second participant.
|
|
7691
7837
|
*/
|
|
7692
7838
|
const pinned = (a, b) => {
|
|
7693
|
-
if (a.
|
|
7694
|
-
if (a.
|
|
7839
|
+
if (a.pin && b.pin) {
|
|
7840
|
+
if (!a.pin.isLocalPin && b.pin.isLocalPin)
|
|
7841
|
+
return -1;
|
|
7842
|
+
if (a.pin.isLocalPin && !b.pin.isLocalPin)
|
|
7843
|
+
return 1;
|
|
7844
|
+
if (a.pin.pinnedAt > b.pin.pinnedAt)
|
|
7695
7845
|
return -1;
|
|
7696
|
-
if (a.pinnedAt < b.pinnedAt)
|
|
7846
|
+
if (a.pin.pinnedAt < b.pin.pinnedAt)
|
|
7697
7847
|
return 1;
|
|
7698
7848
|
}
|
|
7699
|
-
if (a.
|
|
7849
|
+
if (a.pin && !b.pin)
|
|
7700
7850
|
return -1;
|
|
7701
|
-
if (!a.
|
|
7851
|
+
if (!a.pin && b.pin)
|
|
7702
7852
|
return 1;
|
|
7703
7853
|
return 0;
|
|
7704
7854
|
};
|
|
@@ -8097,11 +8247,39 @@ class CallState {
|
|
|
8097
8247
|
return p;
|
|
8098
8248
|
}));
|
|
8099
8249
|
};
|
|
8250
|
+
/**
|
|
8251
|
+
* Updates the participant pinned state with server side pinning data.
|
|
8252
|
+
*
|
|
8253
|
+
* @param pins the latest pins from the server.
|
|
8254
|
+
*/
|
|
8255
|
+
this.setServerSidePins = (pins) => {
|
|
8256
|
+
const pinsLookup = pins.reduce((lookup, pin) => {
|
|
8257
|
+
lookup[pin.sessionId] = Date.now();
|
|
8258
|
+
return lookup;
|
|
8259
|
+
}, {});
|
|
8260
|
+
return this.setParticipants((participants) => participants.map((participant) => {
|
|
8261
|
+
const serverSidePinnedAt = pinsLookup[participant.sessionId];
|
|
8262
|
+
// the participant is newly pinned
|
|
8263
|
+
if (serverSidePinnedAt) {
|
|
8264
|
+
return Object.assign(Object.assign({}, participant), { pin: {
|
|
8265
|
+
isLocalPin: false,
|
|
8266
|
+
pinnedAt: serverSidePinnedAt,
|
|
8267
|
+
} });
|
|
8268
|
+
}
|
|
8269
|
+
// the participant is no longer pinned server side
|
|
8270
|
+
// we need to reset the pin
|
|
8271
|
+
if (participant.pin && !participant.pin.isLocalPin) {
|
|
8272
|
+
return Object.assign(Object.assign({}, participant), { pin: undefined });
|
|
8273
|
+
}
|
|
8274
|
+
// no changes to be applied
|
|
8275
|
+
return participant;
|
|
8276
|
+
}));
|
|
8277
|
+
};
|
|
8100
8278
|
this.logger = getLogger(['call-state']);
|
|
8101
8279
|
this.participants$ = this.participantsSubject.pipe(map$1((ps) => ps.sort(this.sortParticipantsBy)));
|
|
8102
8280
|
this.localParticipant$ = this.participants$.pipe(map$1((participants) => participants.find(isStreamVideoLocalParticipant)));
|
|
8103
8281
|
this.remoteParticipants$ = this.participants$.pipe(map$1((participants) => participants.filter((p) => !p.isLocalParticipant)));
|
|
8104
|
-
this.pinnedParticipants$ = this.participants$.pipe(map$1((participants) => participants.filter((p) => p.
|
|
8282
|
+
this.pinnedParticipants$ = this.participants$.pipe(map$1((participants) => participants.filter((p) => !!p.pin)));
|
|
8105
8283
|
this.dominantSpeaker$ = this.participants$.pipe(map$1((participants) => participants.find((p) => p.isDominantSpeaker)));
|
|
8106
8284
|
this.hasOngoingScreenShare$ = this.participants$.pipe(map$1((participants) => {
|
|
8107
8285
|
return participants.some((p) => p.publishedTracks.includes(TrackType.SCREEN_SHARE));
|
|
@@ -8284,6 +8462,7 @@ const watchCallEnded = (call) => {
|
|
|
8284
8462
|
if (call.state.callingState === CallingState.RINGING ||
|
|
8285
8463
|
call.state.callingState === CallingState.JOINED ||
|
|
8286
8464
|
call.state.callingState === CallingState.JOINING) {
|
|
8465
|
+
call.state.setMetadata(event.call);
|
|
8287
8466
|
yield call.leave();
|
|
8288
8467
|
}
|
|
8289
8468
|
});
|
|
@@ -8414,6 +8593,18 @@ const watchSfuErrorReports = (dispatcher) => {
|
|
|
8414
8593
|
});
|
|
8415
8594
|
});
|
|
8416
8595
|
};
|
|
8596
|
+
/**
|
|
8597
|
+
* Watches for `pinsUpdated` events and updates the pinned state of participants
|
|
8598
|
+
* in the call.
|
|
8599
|
+
*/
|
|
8600
|
+
const watchPinsUpdated = (state) => {
|
|
8601
|
+
return function onPinsUpdated(e) {
|
|
8602
|
+
if (e.eventPayload.oneofKind !== 'pinsUpdated')
|
|
8603
|
+
return;
|
|
8604
|
+
const { pins } = e.eventPayload.pinsUpdated;
|
|
8605
|
+
state.setServerSidePins(pins);
|
|
8606
|
+
};
|
|
8607
|
+
};
|
|
8417
8608
|
|
|
8418
8609
|
/**
|
|
8419
8610
|
* Watches for `call.member_added` events.
|
|
@@ -8792,6 +8983,7 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
8792
8983
|
watchAudioLevelChanged(dispatcher, state),
|
|
8793
8984
|
watchDominantSpeakerChanged(dispatcher, state),
|
|
8794
8985
|
call.on('callGrantsUpdated', watchCallGrantsUpdated(state)),
|
|
8986
|
+
call.on('pinsUpdated', watchPinsUpdated(state)),
|
|
8795
8987
|
];
|
|
8796
8988
|
Object.keys(coordinatorEvents).forEach((event) => {
|
|
8797
8989
|
const eventName = event;
|
|
@@ -8897,14 +9089,8 @@ const getCascadingModeParams = () => {
|
|
|
8897
9089
|
const reconcileParticipantLocalState = (target, source) => {
|
|
8898
9090
|
if (!source)
|
|
8899
9091
|
return target;
|
|
8900
|
-
|
|
8901
|
-
target
|
|
8902
|
-
target.screenShareStream = source.screenShareStream;
|
|
8903
|
-
target.videoDimension = source.videoDimension;
|
|
8904
|
-
target.screenShareDimension = source.screenShareDimension;
|
|
8905
|
-
target.pinnedAt = source.pinnedAt;
|
|
8906
|
-
target.reaction = source.reaction;
|
|
8907
|
-
target.viewportVisibilityState = source.viewportVisibilityState;
|
|
9092
|
+
// copy everything from source to target
|
|
9093
|
+
Object.assign(target, source);
|
|
8908
9094
|
if (isStreamVideoLocalParticipant(source) &&
|
|
8909
9095
|
isStreamVideoLocalParticipant(target)) {
|
|
8910
9096
|
target.audioDeviceId = source.audioDeviceId;
|
|
@@ -9587,7 +9773,7 @@ class Call {
|
|
|
9587
9773
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
9588
9774
|
*/
|
|
9589
9775
|
this.join = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
9590
|
-
var _e, _f;
|
|
9776
|
+
var _e, _f, _g;
|
|
9591
9777
|
const callingState = this.state.callingState;
|
|
9592
9778
|
if ([CallingState.JOINED, CallingState.JOINING].includes(callingState)) {
|
|
9593
9779
|
this.logger('warn', 'Join method called twice, you should only call this once');
|
|
@@ -9835,6 +10021,7 @@ class Call {
|
|
|
9835
10021
|
const startedAt = (callState === null || callState === void 0 ? void 0 : callState.startedAt)
|
|
9836
10022
|
? Timestamp.toDate(callState.startedAt)
|
|
9837
10023
|
: new Date();
|
|
10024
|
+
const pins = (_g = callState === null || callState === void 0 ? void 0 : callState.pins) !== null && _g !== void 0 ? _g : [];
|
|
9838
10025
|
this.state.setParticipants(() => {
|
|
9839
10026
|
const participantLookup = this.state.getParticipantLookupBySessionId();
|
|
9840
10027
|
return currentParticipants.map((p) => {
|
|
@@ -9842,7 +10029,7 @@ class Call {
|
|
|
9842
10029
|
isLocalParticipant: p.sessionId === sfuClient.sessionId,
|
|
9843
10030
|
viewportVisibilityState: VisibilityState.UNKNOWN,
|
|
9844
10031
|
});
|
|
9845
|
-
// We need to preserve
|
|
10032
|
+
// We need to preserve the local state of the participant
|
|
9846
10033
|
// (e.g. videoDimension, visibilityState, pinnedAt, etc.)
|
|
9847
10034
|
// as it doesn't exist on the server.
|
|
9848
10035
|
const existingParticipant = participantLookup[p.sessionId];
|
|
@@ -9852,6 +10039,7 @@ class Call {
|
|
|
9852
10039
|
this.state.setParticipantCount((participantCount === null || participantCount === void 0 ? void 0 : participantCount.total) || 0);
|
|
9853
10040
|
this.state.setAnonymousParticipantCount((participantCount === null || participantCount === void 0 ? void 0 : participantCount.anonymous) || 0);
|
|
9854
10041
|
this.state.setStartedAt(startedAt);
|
|
10042
|
+
this.state.setServerSidePins(pins);
|
|
9855
10043
|
this.reconnectAttempts = 0; // reset the reconnect attempts counter
|
|
9856
10044
|
this.state.setCallingState(CallingState.JOINED);
|
|
9857
10045
|
// 3. once we have the "joinResponse", and possibly reconciled the local state
|
|
@@ -9976,9 +10164,9 @@ class Call {
|
|
|
9976
10164
|
* @param trackType the track type to stop publishing.
|
|
9977
10165
|
*/
|
|
9978
10166
|
this.stopPublish = (trackType) => __awaiter(this, void 0, void 0, function* () {
|
|
9979
|
-
var
|
|
10167
|
+
var _h;
|
|
9980
10168
|
this.logger('info', `stopPublish ${TrackType[trackType]}`);
|
|
9981
|
-
yield ((
|
|
10169
|
+
yield ((_h = this.publisher) === null || _h === void 0 ? void 0 : _h.unpublishStream(trackType));
|
|
9982
10170
|
});
|
|
9983
10171
|
/**
|
|
9984
10172
|
* Update track subscription configuration for one or more participants.
|
|
@@ -10066,6 +10254,8 @@ class Call {
|
|
|
10066
10254
|
* @param deviceId the selected device, `undefined` means the user wants to use the system's default audio output
|
|
10067
10255
|
*/
|
|
10068
10256
|
this.setAudioOutputDevice = (deviceId) => {
|
|
10257
|
+
if (!this.sfuClient)
|
|
10258
|
+
return;
|
|
10069
10259
|
this.state.updateParticipant(this.sfuClient.sessionId, {
|
|
10070
10260
|
audioOutputDeviceId: deviceId,
|
|
10071
10261
|
});
|
|
@@ -10079,6 +10269,8 @@ class Call {
|
|
|
10079
10269
|
* @param deviceId the selected device, pass `undefined` to clear the device selection
|
|
10080
10270
|
*/
|
|
10081
10271
|
this.setAudioDevice = (deviceId) => {
|
|
10272
|
+
if (!this.sfuClient)
|
|
10273
|
+
return;
|
|
10082
10274
|
this.state.updateParticipant(this.sfuClient.sessionId, {
|
|
10083
10275
|
audioDeviceId: deviceId,
|
|
10084
10276
|
});
|
|
@@ -10091,6 +10283,8 @@ class Call {
|
|
|
10091
10283
|
* @param deviceId the selected device, pass `undefined` to clear the device selection
|
|
10092
10284
|
*/
|
|
10093
10285
|
this.setVideoDevice = (deviceId) => {
|
|
10286
|
+
if (!this.sfuClient)
|
|
10287
|
+
return;
|
|
10094
10288
|
this.state.updateParticipant(this.sfuClient.sessionId, {
|
|
10095
10289
|
videoDeviceId: deviceId,
|
|
10096
10290
|
});
|
|
@@ -10119,8 +10313,8 @@ class Call {
|
|
|
10119
10313
|
* @returns
|
|
10120
10314
|
*/
|
|
10121
10315
|
this.updatePublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
|
|
10122
|
-
var
|
|
10123
|
-
return (
|
|
10316
|
+
var _j;
|
|
10317
|
+
return (_j = this.publisher) === null || _j === void 0 ? void 0 : _j.updateVideoPublishQuality(enabledRids);
|
|
10124
10318
|
});
|
|
10125
10319
|
this.assertCallJoined = () => {
|
|
10126
10320
|
return new Promise((resolve) => {
|
|
@@ -10324,16 +10518,48 @@ class Call {
|
|
|
10324
10518
|
return this.streamClient.post(`${this.streamClientBasePath}/mark_ended`);
|
|
10325
10519
|
});
|
|
10326
10520
|
/**
|
|
10327
|
-
*
|
|
10328
|
-
*
|
|
10329
|
-
* @param
|
|
10330
|
-
|
|
10521
|
+
* Pins the given session to the top of the participants list.
|
|
10522
|
+
*
|
|
10523
|
+
* @param sessionId the sessionId to pin.
|
|
10524
|
+
*/
|
|
10525
|
+
this.pin = (sessionId) => {
|
|
10526
|
+
this.state.updateParticipant(sessionId, {
|
|
10527
|
+
pin: {
|
|
10528
|
+
isLocalPin: true,
|
|
10529
|
+
pinnedAt: Date.now(),
|
|
10530
|
+
},
|
|
10531
|
+
});
|
|
10532
|
+
};
|
|
10533
|
+
/**
|
|
10534
|
+
* Unpins the given session from the top of the participants list.
|
|
10535
|
+
*
|
|
10536
|
+
* @param sessionId the sessionId to unpin.
|
|
10331
10537
|
*/
|
|
10332
|
-
this.
|
|
10538
|
+
this.unpin = (sessionId) => {
|
|
10333
10539
|
this.state.updateParticipant(sessionId, {
|
|
10334
|
-
|
|
10540
|
+
pin: undefined,
|
|
10335
10541
|
});
|
|
10336
10542
|
};
|
|
10543
|
+
/**
|
|
10544
|
+
* Pins the given session to the top of the participants list for everyone
|
|
10545
|
+
* in the call.
|
|
10546
|
+
* You can execute this method only if you have the `pin-for-everyone` capability.
|
|
10547
|
+
*
|
|
10548
|
+
* @param request the request object.
|
|
10549
|
+
*/
|
|
10550
|
+
this.pinForEveryone = (request) => __awaiter(this, void 0, void 0, function* () {
|
|
10551
|
+
return this.streamClient.post(`${this.streamClientBasePath}/pin`, request);
|
|
10552
|
+
});
|
|
10553
|
+
/**
|
|
10554
|
+
* Unpins the given session from the top of the participants list for everyone
|
|
10555
|
+
* in the call.
|
|
10556
|
+
* You can execute this method only if you have the `pin-for-everyone` capability.
|
|
10557
|
+
*
|
|
10558
|
+
* @param request the request object.
|
|
10559
|
+
*/
|
|
10560
|
+
this.unpinForEveryone = (request) => __awaiter(this, void 0, void 0, function* () {
|
|
10561
|
+
return this.streamClient.post(`${this.streamClientBasePath}/unpin`, request);
|
|
10562
|
+
});
|
|
10337
10563
|
/**
|
|
10338
10564
|
* Query call members with filter query. The result won't be stored in call state.
|
|
10339
10565
|
* @param request
|
|
@@ -11651,7 +11877,7 @@ class WSConnectionFallback {
|
|
|
11651
11877
|
}
|
|
11652
11878
|
}
|
|
11653
11879
|
|
|
11654
|
-
const version = '0.1
|
|
11880
|
+
const version = '0.2.1';
|
|
11655
11881
|
|
|
11656
11882
|
const logger = getLogger(['location']);
|
|
11657
11883
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|