@livo-tv/sdk 1.16.0 → 1.17.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/dist/studio/index.cjs +93 -31
- package/dist/studio/index.cjs.map +1 -1
- package/dist/studio/index.d.cts +6 -0
- package/dist/studio/index.d.ts +6 -0
- package/dist/studio/index.js +93 -31
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
package/dist/studio/index.cjs
CHANGED
|
@@ -11677,21 +11677,18 @@ function pipSpotlightFrom(tile, kind) {
|
|
|
11677
11677
|
}
|
|
11678
11678
|
function resolveStudioPipSpotlight(tiles, activeSpeakerId) {
|
|
11679
11679
|
const visible = tiles.filter((tile) => isOnStage(tile.stageStatus));
|
|
11680
|
+
const sharing = visible.find((tile) => tile.screenShareEnabled);
|
|
11681
|
+
if (sharing) {
|
|
11682
|
+
return pipSpotlightFrom(sharing, "screen");
|
|
11683
|
+
}
|
|
11680
11684
|
const pinned = visible.find((tile) => tile.pinned === true);
|
|
11681
11685
|
if (pinned) {
|
|
11682
|
-
return pipSpotlightFrom(
|
|
11683
|
-
pinned,
|
|
11684
|
-
pinned.screenShareEnabled ? "screen" : pinned.videoEnabled ? "camera" : "idle"
|
|
11685
|
-
);
|
|
11686
|
+
return pipSpotlightFrom(pinned, pinned.videoEnabled ? "camera" : "idle");
|
|
11686
11687
|
}
|
|
11687
11688
|
const speaker = activeSpeakerId ? visible.find((tile) => tile.id === activeSpeakerId) : void 0;
|
|
11688
11689
|
if (speaker) {
|
|
11689
11690
|
return pipSpotlightFrom(speaker, speaker.videoEnabled ? "camera" : "idle");
|
|
11690
11691
|
}
|
|
11691
|
-
const sharing = visible.find((tile) => tile.screenShareEnabled);
|
|
11692
|
-
if (sharing) {
|
|
11693
|
-
return pipSpotlightFrom(sharing, "screen");
|
|
11694
|
-
}
|
|
11695
11692
|
const remoteCam = visible.find((tile) => !tile.isSelf && tile.videoEnabled);
|
|
11696
11693
|
if (remoteCam) {
|
|
11697
11694
|
return pipSpotlightFrom(remoteCam, "camera");
|
|
@@ -22856,6 +22853,7 @@ function StudioDeviceSelectGroup({
|
|
|
22856
22853
|
devices,
|
|
22857
22854
|
selected,
|
|
22858
22855
|
labels,
|
|
22856
|
+
disabled: disabled2 = false,
|
|
22859
22857
|
onChange,
|
|
22860
22858
|
speakerAction
|
|
22861
22859
|
}) {
|
|
@@ -22867,6 +22865,7 @@ function StudioDeviceSelectGroup({
|
|
|
22867
22865
|
label: labels.cameraDevice,
|
|
22868
22866
|
options: devices.video,
|
|
22869
22867
|
value: selected.video,
|
|
22868
|
+
disabled: disabled2,
|
|
22870
22869
|
onChange: (id) => onChange("video", id)
|
|
22871
22870
|
}
|
|
22872
22871
|
),
|
|
@@ -22877,6 +22876,7 @@ function StudioDeviceSelectGroup({
|
|
|
22877
22876
|
label: labels.micDevice,
|
|
22878
22877
|
options: devices.audio,
|
|
22879
22878
|
value: selected.audio,
|
|
22879
|
+
disabled: disabled2,
|
|
22880
22880
|
onChange: (id) => onChange("audio", id)
|
|
22881
22881
|
}
|
|
22882
22882
|
),
|
|
@@ -22887,6 +22887,7 @@ function StudioDeviceSelectGroup({
|
|
|
22887
22887
|
label: labels.speakerDevice,
|
|
22888
22888
|
options: devices.speaker,
|
|
22889
22889
|
value: selected.speaker,
|
|
22890
|
+
disabled: disabled2,
|
|
22890
22891
|
onChange: (id) => onChange("speaker", id),
|
|
22891
22892
|
action: speakerAction
|
|
22892
22893
|
}
|
|
@@ -22898,6 +22899,7 @@ function DeviceRow({
|
|
|
22898
22899
|
label,
|
|
22899
22900
|
options,
|
|
22900
22901
|
value,
|
|
22902
|
+
disabled: disabled2 = false,
|
|
22901
22903
|
onChange,
|
|
22902
22904
|
action
|
|
22903
22905
|
}) {
|
|
@@ -22916,6 +22918,7 @@ function DeviceRow({
|
|
|
22916
22918
|
"border-input bg-background h-8 min-w-0 flex-1 rounded-md border px-2 text-base md:text-sm"
|
|
22917
22919
|
),
|
|
22918
22920
|
value: display,
|
|
22921
|
+
disabled: disabled2,
|
|
22919
22922
|
onChange: (event) => onChange(event.target.value),
|
|
22920
22923
|
children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.deviceId, children: option.label }, option.deviceId))
|
|
22921
22924
|
}
|
|
@@ -28566,24 +28569,35 @@ function StudioToolbar({
|
|
|
28566
28569
|
children: selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsxRuntime.jsx(EyeOff, {}) : /* @__PURE__ */ jsxRuntime.jsx(Eye, {})
|
|
28567
28570
|
}
|
|
28568
28571
|
) : null,
|
|
28569
|
-
showStageGuest ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
28572
|
+
showStageGuest ? selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
28573
|
+
ConfirmAction,
|
|
28574
|
+
{
|
|
28575
|
+
triggerLabel: labels.moveToAudience,
|
|
28576
|
+
title: labels.moveToAudienceTitle,
|
|
28577
|
+
description: labels.moveToAudienceDescription,
|
|
28578
|
+
confirmLabel: labels.moveToAudienceConfirm,
|
|
28579
|
+
pending,
|
|
28580
|
+
onConfirm: onLeaveStage,
|
|
28581
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28582
|
+
Button3,
|
|
28583
|
+
{
|
|
28584
|
+
type: "button",
|
|
28585
|
+
size: "icon-lg",
|
|
28586
|
+
variant: "secondary",
|
|
28587
|
+
disabled: pending || !canLeaveStage,
|
|
28588
|
+
"aria-label": labels.moveToAudience,
|
|
28589
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Users, {})
|
|
28590
|
+
}
|
|
28591
|
+
)
|
|
28592
|
+
}
|
|
28593
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
28570
28594
|
ControlIcon,
|
|
28571
28595
|
{
|
|
28572
|
-
label: selfStageStatus === "
|
|
28596
|
+
label: selfStageStatus === "REQUESTED_TO_JOIN_STAGE" ? labels.stageRequested : labels.askToGoOnAir,
|
|
28573
28597
|
pressed: selfStageStatus === "REQUESTED_TO_JOIN_STAGE",
|
|
28574
|
-
disabled: selfStageStatus === "REQUESTED_TO_JOIN_STAGE"
|
|
28575
|
-
onClick:
|
|
28576
|
-
|
|
28577
|
-
if (!canLeaveStage) {
|
|
28578
|
-
toast.message(labels.offAirLastVisible);
|
|
28579
|
-
return;
|
|
28580
|
-
}
|
|
28581
|
-
onLeaveStage();
|
|
28582
|
-
return;
|
|
28583
|
-
}
|
|
28584
|
-
onAskStage();
|
|
28585
|
-
},
|
|
28586
|
-
children: selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsxRuntime.jsx(EyeOff, {}) : /* @__PURE__ */ jsxRuntime.jsx(Eye, {})
|
|
28598
|
+
disabled: selfStageStatus === "REQUESTED_TO_JOIN_STAGE",
|
|
28599
|
+
onClick: onAskStage,
|
|
28600
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Eye, {})
|
|
28587
28601
|
}
|
|
28588
28602
|
) : null,
|
|
28589
28603
|
showScreenControl ? canShareFreely ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -29627,6 +29641,7 @@ function StudioRoom({
|
|
|
29627
29641
|
try {
|
|
29628
29642
|
await meeting.leave();
|
|
29629
29643
|
setLeaveState("left");
|
|
29644
|
+
} catch {
|
|
29630
29645
|
} finally {
|
|
29631
29646
|
setPending(false);
|
|
29632
29647
|
}
|
|
@@ -30263,7 +30278,8 @@ var LOBBY_DEVICE_LABEL_DEFAULTS = {
|
|
|
30263
30278
|
speakerDevice: "Speaker",
|
|
30264
30279
|
testSpeaker: "Test",
|
|
30265
30280
|
testSpeakerError: "Could not play the speaker test",
|
|
30266
|
-
cameraOff: "Camera is off"
|
|
30281
|
+
cameraOff: "Camera is off",
|
|
30282
|
+
joining: "Joining\u2026"
|
|
30267
30283
|
};
|
|
30268
30284
|
function StudioGuestLobby({
|
|
30269
30285
|
reducedMotion,
|
|
@@ -30298,7 +30314,9 @@ function StudioGuestLobby({
|
|
|
30298
30314
|
testSpeakerError: labels.testSpeakerError ?? LOBBY_DEVICE_LABEL_DEFAULTS.testSpeakerError,
|
|
30299
30315
|
cameraOff: labels.cameraOff ?? LOBBY_DEVICE_LABEL_DEFAULTS.cameraOff
|
|
30300
30316
|
};
|
|
30317
|
+
const joiningLabel = labels.joining?.trim() || LOBBY_DEVICE_LABEL_DEFAULTS.joining;
|
|
30301
30318
|
function changeDevice(kind, deviceId) {
|
|
30319
|
+
if (joining) return;
|
|
30302
30320
|
persistStudioDeviceSelection(kind, deviceId);
|
|
30303
30321
|
onDeviceChange?.(kind, deviceId);
|
|
30304
30322
|
if (!savedDevices) {
|
|
@@ -30306,7 +30324,7 @@ function StudioGuestLobby({
|
|
|
30306
30324
|
}
|
|
30307
30325
|
}
|
|
30308
30326
|
async function onTestSpeaker() {
|
|
30309
|
-
if (testingSpeaker) return;
|
|
30327
|
+
if (testingSpeaker || joining) return;
|
|
30310
30328
|
const speakerId = effective.speaker || devices.speaker[0]?.deviceId || void 0;
|
|
30311
30329
|
setTestingSpeaker(true);
|
|
30312
30330
|
try {
|
|
@@ -30345,6 +30363,7 @@ function StudioGuestLobby({
|
|
|
30345
30363
|
size: "icon-lg",
|
|
30346
30364
|
"aria-pressed": muted,
|
|
30347
30365
|
"aria-label": labels.mic,
|
|
30366
|
+
disabled: joining,
|
|
30348
30367
|
onClick: () => onMutedChange(!muted),
|
|
30349
30368
|
children: muted ? /* @__PURE__ */ jsxRuntime.jsx(MicOff, {}) : /* @__PURE__ */ jsxRuntime.jsx(Mic, {})
|
|
30350
30369
|
}
|
|
@@ -30357,6 +30376,7 @@ function StudioGuestLobby({
|
|
|
30357
30376
|
size: "icon-lg",
|
|
30358
30377
|
"aria-pressed": cameraOn,
|
|
30359
30378
|
"aria-label": labels.camera,
|
|
30379
|
+
disabled: joining,
|
|
30360
30380
|
onClick: () => onCameraChange(!cameraOn),
|
|
30361
30381
|
children: cameraOn ? /* @__PURE__ */ jsxRuntime.jsx(Video, {}) : /* @__PURE__ */ jsxRuntime.jsx(VideoOff, {})
|
|
30362
30382
|
}
|
|
@@ -30368,6 +30388,7 @@ function StudioGuestLobby({
|
|
|
30368
30388
|
devices,
|
|
30369
30389
|
selected: effective,
|
|
30370
30390
|
labels: deviceLabels,
|
|
30391
|
+
disabled: joining,
|
|
30371
30392
|
onChange: changeDevice,
|
|
30372
30393
|
speakerAction: /* @__PURE__ */ jsxRuntime.jsx(
|
|
30373
30394
|
Button3,
|
|
@@ -30375,7 +30396,7 @@ function StudioGuestLobby({
|
|
|
30375
30396
|
type: "button",
|
|
30376
30397
|
size: "sm",
|
|
30377
30398
|
variant: "outline",
|
|
30378
|
-
disabled: testingSpeaker,
|
|
30399
|
+
disabled: testingSpeaker || joining,
|
|
30379
30400
|
onClick: () => void onTestSpeaker(),
|
|
30380
30401
|
children: deviceLabels.testSpeaker
|
|
30381
30402
|
}
|
|
@@ -30393,6 +30414,7 @@ function StudioGuestLobby({
|
|
|
30393
30414
|
onChange: (event) => onDisplayNameChange(event.target.value),
|
|
30394
30415
|
maxLength: 80,
|
|
30395
30416
|
required: true,
|
|
30417
|
+
disabled: joining,
|
|
30396
30418
|
autoComplete: "name"
|
|
30397
30419
|
}
|
|
30398
30420
|
)
|
|
@@ -30406,8 +30428,18 @@ function StudioGuestLobby({
|
|
|
30406
30428
|
size: "lg",
|
|
30407
30429
|
className: "w-full",
|
|
30408
30430
|
disabled: joining || showName && !displayName.trim(),
|
|
30431
|
+
"aria-busy": joining,
|
|
30409
30432
|
onClick: onJoin,
|
|
30410
|
-
children:
|
|
30433
|
+
children: joining ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
30434
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
30435
|
+
LoaderCircle,
|
|
30436
|
+
{
|
|
30437
|
+
"aria-hidden": true,
|
|
30438
|
+
className: "animate-spin motion-reduce:animate-none"
|
|
30439
|
+
}
|
|
30440
|
+
),
|
|
30441
|
+
joiningLabel
|
|
30442
|
+
] }) : waitingForHost ? labels.waitingForHost : labels.join
|
|
30411
30443
|
}
|
|
30412
30444
|
)
|
|
30413
30445
|
] });
|
|
@@ -30722,6 +30754,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30722
30754
|
const chatSend = /* @__PURE__ */ new Map();
|
|
30723
30755
|
const nameOverrides = /* @__PURE__ */ new Map();
|
|
30724
30756
|
let joinStageInFlight = null;
|
|
30757
|
+
let leaveInProgress = false;
|
|
30725
30758
|
let joinedStageLocally = false;
|
|
30726
30759
|
let stageGrantPending = false;
|
|
30727
30760
|
let stageGrantJoinFailures = 0;
|
|
@@ -30835,6 +30868,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30835
30868
|
for (const listener of stageGrantListeners) listener(userId);
|
|
30836
30869
|
}
|
|
30837
30870
|
function markStageGranted() {
|
|
30871
|
+
if (leaveInProgress) return;
|
|
30838
30872
|
stageGrantPending = true;
|
|
30839
30873
|
void ensureStageJoined();
|
|
30840
30874
|
}
|
|
@@ -30882,6 +30916,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30882
30916
|
async function runJoinStageAttempts() {
|
|
30883
30917
|
let lastError;
|
|
30884
30918
|
for (let attempt = 0; attempt < STAGE_JOIN_MAX_ATTEMPTS; attempt++) {
|
|
30919
|
+
if (leaveInProgress) return;
|
|
30885
30920
|
if (currentStageStatus() === "ON_STAGE") {
|
|
30886
30921
|
notifyStage();
|
|
30887
30922
|
return;
|
|
@@ -30930,6 +30965,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30930
30965
|
}
|
|
30931
30966
|
}
|
|
30932
30967
|
async function ensureStageJoined() {
|
|
30968
|
+
if (leaveInProgress) return;
|
|
30933
30969
|
if (currentStageStatus() === "ON_STAGE") {
|
|
30934
30970
|
clearStageGrantPending();
|
|
30935
30971
|
return;
|
|
@@ -31066,10 +31102,29 @@ function studioMeetingFromRtk(raw) {
|
|
|
31066
31102
|
await applyCurrentVideoEffects();
|
|
31067
31103
|
},
|
|
31068
31104
|
async leave() {
|
|
31069
|
-
|
|
31070
|
-
|
|
31105
|
+
leaveInProgress = true;
|
|
31106
|
+
clearStageGrantPending();
|
|
31107
|
+
try {
|
|
31108
|
+
if (typeof window !== "undefined") {
|
|
31109
|
+
window.removeEventListener(
|
|
31110
|
+
"unhandledrejection",
|
|
31111
|
+
onUnhandledRejection
|
|
31112
|
+
);
|
|
31113
|
+
}
|
|
31114
|
+
let firstFailed = false;
|
|
31115
|
+
try {
|
|
31116
|
+
await meeting.leave?.();
|
|
31117
|
+
} catch {
|
|
31118
|
+
firstFailed = true;
|
|
31119
|
+
}
|
|
31120
|
+
const roomState = meeting.self?.roomState ?? null;
|
|
31121
|
+
if (firstFailed || roomState === "joined" || roomState === "stageLeft") {
|
|
31122
|
+
await meeting.leave?.();
|
|
31123
|
+
}
|
|
31124
|
+
} finally {
|
|
31125
|
+
clearStageGrantPending();
|
|
31126
|
+
leaveInProgress = false;
|
|
31071
31127
|
}
|
|
31072
|
-
await meeting.leave?.();
|
|
31073
31128
|
},
|
|
31074
31129
|
async setAudioEnabled(enabled) {
|
|
31075
31130
|
if (enabled) await meeting.self?.enableAudio?.();
|
|
@@ -31844,6 +31899,9 @@ function LivoGuestStudio({
|
|
|
31844
31899
|
session?.authToken ?? null,
|
|
31845
31900
|
sessionGen
|
|
31846
31901
|
);
|
|
31902
|
+
React18.useEffect(() => {
|
|
31903
|
+
if (meeting) setJoining(false);
|
|
31904
|
+
}, [meeting]);
|
|
31847
31905
|
React18.useEffect(() => {
|
|
31848
31906
|
const identity = readStudioGuestIdentity();
|
|
31849
31907
|
setDisplayName(identity.displayName);
|
|
@@ -31876,6 +31934,7 @@ function LivoGuestStudio({
|
|
|
31876
31934
|
setStatus(null);
|
|
31877
31935
|
setSession(next);
|
|
31878
31936
|
} catch (err) {
|
|
31937
|
+
setJoining(false);
|
|
31879
31938
|
const code = studioErrorCode(err);
|
|
31880
31939
|
if (code === "studio_not_started") {
|
|
31881
31940
|
setWaitingForHost(true);
|
|
@@ -31892,7 +31951,6 @@ function LivoGuestStudio({
|
|
|
31892
31951
|
}
|
|
31893
31952
|
} finally {
|
|
31894
31953
|
joinInFlight.current = false;
|
|
31895
|
-
setJoining(false);
|
|
31896
31954
|
}
|
|
31897
31955
|
}, [apiUrl, displayName, guestId, lobbyLabels, token]);
|
|
31898
31956
|
React18.useEffect(() => {
|
|
@@ -32154,6 +32212,10 @@ function studioRoomLabels(t) {
|
|
|
32154
32212
|
shareRequestTimeout: t("shareRequestTimeout"),
|
|
32155
32213
|
shareRespondError: t("shareRespondError"),
|
|
32156
32214
|
goOffAir: t("goOffAir"),
|
|
32215
|
+
moveToAudience: t("moveToAudience"),
|
|
32216
|
+
moveToAudienceTitle: t("moveToAudienceTitle"),
|
|
32217
|
+
moveToAudienceDescription: t("moveToAudienceDescription"),
|
|
32218
|
+
moveToAudienceConfirm: t("moveToAudienceConfirm"),
|
|
32157
32219
|
goOnAir: t("goOnAir"),
|
|
32158
32220
|
takeOffAir: t("takeOffAir"),
|
|
32159
32221
|
bringOnAir: t("bringOnAir"),
|