@livo-tv/sdk 1.16.0 → 1.18.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/README.md +1 -1
- package/dist/studio/index.cjs +105 -36
- package/dist/studio/index.cjs.map +1 -1
- package/dist/studio/index.d.cts +12 -2
- package/dist/studio/index.d.ts +12 -2
- package/dist/studio/index.js +105 -36
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
package/dist/studio/index.d.cts
CHANGED
|
@@ -417,6 +417,10 @@ declare function studioRoomLabels(t: (key: string, values?: Record<string, strin
|
|
|
417
417
|
shareRequestTimeout: string;
|
|
418
418
|
shareRespondError: string;
|
|
419
419
|
goOffAir: string;
|
|
420
|
+
moveToAudience: string;
|
|
421
|
+
moveToAudienceTitle: string;
|
|
422
|
+
moveToAudienceDescription: string;
|
|
423
|
+
moveToAudienceConfirm: string;
|
|
420
424
|
goOnAir: string;
|
|
421
425
|
takeOffAir: string;
|
|
422
426
|
bringOnAir: string;
|
|
@@ -525,7 +529,7 @@ type StudioDeviceSelection = {
|
|
|
525
529
|
speaker: string;
|
|
526
530
|
};
|
|
527
531
|
|
|
528
|
-
declare function StudioRoom({ session, meeting, control, onRefreshStatus, onRejoin, labels, reducedMotion, embed, chrome, headerStart, playerOrigin, windowGate, initialCameraOn, initialMuted, initialDevices, appDownloadUrl, captionsBaseUrl, apiUrl, cdnBase, endedHref, }: {
|
|
532
|
+
declare function StudioRoom({ session, meeting, control, onRefreshStatus, onRejoin, labels, reducedMotion, embed, chrome, headerStart, playerOrigin, windowGate, initialCameraOn, initialMuted, initialDevices, appDownloadUrl, captionsBaseUrl, apiUrl, cdnBase, endedHref, endedExtra, }: {
|
|
529
533
|
session: StudioSession;
|
|
530
534
|
meeting: StudioMeetingHandle;
|
|
531
535
|
control: StudioControlActions;
|
|
@@ -550,6 +554,8 @@ declare function StudioRoom({ session, meeting, control, onRefreshStatus, onRejo
|
|
|
550
554
|
cdnBase?: string;
|
|
551
555
|
/** Partner URL for the ended-session action. Defaults to `/streams/:id`. */
|
|
552
556
|
endedHref?: string;
|
|
557
|
+
/** Partner content under the return link on the session-over card. */
|
|
558
|
+
endedExtra?: ReactNode;
|
|
553
559
|
}): react.JSX.Element;
|
|
554
560
|
|
|
555
561
|
declare function StudioSkeleton(): react.JSX.Element;
|
|
@@ -559,6 +565,7 @@ type StudioGuestLobbyLabels = {
|
|
|
559
565
|
hint: string;
|
|
560
566
|
name: string;
|
|
561
567
|
join: string;
|
|
568
|
+
joining: string;
|
|
562
569
|
waitingForHost: string;
|
|
563
570
|
camera: string;
|
|
564
571
|
mic: string;
|
|
@@ -605,7 +612,7 @@ declare function StudioWindowGate({ lockKey, allowTakeover, labels, children, }:
|
|
|
605
612
|
children: ReactNode;
|
|
606
613
|
}): react.JSX.Element;
|
|
607
614
|
|
|
608
|
-
declare function LivoHostStudio({ token, apiUrl, labels, redeemError, embed, chrome, headerStart, playerOrigin, theme, appDownloadUrl, guestUrl, endedHref, }: {
|
|
615
|
+
declare function LivoHostStudio({ token, apiUrl, labels, redeemError, embed, chrome, headerStart, playerOrigin, theme, appDownloadUrl, guestUrl, endedHref, endedExtra, }: {
|
|
609
616
|
token: string;
|
|
610
617
|
apiUrl?: string;
|
|
611
618
|
labels: StudioRoomLabels;
|
|
@@ -621,6 +628,8 @@ declare function LivoHostStudio({ token, apiUrl, labels, redeemError, embed, chr
|
|
|
621
628
|
guestUrl?: string | null;
|
|
622
629
|
/** Partner URL for the ended-session action. Defaults to `/streams/:id`. */
|
|
623
630
|
endedHref?: string;
|
|
631
|
+
/** Partner content under the return link on the session-over card. */
|
|
632
|
+
endedExtra?: ReactNode;
|
|
624
633
|
}): react.JSX.Element;
|
|
625
634
|
|
|
626
635
|
type StudioLobbyLabels = {
|
|
@@ -628,6 +637,7 @@ type StudioLobbyLabels = {
|
|
|
628
637
|
hint: string;
|
|
629
638
|
name: string;
|
|
630
639
|
join: string;
|
|
640
|
+
joining: string;
|
|
631
641
|
waitingForHost: string;
|
|
632
642
|
camera: string;
|
|
633
643
|
mic: string;
|
package/dist/studio/index.d.ts
CHANGED
|
@@ -417,6 +417,10 @@ declare function studioRoomLabels(t: (key: string, values?: Record<string, strin
|
|
|
417
417
|
shareRequestTimeout: string;
|
|
418
418
|
shareRespondError: string;
|
|
419
419
|
goOffAir: string;
|
|
420
|
+
moveToAudience: string;
|
|
421
|
+
moveToAudienceTitle: string;
|
|
422
|
+
moveToAudienceDescription: string;
|
|
423
|
+
moveToAudienceConfirm: string;
|
|
420
424
|
goOnAir: string;
|
|
421
425
|
takeOffAir: string;
|
|
422
426
|
bringOnAir: string;
|
|
@@ -525,7 +529,7 @@ type StudioDeviceSelection = {
|
|
|
525
529
|
speaker: string;
|
|
526
530
|
};
|
|
527
531
|
|
|
528
|
-
declare function StudioRoom({ session, meeting, control, onRefreshStatus, onRejoin, labels, reducedMotion, embed, chrome, headerStart, playerOrigin, windowGate, initialCameraOn, initialMuted, initialDevices, appDownloadUrl, captionsBaseUrl, apiUrl, cdnBase, endedHref, }: {
|
|
532
|
+
declare function StudioRoom({ session, meeting, control, onRefreshStatus, onRejoin, labels, reducedMotion, embed, chrome, headerStart, playerOrigin, windowGate, initialCameraOn, initialMuted, initialDevices, appDownloadUrl, captionsBaseUrl, apiUrl, cdnBase, endedHref, endedExtra, }: {
|
|
529
533
|
session: StudioSession;
|
|
530
534
|
meeting: StudioMeetingHandle;
|
|
531
535
|
control: StudioControlActions;
|
|
@@ -550,6 +554,8 @@ declare function StudioRoom({ session, meeting, control, onRefreshStatus, onRejo
|
|
|
550
554
|
cdnBase?: string;
|
|
551
555
|
/** Partner URL for the ended-session action. Defaults to `/streams/:id`. */
|
|
552
556
|
endedHref?: string;
|
|
557
|
+
/** Partner content under the return link on the session-over card. */
|
|
558
|
+
endedExtra?: ReactNode;
|
|
553
559
|
}): react.JSX.Element;
|
|
554
560
|
|
|
555
561
|
declare function StudioSkeleton(): react.JSX.Element;
|
|
@@ -559,6 +565,7 @@ type StudioGuestLobbyLabels = {
|
|
|
559
565
|
hint: string;
|
|
560
566
|
name: string;
|
|
561
567
|
join: string;
|
|
568
|
+
joining: string;
|
|
562
569
|
waitingForHost: string;
|
|
563
570
|
camera: string;
|
|
564
571
|
mic: string;
|
|
@@ -605,7 +612,7 @@ declare function StudioWindowGate({ lockKey, allowTakeover, labels, children, }:
|
|
|
605
612
|
children: ReactNode;
|
|
606
613
|
}): react.JSX.Element;
|
|
607
614
|
|
|
608
|
-
declare function LivoHostStudio({ token, apiUrl, labels, redeemError, embed, chrome, headerStart, playerOrigin, theme, appDownloadUrl, guestUrl, endedHref, }: {
|
|
615
|
+
declare function LivoHostStudio({ token, apiUrl, labels, redeemError, embed, chrome, headerStart, playerOrigin, theme, appDownloadUrl, guestUrl, endedHref, endedExtra, }: {
|
|
609
616
|
token: string;
|
|
610
617
|
apiUrl?: string;
|
|
611
618
|
labels: StudioRoomLabels;
|
|
@@ -621,6 +628,8 @@ declare function LivoHostStudio({ token, apiUrl, labels, redeemError, embed, chr
|
|
|
621
628
|
guestUrl?: string | null;
|
|
622
629
|
/** Partner URL for the ended-session action. Defaults to `/streams/:id`. */
|
|
623
630
|
endedHref?: string;
|
|
631
|
+
/** Partner content under the return link on the session-over card. */
|
|
632
|
+
endedExtra?: ReactNode;
|
|
624
633
|
}): react.JSX.Element;
|
|
625
634
|
|
|
626
635
|
type StudioLobbyLabels = {
|
|
@@ -628,6 +637,7 @@ type StudioLobbyLabels = {
|
|
|
628
637
|
hint: string;
|
|
629
638
|
name: string;
|
|
630
639
|
join: string;
|
|
640
|
+
joining: string;
|
|
631
641
|
waitingForHost: string;
|
|
632
642
|
camera: string;
|
|
633
643
|
mic: string;
|
package/dist/studio/index.js
CHANGED
|
@@ -11574,6 +11574,7 @@ function EmptyState({
|
|
|
11574
11574
|
actionLabel,
|
|
11575
11575
|
onAction,
|
|
11576
11576
|
actionHref,
|
|
11577
|
+
extra,
|
|
11577
11578
|
role = "status"
|
|
11578
11579
|
}) {
|
|
11579
11580
|
const action = actionLabel && actionHref ? /* @__PURE__ */ jsx(Button3, { render: /* @__PURE__ */ jsx("a", { href: actionHref }), children: actionLabel }) : actionLabel ? /* @__PURE__ */ jsx(Button3, { type: "button", onClick: onAction, children: actionLabel }) : null;
|
|
@@ -11585,7 +11586,8 @@ function EmptyState({
|
|
|
11585
11586
|
children: [
|
|
11586
11587
|
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: title }),
|
|
11587
11588
|
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-md text-sm", children: description }),
|
|
11588
|
-
action
|
|
11589
|
+
action,
|
|
11590
|
+
extra
|
|
11589
11591
|
]
|
|
11590
11592
|
}
|
|
11591
11593
|
);
|
|
@@ -11656,21 +11658,18 @@ function pipSpotlightFrom(tile, kind) {
|
|
|
11656
11658
|
}
|
|
11657
11659
|
function resolveStudioPipSpotlight(tiles, activeSpeakerId) {
|
|
11658
11660
|
const visible = tiles.filter((tile) => isOnStage(tile.stageStatus));
|
|
11661
|
+
const sharing = visible.find((tile) => tile.screenShareEnabled);
|
|
11662
|
+
if (sharing) {
|
|
11663
|
+
return pipSpotlightFrom(sharing, "screen");
|
|
11664
|
+
}
|
|
11659
11665
|
const pinned = visible.find((tile) => tile.pinned === true);
|
|
11660
11666
|
if (pinned) {
|
|
11661
|
-
return pipSpotlightFrom(
|
|
11662
|
-
pinned,
|
|
11663
|
-
pinned.screenShareEnabled ? "screen" : pinned.videoEnabled ? "camera" : "idle"
|
|
11664
|
-
);
|
|
11667
|
+
return pipSpotlightFrom(pinned, pinned.videoEnabled ? "camera" : "idle");
|
|
11665
11668
|
}
|
|
11666
11669
|
const speaker = activeSpeakerId ? visible.find((tile) => tile.id === activeSpeakerId) : void 0;
|
|
11667
11670
|
if (speaker) {
|
|
11668
11671
|
return pipSpotlightFrom(speaker, speaker.videoEnabled ? "camera" : "idle");
|
|
11669
11672
|
}
|
|
11670
|
-
const sharing = visible.find((tile) => tile.screenShareEnabled);
|
|
11671
|
-
if (sharing) {
|
|
11672
|
-
return pipSpotlightFrom(sharing, "screen");
|
|
11673
|
-
}
|
|
11674
11673
|
const remoteCam = visible.find((tile) => !tile.isSelf && tile.videoEnabled);
|
|
11675
11674
|
if (remoteCam) {
|
|
11676
11675
|
return pipSpotlightFrom(remoteCam, "camera");
|
|
@@ -22835,6 +22834,7 @@ function StudioDeviceSelectGroup({
|
|
|
22835
22834
|
devices,
|
|
22836
22835
|
selected,
|
|
22837
22836
|
labels,
|
|
22837
|
+
disabled: disabled2 = false,
|
|
22838
22838
|
onChange,
|
|
22839
22839
|
speakerAction
|
|
22840
22840
|
}) {
|
|
@@ -22846,6 +22846,7 @@ function StudioDeviceSelectGroup({
|
|
|
22846
22846
|
label: labels.cameraDevice,
|
|
22847
22847
|
options: devices.video,
|
|
22848
22848
|
value: selected.video,
|
|
22849
|
+
disabled: disabled2,
|
|
22849
22850
|
onChange: (id) => onChange("video", id)
|
|
22850
22851
|
}
|
|
22851
22852
|
),
|
|
@@ -22856,6 +22857,7 @@ function StudioDeviceSelectGroup({
|
|
|
22856
22857
|
label: labels.micDevice,
|
|
22857
22858
|
options: devices.audio,
|
|
22858
22859
|
value: selected.audio,
|
|
22860
|
+
disabled: disabled2,
|
|
22859
22861
|
onChange: (id) => onChange("audio", id)
|
|
22860
22862
|
}
|
|
22861
22863
|
),
|
|
@@ -22866,6 +22868,7 @@ function StudioDeviceSelectGroup({
|
|
|
22866
22868
|
label: labels.speakerDevice,
|
|
22867
22869
|
options: devices.speaker,
|
|
22868
22870
|
value: selected.speaker,
|
|
22871
|
+
disabled: disabled2,
|
|
22869
22872
|
onChange: (id) => onChange("speaker", id),
|
|
22870
22873
|
action: speakerAction
|
|
22871
22874
|
}
|
|
@@ -22877,6 +22880,7 @@ function DeviceRow({
|
|
|
22877
22880
|
label,
|
|
22878
22881
|
options,
|
|
22879
22882
|
value,
|
|
22883
|
+
disabled: disabled2 = false,
|
|
22880
22884
|
onChange,
|
|
22881
22885
|
action
|
|
22882
22886
|
}) {
|
|
@@ -22895,6 +22899,7 @@ function DeviceRow({
|
|
|
22895
22899
|
"border-input bg-background h-8 min-w-0 flex-1 rounded-md border px-2 text-base md:text-sm"
|
|
22896
22900
|
),
|
|
22897
22901
|
value: display,
|
|
22902
|
+
disabled: disabled2,
|
|
22898
22903
|
onChange: (event) => onChange(event.target.value),
|
|
22899
22904
|
children: options.map((option) => /* @__PURE__ */ jsx("option", { value: option.deviceId, children: option.label }, option.deviceId))
|
|
22900
22905
|
}
|
|
@@ -28545,24 +28550,35 @@ function StudioToolbar({
|
|
|
28545
28550
|
children: selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsx(EyeOff, {}) : /* @__PURE__ */ jsx(Eye, {})
|
|
28546
28551
|
}
|
|
28547
28552
|
) : null,
|
|
28548
|
-
showStageGuest ? /* @__PURE__ */ jsx(
|
|
28553
|
+
showStageGuest ? selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsx(
|
|
28554
|
+
ConfirmAction,
|
|
28555
|
+
{
|
|
28556
|
+
triggerLabel: labels.moveToAudience,
|
|
28557
|
+
title: labels.moveToAudienceTitle,
|
|
28558
|
+
description: labels.moveToAudienceDescription,
|
|
28559
|
+
confirmLabel: labels.moveToAudienceConfirm,
|
|
28560
|
+
pending,
|
|
28561
|
+
onConfirm: onLeaveStage,
|
|
28562
|
+
trigger: /* @__PURE__ */ jsx(
|
|
28563
|
+
Button3,
|
|
28564
|
+
{
|
|
28565
|
+
type: "button",
|
|
28566
|
+
size: "icon-lg",
|
|
28567
|
+
variant: "secondary",
|
|
28568
|
+
disabled: pending || !canLeaveStage,
|
|
28569
|
+
"aria-label": labels.moveToAudience,
|
|
28570
|
+
children: /* @__PURE__ */ jsx(Users, {})
|
|
28571
|
+
}
|
|
28572
|
+
)
|
|
28573
|
+
}
|
|
28574
|
+
) : /* @__PURE__ */ jsx(
|
|
28549
28575
|
ControlIcon,
|
|
28550
28576
|
{
|
|
28551
|
-
label: selfStageStatus === "
|
|
28577
|
+
label: selfStageStatus === "REQUESTED_TO_JOIN_STAGE" ? labels.stageRequested : labels.askToGoOnAir,
|
|
28552
28578
|
pressed: selfStageStatus === "REQUESTED_TO_JOIN_STAGE",
|
|
28553
|
-
disabled: selfStageStatus === "REQUESTED_TO_JOIN_STAGE"
|
|
28554
|
-
onClick:
|
|
28555
|
-
|
|
28556
|
-
if (!canLeaveStage) {
|
|
28557
|
-
toast.message(labels.offAirLastVisible);
|
|
28558
|
-
return;
|
|
28559
|
-
}
|
|
28560
|
-
onLeaveStage();
|
|
28561
|
-
return;
|
|
28562
|
-
}
|
|
28563
|
-
onAskStage();
|
|
28564
|
-
},
|
|
28565
|
-
children: selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsx(EyeOff, {}) : /* @__PURE__ */ jsx(Eye, {})
|
|
28579
|
+
disabled: selfStageStatus === "REQUESTED_TO_JOIN_STAGE",
|
|
28580
|
+
onClick: onAskStage,
|
|
28581
|
+
children: /* @__PURE__ */ jsx(Eye, {})
|
|
28566
28582
|
}
|
|
28567
28583
|
) : null,
|
|
28568
28584
|
showScreenControl ? canShareFreely ? /* @__PURE__ */ jsx(
|
|
@@ -28894,7 +28910,8 @@ function StudioRoom({
|
|
|
28894
28910
|
captionsBaseUrl,
|
|
28895
28911
|
apiUrl,
|
|
28896
28912
|
cdnBase,
|
|
28897
|
-
endedHref
|
|
28913
|
+
endedHref,
|
|
28914
|
+
endedExtra
|
|
28898
28915
|
}) {
|
|
28899
28916
|
const [cameraOn, setCameraOn] = useState(initialCameraOn);
|
|
28900
28917
|
const [screenOn, setScreenOn] = useState(false);
|
|
@@ -29606,6 +29623,7 @@ function StudioRoom({
|
|
|
29606
29623
|
try {
|
|
29607
29624
|
await meeting.leave();
|
|
29608
29625
|
setLeaveState("left");
|
|
29626
|
+
} catch {
|
|
29609
29627
|
} finally {
|
|
29610
29628
|
setPending(false);
|
|
29611
29629
|
}
|
|
@@ -29626,6 +29644,7 @@ function StudioRoom({
|
|
|
29626
29644
|
}
|
|
29627
29645
|
if (sessionOver) {
|
|
29628
29646
|
const canRejoin = session.role === "moderator" && onRejoin != null && isStudioActiveStatus(session.stream.status);
|
|
29647
|
+
const returnHref = canRejoin || session.role !== "moderator" ? void 0 : endedHref?.trim() || `/streams/${session.stream.id}`;
|
|
29629
29648
|
return withStudioToaster(
|
|
29630
29649
|
/* @__PURE__ */ jsx("div", { className: "flex h-dvh flex-col items-center justify-center p-6", children: /* @__PURE__ */ jsx(
|
|
29631
29650
|
EmptyState,
|
|
@@ -29634,7 +29653,8 @@ function StudioRoom({
|
|
|
29634
29653
|
description: labels.endedDescription,
|
|
29635
29654
|
actionLabel: canRejoin ? labels.rejoin : session.role === "moderator" ? labels.endedAction : void 0,
|
|
29636
29655
|
onAction: canRejoin ? onRejoin : void 0,
|
|
29637
|
-
actionHref:
|
|
29656
|
+
actionHref: returnHref,
|
|
29657
|
+
extra: returnHref ? endedExtra : void 0
|
|
29638
29658
|
}
|
|
29639
29659
|
) })
|
|
29640
29660
|
);
|
|
@@ -30242,7 +30262,8 @@ var LOBBY_DEVICE_LABEL_DEFAULTS = {
|
|
|
30242
30262
|
speakerDevice: "Speaker",
|
|
30243
30263
|
testSpeaker: "Test",
|
|
30244
30264
|
testSpeakerError: "Could not play the speaker test",
|
|
30245
|
-
cameraOff: "Camera is off"
|
|
30265
|
+
cameraOff: "Camera is off",
|
|
30266
|
+
joining: "Joining\u2026"
|
|
30246
30267
|
};
|
|
30247
30268
|
function StudioGuestLobby({
|
|
30248
30269
|
reducedMotion,
|
|
@@ -30277,7 +30298,9 @@ function StudioGuestLobby({
|
|
|
30277
30298
|
testSpeakerError: labels.testSpeakerError ?? LOBBY_DEVICE_LABEL_DEFAULTS.testSpeakerError,
|
|
30278
30299
|
cameraOff: labels.cameraOff ?? LOBBY_DEVICE_LABEL_DEFAULTS.cameraOff
|
|
30279
30300
|
};
|
|
30301
|
+
const joiningLabel = labels.joining?.trim() || LOBBY_DEVICE_LABEL_DEFAULTS.joining;
|
|
30280
30302
|
function changeDevice(kind, deviceId) {
|
|
30303
|
+
if (joining) return;
|
|
30281
30304
|
persistStudioDeviceSelection(kind, deviceId);
|
|
30282
30305
|
onDeviceChange?.(kind, deviceId);
|
|
30283
30306
|
if (!savedDevices) {
|
|
@@ -30285,7 +30308,7 @@ function StudioGuestLobby({
|
|
|
30285
30308
|
}
|
|
30286
30309
|
}
|
|
30287
30310
|
async function onTestSpeaker() {
|
|
30288
|
-
if (testingSpeaker) return;
|
|
30311
|
+
if (testingSpeaker || joining) return;
|
|
30289
30312
|
const speakerId = effective.speaker || devices.speaker[0]?.deviceId || void 0;
|
|
30290
30313
|
setTestingSpeaker(true);
|
|
30291
30314
|
try {
|
|
@@ -30324,6 +30347,7 @@ function StudioGuestLobby({
|
|
|
30324
30347
|
size: "icon-lg",
|
|
30325
30348
|
"aria-pressed": muted,
|
|
30326
30349
|
"aria-label": labels.mic,
|
|
30350
|
+
disabled: joining,
|
|
30327
30351
|
onClick: () => onMutedChange(!muted),
|
|
30328
30352
|
children: muted ? /* @__PURE__ */ jsx(MicOff, {}) : /* @__PURE__ */ jsx(Mic, {})
|
|
30329
30353
|
}
|
|
@@ -30336,6 +30360,7 @@ function StudioGuestLobby({
|
|
|
30336
30360
|
size: "icon-lg",
|
|
30337
30361
|
"aria-pressed": cameraOn,
|
|
30338
30362
|
"aria-label": labels.camera,
|
|
30363
|
+
disabled: joining,
|
|
30339
30364
|
onClick: () => onCameraChange(!cameraOn),
|
|
30340
30365
|
children: cameraOn ? /* @__PURE__ */ jsx(Video, {}) : /* @__PURE__ */ jsx(VideoOff, {})
|
|
30341
30366
|
}
|
|
@@ -30347,6 +30372,7 @@ function StudioGuestLobby({
|
|
|
30347
30372
|
devices,
|
|
30348
30373
|
selected: effective,
|
|
30349
30374
|
labels: deviceLabels,
|
|
30375
|
+
disabled: joining,
|
|
30350
30376
|
onChange: changeDevice,
|
|
30351
30377
|
speakerAction: /* @__PURE__ */ jsx(
|
|
30352
30378
|
Button3,
|
|
@@ -30354,7 +30380,7 @@ function StudioGuestLobby({
|
|
|
30354
30380
|
type: "button",
|
|
30355
30381
|
size: "sm",
|
|
30356
30382
|
variant: "outline",
|
|
30357
|
-
disabled: testingSpeaker,
|
|
30383
|
+
disabled: testingSpeaker || joining,
|
|
30358
30384
|
onClick: () => void onTestSpeaker(),
|
|
30359
30385
|
children: deviceLabels.testSpeaker
|
|
30360
30386
|
}
|
|
@@ -30372,6 +30398,7 @@ function StudioGuestLobby({
|
|
|
30372
30398
|
onChange: (event) => onDisplayNameChange(event.target.value),
|
|
30373
30399
|
maxLength: 80,
|
|
30374
30400
|
required: true,
|
|
30401
|
+
disabled: joining,
|
|
30375
30402
|
autoComplete: "name"
|
|
30376
30403
|
}
|
|
30377
30404
|
)
|
|
@@ -30385,8 +30412,18 @@ function StudioGuestLobby({
|
|
|
30385
30412
|
size: "lg",
|
|
30386
30413
|
className: "w-full",
|
|
30387
30414
|
disabled: joining || showName && !displayName.trim(),
|
|
30415
|
+
"aria-busy": joining,
|
|
30388
30416
|
onClick: onJoin,
|
|
30389
|
-
children:
|
|
30417
|
+
children: joining ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30418
|
+
/* @__PURE__ */ jsx(
|
|
30419
|
+
LoaderCircle,
|
|
30420
|
+
{
|
|
30421
|
+
"aria-hidden": true,
|
|
30422
|
+
className: "animate-spin motion-reduce:animate-none"
|
|
30423
|
+
}
|
|
30424
|
+
),
|
|
30425
|
+
joiningLabel
|
|
30426
|
+
] }) : waitingForHost ? labels.waitingForHost : labels.join
|
|
30390
30427
|
}
|
|
30391
30428
|
)
|
|
30392
30429
|
] });
|
|
@@ -30701,6 +30738,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30701
30738
|
const chatSend = /* @__PURE__ */ new Map();
|
|
30702
30739
|
const nameOverrides = /* @__PURE__ */ new Map();
|
|
30703
30740
|
let joinStageInFlight = null;
|
|
30741
|
+
let leaveInProgress = false;
|
|
30704
30742
|
let joinedStageLocally = false;
|
|
30705
30743
|
let stageGrantPending = false;
|
|
30706
30744
|
let stageGrantJoinFailures = 0;
|
|
@@ -30814,6 +30852,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30814
30852
|
for (const listener of stageGrantListeners) listener(userId);
|
|
30815
30853
|
}
|
|
30816
30854
|
function markStageGranted() {
|
|
30855
|
+
if (leaveInProgress) return;
|
|
30817
30856
|
stageGrantPending = true;
|
|
30818
30857
|
void ensureStageJoined();
|
|
30819
30858
|
}
|
|
@@ -30861,6 +30900,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30861
30900
|
async function runJoinStageAttempts() {
|
|
30862
30901
|
let lastError;
|
|
30863
30902
|
for (let attempt = 0; attempt < STAGE_JOIN_MAX_ATTEMPTS; attempt++) {
|
|
30903
|
+
if (leaveInProgress) return;
|
|
30864
30904
|
if (currentStageStatus() === "ON_STAGE") {
|
|
30865
30905
|
notifyStage();
|
|
30866
30906
|
return;
|
|
@@ -30909,6 +30949,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30909
30949
|
}
|
|
30910
30950
|
}
|
|
30911
30951
|
async function ensureStageJoined() {
|
|
30952
|
+
if (leaveInProgress) return;
|
|
30912
30953
|
if (currentStageStatus() === "ON_STAGE") {
|
|
30913
30954
|
clearStageGrantPending();
|
|
30914
30955
|
return;
|
|
@@ -31045,10 +31086,29 @@ function studioMeetingFromRtk(raw) {
|
|
|
31045
31086
|
await applyCurrentVideoEffects();
|
|
31046
31087
|
},
|
|
31047
31088
|
async leave() {
|
|
31048
|
-
|
|
31049
|
-
|
|
31089
|
+
leaveInProgress = true;
|
|
31090
|
+
clearStageGrantPending();
|
|
31091
|
+
try {
|
|
31092
|
+
if (typeof window !== "undefined") {
|
|
31093
|
+
window.removeEventListener(
|
|
31094
|
+
"unhandledrejection",
|
|
31095
|
+
onUnhandledRejection
|
|
31096
|
+
);
|
|
31097
|
+
}
|
|
31098
|
+
let firstFailed = false;
|
|
31099
|
+
try {
|
|
31100
|
+
await meeting.leave?.();
|
|
31101
|
+
} catch {
|
|
31102
|
+
firstFailed = true;
|
|
31103
|
+
}
|
|
31104
|
+
const roomState = meeting.self?.roomState ?? null;
|
|
31105
|
+
if (firstFailed || roomState === "joined" || roomState === "stageLeft") {
|
|
31106
|
+
await meeting.leave?.();
|
|
31107
|
+
}
|
|
31108
|
+
} finally {
|
|
31109
|
+
clearStageGrantPending();
|
|
31110
|
+
leaveInProgress = false;
|
|
31050
31111
|
}
|
|
31051
|
-
await meeting.leave?.();
|
|
31052
31112
|
},
|
|
31053
31113
|
async setAudioEnabled(enabled) {
|
|
31054
31114
|
if (enabled) await meeting.self?.enableAudio?.();
|
|
@@ -31661,7 +31721,8 @@ function LivoHostStudio({
|
|
|
31661
31721
|
theme,
|
|
31662
31722
|
appDownloadUrl,
|
|
31663
31723
|
guestUrl,
|
|
31664
|
-
endedHref
|
|
31724
|
+
endedHref,
|
|
31725
|
+
endedExtra
|
|
31665
31726
|
}) {
|
|
31666
31727
|
const reducedMotion = usePrefersReducedMotion();
|
|
31667
31728
|
const [session, setSession] = useState(null);
|
|
@@ -31783,7 +31844,8 @@ function LivoHostStudio({
|
|
|
31783
31844
|
playerOrigin,
|
|
31784
31845
|
appDownloadUrl,
|
|
31785
31846
|
apiUrl,
|
|
31786
|
-
endedHref
|
|
31847
|
+
endedHref,
|
|
31848
|
+
endedExtra
|
|
31787
31849
|
}
|
|
31788
31850
|
) });
|
|
31789
31851
|
}
|
|
@@ -31823,6 +31885,9 @@ function LivoGuestStudio({
|
|
|
31823
31885
|
session?.authToken ?? null,
|
|
31824
31886
|
sessionGen
|
|
31825
31887
|
);
|
|
31888
|
+
useEffect(() => {
|
|
31889
|
+
if (meeting) setJoining(false);
|
|
31890
|
+
}, [meeting]);
|
|
31826
31891
|
useEffect(() => {
|
|
31827
31892
|
const identity = readStudioGuestIdentity();
|
|
31828
31893
|
setDisplayName(identity.displayName);
|
|
@@ -31855,6 +31920,7 @@ function LivoGuestStudio({
|
|
|
31855
31920
|
setStatus(null);
|
|
31856
31921
|
setSession(next);
|
|
31857
31922
|
} catch (err) {
|
|
31923
|
+
setJoining(false);
|
|
31858
31924
|
const code = studioErrorCode(err);
|
|
31859
31925
|
if (code === "studio_not_started") {
|
|
31860
31926
|
setWaitingForHost(true);
|
|
@@ -31871,7 +31937,6 @@ function LivoGuestStudio({
|
|
|
31871
31937
|
}
|
|
31872
31938
|
} finally {
|
|
31873
31939
|
joinInFlight.current = false;
|
|
31874
|
-
setJoining(false);
|
|
31875
31940
|
}
|
|
31876
31941
|
}, [apiUrl, displayName, guestId, lobbyLabels, token]);
|
|
31877
31942
|
useEffect(() => {
|
|
@@ -32133,6 +32198,10 @@ function studioRoomLabels(t) {
|
|
|
32133
32198
|
shareRequestTimeout: t("shareRequestTimeout"),
|
|
32134
32199
|
shareRespondError: t("shareRespondError"),
|
|
32135
32200
|
goOffAir: t("goOffAir"),
|
|
32201
|
+
moveToAudience: t("moveToAudience"),
|
|
32202
|
+
moveToAudienceTitle: t("moveToAudienceTitle"),
|
|
32203
|
+
moveToAudienceDescription: t("moveToAudienceDescription"),
|
|
32204
|
+
moveToAudienceConfirm: t("moveToAudienceConfirm"),
|
|
32136
32205
|
goOnAir: t("goOnAir"),
|
|
32137
32206
|
takeOffAir: t("takeOffAir"),
|
|
32138
32207
|
bringOnAir: t("bringOnAir"),
|