@defcomm/meetingsdk 0.2.7 → 0.2.8
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/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +124 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -22,6 +22,7 @@ type Events = {
|
|
|
22
22
|
onUserLeft?: (id: string) => void;
|
|
23
23
|
onMeetingLeft?: () => void;
|
|
24
24
|
onChatMessage?: (msg: ChatMessage) => void;
|
|
25
|
+
onReaction?: (reaction: Reaction) => void;
|
|
25
26
|
onScreenShareStarted?: (peerId: string, stream: MediaStream) => void;
|
|
26
27
|
onScreenShareStopped?: (peerId: string) => void;
|
|
27
28
|
onMuteStateChanged?: (peerId: string, kind: "audio" | "video", muted: boolean) => void;
|
|
@@ -39,6 +40,13 @@ type Events = {
|
|
|
39
40
|
stopped_at: string;
|
|
40
41
|
}) => void;
|
|
41
42
|
};
|
|
43
|
+
type Reaction = {
|
|
44
|
+
id: string;
|
|
45
|
+
participant_id: string;
|
|
46
|
+
sender_name?: string | null;
|
|
47
|
+
emoji: string;
|
|
48
|
+
timestamp: string | number;
|
|
49
|
+
};
|
|
42
50
|
type ChatMessage = {
|
|
43
51
|
id: string;
|
|
44
52
|
text: string;
|
|
@@ -219,6 +227,7 @@ declare class VideoSDKCore {
|
|
|
219
227
|
recording: RecordingInfo | null;
|
|
220
228
|
}>;
|
|
221
229
|
sendChatMessage(payload: ChatInput): void;
|
|
230
|
+
sendReaction(reaction: string): void;
|
|
222
231
|
private cleanupRemoteParticipant;
|
|
223
232
|
disconnect(): Promise<void>;
|
|
224
233
|
private performDisconnect;
|
|
@@ -285,6 +294,7 @@ interface SFUClientOptions {
|
|
|
285
294
|
}) => void;
|
|
286
295
|
onError?: (error: any) => void;
|
|
287
296
|
onChatMessage?: (message: any) => void;
|
|
297
|
+
onReaction?: (reaction: any) => void;
|
|
288
298
|
onRoomUpdate?: (data: any) => void;
|
|
289
299
|
onParticipantMediaState?: (participantId: string, audioMuted: boolean, videoMuted: boolean) => void;
|
|
290
300
|
autoSubscribe?: boolean;
|
|
@@ -307,6 +317,7 @@ declare class SFUClient {
|
|
|
307
317
|
private iceServers;
|
|
308
318
|
private requestId;
|
|
309
319
|
private publisherRevision;
|
|
320
|
+
private screenShareGeneration;
|
|
310
321
|
private currentParticipantId;
|
|
311
322
|
private token;
|
|
312
323
|
private room;
|
|
@@ -362,6 +373,7 @@ declare class SFUClient {
|
|
|
362
373
|
private onRecordingStopped;
|
|
363
374
|
private onError;
|
|
364
375
|
private onChatMessage;
|
|
376
|
+
private onReaction;
|
|
365
377
|
private onRoomUpdate;
|
|
366
378
|
private onParticipantMediaState;
|
|
367
379
|
private autoSubscribe;
|
|
@@ -440,6 +452,7 @@ declare class SFUClient {
|
|
|
440
452
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
441
453
|
private isSocketOpen;
|
|
442
454
|
private send;
|
|
455
|
+
sendReaction(reaction: string): void;
|
|
443
456
|
private removeRemoteParticipant;
|
|
444
457
|
leave(): Promise<void>;
|
|
445
458
|
private closePeerConnectionsOnly;
|
|
@@ -469,6 +482,7 @@ type MeetingContextValue = {
|
|
|
469
482
|
startScreenShare: () => Promise<MediaStream>;
|
|
470
483
|
stopScreenShare: () => void;
|
|
471
484
|
sendMessage: (input: ChatInput) => void;
|
|
485
|
+
sendReaction: (emoji: string) => void;
|
|
472
486
|
room: {
|
|
473
487
|
id: string | null;
|
|
474
488
|
name: string | null;
|
|
@@ -491,6 +505,7 @@ type MeetingContextValue = {
|
|
|
491
505
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
492
506
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
493
507
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
508
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
494
509
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
495
510
|
};
|
|
496
511
|
declare const MeetingProvider: ({ config, children, }: {
|
|
@@ -507,6 +522,7 @@ declare const useMeeting: (handlers?: {
|
|
|
507
522
|
onTrackStateChanged?: (track: any) => void;
|
|
508
523
|
onRecordingStarted?: (recording: any) => void;
|
|
509
524
|
onRecordingStopped?: (recording: any) => void;
|
|
525
|
+
onReaction?: (reaction: any) => void;
|
|
510
526
|
onActiveSpeakersChanged?: (participantIds: string[]) => void;
|
|
511
527
|
}) => {
|
|
512
528
|
join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
|
|
@@ -524,6 +540,7 @@ declare const useMeeting: (handlers?: {
|
|
|
524
540
|
startScreenShare: () => Promise<MediaStream>;
|
|
525
541
|
stopScreenShare: () => void;
|
|
526
542
|
sendMessage: (input: ChatInput) => void;
|
|
543
|
+
sendReaction: (emoji: string) => void;
|
|
527
544
|
room: {
|
|
528
545
|
id: string | null;
|
|
529
546
|
name: string | null;
|
|
@@ -549,6 +566,7 @@ declare const useMeeting: (handlers?: {
|
|
|
549
566
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
550
567
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
551
568
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
569
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
552
570
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
553
571
|
};
|
|
554
572
|
|
|
@@ -629,4 +647,4 @@ declare class ActiveSpeakerDetector {
|
|
|
629
647
|
destroy(): Promise<void>;
|
|
630
648
|
}
|
|
631
649
|
|
|
632
|
-
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
|
650
|
+
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ type Events = {
|
|
|
22
22
|
onUserLeft?: (id: string) => void;
|
|
23
23
|
onMeetingLeft?: () => void;
|
|
24
24
|
onChatMessage?: (msg: ChatMessage) => void;
|
|
25
|
+
onReaction?: (reaction: Reaction) => void;
|
|
25
26
|
onScreenShareStarted?: (peerId: string, stream: MediaStream) => void;
|
|
26
27
|
onScreenShareStopped?: (peerId: string) => void;
|
|
27
28
|
onMuteStateChanged?: (peerId: string, kind: "audio" | "video", muted: boolean) => void;
|
|
@@ -39,6 +40,13 @@ type Events = {
|
|
|
39
40
|
stopped_at: string;
|
|
40
41
|
}) => void;
|
|
41
42
|
};
|
|
43
|
+
type Reaction = {
|
|
44
|
+
id: string;
|
|
45
|
+
participant_id: string;
|
|
46
|
+
sender_name?: string | null;
|
|
47
|
+
emoji: string;
|
|
48
|
+
timestamp: string | number;
|
|
49
|
+
};
|
|
42
50
|
type ChatMessage = {
|
|
43
51
|
id: string;
|
|
44
52
|
text: string;
|
|
@@ -219,6 +227,7 @@ declare class VideoSDKCore {
|
|
|
219
227
|
recording: RecordingInfo | null;
|
|
220
228
|
}>;
|
|
221
229
|
sendChatMessage(payload: ChatInput): void;
|
|
230
|
+
sendReaction(reaction: string): void;
|
|
222
231
|
private cleanupRemoteParticipant;
|
|
223
232
|
disconnect(): Promise<void>;
|
|
224
233
|
private performDisconnect;
|
|
@@ -285,6 +294,7 @@ interface SFUClientOptions {
|
|
|
285
294
|
}) => void;
|
|
286
295
|
onError?: (error: any) => void;
|
|
287
296
|
onChatMessage?: (message: any) => void;
|
|
297
|
+
onReaction?: (reaction: any) => void;
|
|
288
298
|
onRoomUpdate?: (data: any) => void;
|
|
289
299
|
onParticipantMediaState?: (participantId: string, audioMuted: boolean, videoMuted: boolean) => void;
|
|
290
300
|
autoSubscribe?: boolean;
|
|
@@ -307,6 +317,7 @@ declare class SFUClient {
|
|
|
307
317
|
private iceServers;
|
|
308
318
|
private requestId;
|
|
309
319
|
private publisherRevision;
|
|
320
|
+
private screenShareGeneration;
|
|
310
321
|
private currentParticipantId;
|
|
311
322
|
private token;
|
|
312
323
|
private room;
|
|
@@ -362,6 +373,7 @@ declare class SFUClient {
|
|
|
362
373
|
private onRecordingStopped;
|
|
363
374
|
private onError;
|
|
364
375
|
private onChatMessage;
|
|
376
|
+
private onReaction;
|
|
365
377
|
private onRoomUpdate;
|
|
366
378
|
private onParticipantMediaState;
|
|
367
379
|
private autoSubscribe;
|
|
@@ -440,6 +452,7 @@ declare class SFUClient {
|
|
|
440
452
|
rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
|
|
441
453
|
private isSocketOpen;
|
|
442
454
|
private send;
|
|
455
|
+
sendReaction(reaction: string): void;
|
|
443
456
|
private removeRemoteParticipant;
|
|
444
457
|
leave(): Promise<void>;
|
|
445
458
|
private closePeerConnectionsOnly;
|
|
@@ -469,6 +482,7 @@ type MeetingContextValue = {
|
|
|
469
482
|
startScreenShare: () => Promise<MediaStream>;
|
|
470
483
|
stopScreenShare: () => void;
|
|
471
484
|
sendMessage: (input: ChatInput) => void;
|
|
485
|
+
sendReaction: (emoji: string) => void;
|
|
472
486
|
room: {
|
|
473
487
|
id: string | null;
|
|
474
488
|
name: string | null;
|
|
@@ -491,6 +505,7 @@ type MeetingContextValue = {
|
|
|
491
505
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
492
506
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
493
507
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
508
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
494
509
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
495
510
|
};
|
|
496
511
|
declare const MeetingProvider: ({ config, children, }: {
|
|
@@ -507,6 +522,7 @@ declare const useMeeting: (handlers?: {
|
|
|
507
522
|
onTrackStateChanged?: (track: any) => void;
|
|
508
523
|
onRecordingStarted?: (recording: any) => void;
|
|
509
524
|
onRecordingStopped?: (recording: any) => void;
|
|
525
|
+
onReaction?: (reaction: any) => void;
|
|
510
526
|
onActiveSpeakersChanged?: (participantIds: string[]) => void;
|
|
511
527
|
}) => {
|
|
512
528
|
join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
|
|
@@ -524,6 +540,7 @@ declare const useMeeting: (handlers?: {
|
|
|
524
540
|
startScreenShare: () => Promise<MediaStream>;
|
|
525
541
|
stopScreenShare: () => void;
|
|
526
542
|
sendMessage: (input: ChatInput) => void;
|
|
543
|
+
sendReaction: (emoji: string) => void;
|
|
527
544
|
room: {
|
|
528
545
|
id: string | null;
|
|
529
546
|
name: string | null;
|
|
@@ -549,6 +566,7 @@ declare const useMeeting: (handlers?: {
|
|
|
549
566
|
onTrackStateChanged: (cb: (track: any) => void) => () => void;
|
|
550
567
|
onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
|
|
551
568
|
onRecordingStopped: (cb: (recording: any) => void) => () => void;
|
|
569
|
+
onReaction: (cb: (reaction: Reaction) => void) => () => void;
|
|
552
570
|
onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
|
|
553
571
|
};
|
|
554
572
|
|
|
@@ -629,4 +647,4 @@ declare class ActiveSpeakerDetector {
|
|
|
629
647
|
destroy(): Promise<void>;
|
|
630
648
|
}
|
|
631
649
|
|
|
632
|
-
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
|
650
|
+
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
|
package/dist/index.js
CHANGED
|
@@ -393,6 +393,7 @@ var SFUClient = class {
|
|
|
393
393
|
this.iceServers = [];
|
|
394
394
|
this.requestId = 0;
|
|
395
395
|
this.publisherRevision = 0;
|
|
396
|
+
this.screenShareGeneration = 0;
|
|
396
397
|
this.currentParticipantId = null;
|
|
397
398
|
this.token = null;
|
|
398
399
|
this.room = null;
|
|
@@ -475,6 +476,8 @@ var SFUClient = class {
|
|
|
475
476
|
this.onError = options.onError || console.error;
|
|
476
477
|
this.onChatMessage = options.onChatMessage || (() => {
|
|
477
478
|
});
|
|
479
|
+
this.onReaction = options.onReaction || (() => {
|
|
480
|
+
});
|
|
478
481
|
this.onRoomUpdate = options.onRoomUpdate || (() => {
|
|
479
482
|
});
|
|
480
483
|
this.onParticipantMediaState = options.onParticipantMediaState || (() => {
|
|
@@ -601,8 +604,10 @@ var SFUClient = class {
|
|
|
601
604
|
avatarUrl: options.avatarUrl
|
|
602
605
|
};
|
|
603
606
|
if (options.participantId) this.participantId = options.participantId;
|
|
604
|
-
if (typeof options.audioMuted === "boolean")
|
|
605
|
-
|
|
607
|
+
if (typeof options.audioMuted === "boolean")
|
|
608
|
+
this.desiredAudioMuted = options.audioMuted;
|
|
609
|
+
if (typeof options.videoMuted === "boolean")
|
|
610
|
+
this.desiredVideoMuted = options.videoMuted;
|
|
606
611
|
if (!this.resumeToken) {
|
|
607
612
|
this.resumeToken = this.loadResumeToken(this.room);
|
|
608
613
|
}
|
|
@@ -987,8 +992,15 @@ var SFUClient = class {
|
|
|
987
992
|
if (!pid) continue;
|
|
988
993
|
if (pid !== this.currentParticipantId) {
|
|
989
994
|
this.participants.set(pid, participant);
|
|
990
|
-
this.onParticipantPresence(
|
|
991
|
-
|
|
995
|
+
this.onParticipantPresence(
|
|
996
|
+
pid,
|
|
997
|
+
String(participant.presence || "connected")
|
|
998
|
+
);
|
|
999
|
+
this.onParticipantMediaState(
|
|
1000
|
+
pid,
|
|
1001
|
+
Boolean(participant.audio_muted),
|
|
1002
|
+
Boolean(participant.video_muted)
|
|
1003
|
+
);
|
|
992
1004
|
}
|
|
993
1005
|
}
|
|
994
1006
|
for (const [pid] of this.participants) {
|
|
@@ -1000,7 +1012,8 @@ var SFUClient = class {
|
|
|
1000
1012
|
}
|
|
1001
1013
|
for (const track of payload.tracks || []) this.rememberTrack(track);
|
|
1002
1014
|
if (Array.isArray(payload.chat_history)) {
|
|
1003
|
-
for (const message2 of payload.chat_history)
|
|
1015
|
+
for (const message2 of payload.chat_history)
|
|
1016
|
+
this.onChatMessage(message2);
|
|
1004
1017
|
}
|
|
1005
1018
|
break;
|
|
1006
1019
|
}
|
|
@@ -1009,6 +1022,11 @@ var SFUClient = class {
|
|
|
1009
1022
|
if (msg?.id) this.onChatMessage(msg);
|
|
1010
1023
|
break;
|
|
1011
1024
|
}
|
|
1025
|
+
case "reaction": {
|
|
1026
|
+
const reaction = payload.reaction || payload;
|
|
1027
|
+
if (reaction?.id && reaction?.emoji) this.onReaction(reaction);
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1012
1030
|
case "error": {
|
|
1013
1031
|
const message2 = payload.message || "SFU signaling error";
|
|
1014
1032
|
if (this.state === "reconnecting" && message2.includes("participant session is stale")) {
|
|
@@ -1033,7 +1051,9 @@ var SFUClient = class {
|
|
|
1033
1051
|
}
|
|
1034
1052
|
onRoomStateReconciled(payload) {
|
|
1035
1053
|
const participants = payload.participants || [];
|
|
1036
|
-
const local = participants.find(
|
|
1054
|
+
const local = participants.find(
|
|
1055
|
+
(p) => p?.participant_id === this.currentParticipantId
|
|
1056
|
+
);
|
|
1037
1057
|
if (local) {
|
|
1038
1058
|
this.desiredAudioMuted = Boolean(local.audio_muted);
|
|
1039
1059
|
this.desiredVideoMuted = Boolean(local.video_muted);
|
|
@@ -1447,9 +1467,27 @@ var SFUClient = class {
|
|
|
1447
1467
|
if (!this.screenTransceiver || !this.screenSender) {
|
|
1448
1468
|
throw new Error("Screen transceiver is not initialized");
|
|
1449
1469
|
}
|
|
1450
|
-
|
|
1470
|
+
const existingTrack = this.screenSender.track;
|
|
1471
|
+
if (this.screenStream && existingTrack && existingTrack.readyState === "live") {
|
|
1451
1472
|
return this.screenStream;
|
|
1452
1473
|
}
|
|
1474
|
+
const generation = ++this.screenShareGeneration;
|
|
1475
|
+
try {
|
|
1476
|
+
await this.screenSender.replaceTrack(null);
|
|
1477
|
+
} catch (err) {
|
|
1478
|
+
console.warn("[SFU] Failed to clear previous screen track", err);
|
|
1479
|
+
}
|
|
1480
|
+
if (this.screenStream) {
|
|
1481
|
+
for (const track of this.screenStream.getTracks()) {
|
|
1482
|
+
try {
|
|
1483
|
+
track.onended = null;
|
|
1484
|
+
track.stop();
|
|
1485
|
+
} catch {
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
this.screenStream = null;
|
|
1490
|
+
this.screenTransceiver.direction = "inactive";
|
|
1453
1491
|
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
1454
1492
|
video: true,
|
|
1455
1493
|
audio: false
|
|
@@ -1463,74 +1501,87 @@ var SFUClient = class {
|
|
|
1463
1501
|
try {
|
|
1464
1502
|
await this.screenSender.replaceTrack(screenTrack);
|
|
1465
1503
|
this.screenTransceiver.direction = "sendonly";
|
|
1504
|
+
this.send({
|
|
1505
|
+
type: "start_screen_share"
|
|
1506
|
+
});
|
|
1507
|
+
await new Promise((resolve) => {
|
|
1508
|
+
queueMicrotask(resolve);
|
|
1509
|
+
});
|
|
1466
1510
|
const offer = await this.publisher.createOffer();
|
|
1467
1511
|
await this.publisher.setLocalDescription(offer);
|
|
1512
|
+
const localDescription = this.publisher.localDescription;
|
|
1513
|
+
if (!localDescription?.sdp) {
|
|
1514
|
+
throw new Error("Publisher did not produce a valid screen-share SDP");
|
|
1515
|
+
}
|
|
1516
|
+
const revision = ++this.publisherRevision;
|
|
1468
1517
|
this.send({
|
|
1469
1518
|
type: "publish_offer",
|
|
1470
1519
|
payload: {
|
|
1471
|
-
revision
|
|
1472
|
-
sdp:
|
|
1520
|
+
revision,
|
|
1521
|
+
sdp: localDescription.sdp
|
|
1473
1522
|
}
|
|
1474
1523
|
});
|
|
1475
|
-
this.send({ type: "start_screen_share" });
|
|
1476
1524
|
screenTrack.onended = () => {
|
|
1525
|
+
if (generation !== this.screenShareGeneration) {
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1477
1528
|
void this.stopScreenShare();
|
|
1478
1529
|
};
|
|
1479
|
-
|
|
1480
|
-
screenTrackId: screenTrack.id,
|
|
1481
|
-
cameraTrackId: this.videoSender?.track?.id,
|
|
1482
|
-
screenMid: this.screenTransceiver.mid,
|
|
1483
|
-
cameraMid: this.cameraTransceiver?.mid
|
|
1484
|
-
});
|
|
1485
|
-
return this.screenStream;
|
|
1530
|
+
return screenStream;
|
|
1486
1531
|
} catch (error) {
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1532
|
+
if (generation === this.screenShareGeneration) {
|
|
1533
|
+
try {
|
|
1534
|
+
await this.screenSender.replaceTrack(null);
|
|
1535
|
+
} catch {
|
|
1536
|
+
}
|
|
1537
|
+
this.screenTransceiver.direction = "inactive";
|
|
1538
|
+
screenTrack.onended = null;
|
|
1539
|
+
screenStream.getTracks().forEach((track) => {
|
|
1540
|
+
try {
|
|
1541
|
+
track.stop();
|
|
1542
|
+
} catch {
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
this.screenStream = null;
|
|
1546
|
+
try {
|
|
1547
|
+
this.send({
|
|
1548
|
+
type: "stop_screen_share"
|
|
1549
|
+
});
|
|
1550
|
+
} catch {
|
|
1551
|
+
}
|
|
1497
1552
|
}
|
|
1498
1553
|
throw error;
|
|
1499
1554
|
}
|
|
1500
1555
|
}
|
|
1501
1556
|
async stopScreenShare() {
|
|
1502
|
-
|
|
1503
|
-
const
|
|
1504
|
-
if (
|
|
1557
|
+
const stream = this.screenStream;
|
|
1558
|
+
const senderTrack = this.screenSender?.track || null;
|
|
1559
|
+
if (!stream && !senderTrack) return;
|
|
1560
|
+
++this.screenShareGeneration;
|
|
1561
|
+
if (senderTrack) senderTrack.onended = null;
|
|
1505
1562
|
try {
|
|
1506
1563
|
await this.screenSender?.replaceTrack(null);
|
|
1507
1564
|
} catch (error) {
|
|
1508
1565
|
this.onError(error);
|
|
1509
1566
|
}
|
|
1510
|
-
if (this.screenTransceiver)
|
|
1511
|
-
this.screenTransceiver.direction = "inactive";
|
|
1512
|
-
}
|
|
1513
|
-
this.send({ type: "stop_screen_share" });
|
|
1567
|
+
if (this.screenTransceiver) this.screenTransceiver.direction = "inactive";
|
|
1514
1568
|
try {
|
|
1515
1569
|
const offer = await this.publisher?.createOffer();
|
|
1516
1570
|
if (offer && this.publisher) {
|
|
1517
1571
|
await this.publisher.setLocalDescription(offer);
|
|
1518
1572
|
this.send({
|
|
1519
1573
|
type: "publish_offer",
|
|
1520
|
-
payload: {
|
|
1521
|
-
revision: ++this.publisherRevision,
|
|
1522
|
-
sdp: offer.sdp
|
|
1523
|
-
}
|
|
1574
|
+
payload: { revision: ++this.publisherRevision, sdp: offer.sdp }
|
|
1524
1575
|
});
|
|
1525
1576
|
}
|
|
1526
1577
|
} catch (error) {
|
|
1527
1578
|
this.onError(error);
|
|
1528
1579
|
}
|
|
1529
|
-
this.
|
|
1580
|
+
this.send({ type: "stop_screen_share" });
|
|
1581
|
+
stream?.getTracks().forEach((track) => track.stop());
|
|
1530
1582
|
this.screenStream = null;
|
|
1531
|
-
if (this.currentParticipantId)
|
|
1583
|
+
if (this.currentParticipantId)
|
|
1532
1584
|
this.onScreenShareStopped(this.currentParticipantId);
|
|
1533
|
-
}
|
|
1534
1585
|
}
|
|
1535
1586
|
muteAudio(muted) {
|
|
1536
1587
|
this.desiredAudioMuted = muted;
|
|
@@ -1633,6 +1684,12 @@ var SFUClient = class {
|
|
|
1633
1684
|
);
|
|
1634
1685
|
return true;
|
|
1635
1686
|
}
|
|
1687
|
+
sendReaction(reaction) {
|
|
1688
|
+
this.send({
|
|
1689
|
+
type: "send_reaction",
|
|
1690
|
+
reaction
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1636
1693
|
removeRemoteParticipant(participantId) {
|
|
1637
1694
|
const stream = this.remoteStreams.get(participantId);
|
|
1638
1695
|
if (stream) {
|
|
@@ -2051,7 +2108,9 @@ var VideoSDKCore = class {
|
|
|
2051
2108
|
// ADMISSION CONTROL
|
|
2052
2109
|
onRoomUpdate: (payload) => {
|
|
2053
2110
|
const participants = payload?.participants || [];
|
|
2054
|
-
const local = participants.find(
|
|
2111
|
+
const local = participants.find(
|
|
2112
|
+
(p) => p?.participant_id === this.myId
|
|
2113
|
+
);
|
|
2055
2114
|
if (local) {
|
|
2056
2115
|
const media = this.state.localParticipant?.media;
|
|
2057
2116
|
this.state.updateLocalParticipant({
|
|
@@ -2074,7 +2133,8 @@ var VideoSDKCore = class {
|
|
|
2074
2133
|
});
|
|
2075
2134
|
}
|
|
2076
2135
|
if (local.screen_sharing) this.state.setPresenterId(this.myId);
|
|
2077
|
-
else if (this.state.presenterId === this.myId)
|
|
2136
|
+
else if (this.state.presenterId === this.myId)
|
|
2137
|
+
this.state.setPresenterId(null);
|
|
2078
2138
|
}
|
|
2079
2139
|
const presenter = participants.find((p) => p?.screen_sharing);
|
|
2080
2140
|
if (presenter) this.state.setPresenterId(presenter.participant_id);
|
|
@@ -2505,7 +2565,7 @@ var VideoSDKCore = class {
|
|
|
2505
2565
|
media: {
|
|
2506
2566
|
isScreenSharing: true,
|
|
2507
2567
|
screenStream: this.screenStream,
|
|
2508
|
-
screenTrack: this.screenStream
|
|
2568
|
+
screenTrack: this.screenStream?.getVideoTracks()[0]
|
|
2509
2569
|
}
|
|
2510
2570
|
});
|
|
2511
2571
|
return this.screenStream;
|
|
@@ -2570,6 +2630,13 @@ var VideoSDKCore = class {
|
|
|
2570
2630
|
target: payload.target ?? null
|
|
2571
2631
|
});
|
|
2572
2632
|
}
|
|
2633
|
+
sendReaction(reaction) {
|
|
2634
|
+
if (!this.sfuClient) {
|
|
2635
|
+
console.warn("SFU Client not connected");
|
|
2636
|
+
return;
|
|
2637
|
+
}
|
|
2638
|
+
this.sfuClient.sendReaction(reaction);
|
|
2639
|
+
}
|
|
2573
2640
|
// CLEANUP
|
|
2574
2641
|
cleanupRemoteParticipant(participantId) {
|
|
2575
2642
|
this.activeSpeakerDetector.removeParticipant(participantId);
|
|
@@ -2656,6 +2723,7 @@ var MeetingProvider = ({
|
|
|
2656
2723
|
const trackStateListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2657
2724
|
const recordingStartedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2658
2725
|
const recordingStoppedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2726
|
+
const reactionListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2659
2727
|
const activeSpeakerListeners = (0, import_react2.useRef)(
|
|
2660
2728
|
/* @__PURE__ */ new Set()
|
|
2661
2729
|
);
|
|
@@ -2685,6 +2753,9 @@ var MeetingProvider = ({
|
|
|
2685
2753
|
},
|
|
2686
2754
|
onRecordingStopped: (recording) => {
|
|
2687
2755
|
recordingStoppedListeners.current.forEach((fn) => fn(recording));
|
|
2756
|
+
},
|
|
2757
|
+
onReaction: (reaction) => {
|
|
2758
|
+
reactionListeners.current.forEach((fn) => fn(reaction));
|
|
2688
2759
|
}
|
|
2689
2760
|
}
|
|
2690
2761
|
);
|
|
@@ -2731,6 +2802,7 @@ var MeetingProvider = ({
|
|
|
2731
2802
|
startScreenShare: sdk.startScreenShare.bind(sdk),
|
|
2732
2803
|
stopScreenShare: sdk.stopScreenShare.bind(sdk),
|
|
2733
2804
|
sendMessage: sdk.sendChatMessage.bind(sdk),
|
|
2805
|
+
sendReaction: sdk.sendReaction.bind(sdk),
|
|
2734
2806
|
room: sdk.getMeeting(),
|
|
2735
2807
|
localParticipant,
|
|
2736
2808
|
participants,
|
|
@@ -2787,6 +2859,10 @@ var MeetingProvider = ({
|
|
|
2787
2859
|
recordingStoppedListeners.current.add(cb);
|
|
2788
2860
|
return () => recordingStoppedListeners.current.delete(cb);
|
|
2789
2861
|
},
|
|
2862
|
+
onReaction: (cb) => {
|
|
2863
|
+
reactionListeners.current.add(cb);
|
|
2864
|
+
return () => reactionListeners.current.delete(cb);
|
|
2865
|
+
},
|
|
2790
2866
|
onActiveSpeakersChanged: (cb) => {
|
|
2791
2867
|
activeSpeakerListeners.current.add(cb);
|
|
2792
2868
|
return () => {
|
|
@@ -2883,6 +2959,10 @@ var useMeeting = (handlers) => {
|
|
|
2883
2959
|
if (!handlers?.onRecordingStopped) return;
|
|
2884
2960
|
return ctx.onRecordingStopped(handlers.onRecordingStopped);
|
|
2885
2961
|
}, [handlers?.onRecordingStopped]);
|
|
2962
|
+
(0, import_react4.useEffect)(() => {
|
|
2963
|
+
if (!handlers?.onReaction) return;
|
|
2964
|
+
return ctx.onReaction(handlers.onReaction);
|
|
2965
|
+
}, [handlers?.onReaction]);
|
|
2886
2966
|
const { sdk: _, ...publicApi } = ctx;
|
|
2887
2967
|
return publicApi;
|
|
2888
2968
|
};
|