@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/README.md
CHANGED
|
@@ -79,7 +79,7 @@ Wrap the studio in `StudioWindowGate` with a **stable** `lockKey` (stream id or
|
|
|
79
79
|
|
|
80
80
|
Omit `playerOrigin` in native embeds. The watch-share control only appears when you pass a player origin; native partners should share their own watch URL.
|
|
81
81
|
|
|
82
|
-
`endedHref` is the link on the host's ended-session action. When it is omitted or blank, that action goes to `/streams/:id`.
|
|
82
|
+
`endedHref` is the link on the host's ended-session action. When it is omitted or blank, that action goes to `/streams/:id`. Optional `endedExtra` renders under that action. Omit it and the card stays the same.
|
|
83
83
|
|
|
84
84
|
Regression page: `pnpm example:embed` serves `examples/partner-embed` on `http://localhost:3003`.
|
|
85
85
|
|
package/dist/studio/index.cjs
CHANGED
|
@@ -11595,6 +11595,7 @@ function EmptyState({
|
|
|
11595
11595
|
actionLabel,
|
|
11596
11596
|
onAction,
|
|
11597
11597
|
actionHref,
|
|
11598
|
+
extra,
|
|
11598
11599
|
role = "status"
|
|
11599
11600
|
}) {
|
|
11600
11601
|
const action = actionLabel && actionHref ? /* @__PURE__ */ jsxRuntime.jsx(Button3, { render: /* @__PURE__ */ jsxRuntime.jsx("a", { href: actionHref }), children: actionLabel }) : actionLabel ? /* @__PURE__ */ jsxRuntime.jsx(Button3, { type: "button", onClick: onAction, children: actionLabel }) : null;
|
|
@@ -11606,7 +11607,8 @@ function EmptyState({
|
|
|
11606
11607
|
children: [
|
|
11607
11608
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold", children: title }),
|
|
11608
11609
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground max-w-md text-sm", children: description }),
|
|
11609
|
-
action
|
|
11610
|
+
action,
|
|
11611
|
+
extra
|
|
11610
11612
|
]
|
|
11611
11613
|
}
|
|
11612
11614
|
);
|
|
@@ -11677,21 +11679,18 @@ function pipSpotlightFrom(tile, kind) {
|
|
|
11677
11679
|
}
|
|
11678
11680
|
function resolveStudioPipSpotlight(tiles, activeSpeakerId) {
|
|
11679
11681
|
const visible = tiles.filter((tile) => isOnStage(tile.stageStatus));
|
|
11682
|
+
const sharing = visible.find((tile) => tile.screenShareEnabled);
|
|
11683
|
+
if (sharing) {
|
|
11684
|
+
return pipSpotlightFrom(sharing, "screen");
|
|
11685
|
+
}
|
|
11680
11686
|
const pinned = visible.find((tile) => tile.pinned === true);
|
|
11681
11687
|
if (pinned) {
|
|
11682
|
-
return pipSpotlightFrom(
|
|
11683
|
-
pinned,
|
|
11684
|
-
pinned.screenShareEnabled ? "screen" : pinned.videoEnabled ? "camera" : "idle"
|
|
11685
|
-
);
|
|
11688
|
+
return pipSpotlightFrom(pinned, pinned.videoEnabled ? "camera" : "idle");
|
|
11686
11689
|
}
|
|
11687
11690
|
const speaker = activeSpeakerId ? visible.find((tile) => tile.id === activeSpeakerId) : void 0;
|
|
11688
11691
|
if (speaker) {
|
|
11689
11692
|
return pipSpotlightFrom(speaker, speaker.videoEnabled ? "camera" : "idle");
|
|
11690
11693
|
}
|
|
11691
|
-
const sharing = visible.find((tile) => tile.screenShareEnabled);
|
|
11692
|
-
if (sharing) {
|
|
11693
|
-
return pipSpotlightFrom(sharing, "screen");
|
|
11694
|
-
}
|
|
11695
11694
|
const remoteCam = visible.find((tile) => !tile.isSelf && tile.videoEnabled);
|
|
11696
11695
|
if (remoteCam) {
|
|
11697
11696
|
return pipSpotlightFrom(remoteCam, "camera");
|
|
@@ -22856,6 +22855,7 @@ function StudioDeviceSelectGroup({
|
|
|
22856
22855
|
devices,
|
|
22857
22856
|
selected,
|
|
22858
22857
|
labels,
|
|
22858
|
+
disabled: disabled2 = false,
|
|
22859
22859
|
onChange,
|
|
22860
22860
|
speakerAction
|
|
22861
22861
|
}) {
|
|
@@ -22867,6 +22867,7 @@ function StudioDeviceSelectGroup({
|
|
|
22867
22867
|
label: labels.cameraDevice,
|
|
22868
22868
|
options: devices.video,
|
|
22869
22869
|
value: selected.video,
|
|
22870
|
+
disabled: disabled2,
|
|
22870
22871
|
onChange: (id) => onChange("video", id)
|
|
22871
22872
|
}
|
|
22872
22873
|
),
|
|
@@ -22877,6 +22878,7 @@ function StudioDeviceSelectGroup({
|
|
|
22877
22878
|
label: labels.micDevice,
|
|
22878
22879
|
options: devices.audio,
|
|
22879
22880
|
value: selected.audio,
|
|
22881
|
+
disabled: disabled2,
|
|
22880
22882
|
onChange: (id) => onChange("audio", id)
|
|
22881
22883
|
}
|
|
22882
22884
|
),
|
|
@@ -22887,6 +22889,7 @@ function StudioDeviceSelectGroup({
|
|
|
22887
22889
|
label: labels.speakerDevice,
|
|
22888
22890
|
options: devices.speaker,
|
|
22889
22891
|
value: selected.speaker,
|
|
22892
|
+
disabled: disabled2,
|
|
22890
22893
|
onChange: (id) => onChange("speaker", id),
|
|
22891
22894
|
action: speakerAction
|
|
22892
22895
|
}
|
|
@@ -22898,6 +22901,7 @@ function DeviceRow({
|
|
|
22898
22901
|
label,
|
|
22899
22902
|
options,
|
|
22900
22903
|
value,
|
|
22904
|
+
disabled: disabled2 = false,
|
|
22901
22905
|
onChange,
|
|
22902
22906
|
action
|
|
22903
22907
|
}) {
|
|
@@ -22916,6 +22920,7 @@ function DeviceRow({
|
|
|
22916
22920
|
"border-input bg-background h-8 min-w-0 flex-1 rounded-md border px-2 text-base md:text-sm"
|
|
22917
22921
|
),
|
|
22918
22922
|
value: display,
|
|
22923
|
+
disabled: disabled2,
|
|
22919
22924
|
onChange: (event) => onChange(event.target.value),
|
|
22920
22925
|
children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.deviceId, children: option.label }, option.deviceId))
|
|
22921
22926
|
}
|
|
@@ -28566,24 +28571,35 @@ function StudioToolbar({
|
|
|
28566
28571
|
children: selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsxRuntime.jsx(EyeOff, {}) : /* @__PURE__ */ jsxRuntime.jsx(Eye, {})
|
|
28567
28572
|
}
|
|
28568
28573
|
) : null,
|
|
28569
|
-
showStageGuest ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
28574
|
+
showStageGuest ? selfStageStatus === "ON_STAGE" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
28575
|
+
ConfirmAction,
|
|
28576
|
+
{
|
|
28577
|
+
triggerLabel: labels.moveToAudience,
|
|
28578
|
+
title: labels.moveToAudienceTitle,
|
|
28579
|
+
description: labels.moveToAudienceDescription,
|
|
28580
|
+
confirmLabel: labels.moveToAudienceConfirm,
|
|
28581
|
+
pending,
|
|
28582
|
+
onConfirm: onLeaveStage,
|
|
28583
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28584
|
+
Button3,
|
|
28585
|
+
{
|
|
28586
|
+
type: "button",
|
|
28587
|
+
size: "icon-lg",
|
|
28588
|
+
variant: "secondary",
|
|
28589
|
+
disabled: pending || !canLeaveStage,
|
|
28590
|
+
"aria-label": labels.moveToAudience,
|
|
28591
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Users, {})
|
|
28592
|
+
}
|
|
28593
|
+
)
|
|
28594
|
+
}
|
|
28595
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
28570
28596
|
ControlIcon,
|
|
28571
28597
|
{
|
|
28572
|
-
label: selfStageStatus === "
|
|
28598
|
+
label: selfStageStatus === "REQUESTED_TO_JOIN_STAGE" ? labels.stageRequested : labels.askToGoOnAir,
|
|
28573
28599
|
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, {})
|
|
28600
|
+
disabled: selfStageStatus === "REQUESTED_TO_JOIN_STAGE",
|
|
28601
|
+
onClick: onAskStage,
|
|
28602
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Eye, {})
|
|
28587
28603
|
}
|
|
28588
28604
|
) : null,
|
|
28589
28605
|
showScreenControl ? canShareFreely ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -28915,7 +28931,8 @@ function StudioRoom({
|
|
|
28915
28931
|
captionsBaseUrl,
|
|
28916
28932
|
apiUrl,
|
|
28917
28933
|
cdnBase,
|
|
28918
|
-
endedHref
|
|
28934
|
+
endedHref,
|
|
28935
|
+
endedExtra
|
|
28919
28936
|
}) {
|
|
28920
28937
|
const [cameraOn, setCameraOn] = React18.useState(initialCameraOn);
|
|
28921
28938
|
const [screenOn, setScreenOn] = React18.useState(false);
|
|
@@ -29627,6 +29644,7 @@ function StudioRoom({
|
|
|
29627
29644
|
try {
|
|
29628
29645
|
await meeting.leave();
|
|
29629
29646
|
setLeaveState("left");
|
|
29647
|
+
} catch {
|
|
29630
29648
|
} finally {
|
|
29631
29649
|
setPending(false);
|
|
29632
29650
|
}
|
|
@@ -29647,6 +29665,7 @@ function StudioRoom({
|
|
|
29647
29665
|
}
|
|
29648
29666
|
if (sessionOver) {
|
|
29649
29667
|
const canRejoin = session.role === "moderator" && onRejoin != null && isStudioActiveStatus(session.stream.status);
|
|
29668
|
+
const returnHref = canRejoin || session.role !== "moderator" ? void 0 : endedHref?.trim() || `/streams/${session.stream.id}`;
|
|
29650
29669
|
return withStudioToaster(
|
|
29651
29670
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-dvh flex-col items-center justify-center p-6", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29652
29671
|
EmptyState,
|
|
@@ -29655,7 +29674,8 @@ function StudioRoom({
|
|
|
29655
29674
|
description: labels.endedDescription,
|
|
29656
29675
|
actionLabel: canRejoin ? labels.rejoin : session.role === "moderator" ? labels.endedAction : void 0,
|
|
29657
29676
|
onAction: canRejoin ? onRejoin : void 0,
|
|
29658
|
-
actionHref:
|
|
29677
|
+
actionHref: returnHref,
|
|
29678
|
+
extra: returnHref ? endedExtra : void 0
|
|
29659
29679
|
}
|
|
29660
29680
|
) })
|
|
29661
29681
|
);
|
|
@@ -30263,7 +30283,8 @@ var LOBBY_DEVICE_LABEL_DEFAULTS = {
|
|
|
30263
30283
|
speakerDevice: "Speaker",
|
|
30264
30284
|
testSpeaker: "Test",
|
|
30265
30285
|
testSpeakerError: "Could not play the speaker test",
|
|
30266
|
-
cameraOff: "Camera is off"
|
|
30286
|
+
cameraOff: "Camera is off",
|
|
30287
|
+
joining: "Joining\u2026"
|
|
30267
30288
|
};
|
|
30268
30289
|
function StudioGuestLobby({
|
|
30269
30290
|
reducedMotion,
|
|
@@ -30298,7 +30319,9 @@ function StudioGuestLobby({
|
|
|
30298
30319
|
testSpeakerError: labels.testSpeakerError ?? LOBBY_DEVICE_LABEL_DEFAULTS.testSpeakerError,
|
|
30299
30320
|
cameraOff: labels.cameraOff ?? LOBBY_DEVICE_LABEL_DEFAULTS.cameraOff
|
|
30300
30321
|
};
|
|
30322
|
+
const joiningLabel = labels.joining?.trim() || LOBBY_DEVICE_LABEL_DEFAULTS.joining;
|
|
30301
30323
|
function changeDevice(kind, deviceId) {
|
|
30324
|
+
if (joining) return;
|
|
30302
30325
|
persistStudioDeviceSelection(kind, deviceId);
|
|
30303
30326
|
onDeviceChange?.(kind, deviceId);
|
|
30304
30327
|
if (!savedDevices) {
|
|
@@ -30306,7 +30329,7 @@ function StudioGuestLobby({
|
|
|
30306
30329
|
}
|
|
30307
30330
|
}
|
|
30308
30331
|
async function onTestSpeaker() {
|
|
30309
|
-
if (testingSpeaker) return;
|
|
30332
|
+
if (testingSpeaker || joining) return;
|
|
30310
30333
|
const speakerId = effective.speaker || devices.speaker[0]?.deviceId || void 0;
|
|
30311
30334
|
setTestingSpeaker(true);
|
|
30312
30335
|
try {
|
|
@@ -30345,6 +30368,7 @@ function StudioGuestLobby({
|
|
|
30345
30368
|
size: "icon-lg",
|
|
30346
30369
|
"aria-pressed": muted,
|
|
30347
30370
|
"aria-label": labels.mic,
|
|
30371
|
+
disabled: joining,
|
|
30348
30372
|
onClick: () => onMutedChange(!muted),
|
|
30349
30373
|
children: muted ? /* @__PURE__ */ jsxRuntime.jsx(MicOff, {}) : /* @__PURE__ */ jsxRuntime.jsx(Mic, {})
|
|
30350
30374
|
}
|
|
@@ -30357,6 +30381,7 @@ function StudioGuestLobby({
|
|
|
30357
30381
|
size: "icon-lg",
|
|
30358
30382
|
"aria-pressed": cameraOn,
|
|
30359
30383
|
"aria-label": labels.camera,
|
|
30384
|
+
disabled: joining,
|
|
30360
30385
|
onClick: () => onCameraChange(!cameraOn),
|
|
30361
30386
|
children: cameraOn ? /* @__PURE__ */ jsxRuntime.jsx(Video, {}) : /* @__PURE__ */ jsxRuntime.jsx(VideoOff, {})
|
|
30362
30387
|
}
|
|
@@ -30368,6 +30393,7 @@ function StudioGuestLobby({
|
|
|
30368
30393
|
devices,
|
|
30369
30394
|
selected: effective,
|
|
30370
30395
|
labels: deviceLabels,
|
|
30396
|
+
disabled: joining,
|
|
30371
30397
|
onChange: changeDevice,
|
|
30372
30398
|
speakerAction: /* @__PURE__ */ jsxRuntime.jsx(
|
|
30373
30399
|
Button3,
|
|
@@ -30375,7 +30401,7 @@ function StudioGuestLobby({
|
|
|
30375
30401
|
type: "button",
|
|
30376
30402
|
size: "sm",
|
|
30377
30403
|
variant: "outline",
|
|
30378
|
-
disabled: testingSpeaker,
|
|
30404
|
+
disabled: testingSpeaker || joining,
|
|
30379
30405
|
onClick: () => void onTestSpeaker(),
|
|
30380
30406
|
children: deviceLabels.testSpeaker
|
|
30381
30407
|
}
|
|
@@ -30393,6 +30419,7 @@ function StudioGuestLobby({
|
|
|
30393
30419
|
onChange: (event) => onDisplayNameChange(event.target.value),
|
|
30394
30420
|
maxLength: 80,
|
|
30395
30421
|
required: true,
|
|
30422
|
+
disabled: joining,
|
|
30396
30423
|
autoComplete: "name"
|
|
30397
30424
|
}
|
|
30398
30425
|
)
|
|
@@ -30406,8 +30433,18 @@ function StudioGuestLobby({
|
|
|
30406
30433
|
size: "lg",
|
|
30407
30434
|
className: "w-full",
|
|
30408
30435
|
disabled: joining || showName && !displayName.trim(),
|
|
30436
|
+
"aria-busy": joining,
|
|
30409
30437
|
onClick: onJoin,
|
|
30410
|
-
children:
|
|
30438
|
+
children: joining ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
30439
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
30440
|
+
LoaderCircle,
|
|
30441
|
+
{
|
|
30442
|
+
"aria-hidden": true,
|
|
30443
|
+
className: "animate-spin motion-reduce:animate-none"
|
|
30444
|
+
}
|
|
30445
|
+
),
|
|
30446
|
+
joiningLabel
|
|
30447
|
+
] }) : waitingForHost ? labels.waitingForHost : labels.join
|
|
30411
30448
|
}
|
|
30412
30449
|
)
|
|
30413
30450
|
] });
|
|
@@ -30722,6 +30759,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30722
30759
|
const chatSend = /* @__PURE__ */ new Map();
|
|
30723
30760
|
const nameOverrides = /* @__PURE__ */ new Map();
|
|
30724
30761
|
let joinStageInFlight = null;
|
|
30762
|
+
let leaveInProgress = false;
|
|
30725
30763
|
let joinedStageLocally = false;
|
|
30726
30764
|
let stageGrantPending = false;
|
|
30727
30765
|
let stageGrantJoinFailures = 0;
|
|
@@ -30835,6 +30873,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30835
30873
|
for (const listener of stageGrantListeners) listener(userId);
|
|
30836
30874
|
}
|
|
30837
30875
|
function markStageGranted() {
|
|
30876
|
+
if (leaveInProgress) return;
|
|
30838
30877
|
stageGrantPending = true;
|
|
30839
30878
|
void ensureStageJoined();
|
|
30840
30879
|
}
|
|
@@ -30882,6 +30921,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30882
30921
|
async function runJoinStageAttempts() {
|
|
30883
30922
|
let lastError;
|
|
30884
30923
|
for (let attempt = 0; attempt < STAGE_JOIN_MAX_ATTEMPTS; attempt++) {
|
|
30924
|
+
if (leaveInProgress) return;
|
|
30885
30925
|
if (currentStageStatus() === "ON_STAGE") {
|
|
30886
30926
|
notifyStage();
|
|
30887
30927
|
return;
|
|
@@ -30930,6 +30970,7 @@ function studioMeetingFromRtk(raw) {
|
|
|
30930
30970
|
}
|
|
30931
30971
|
}
|
|
30932
30972
|
async function ensureStageJoined() {
|
|
30973
|
+
if (leaveInProgress) return;
|
|
30933
30974
|
if (currentStageStatus() === "ON_STAGE") {
|
|
30934
30975
|
clearStageGrantPending();
|
|
30935
30976
|
return;
|
|
@@ -31066,10 +31107,29 @@ function studioMeetingFromRtk(raw) {
|
|
|
31066
31107
|
await applyCurrentVideoEffects();
|
|
31067
31108
|
},
|
|
31068
31109
|
async leave() {
|
|
31069
|
-
|
|
31070
|
-
|
|
31110
|
+
leaveInProgress = true;
|
|
31111
|
+
clearStageGrantPending();
|
|
31112
|
+
try {
|
|
31113
|
+
if (typeof window !== "undefined") {
|
|
31114
|
+
window.removeEventListener(
|
|
31115
|
+
"unhandledrejection",
|
|
31116
|
+
onUnhandledRejection
|
|
31117
|
+
);
|
|
31118
|
+
}
|
|
31119
|
+
let firstFailed = false;
|
|
31120
|
+
try {
|
|
31121
|
+
await meeting.leave?.();
|
|
31122
|
+
} catch {
|
|
31123
|
+
firstFailed = true;
|
|
31124
|
+
}
|
|
31125
|
+
const roomState = meeting.self?.roomState ?? null;
|
|
31126
|
+
if (firstFailed || roomState === "joined" || roomState === "stageLeft") {
|
|
31127
|
+
await meeting.leave?.();
|
|
31128
|
+
}
|
|
31129
|
+
} finally {
|
|
31130
|
+
clearStageGrantPending();
|
|
31131
|
+
leaveInProgress = false;
|
|
31071
31132
|
}
|
|
31072
|
-
await meeting.leave?.();
|
|
31073
31133
|
},
|
|
31074
31134
|
async setAudioEnabled(enabled) {
|
|
31075
31135
|
if (enabled) await meeting.self?.enableAudio?.();
|
|
@@ -31682,7 +31742,8 @@ function LivoHostStudio({
|
|
|
31682
31742
|
theme,
|
|
31683
31743
|
appDownloadUrl,
|
|
31684
31744
|
guestUrl,
|
|
31685
|
-
endedHref
|
|
31745
|
+
endedHref,
|
|
31746
|
+
endedExtra
|
|
31686
31747
|
}) {
|
|
31687
31748
|
const reducedMotion = usePrefersReducedMotion();
|
|
31688
31749
|
const [session, setSession] = React18.useState(null);
|
|
@@ -31804,7 +31865,8 @@ function LivoHostStudio({
|
|
|
31804
31865
|
playerOrigin,
|
|
31805
31866
|
appDownloadUrl,
|
|
31806
31867
|
apiUrl,
|
|
31807
|
-
endedHref
|
|
31868
|
+
endedHref,
|
|
31869
|
+
endedExtra
|
|
31808
31870
|
}
|
|
31809
31871
|
) });
|
|
31810
31872
|
}
|
|
@@ -31844,6 +31906,9 @@ function LivoGuestStudio({
|
|
|
31844
31906
|
session?.authToken ?? null,
|
|
31845
31907
|
sessionGen
|
|
31846
31908
|
);
|
|
31909
|
+
React18.useEffect(() => {
|
|
31910
|
+
if (meeting) setJoining(false);
|
|
31911
|
+
}, [meeting]);
|
|
31847
31912
|
React18.useEffect(() => {
|
|
31848
31913
|
const identity = readStudioGuestIdentity();
|
|
31849
31914
|
setDisplayName(identity.displayName);
|
|
@@ -31876,6 +31941,7 @@ function LivoGuestStudio({
|
|
|
31876
31941
|
setStatus(null);
|
|
31877
31942
|
setSession(next);
|
|
31878
31943
|
} catch (err) {
|
|
31944
|
+
setJoining(false);
|
|
31879
31945
|
const code = studioErrorCode(err);
|
|
31880
31946
|
if (code === "studio_not_started") {
|
|
31881
31947
|
setWaitingForHost(true);
|
|
@@ -31892,7 +31958,6 @@ function LivoGuestStudio({
|
|
|
31892
31958
|
}
|
|
31893
31959
|
} finally {
|
|
31894
31960
|
joinInFlight.current = false;
|
|
31895
|
-
setJoining(false);
|
|
31896
31961
|
}
|
|
31897
31962
|
}, [apiUrl, displayName, guestId, lobbyLabels, token]);
|
|
31898
31963
|
React18.useEffect(() => {
|
|
@@ -32154,6 +32219,10 @@ function studioRoomLabels(t) {
|
|
|
32154
32219
|
shareRequestTimeout: t("shareRequestTimeout"),
|
|
32155
32220
|
shareRespondError: t("shareRespondError"),
|
|
32156
32221
|
goOffAir: t("goOffAir"),
|
|
32222
|
+
moveToAudience: t("moveToAudience"),
|
|
32223
|
+
moveToAudienceTitle: t("moveToAudienceTitle"),
|
|
32224
|
+
moveToAudienceDescription: t("moveToAudienceDescription"),
|
|
32225
|
+
moveToAudienceConfirm: t("moveToAudienceConfirm"),
|
|
32157
32226
|
goOnAir: t("goOnAir"),
|
|
32158
32227
|
takeOffAir: t("takeOffAir"),
|
|
32159
32228
|
bringOnAir: t("bringOnAir"),
|