@stream-io/video-client 0.1.11 → 0.2.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 +11 -0
- package/dist/index.browser.es.js +253 -28
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +253 -28
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +253 -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 +115 -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/callEventHandlers.ts +2 -0
- package/src/events/internal.ts +13 -0
- package/src/gen/coordinator/index.ts +115 -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,17 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [0.2.0](https://github.com/GetStream/stream-video-js/compare/client0.1.11...client0.2.0) (2023-08-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* Server-side participant pinning (#881)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* Server-side participant pinning ([#881](https://github.com/GetStream/stream-video-js/issues/881)) ([72829f1](https://github.com/GetStream/stream-video-js/commit/72829f1caf5b9c719d063a7e5175b7aa7431cd71))
|
|
15
|
+
|
|
5
16
|
### [0.1.11](https://github.com/GetStream/stream-video-js/compare/client0.1.10...client0.1.11) (2023-08-04)
|
|
6
17
|
|
|
7
18
|
|
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));
|
|
@@ -8414,6 +8592,18 @@ const watchSfuErrorReports = (dispatcher) => {
|
|
|
8414
8592
|
});
|
|
8415
8593
|
});
|
|
8416
8594
|
};
|
|
8595
|
+
/**
|
|
8596
|
+
* Watches for `pinsUpdated` events and updates the pinned state of participants
|
|
8597
|
+
* in the call.
|
|
8598
|
+
*/
|
|
8599
|
+
const watchPinsUpdated = (state) => {
|
|
8600
|
+
return function onPinsUpdated(e) {
|
|
8601
|
+
if (e.eventPayload.oneofKind !== 'pinsUpdated')
|
|
8602
|
+
return;
|
|
8603
|
+
const { pins } = e.eventPayload.pinsUpdated;
|
|
8604
|
+
state.setServerSidePins(pins);
|
|
8605
|
+
};
|
|
8606
|
+
};
|
|
8417
8607
|
|
|
8418
8608
|
/**
|
|
8419
8609
|
* Watches for `call.member_added` events.
|
|
@@ -8792,6 +8982,7 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
8792
8982
|
watchAudioLevelChanged(dispatcher, state),
|
|
8793
8983
|
watchDominantSpeakerChanged(dispatcher, state),
|
|
8794
8984
|
call.on('callGrantsUpdated', watchCallGrantsUpdated(state)),
|
|
8985
|
+
call.on('pinsUpdated', watchPinsUpdated(state)),
|
|
8795
8986
|
];
|
|
8796
8987
|
Object.keys(coordinatorEvents).forEach((event) => {
|
|
8797
8988
|
const eventName = event;
|
|
@@ -8897,14 +9088,8 @@ const getCascadingModeParams = () => {
|
|
|
8897
9088
|
const reconcileParticipantLocalState = (target, source) => {
|
|
8898
9089
|
if (!source)
|
|
8899
9090
|
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;
|
|
9091
|
+
// copy everything from source to target
|
|
9092
|
+
Object.assign(target, source);
|
|
8908
9093
|
if (isStreamVideoLocalParticipant(source) &&
|
|
8909
9094
|
isStreamVideoLocalParticipant(target)) {
|
|
8910
9095
|
target.audioDeviceId = source.audioDeviceId;
|
|
@@ -9587,7 +9772,7 @@ class Call {
|
|
|
9587
9772
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
9588
9773
|
*/
|
|
9589
9774
|
this.join = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
9590
|
-
var _e, _f;
|
|
9775
|
+
var _e, _f, _g;
|
|
9591
9776
|
const callingState = this.state.callingState;
|
|
9592
9777
|
if ([CallingState.JOINED, CallingState.JOINING].includes(callingState)) {
|
|
9593
9778
|
this.logger('warn', 'Join method called twice, you should only call this once');
|
|
@@ -9835,6 +10020,7 @@ class Call {
|
|
|
9835
10020
|
const startedAt = (callState === null || callState === void 0 ? void 0 : callState.startedAt)
|
|
9836
10021
|
? Timestamp.toDate(callState.startedAt)
|
|
9837
10022
|
: new Date();
|
|
10023
|
+
const pins = (_g = callState === null || callState === void 0 ? void 0 : callState.pins) !== null && _g !== void 0 ? _g : [];
|
|
9838
10024
|
this.state.setParticipants(() => {
|
|
9839
10025
|
const participantLookup = this.state.getParticipantLookupBySessionId();
|
|
9840
10026
|
return currentParticipants.map((p) => {
|
|
@@ -9842,7 +10028,7 @@ class Call {
|
|
|
9842
10028
|
isLocalParticipant: p.sessionId === sfuClient.sessionId,
|
|
9843
10029
|
viewportVisibilityState: VisibilityState.UNKNOWN,
|
|
9844
10030
|
});
|
|
9845
|
-
// We need to preserve
|
|
10031
|
+
// We need to preserve the local state of the participant
|
|
9846
10032
|
// (e.g. videoDimension, visibilityState, pinnedAt, etc.)
|
|
9847
10033
|
// as it doesn't exist on the server.
|
|
9848
10034
|
const existingParticipant = participantLookup[p.sessionId];
|
|
@@ -9852,6 +10038,7 @@ class Call {
|
|
|
9852
10038
|
this.state.setParticipantCount((participantCount === null || participantCount === void 0 ? void 0 : participantCount.total) || 0);
|
|
9853
10039
|
this.state.setAnonymousParticipantCount((participantCount === null || participantCount === void 0 ? void 0 : participantCount.anonymous) || 0);
|
|
9854
10040
|
this.state.setStartedAt(startedAt);
|
|
10041
|
+
this.state.setServerSidePins(pins);
|
|
9855
10042
|
this.reconnectAttempts = 0; // reset the reconnect attempts counter
|
|
9856
10043
|
this.state.setCallingState(CallingState.JOINED);
|
|
9857
10044
|
// 3. once we have the "joinResponse", and possibly reconciled the local state
|
|
@@ -9976,9 +10163,9 @@ class Call {
|
|
|
9976
10163
|
* @param trackType the track type to stop publishing.
|
|
9977
10164
|
*/
|
|
9978
10165
|
this.stopPublish = (trackType) => __awaiter(this, void 0, void 0, function* () {
|
|
9979
|
-
var
|
|
10166
|
+
var _h;
|
|
9980
10167
|
this.logger('info', `stopPublish ${TrackType[trackType]}`);
|
|
9981
|
-
yield ((
|
|
10168
|
+
yield ((_h = this.publisher) === null || _h === void 0 ? void 0 : _h.unpublishStream(trackType));
|
|
9982
10169
|
});
|
|
9983
10170
|
/**
|
|
9984
10171
|
* Update track subscription configuration for one or more participants.
|
|
@@ -10066,6 +10253,8 @@ class Call {
|
|
|
10066
10253
|
* @param deviceId the selected device, `undefined` means the user wants to use the system's default audio output
|
|
10067
10254
|
*/
|
|
10068
10255
|
this.setAudioOutputDevice = (deviceId) => {
|
|
10256
|
+
if (!this.sfuClient)
|
|
10257
|
+
return;
|
|
10069
10258
|
this.state.updateParticipant(this.sfuClient.sessionId, {
|
|
10070
10259
|
audioOutputDeviceId: deviceId,
|
|
10071
10260
|
});
|
|
@@ -10079,6 +10268,8 @@ class Call {
|
|
|
10079
10268
|
* @param deviceId the selected device, pass `undefined` to clear the device selection
|
|
10080
10269
|
*/
|
|
10081
10270
|
this.setAudioDevice = (deviceId) => {
|
|
10271
|
+
if (!this.sfuClient)
|
|
10272
|
+
return;
|
|
10082
10273
|
this.state.updateParticipant(this.sfuClient.sessionId, {
|
|
10083
10274
|
audioDeviceId: deviceId,
|
|
10084
10275
|
});
|
|
@@ -10091,6 +10282,8 @@ class Call {
|
|
|
10091
10282
|
* @param deviceId the selected device, pass `undefined` to clear the device selection
|
|
10092
10283
|
*/
|
|
10093
10284
|
this.setVideoDevice = (deviceId) => {
|
|
10285
|
+
if (!this.sfuClient)
|
|
10286
|
+
return;
|
|
10094
10287
|
this.state.updateParticipant(this.sfuClient.sessionId, {
|
|
10095
10288
|
videoDeviceId: deviceId,
|
|
10096
10289
|
});
|
|
@@ -10119,8 +10312,8 @@ class Call {
|
|
|
10119
10312
|
* @returns
|
|
10120
10313
|
*/
|
|
10121
10314
|
this.updatePublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
|
|
10122
|
-
var
|
|
10123
|
-
return (
|
|
10315
|
+
var _j;
|
|
10316
|
+
return (_j = this.publisher) === null || _j === void 0 ? void 0 : _j.updateVideoPublishQuality(enabledRids);
|
|
10124
10317
|
});
|
|
10125
10318
|
this.assertCallJoined = () => {
|
|
10126
10319
|
return new Promise((resolve) => {
|
|
@@ -10324,16 +10517,48 @@ class Call {
|
|
|
10324
10517
|
return this.streamClient.post(`${this.streamClientBasePath}/mark_ended`);
|
|
10325
10518
|
});
|
|
10326
10519
|
/**
|
|
10327
|
-
*
|
|
10328
|
-
*
|
|
10329
|
-
* @param
|
|
10330
|
-
|
|
10520
|
+
* Pins the given session to the top of the participants list.
|
|
10521
|
+
*
|
|
10522
|
+
* @param sessionId the sessionId to pin.
|
|
10523
|
+
*/
|
|
10524
|
+
this.pin = (sessionId) => {
|
|
10525
|
+
this.state.updateParticipant(sessionId, {
|
|
10526
|
+
pin: {
|
|
10527
|
+
isLocalPin: true,
|
|
10528
|
+
pinnedAt: Date.now(),
|
|
10529
|
+
},
|
|
10530
|
+
});
|
|
10531
|
+
};
|
|
10532
|
+
/**
|
|
10533
|
+
* Unpins the given session from the top of the participants list.
|
|
10534
|
+
*
|
|
10535
|
+
* @param sessionId the sessionId to unpin.
|
|
10331
10536
|
*/
|
|
10332
|
-
this.
|
|
10537
|
+
this.unpin = (sessionId) => {
|
|
10333
10538
|
this.state.updateParticipant(sessionId, {
|
|
10334
|
-
|
|
10539
|
+
pin: undefined,
|
|
10335
10540
|
});
|
|
10336
10541
|
};
|
|
10542
|
+
/**
|
|
10543
|
+
* Pins the given session to the top of the participants list for everyone
|
|
10544
|
+
* in the call.
|
|
10545
|
+
* You can execute this method only if you have the `pin-for-everyone` capability.
|
|
10546
|
+
*
|
|
10547
|
+
* @param request the request object.
|
|
10548
|
+
*/
|
|
10549
|
+
this.pinForEveryone = (request) => __awaiter(this, void 0, void 0, function* () {
|
|
10550
|
+
return this.streamClient.post(`${this.streamClientBasePath}/pin`, request);
|
|
10551
|
+
});
|
|
10552
|
+
/**
|
|
10553
|
+
* Unpins the given session from the top of the participants list for everyone
|
|
10554
|
+
* in the call.
|
|
10555
|
+
* You can execute this method only if you have the `pin-for-everyone` capability.
|
|
10556
|
+
*
|
|
10557
|
+
* @param request the request object.
|
|
10558
|
+
*/
|
|
10559
|
+
this.unpinForEveryone = (request) => __awaiter(this, void 0, void 0, function* () {
|
|
10560
|
+
return this.streamClient.post(`${this.streamClientBasePath}/unpin`, request);
|
|
10561
|
+
});
|
|
10337
10562
|
/**
|
|
10338
10563
|
* Query call members with filter query. The result won't be stored in call state.
|
|
10339
10564
|
* @param request
|
|
@@ -11651,7 +11876,7 @@ class WSConnectionFallback {
|
|
|
11651
11876
|
}
|
|
11652
11877
|
}
|
|
11653
11878
|
|
|
11654
|
-
const version = '0.
|
|
11879
|
+
const version = '0.2.0';
|
|
11655
11880
|
|
|
11656
11881
|
const logger = getLogger(['location']);
|
|
11657
11882
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|