@q9labsai/chalk-react 5.2.1 → 5.2.3
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 +9 -1
- package/dist/{chunk-RQXFFDOS.js → chunk-34SIWIY5.js} +350 -332
- package/dist/{chunk-53ZA776J.js → chunk-IZ44PX4W.js} +2 -1
- package/dist/components/index.js +2 -2
- package/dist/components/participant-tile/ParticipantTile.d.ts +2 -3
- package/dist/components/participants-panel/ParticipantsPanel.d.ts +2 -1
- package/dist/components/participants-panel/participant-row.d.ts +2 -1
- package/dist/components/space-view/SpaceView.d.ts +1 -0
- package/dist/components/stage/SpaceStage.d.ts +3 -1
- package/dist/components/stage/Stage.d.ts +2 -3
- package/dist/index.js +2 -2
- package/dist/internal/sound-cues.d.ts +1 -1
- package/dist/test-support/index.js +1 -1
- package/package.json +5 -5
|
@@ -866,7 +866,7 @@ function MediaRequestDialog({ request, onDecline, onAllow, onActionError }) {
|
|
|
866
866
|
}
|
|
867
867
|
|
|
868
868
|
// src/components/admission-panel/AdmissionPanel.tsx
|
|
869
|
-
import React8, { useEffect as useEffect10, useState as
|
|
869
|
+
import React8, { useEffect as useEffect10, useState as useState13 } from "react";
|
|
870
870
|
import { IconButton, Spinner } from "@q9labsai/chalk-ui";
|
|
871
871
|
|
|
872
872
|
// src/components/audio-output/AudioOutput.tsx
|
|
@@ -1226,7 +1226,7 @@ function useHaptics({ enabled = true } = {}) {
|
|
|
1226
1226
|
|
|
1227
1227
|
// src/components/participant-tile/ParticipantTile.tsx
|
|
1228
1228
|
import { Facehash as Facehash2 } from "@q9labsai/facehash/react";
|
|
1229
|
-
import React5, { useMemo as useMemo6, useRef as useRef6
|
|
1229
|
+
import React5, { useMemo as useMemo6, useRef as useRef6 } from "react";
|
|
1230
1230
|
|
|
1231
1231
|
// src/internal/useMirrorSetting.ts
|
|
1232
1232
|
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
@@ -1478,7 +1478,7 @@ var ParticipantTileSurface = React5.memo(function ParticipantTileSurface2({
|
|
|
1478
1478
|
onClick,
|
|
1479
1479
|
onDoubleClick,
|
|
1480
1480
|
pinned,
|
|
1481
|
-
|
|
1481
|
+
onFollow,
|
|
1482
1482
|
following = false,
|
|
1483
1483
|
primary,
|
|
1484
1484
|
className,
|
|
@@ -1492,34 +1492,24 @@ var ParticipantTileSurface = React5.memo(function ParticipantTileSurface2({
|
|
|
1492
1492
|
}) {
|
|
1493
1493
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
1494
1494
|
const phone = useMediaQuery("(max-width:640px)");
|
|
1495
|
-
const [optionsOpen, setOptionsOpen] = useState12(false);
|
|
1496
|
-
const returnFocus = useRef6(null);
|
|
1497
|
-
const openOptions = () => {
|
|
1498
|
-
returnFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
1499
|
-
setOptionsOpen(true);
|
|
1500
|
-
};
|
|
1501
|
-
const closeOptions = () => {
|
|
1502
|
-
setOptionsOpen(false);
|
|
1503
|
-
queueMicrotask(() => returnFocus.current?.focus());
|
|
1504
|
-
};
|
|
1505
1495
|
const [localMirrored] = useMirrorSetting();
|
|
1506
1496
|
const mirrored = mirror ?? (participant.isLocal === true && localMirrored);
|
|
1507
1497
|
const colors = useMemo6(() => getParticipantColor(participant.displayName || participant.id, gradientPreference), [gradientPreference, participant.displayName, participant.id]);
|
|
1508
1498
|
const recipe = useMemo6(() => getParticipantAvatarRecipe(participant.displayName || participant.id, gradientPreference), [participant.displayName, participant.id, gradientPreference]);
|
|
1509
|
-
const
|
|
1510
|
-
const
|
|
1499
|
+
const actionLabel = `${pinned ? "Unpin" : "Pin"} ${participant.displayName}`;
|
|
1500
|
+
const followLabel = following ? "Stop following" : "Follow";
|
|
1511
1501
|
const hasPoorConnection = participant.connectionQuality !== void 0 && participant.connectionQuality > 0 && participant.connectionQuality <= 2;
|
|
1512
1502
|
return /* @__PURE__ */ jsxs12(
|
|
1513
1503
|
TileShell,
|
|
1514
1504
|
{
|
|
1515
|
-
label:
|
|
1505
|
+
label: `Video tile for ${participant.displayName}`,
|
|
1516
1506
|
accentColor: colors.primary,
|
|
1517
|
-
pinned
|
|
1507
|
+
pinned,
|
|
1518
1508
|
ring: following,
|
|
1519
1509
|
lift: !primary,
|
|
1520
1510
|
speaking: mediaVisible && participant.isSpeaking && !participant.isMuted,
|
|
1521
1511
|
audioLevel: participant.audioLevel,
|
|
1522
|
-
onClick
|
|
1512
|
+
onClick,
|
|
1523
1513
|
onDoubleClick,
|
|
1524
1514
|
className: cn(aspectRatioClasses[aspectRatio], className),
|
|
1525
1515
|
style,
|
|
@@ -1527,11 +1517,14 @@ var ParticipantTileSurface = React5.memo(function ParticipantTileSurface2({
|
|
|
1527
1517
|
hidden,
|
|
1528
1518
|
corner: /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
1529
1519
|
showStatus && hasPoorConnection ? /* @__PURE__ */ jsx27("span", { role: "img", "data-part": "tile-signal", "aria-label": `${participant.displayName} has a weak connection`, className: "pointer-events-none absolute top-2 left-2 z-30 flex h-6 items-center rounded-[6px] bg-[rgba(12,14,18,.75)] px-[7px]", children: /* @__PURE__ */ jsx27(SignalBars, {}) }) : null,
|
|
1530
|
-
onClick
|
|
1520
|
+
onClick || onFollow ? /* @__PURE__ */ jsx27("span", { "data-part": "tile-menu", className: "absolute top-2 right-2 z-30 transition-opacity duration-150 min-[641px]:opacity-0 group-hover/tile:opacity-100 focus-within:opacity-100", children: /* @__PURE__ */ jsxs12(
|
|
1531
1521
|
ChalkMenu,
|
|
1532
1522
|
{
|
|
1533
1523
|
trigger: /* @__PURE__ */ jsx27("button", { type: "button", "aria-label": `More options for ${participant.displayName}`, className: "grid h-8 w-8 place-items-center rounded-full bg-[rgba(12,14,18,.75)] text-white outline-none hover:bg-[rgba(40,42,48,.95)] focus-visible:ring-2 focus-visible:ring-[var(--chalk-focus)]", children: /* @__PURE__ */ jsx27(StageIcon, { name: "more", size: 18 }) }),
|
|
1534
|
-
children:
|
|
1524
|
+
children: [
|
|
1525
|
+
onClick ? /* @__PURE__ */ jsx27(ChalkMenuItem, { onClick, children: actionLabel }) : null,
|
|
1526
|
+
onFollow ? /* @__PURE__ */ jsx27(ChalkMenuItem, { onClick: onFollow, children: followLabel }) : null
|
|
1527
|
+
]
|
|
1535
1528
|
}
|
|
1536
1529
|
) }) : null
|
|
1537
1530
|
] }),
|
|
@@ -1571,38 +1564,6 @@ var ParticipantTileSurface = React5.memo(function ParticipantTileSurface2({
|
|
|
1571
1564
|
colors: recipe.facehashColors
|
|
1572
1565
|
}
|
|
1573
1566
|
) : /* @__PURE__ */ jsx27(Avatar, { name: participant.displayName, src: participant.avatarUrl, size: "xl", generated: false, style: { width: "100%", height: "100%" } }) }) }),
|
|
1574
|
-
phone && onClick && clickAction === "pin" ? /* @__PURE__ */ jsxs12(
|
|
1575
|
-
ChalkSheet,
|
|
1576
|
-
{
|
|
1577
|
-
open: optionsOpen,
|
|
1578
|
-
onOpenChange: (open) => {
|
|
1579
|
-
if (open) openOptions();
|
|
1580
|
-
else closeOptions();
|
|
1581
|
-
},
|
|
1582
|
-
title: `Options for ${participant.displayName}`,
|
|
1583
|
-
children: [
|
|
1584
|
-
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3 px-2 pt-1 pb-3.5 text-base font-semibold", children: [
|
|
1585
|
-
/* @__PURE__ */ jsx27(Avatar, { name: participant.displayName, size: "sm" }),
|
|
1586
|
-
participant.displayName
|
|
1587
|
-
] }),
|
|
1588
|
-
/* @__PURE__ */ jsxs12(
|
|
1589
|
-
"button",
|
|
1590
|
-
{
|
|
1591
|
-
type: "button",
|
|
1592
|
-
className: "flex min-h-[52px] w-full items-center gap-3.5 rounded-[16px] bg-[var(--chalk-raised)] px-4 text-left text-base leading-[1.4] hover:bg-[var(--chalk-hover)] active:bg-[var(--chalk-pressed)]",
|
|
1593
|
-
onClick: () => {
|
|
1594
|
-
onClick();
|
|
1595
|
-
closeOptions();
|
|
1596
|
-
},
|
|
1597
|
-
children: [
|
|
1598
|
-
/* @__PURE__ */ jsx27(StageIcon, { name: "pin", size: 20, className: "text-[var(--chalk-soft-text)]" }),
|
|
1599
|
-
/* @__PURE__ */ jsx27("span", { children: pinned ? "Unpin" : "Pin" })
|
|
1600
|
-
]
|
|
1601
|
-
}
|
|
1602
|
-
)
|
|
1603
|
-
]
|
|
1604
|
-
}
|
|
1605
|
-
) : null,
|
|
1606
1567
|
children
|
|
1607
1568
|
]
|
|
1608
1569
|
}
|
|
@@ -1615,7 +1576,7 @@ function SignalBars() {
|
|
|
1615
1576
|
}
|
|
1616
1577
|
|
|
1617
1578
|
// src/components/atomic/ReactionBubble.tsx
|
|
1618
|
-
import React6, { useEffect as useEffect9, useState as
|
|
1579
|
+
import React6, { useEffect as useEffect9, useState as useState12, useMemo as useMemo7 } from "react";
|
|
1619
1580
|
import { CELEBRATION_EMOJIS } from "@q9labsai/chalk-ui/reactions";
|
|
1620
1581
|
import { jsx as jsx28, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1621
1582
|
var BASE_PARTICLE_COLORS = ["#14b8a6", "#f59e0b", "#ec4899", "#8b5cf6", "#06b6d4", "#22c55e"];
|
|
@@ -1659,7 +1620,7 @@ function getParticleStyle(particle) {
|
|
|
1659
1620
|
};
|
|
1660
1621
|
}
|
|
1661
1622
|
var ReactionBubble = React6.memo(({ emoji, participantName, onComplete, duration: baseDuration = 3e3, animated = true, className }) => {
|
|
1662
|
-
const [isVisible, setIsVisible] =
|
|
1623
|
+
const [isVisible, setIsVisible] = useState12(true);
|
|
1663
1624
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
1664
1625
|
const participantColors = useMemo7(() => getParticipantColor(participantName || "unknown"), [participantName]);
|
|
1665
1626
|
const isCelebration = CELEBRATION_EMOJIS.includes(emoji);
|
|
@@ -1747,13 +1708,13 @@ function getWaitingLabel(joinedAt) {
|
|
|
1747
1708
|
return `Waiting ${minutes} min`;
|
|
1748
1709
|
}
|
|
1749
1710
|
var AdmissionPanelSurface = React8.memo(({ participants, onAdmit, onDeny, onAdmitAll, onDenyAll, loading = false, className, onClose, inline = false }) => {
|
|
1750
|
-
const [, setTick] =
|
|
1711
|
+
const [, setTick] = useState13(0);
|
|
1751
1712
|
useEffect10(() => {
|
|
1752
1713
|
const timer = window.setInterval(() => setTick((t) => t + 1), 6e4);
|
|
1753
1714
|
return () => window.clearInterval(timer);
|
|
1754
1715
|
}, []);
|
|
1755
|
-
const [busy, setBusy] =
|
|
1756
|
-
const [error, setError] =
|
|
1716
|
+
const [busy, setBusy] = useState13(false);
|
|
1717
|
+
const [error, setError] = useState13(null);
|
|
1757
1718
|
const perform = async (action) => {
|
|
1758
1719
|
if (busy) return;
|
|
1759
1720
|
setBusy(true);
|
|
@@ -1826,7 +1787,7 @@ AdmissionPanel.displayName = "AdmissionPanel";
|
|
|
1826
1787
|
|
|
1827
1788
|
// src/components/composite/ChatPanel.tsx
|
|
1828
1789
|
import { CHALK_CHAT_ATTACHMENT_LIMITS, CHALK_CHAT_ATTACHMENT_MIME_TYPES } from "@q9labsai/chalk-client";
|
|
1829
|
-
import React10, { useEffect as useEffect13, useLayoutEffect, useMemo as useMemo8, useRef as useRef9, useState as
|
|
1790
|
+
import React10, { useEffect as useEffect13, useLayoutEffect, useMemo as useMemo8, useRef as useRef9, useState as useState16 } from "react";
|
|
1830
1791
|
import { Button } from "@q9labsai/chalk-ui";
|
|
1831
1792
|
|
|
1832
1793
|
// src/components/call-card/CallCardStyles.tsx
|
|
@@ -2689,14 +2650,14 @@ function CallCardStyles() {
|
|
|
2689
2650
|
|
|
2690
2651
|
// src/components/composite/MessageBubble.tsx
|
|
2691
2652
|
import { CHALK_REACTIONS } from "@q9labsai/chalk-client";
|
|
2692
|
-
import React9, { useEffect as useEffect12, useRef as useRef8, useState as
|
|
2653
|
+
import React9, { useEffect as useEffect12, useRef as useRef8, useState as useState15 } from "react";
|
|
2693
2654
|
|
|
2694
2655
|
// src/components/composite/use-chat-attachment-previews.ts
|
|
2695
|
-
import { useCallback as useCallback4, useEffect as useEffect11, useRef as useRef7, useState as
|
|
2656
|
+
import { useCallback as useCallback4, useEffect as useEffect11, useRef as useRef7, useState as useState14 } from "react";
|
|
2696
2657
|
function useChatAttachmentPreviews(attachments, resolveUrl) {
|
|
2697
|
-
const [resolvedUrls, setResolvedUrls] =
|
|
2698
|
-
const [failedAttachmentIds, setFailedAttachmentIds] =
|
|
2699
|
-
const [retryGeneration, setRetryGeneration] =
|
|
2658
|
+
const [resolvedUrls, setResolvedUrls] = useState14(() => /* @__PURE__ */ new Map());
|
|
2659
|
+
const [failedAttachmentIds, setFailedAttachmentIds] = useState14(() => /* @__PURE__ */ new Set());
|
|
2660
|
+
const [retryGeneration, setRetryGeneration] = useState14(0);
|
|
2700
2661
|
const resolvingAttachmentIds = useRef7(/* @__PURE__ */ new Set());
|
|
2701
2662
|
const resolvedUrlsRef = useRef7(resolvedUrls);
|
|
2702
2663
|
const failedAttachmentIdsRef = useRef7(failedAttachmentIds);
|
|
@@ -2779,9 +2740,9 @@ var MessageBubble = React9.memo(
|
|
|
2779
2740
|
className
|
|
2780
2741
|
}) => {
|
|
2781
2742
|
const { resolvedUrls, failedAttachmentIds, markFailed, retry } = useChatAttachmentPreviews(attachments, onResolveAttachmentUrl);
|
|
2782
|
-
const [reactionError, setReactionError] =
|
|
2783
|
-
const [reacting, setReacting] =
|
|
2784
|
-
const [reactionBarOpen, setReactionBarOpen] =
|
|
2743
|
+
const [reactionError, setReactionError] = useState15(null);
|
|
2744
|
+
const [reacting, setReacting] = useState15(false);
|
|
2745
|
+
const [reactionBarOpen, setReactionBarOpen] = useState15(false);
|
|
2785
2746
|
const messageRef = useRef8(null);
|
|
2786
2747
|
const press = useRef8(null);
|
|
2787
2748
|
const cancelPress = () => {
|
|
@@ -2798,9 +2759,9 @@ var MessageBubble = React9.memo(
|
|
|
2798
2759
|
document.addEventListener("pointerdown", dismiss);
|
|
2799
2760
|
return () => document.removeEventListener("pointerdown", dismiss);
|
|
2800
2761
|
}, [reactionBarOpen]);
|
|
2801
|
-
const [photo, setPhoto] =
|
|
2802
|
-
const [downloading, setDownloading] =
|
|
2803
|
-
const [downloadError, setDownloadError] =
|
|
2762
|
+
const [photo, setPhoto] = useState15(null);
|
|
2763
|
+
const [downloading, setDownloading] = useState15(false);
|
|
2764
|
+
const [downloadError, setDownloadError] = useState15(null);
|
|
2804
2765
|
const downloadController = useRef8(null);
|
|
2805
2766
|
useEffect12(() => () => downloadController.current?.abort(), []);
|
|
2806
2767
|
const downloadPhoto = async () => {
|
|
@@ -2832,7 +2793,7 @@ var MessageBubble = React9.memo(
|
|
|
2832
2793
|
downloadController.current = null;
|
|
2833
2794
|
}
|
|
2834
2795
|
};
|
|
2835
|
-
const [photoClosing, setPhotoClosing] =
|
|
2796
|
+
const [photoClosing, setPhotoClosing] = useState15(false);
|
|
2836
2797
|
const closeTimer = useRef8(null);
|
|
2837
2798
|
useEffect12(
|
|
2838
2799
|
() => () => {
|
|
@@ -3188,12 +3149,12 @@ var ChatPanelSurface = React10.memo(
|
|
|
3188
3149
|
autoScrollBehavior,
|
|
3189
3150
|
className
|
|
3190
3151
|
}) => {
|
|
3191
|
-
const [draft, setDraft] =
|
|
3192
|
-
const [stagedFiles, setStagedFiles] =
|
|
3152
|
+
const [draft, setDraft] = useState16("");
|
|
3153
|
+
const [stagedFiles, setStagedFiles] = useState16([]);
|
|
3193
3154
|
const uploads = useRef9(/* @__PURE__ */ new Map());
|
|
3194
|
-
const [failedUploads, setFailedUploads] =
|
|
3195
|
-
const [uploading, setUploading] =
|
|
3196
|
-
const [previews, setPreviews] =
|
|
3155
|
+
const [failedUploads, setFailedUploads] = useState16(/* @__PURE__ */ new Set());
|
|
3156
|
+
const [uploading, setUploading] = useState16(/* @__PURE__ */ new Set());
|
|
3157
|
+
const [previews, setPreviews] = useState16(/* @__PURE__ */ new Map());
|
|
3197
3158
|
useEffect13(() => {
|
|
3198
3159
|
const urls = new Map(stagedFiles.flatMap((file) => file instanceof File && file.type.startsWith("image/") ? [[file, URL.createObjectURL(file)]] : []));
|
|
3199
3160
|
setPreviews(urls);
|
|
@@ -3201,9 +3162,9 @@ var ChatPanelSurface = React10.memo(
|
|
|
3201
3162
|
for (const url of urls.values()) URL.revokeObjectURL(url);
|
|
3202
3163
|
};
|
|
3203
3164
|
}, [stagedFiles]);
|
|
3204
|
-
const [sending, setSending] =
|
|
3205
|
-
const [pickingFiles, setPickingFiles] =
|
|
3206
|
-
const [composerError, setComposerError] =
|
|
3165
|
+
const [sending, setSending] = useState16(false);
|
|
3166
|
+
const [pickingFiles, setPickingFiles] = useState16(false);
|
|
3167
|
+
const [composerError, setComposerError] = useState16(null);
|
|
3207
3168
|
const scrollRef = useRef9(null);
|
|
3208
3169
|
const textareaRef = useRef9(null);
|
|
3209
3170
|
const fileInputRef = useRef9(null);
|
|
@@ -3519,7 +3480,7 @@ var ChatPanel = React10.memo((props) => {
|
|
|
3519
3480
|
ChatPanel.displayName = "ChatPanel";
|
|
3520
3481
|
|
|
3521
3482
|
// src/components/composite/ReactionsOverlay.tsx
|
|
3522
|
-
import { useEffect as useEffect14, useRef as useRef10, useState as
|
|
3483
|
+
import { useEffect as useEffect14, useRef as useRef10, useState as useState17 } from "react";
|
|
3523
3484
|
import { createPortal } from "react-dom";
|
|
3524
3485
|
|
|
3525
3486
|
// src/components/composite/reaction-float.ts
|
|
@@ -3563,7 +3524,7 @@ function ReactionsOverlaySurface({ reactions, maxVisible = 6, className }) {
|
|
|
3563
3524
|
return /* @__PURE__ */ jsx34("div", { ref: root, className: cn("pointer-events-none absolute inset-0 z-30", className), "aria-live": "polite", "aria-atomic": "false", children: reactions.slice(-maxVisible).map((reaction) => /* @__PURE__ */ jsx34(TileReaction, { reaction, root }, reaction.eventId)) });
|
|
3564
3525
|
}
|
|
3565
3526
|
function TileReaction({ reaction, root }) {
|
|
3566
|
-
const [host, setHost] =
|
|
3527
|
+
const [host, setHost] = useState17(null);
|
|
3567
3528
|
const emoji = useRef10(null);
|
|
3568
3529
|
const reduced = usePrefersReducedMotion();
|
|
3569
3530
|
useEffect14(() => {
|
|
@@ -3609,10 +3570,10 @@ function CommandErrorAlert({ message }) {
|
|
|
3609
3570
|
}
|
|
3610
3571
|
|
|
3611
3572
|
// src/components/control-bar/ControlBar.tsx
|
|
3612
|
-
import React12, { useEffect as useEffect17, useRef as useRef12, useState as
|
|
3573
|
+
import React12, { useEffect as useEffect17, useRef as useRef12, useState as useState22 } from "react";
|
|
3613
3574
|
|
|
3614
3575
|
// src/components/device-popover/DevicePopover.tsx
|
|
3615
|
-
import { useEffect as useEffect15, useRef as useRef11, useState as
|
|
3576
|
+
import { useEffect as useEffect15, useRef as useRef11, useState as useState18 } from "react";
|
|
3616
3577
|
|
|
3617
3578
|
// src/components/control-bar/ShellIcon.tsx
|
|
3618
3579
|
import { Fragment as Fragment11, jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
@@ -4271,7 +4232,7 @@ var CALL_SHELL_CSS = `.chalk-shell-dock {
|
|
|
4271
4232
|
// src/components/device-popover/DevicePopover.tsx
|
|
4272
4233
|
import { Fragment as Fragment12, jsx as jsx38, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4273
4234
|
function InputLevel({ track }) {
|
|
4274
|
-
const [level, setLevel] =
|
|
4235
|
+
const [level, setLevel] = useState18(0);
|
|
4275
4236
|
useEffect15(() => {
|
|
4276
4237
|
if (!track || track.readyState !== "live") return;
|
|
4277
4238
|
const context = new AudioContext();
|
|
@@ -4295,7 +4256,7 @@ function InputLevel({ track }) {
|
|
|
4295
4256
|
}
|
|
4296
4257
|
function CameraPreview({ track, mirrored, open, selectedDeviceId, captureCameraPreview }) {
|
|
4297
4258
|
const video = useRef11(null);
|
|
4298
|
-
const [unavailable2, setUnavailable] =
|
|
4259
|
+
const [unavailable2, setUnavailable] = useState18(false);
|
|
4299
4260
|
const trackEnabled = track?.enabled;
|
|
4300
4261
|
useEffect15(() => {
|
|
4301
4262
|
const element = video.current;
|
|
@@ -4364,7 +4325,7 @@ function DevicePopover({
|
|
|
4364
4325
|
toggleDisabled,
|
|
4365
4326
|
busy
|
|
4366
4327
|
}) {
|
|
4367
|
-
const [open, setOpen] =
|
|
4328
|
+
const [open, setOpen] = useState18(false);
|
|
4368
4329
|
const mic = type === "mic";
|
|
4369
4330
|
const label = mic ? isActive ? "Mute microphone" : "Unmute microphone" : isActive ? "Turn off camera" : "Turn on camera";
|
|
4370
4331
|
return /* @__PURE__ */ jsxs20("div", { "data-part": `${type}-split`, className: cn("chalk-shell-split", className), "data-off": !isActive, children: [
|
|
@@ -4431,10 +4392,10 @@ function LeaveMenu({ onLeave, onEndForEveryone, renderButton }) {
|
|
|
4431
4392
|
}
|
|
4432
4393
|
|
|
4433
4394
|
// src/components/control-bar/DockLayout.tsx
|
|
4434
|
-
import { useState as
|
|
4395
|
+
import { useState as useState19 } from "react";
|
|
4435
4396
|
import { Fragment as Fragment13, jsx as jsx41, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4436
4397
|
function DockLayout({ layout, onLayoutChange, children }) {
|
|
4437
|
-
const [open, setOpen] =
|
|
4398
|
+
const [open, setOpen] = useState19(false);
|
|
4438
4399
|
return /* @__PURE__ */ jsxs23(Fragment13, { children: [
|
|
4439
4400
|
/* @__PURE__ */ jsx41(ChalkIconButton, { size: "lg", "aria-label": "More options", "aria-haspopup": "dialog", "aria-expanded": open, onClick: () => setOpen(true), children: /* @__PURE__ */ jsx41("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx41("path", { "data-part": "dock-more-glyph", d: "M5 12h.01M12 12h.01M19 12h.01", strokeWidth: "3" }) }) }),
|
|
4440
4401
|
/* @__PURE__ */ jsx41(ChalkSheet, { title: "More options", open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs23(
|
|
@@ -4475,7 +4436,7 @@ function DockLayout({ layout, onLayoutChange, children }) {
|
|
|
4475
4436
|
}
|
|
4476
4437
|
|
|
4477
4438
|
// src/components/control-bar/ShareControl.tsx
|
|
4478
|
-
import { useState as
|
|
4439
|
+
import { useState as useState20 } from "react";
|
|
4479
4440
|
import { Fragment as Fragment14, jsx as jsx42, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4480
4441
|
function SourceIcon({ source }) {
|
|
4481
4442
|
return /* @__PURE__ */ jsx42("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: source === "monitor" ? /* @__PURE__ */ jsxs24(Fragment14, { children: [
|
|
@@ -4490,9 +4451,9 @@ function SourceIcon({ source }) {
|
|
|
4490
4451
|
] }) });
|
|
4491
4452
|
}
|
|
4492
4453
|
function ShareControl({ sharing, onToggle, onStart, disabled = false, startDisabled = false }) {
|
|
4493
|
-
const [surface, setSurface] =
|
|
4494
|
-
const [audio, setAudio] =
|
|
4495
|
-
const [replace, setReplace] =
|
|
4454
|
+
const [surface, setSurface] = useState20("window");
|
|
4455
|
+
const [audio, setAudio] = useState20(true);
|
|
4456
|
+
const [replace, setReplace] = useState20(false);
|
|
4496
4457
|
const start2 = (next) => {
|
|
4497
4458
|
if (disabled || startDisabled) return;
|
|
4498
4459
|
setSurface(next);
|
|
@@ -4547,7 +4508,7 @@ function ShareControl({ sharing, onToggle, onStart, disabled = false, startDisab
|
|
|
4547
4508
|
}
|
|
4548
4509
|
|
|
4549
4510
|
// src/components/control-bar/control-bar-behavior.ts
|
|
4550
|
-
import { useCallback as useCallback5, useEffect as useEffect16, useMemo as useMemo9, useState as
|
|
4511
|
+
import { useCallback as useCallback5, useEffect as useEffect16, useMemo as useMemo9, useState as useState21 } from "react";
|
|
4551
4512
|
var DEFAULT_CONTROL_BAR_BUTTONS = ["mic", "video", "screenshare", "record", "whiteboard", "handraise", "leave", "participants", "chat", "reactions"];
|
|
4552
4513
|
var EMPTY_DETECTED_DEVICES = {
|
|
4553
4514
|
audioinput: [],
|
|
@@ -4584,7 +4545,7 @@ function useControlBarSurfaceBehavior({
|
|
|
4584
4545
|
detectDevices = true
|
|
4585
4546
|
}) {
|
|
4586
4547
|
const themeVariables = useMemo9(() => getParticipantThemeVariables(participantColorSeed, participantGradientPreference), [participantColorSeed, participantGradientPreference]);
|
|
4587
|
-
const [detectedDevices, setDetectedDevices] =
|
|
4548
|
+
const [detectedDevices, setDetectedDevices] = useState21(EMPTY_DETECTED_DEVICES);
|
|
4588
4549
|
const buttonsToRender = buttons ?? DEFAULT_CONTROL_BAR_BUTTONS;
|
|
4589
4550
|
useEffect16(() => {
|
|
4590
4551
|
if (!detectDevices || density !== "comfortable" || !navigator.mediaDevices?.enumerateDevices) return;
|
|
@@ -4643,10 +4604,10 @@ function useConnectedControlBarBehavior(props) {
|
|
|
4643
4604
|
const recordingStatus = recording.current?.status;
|
|
4644
4605
|
const isRecording = recordingStatus === "recording" || recordingStatus === "stopping";
|
|
4645
4606
|
const isRecordingPending = recordingStatus === "starting" || recordingStatus === "stopping";
|
|
4646
|
-
const [noiseSuppression, setNoiseSuppression] =
|
|
4647
|
-
const [commandError, setCommandError] =
|
|
4648
|
-
const [commandSource, setCommandSource] =
|
|
4649
|
-
const [commandAction, setCommandAction] =
|
|
4607
|
+
const [noiseSuppression, setNoiseSuppression] = useState21(true);
|
|
4608
|
+
const [commandError, setCommandError] = useState21(null);
|
|
4609
|
+
const [commandSource, setCommandSource] = useState21();
|
|
4610
|
+
const [commandAction, setCommandAction] = useState21();
|
|
4650
4611
|
const run = useCallback5(
|
|
4651
4612
|
async (command, source, action) => {
|
|
4652
4613
|
setCommandError(null);
|
|
@@ -4806,8 +4767,8 @@ function ControlBarPresentation(props) {
|
|
|
4806
4767
|
var ControlBarSurface = React12.memo((props) => {
|
|
4807
4768
|
const { buttonsToRender, effectiveAudioInputDevices, effectiveAudioOutputDevices, effectiveVideoInputDevices, showLeave } = useControlBarSurfaceBehavior({ ...props, density: props.density ?? "comfortable", detectDevices: props.detectDevices ?? true });
|
|
4808
4769
|
const dock = useRef12(null);
|
|
4809
|
-
const [fullscreen, setFullscreen] =
|
|
4810
|
-
const [canCaptureDisplay, setCanCaptureDisplay] =
|
|
4770
|
+
const [fullscreen, setFullscreen] = useState22(false);
|
|
4771
|
+
const [canCaptureDisplay, setCanCaptureDisplay] = useState22(false);
|
|
4811
4772
|
useEffect17(() => setCanCaptureDisplay(typeof navigator.mediaDevices?.getDisplayMedia === "function"), []);
|
|
4812
4773
|
useEffect17(() => {
|
|
4813
4774
|
const changed = () => setFullscreen(Boolean(document.fullscreenElement));
|
|
@@ -4958,10 +4919,10 @@ function ControlBar(props) {
|
|
|
4958
4919
|
}
|
|
4959
4920
|
|
|
4960
4921
|
// src/components/participants-panel/ParticipantsPanel.tsx
|
|
4961
|
-
import React13, { useMemo as useMemo10, useState as
|
|
4922
|
+
import React13, { useMemo as useMemo10, useState as useState24 } from "react";
|
|
4962
4923
|
|
|
4963
4924
|
// src/components/participants-panel/participant-row.tsx
|
|
4964
|
-
import { useState as
|
|
4925
|
+
import { useState as useState23, useRef as useRef13, useEffect as useEffect18 } from "react";
|
|
4965
4926
|
|
|
4966
4927
|
// src/components/participants-panel/participant-options-menu-contract.ts
|
|
4967
4928
|
function runParticipantAction(action, onClose, onCommandError) {
|
|
@@ -5129,14 +5090,15 @@ function ParticipantRow({
|
|
|
5129
5090
|
onCommandError,
|
|
5130
5091
|
participantVolumes,
|
|
5131
5092
|
onParticipantVolumeChange,
|
|
5093
|
+
onParticipantClick,
|
|
5132
5094
|
participantGradientPreference,
|
|
5133
5095
|
generatedAvatars = true,
|
|
5134
5096
|
menuOpen,
|
|
5135
5097
|
onMenuToggle,
|
|
5136
5098
|
onMenuClose
|
|
5137
5099
|
}) {
|
|
5138
|
-
const [isEditing, setIsEditing] =
|
|
5139
|
-
const [editName, setEditName] =
|
|
5100
|
+
const [isEditing, setIsEditing] = useState23(false);
|
|
5101
|
+
const [editName, setEditName] = useState23(participant.displayName);
|
|
5140
5102
|
const inputRef = useRef13(null);
|
|
5141
5103
|
const rootRef = useRef13(null);
|
|
5142
5104
|
const hasVolumeControl = !!participantVolumes && !!onParticipantVolumeChange;
|
|
@@ -5161,78 +5123,100 @@ function ParticipantRow({
|
|
|
5161
5123
|
}
|
|
5162
5124
|
};
|
|
5163
5125
|
const optionsButtonClassName = variant === "mobile" ? "text-[var(--chalk-app-text-muted)] hover:text-[var(--chalk-app-text)]" : variant === "sidebar" ? "opacity-70 text-[var(--chalk-app-text-muted)] hover:text-[var(--chalk-app-text)] hover:opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100";
|
|
5164
|
-
return /* @__PURE__ */ jsxs27(
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5126
|
+
return /* @__PURE__ */ jsxs27(
|
|
5127
|
+
"div",
|
|
5128
|
+
{
|
|
5129
|
+
ref: rootRef,
|
|
5130
|
+
className: "call-person-row group",
|
|
5131
|
+
onClick: (event) => {
|
|
5132
|
+
if (event.target instanceof Element && event.currentTarget.contains(event.target) && !event.target.closest("button, input, [role=menu]")) onParticipantClick?.(participant.id);
|
|
5133
|
+
},
|
|
5134
|
+
children: [
|
|
5135
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
|
|
5136
|
+
/* @__PURE__ */ jsx45("div", { className: "relative", children: /* @__PURE__ */ jsx45(Avatar, { name: participant.displayName, src: participant.avatarUrl, size: "sm", generated: generatedAvatars, className: "!h-8 !w-8", gradientPreference: participantGradientPreference }) }),
|
|
5137
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
5138
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-1.5 w-full", children: [
|
|
5139
|
+
isEditing ? /* @__PURE__ */ jsx45("div", { className: "flex items-center gap-1 flex-1", children: /* @__PURE__ */ jsx45(
|
|
5140
|
+
"input",
|
|
5141
|
+
{
|
|
5142
|
+
ref: inputRef,
|
|
5143
|
+
type: "text",
|
|
5144
|
+
"aria-label": "Your name",
|
|
5145
|
+
value: editName,
|
|
5146
|
+
onChange: (e) => setEditName(e.target.value),
|
|
5147
|
+
onKeyDown: handleKeyDown,
|
|
5148
|
+
onBlur: handleSave,
|
|
5149
|
+
className: "w-full min-w-0 rounded border border-[var(--chalk-app-control-active-line)]/30 bg-[var(--chalk-app-input)] px-1.5 py-0.5 text-sm font-normal text-[var(--chalk-app-text)] outline-none focus:border-[var(--chalk-app-control-active-line)]"
|
|
5150
|
+
}
|
|
5151
|
+
) }) : /* @__PURE__ */ jsx45(
|
|
5152
|
+
"button",
|
|
5153
|
+
{
|
|
5154
|
+
type: "button",
|
|
5155
|
+
className: "min-w-0 truncate text-left text-sm font-medium text-[var(--chalk-app-text)]",
|
|
5156
|
+
onClick: () => {
|
|
5157
|
+
if (onParticipantClick) onParticipantClick(participant.id);
|
|
5158
|
+
else if (participant.isLocal && onUpdateDisplayName) setIsEditing(true);
|
|
5159
|
+
},
|
|
5160
|
+
"aria-label": onParticipantClick ? `Show ${participant.displayName} on main screen` : participant.displayName,
|
|
5161
|
+
children: /* @__PURE__ */ jsx45("bdi", { children: participant.displayName })
|
|
5162
|
+
}
|
|
5163
|
+
),
|
|
5164
|
+
participant.isHost && !isEditing ? /* @__PURE__ */ jsx45("span", { className: "shrink-0 text-xs text-[var(--chalk-app-text-muted)]", children: "Host" }) : null,
|
|
5165
|
+
participant.isLocal && !isEditing && /* @__PURE__ */ jsxs27("span", { className: "flex shrink-0 items-center gap-1 text-xs text-[var(--chalk-app-text-muted)]", children: [
|
|
5166
|
+
"(You)",
|
|
5167
|
+
onUpdateDisplayName && /* @__PURE__ */ jsx45("button", { type: "button", onClick: () => setIsEditing(true), "aria-label": "Edit your name", className: "call-edit-name", children: /* @__PURE__ */ jsx45(Edit02Icon, { className: "w-3 h-3" }) })
|
|
5168
|
+
] })
|
|
5169
|
+
] }),
|
|
5170
|
+
/* @__PURE__ */ jsx45("div", { className: "flex items-center gap-1.5" })
|
|
5186
5171
|
] })
|
|
5187
5172
|
] }),
|
|
5188
|
-
/* @__PURE__ */
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
] });
|
|
5173
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
5174
|
+
participant.isMuted ? /* @__PURE__ */ jsx45(MicrophoneOff01Icon, { className: "h-4 w-4 text-[var(--chalk-danger-text)]", "aria-label": "Microphone off", role: "img" }) : null,
|
|
5175
|
+
participant.isHandRaised ? /* @__PURE__ */ jsxs27("span", { className: "call-hand", role: "img", "aria-label": `Hand raised${participant.handOrder ? `, number ${participant.handOrder}` : ""}`, children: [
|
|
5176
|
+
"\u270B",
|
|
5177
|
+
participant.handOrder
|
|
5178
|
+
] }) : null,
|
|
5179
|
+
!participant.isVideoEnabled ? /* @__PURE__ */ jsx45(VideoOffIcon, { className: "h-4 w-4 text-[var(--chalk-app-text-muted)]", "aria-label": "Camera off", role: "img" }) : null,
|
|
5180
|
+
showMenuButton && !isEditing && /* @__PURE__ */ jsxs27(
|
|
5181
|
+
ChalkPopoverPrimitive.Root,
|
|
5182
|
+
{
|
|
5183
|
+
open: menuOpen,
|
|
5184
|
+
onOpenChange: (open) => {
|
|
5185
|
+
if (open) onMenuToggle();
|
|
5186
|
+
else onMenuClose();
|
|
5187
|
+
},
|
|
5188
|
+
children: [
|
|
5189
|
+
/* @__PURE__ */ jsx45(ChalkPopoverPrimitive.Trigger, { className: cn("call-person-options", optionsButtonClassName), "aria-label": `Options for ${participant.displayName}`, children: /* @__PURE__ */ jsx45("svg", { className: "size-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx45("path", { d: "M5 12h.01M12 12h.01M19 12h.01" }) }) }),
|
|
5190
|
+
/* @__PURE__ */ jsx45(ChalkPopoverPrimitive.Portal, { container: rootRef.current?.closest("[data-chalk]") ?? void 0, children: /* @__PURE__ */ jsx45(ChalkPopoverPrimitive.Positioner, { side: "bottom", align: "end", sideOffset: 6, collisionPadding: 8, className: "chalk-popover-positioner", children: /* @__PURE__ */ jsx45(ChalkPopoverPrimitive.Popup, { "aria-label": `Options for ${participant.displayName}`, className: "chalk-menu w-60", children: /* @__PURE__ */ jsx45(
|
|
5191
|
+
ParticipantOptionsMenu,
|
|
5192
|
+
{
|
|
5193
|
+
participant,
|
|
5194
|
+
variant,
|
|
5195
|
+
canManageParticipants,
|
|
5196
|
+
onClose: onMenuClose,
|
|
5197
|
+
onAssignRole,
|
|
5198
|
+
onStopParticipantScreenShare,
|
|
5199
|
+
onMuteParticipant,
|
|
5200
|
+
onRequestUnmute,
|
|
5201
|
+
onStopParticipantCamera,
|
|
5202
|
+
onRequestStartCamera,
|
|
5203
|
+
onRemoveParticipant,
|
|
5204
|
+
onEditName: participant.isLocal ? () => {
|
|
5205
|
+
setIsEditing(true);
|
|
5206
|
+
onMenuClose();
|
|
5207
|
+
} : void 0,
|
|
5208
|
+
participantVolumes,
|
|
5209
|
+
onParticipantVolumeChange,
|
|
5210
|
+
onCommandError
|
|
5211
|
+
}
|
|
5212
|
+
) }) }) })
|
|
5213
|
+
]
|
|
5214
|
+
}
|
|
5215
|
+
)
|
|
5216
|
+
] })
|
|
5217
|
+
]
|
|
5218
|
+
}
|
|
5219
|
+
);
|
|
5236
5220
|
}
|
|
5237
5221
|
|
|
5238
5222
|
// src/components/participants-panel/ParticipantsPanel.tsx
|
|
@@ -5259,13 +5243,14 @@ var ParticipantsPanelSurface = React13.memo(
|
|
|
5259
5243
|
onCommandError,
|
|
5260
5244
|
participantVolumes,
|
|
5261
5245
|
onParticipantVolumeChange,
|
|
5246
|
+
onParticipantClick,
|
|
5262
5247
|
participantGradientPreference,
|
|
5263
5248
|
generatedAvatars = true
|
|
5264
5249
|
}) => {
|
|
5265
|
-
const [query, setQuery] =
|
|
5266
|
-
const [activeMenuId, setActiveMenuId] =
|
|
5267
|
-
const [muting, setMuting] =
|
|
5268
|
-
const [error, setError] =
|
|
5250
|
+
const [query, setQuery] = useState24("");
|
|
5251
|
+
const [activeMenuId, setActiveMenuId] = useState24(null);
|
|
5252
|
+
const [muting, setMuting] = useState24(false);
|
|
5253
|
+
const [error, setError] = useState24(null);
|
|
5269
5254
|
const filtered = participants.filter((person) => person.displayName.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase()));
|
|
5270
5255
|
const raised = participants.filter((person) => person.isHandRaised);
|
|
5271
5256
|
const unmutedCount = participants.filter((person) => !person.isLocal && !person.isMuted).length;
|
|
@@ -5328,6 +5313,7 @@ var ParticipantsPanelSurface = React13.memo(
|
|
|
5328
5313
|
ParticipantRow,
|
|
5329
5314
|
{
|
|
5330
5315
|
participant,
|
|
5316
|
+
onParticipantClick,
|
|
5331
5317
|
variant,
|
|
5332
5318
|
canManageParticipants,
|
|
5333
5319
|
onAssignRole,
|
|
@@ -5368,7 +5354,7 @@ var ParticipantsPanel = React13.memo((props) => {
|
|
|
5368
5354
|
const canRemoveParticipants = useCan("removeParticipant");
|
|
5369
5355
|
const canManageAdmission = useCan("manageAdmission");
|
|
5370
5356
|
const contextVolumeState = useParticipantVolumeContext();
|
|
5371
|
-
const [localVolumes, setLocalVolumes] =
|
|
5357
|
+
const [localVolumes, setLocalVolumes] = useState24(/* @__PURE__ */ new Map());
|
|
5372
5358
|
const isControlled = props.participantVolumes !== void 0 && props.onParticipantVolumeChange !== void 0;
|
|
5373
5359
|
const participantVolumes = isControlled ? props.participantVolumes : contextVolumeState?.volumes ?? localVolumes;
|
|
5374
5360
|
const onParticipantVolumeChange = isControlled ? props.onParticipantVolumeChange : contextVolumeState?.setVolume ?? ((participantId, volume) => setLocalVolumes((current) => {
|
|
@@ -5420,26 +5406,15 @@ var ParticipantsPanel = React13.memo((props) => {
|
|
|
5420
5406
|
ParticipantsPanel.displayName = "ParticipantsPanel";
|
|
5421
5407
|
|
|
5422
5408
|
// src/components/chalk/StatusSurface.tsx
|
|
5423
|
-
import { formatSyncConnectDiagnostic } from "@q9labsai/chalk-client";
|
|
5409
|
+
import { formatSyncConnectDiagnostic, getConnectionFailureDetail } from "@q9labsai/chalk-client";
|
|
5424
5410
|
import { Fragment as Fragment18, jsx as jsx47, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5425
|
-
var DEFAULT_FAILURE_DETAIL = "Something went wrong while joining. Try again.";
|
|
5426
|
-
var FAILURE_DETAILS = {
|
|
5427
|
-
"access.invalid": "Access to this call was rejected. Refresh the page and try again.",
|
|
5428
|
-
"access.unavailable": "Couldn\u2019t get access to the call. Try again.",
|
|
5429
|
-
"connection.sync_start_failed": "Couldn\u2019t reach the call service. Try again.",
|
|
5430
|
-
"connection.sync_hello_timeout": "The call service did not respond in time. Try again.",
|
|
5431
|
-
"connection.sync_recovery_exhausted": "The call connection could not recover. Try again.",
|
|
5432
|
-
"connection.media_start_failed": "Audio and video could not connect. Try again.",
|
|
5433
|
-
"connection.media_recovery_exhausted": "Audio and video could not reconnect. Try again.",
|
|
5434
|
-
"environment.unsupported": "This browser cannot start the call. Use an up-to-date browser over HTTPS.",
|
|
5435
|
-
"client.internal_error": DEFAULT_FAILURE_DETAIL
|
|
5436
|
-
};
|
|
5437
5411
|
function StatusSurface({ phase, callName = "the call", reason, episodeEndReason, endAction, errorCode, sync, theme, onRejoin, onHome, onRetry, onReportProblem, rejoinDisabled = false, retryPending = false }) {
|
|
5412
|
+
const connectionLost = phase === "failed" && errorCode === "connection.sync_recovery_exhausted";
|
|
5438
5413
|
const copy = {
|
|
5439
5414
|
entering: { title: `Joining ${callName}\u2026`, detail: "" },
|
|
5440
5415
|
left: { title: `You left ${callName}`, detail: "" },
|
|
5441
5416
|
"episode-ended": episodeEndReason === "maximum_duration" ? { title: "The call reached its time limit", detail: "This call has ended for everyone." } : { title: "The call ended", detail: "" },
|
|
5442
|
-
failed: { title: `Couldn\u2019t connect to ${callName}`, detail: (
|
|
5417
|
+
failed: { title: connectionLost ? "Connection lost" : `Couldn\u2019t connect to ${callName}`, detail: getConnectionFailureDetail({ code: errorCode, sync }) },
|
|
5443
5418
|
removed: { title: `You were removed from ${callName}`, detail: "The host removed you from this call." },
|
|
5444
5419
|
full: { title: "This call is full", detail: `${callName} has reached 100 people. Ask the host to make room, then try again.` },
|
|
5445
5420
|
elsewhere: { title: "You joined from another tab", detail: `${callName} is open in another tab or window. Use it here instead?` }
|
|
@@ -5467,7 +5442,7 @@ function StatusSurface({ phase, callName = "the call", reason, episodeEndReason,
|
|
|
5467
5442
|
] }) : null,
|
|
5468
5443
|
/* @__PURE__ */ jsxs29("div", { "data-part": "status-actions", className: "mt-5 flex gap-7", children: [
|
|
5469
5444
|
phase === "episode-ended" && episodeEndReason === "maximum_duration" && endAction ? /* @__PURE__ */ jsx47(StatusAction, { icon: /* @__PURE__ */ jsx47(StatusIcon, { retry: true }), label: endAction.label, onClick: endAction.onClick }) : null,
|
|
5470
|
-
canRetry && retry ? /* @__PURE__ */ jsx47(StatusAction, { icon: /* @__PURE__ */ jsx47(StatusIcon, { retry: true }), label: phase === "elsewhere" ? "Use here" : phase === "left" ? "Rejoin" : "Try again", onClick: retry, disabled: rejoinDisabled || retryPending }) : null,
|
|
5445
|
+
canRetry && retry ? /* @__PURE__ */ jsx47(StatusAction, { icon: /* @__PURE__ */ jsx47(StatusIcon, { retry: true }), label: phase === "elsewhere" ? "Use here" : phase === "left" || connectionLost ? "Rejoin" : "Try again", onClick: retry, disabled: rejoinDisabled || retryPending }) : null,
|
|
5471
5446
|
phase !== "entering" && onHome ? /* @__PURE__ */ jsx47(StatusAction, { icon: /* @__PURE__ */ jsx47(StatusIcon, {}), label: "Home", onClick: onHome }) : null
|
|
5472
5447
|
] }),
|
|
5473
5448
|
onReportProblem && phase !== "entering" ? /* @__PURE__ */ jsx47("button", { type: "button", onClick: onReportProblem, className: "mt-[18px] px-2.5 py-2 text-[13px] text-[var(--chalk-muted-text)] underline underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-2", children: "Report a problem" }) : null
|
|
@@ -5498,7 +5473,7 @@ function StatusAction({ icon, label, onClick, disabled }) {
|
|
|
5498
5473
|
}
|
|
5499
5474
|
|
|
5500
5475
|
// src/components/call-limbo/CallReady.tsx
|
|
5501
|
-
import { useEffect as useEffect19, useId, useRef as useRef14, useState as
|
|
5476
|
+
import { useEffect as useEffect19, useId, useRef as useRef14, useState as useState25 } from "react";
|
|
5502
5477
|
|
|
5503
5478
|
// src/components/call-limbo/qr-code.ts
|
|
5504
5479
|
function inviteQR(text) {
|
|
@@ -5641,13 +5616,13 @@ function inviteQR(text) {
|
|
|
5641
5616
|
// src/components/call-limbo/CallReady.tsx
|
|
5642
5617
|
import { Fragment as Fragment19, jsx as jsx48, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5643
5618
|
function CallReady({ open, onClose, link = typeof location === "undefined" ? "" : location.href }) {
|
|
5644
|
-
const [showQR, setShowQR] =
|
|
5619
|
+
const [showQR, setShowQR] = useState25(false);
|
|
5645
5620
|
const qrRef = useRef14(null);
|
|
5646
5621
|
const cardRef = useRef14(null);
|
|
5647
5622
|
const phone = useIsMobile();
|
|
5648
5623
|
const reducedMotion = usePrefersReducedMotion();
|
|
5649
|
-
const [entered, setEntered] =
|
|
5650
|
-
const [present, setPresent] =
|
|
5624
|
+
const [entered, setEntered] = useState25(false);
|
|
5625
|
+
const [present, setPresent] = useState25(open);
|
|
5651
5626
|
const id = useId();
|
|
5652
5627
|
const qr = showQR ? inviteQR(link) : null;
|
|
5653
5628
|
const close = () => {
|
|
@@ -5728,11 +5703,11 @@ function CallReady({ open, onClose, link = typeof location === "undefined" ? ""
|
|
|
5728
5703
|
}
|
|
5729
5704
|
|
|
5730
5705
|
// src/components/toast-stack/ToastStack.tsx
|
|
5731
|
-
import { memo, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as
|
|
5706
|
+
import { memo, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as useState27 } from "react";
|
|
5732
5707
|
import { flushSync as flushSync2 } from "react-dom";
|
|
5733
5708
|
|
|
5734
5709
|
// src/components/toast-stack/useToastCapacity.ts
|
|
5735
|
-
import { isValidElement as isValidElement2, useLayoutEffect as useLayoutEffect2, useState as
|
|
5710
|
+
import { isValidElement as isValidElement2, useLayoutEffect as useLayoutEffect2, useState as useState26 } from "react";
|
|
5736
5711
|
import { flushSync } from "react-dom";
|
|
5737
5712
|
|
|
5738
5713
|
// src/components/toast-stack/toast-layout-snapshot.ts
|
|
@@ -5777,7 +5752,7 @@ function measureToastLayout(stack, snapshot) {
|
|
|
5777
5752
|
|
|
5778
5753
|
// src/components/toast-stack/useToastCapacity.ts
|
|
5779
5754
|
function useToastCapacity(stack, candidates, enabled, ownedIds) {
|
|
5780
|
-
const [fit, setFit] =
|
|
5755
|
+
const [fit, setFit] = useState26(null);
|
|
5781
5756
|
let count = candidates.length;
|
|
5782
5757
|
if (enabled) {
|
|
5783
5758
|
count = 0;
|
|
@@ -5871,7 +5846,7 @@ var ToastStack = memo(function ToastStack2({ toasts, onDismiss, maxVisible = 3,
|
|
|
5871
5846
|
const stack = useRef15(null);
|
|
5872
5847
|
const short = useShortCall(stack, onFold !== void 0);
|
|
5873
5848
|
const candidates = maxVisible > 0 ? toasts.slice(-maxVisible) : [];
|
|
5874
|
-
const [ownedIds, setOwnedIds] =
|
|
5849
|
+
const [ownedIds, setOwnedIds] = useState27([]);
|
|
5875
5850
|
const fold = useRef15(onFold);
|
|
5876
5851
|
const capacity = useToastCapacity(stack, candidates, onFold !== void 0 && short === false, ownedIds);
|
|
5877
5852
|
const selected = onFold !== void 0 && short !== false ? [] : candidates.slice(candidates.length - capacity.count);
|
|
@@ -5880,7 +5855,7 @@ var ToastStack = memo(function ToastStack2({ toasts, onDismiss, maxVisible = 3,
|
|
|
5880
5855
|
const foldedIds = folded.map((toast) => toast.id);
|
|
5881
5856
|
const announced = useRef15(/* @__PURE__ */ new Map());
|
|
5882
5857
|
const wasAnnounced = (toast) => announced.current.get(toast.id) === noticeIdentity(toast);
|
|
5883
|
-
const [unheard, setUnheard] =
|
|
5858
|
+
const [unheard, setUnheard] = useState27([]);
|
|
5884
5859
|
const reported = useRef15([]);
|
|
5885
5860
|
const reporting = useRef15(false);
|
|
5886
5861
|
useLayoutEffect3(() => {
|
|
@@ -5927,7 +5902,7 @@ var ToastStack = memo(function ToastStack2({ toasts, onDismiss, maxVisible = 3,
|
|
|
5927
5902
|
] });
|
|
5928
5903
|
});
|
|
5929
5904
|
function useShortCall(stack, enabled) {
|
|
5930
|
-
const [short, setShort] =
|
|
5905
|
+
const [short, setShort] = useState27(null);
|
|
5931
5906
|
useLayoutEffect3(() => {
|
|
5932
5907
|
if (!enabled) {
|
|
5933
5908
|
setShort(null);
|
|
@@ -5948,7 +5923,7 @@ function sameIds(a, b) {
|
|
|
5948
5923
|
}
|
|
5949
5924
|
|
|
5950
5925
|
// src/internal/call-motion.ts
|
|
5951
|
-
import { useEffect as useEffect20, useState as
|
|
5926
|
+
import { useEffect as useEffect20, useState as useState28 } from "react";
|
|
5952
5927
|
var moves = /* @__PURE__ */ new WeakMap();
|
|
5953
5928
|
function captureFlip(elements) {
|
|
5954
5929
|
const previous = Array.from(elements, (element) => ({ element, box: element.getBoundingClientRect() }));
|
|
@@ -5976,7 +5951,7 @@ function playFlip(previous) {
|
|
|
5976
5951
|
}
|
|
5977
5952
|
var ACTIVE_LAYERS = '[role="menu"],[role="dialog"],[data-part="toast"],[data-part="notice-button"],[data-chalk-drawer]';
|
|
5978
5953
|
function useIdleChrome(root, enabled) {
|
|
5979
|
-
const [idle, setIdle] =
|
|
5954
|
+
const [idle, setIdle] = useState28(false);
|
|
5980
5955
|
const fine = useMediaQuery("(pointer:fine) and (min-width:641px)");
|
|
5981
5956
|
useEffect20(() => {
|
|
5982
5957
|
const element = root.current;
|
|
@@ -6008,7 +5983,7 @@ function useIdleChrome(root, enabled) {
|
|
|
6008
5983
|
}
|
|
6009
5984
|
|
|
6010
5985
|
// src/components/space-header/SpaceHeader.tsx
|
|
6011
|
-
import React14, { useCallback as useCallback6, useRef as useRef18, useState as
|
|
5986
|
+
import React14, { useCallback as useCallback6, useRef as useRef18, useState as useState30 } from "react";
|
|
6012
5987
|
|
|
6013
5988
|
// src/internal/useSoundsSetting.ts
|
|
6014
5989
|
import { useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
@@ -6060,7 +6035,7 @@ function LayoutMenu({ layout, onLayoutChange }) {
|
|
|
6060
6035
|
|
|
6061
6036
|
// src/components/space-header/CallDetails.tsx
|
|
6062
6037
|
import { Dialog as Dialog2 } from "@base-ui/react/dialog";
|
|
6063
|
-
import { useEffect as useEffect21, useRef as useRef16, useState as
|
|
6038
|
+
import { useEffect as useEffect21, useRef as useRef16, useState as useState29 } from "react";
|
|
6064
6039
|
|
|
6065
6040
|
// src/components/space-header/share-qr.ts
|
|
6066
6041
|
function shareQr(text) {
|
|
@@ -6215,10 +6190,10 @@ function CallDialog({
|
|
|
6215
6190
|
const container = useRef16(null);
|
|
6216
6191
|
const reportInput = useRef16(null);
|
|
6217
6192
|
const reportOpener = useRef16(null);
|
|
6218
|
-
const [text, setText] =
|
|
6219
|
-
const [includeDiagnostics, setIncludeDiagnostics] =
|
|
6220
|
-
const [status, setStatus] =
|
|
6221
|
-
const [error, setError] =
|
|
6193
|
+
const [text, setText] = useState29("");
|
|
6194
|
+
const [includeDiagnostics, setIncludeDiagnostics] = useState29(false);
|
|
6195
|
+
const [status, setStatus] = useState29("idle");
|
|
6196
|
+
const [error, setError] = useState29("");
|
|
6222
6197
|
useEffect21(() => {
|
|
6223
6198
|
if (open && kind === "report") {
|
|
6224
6199
|
setText("");
|
|
@@ -6353,7 +6328,7 @@ function CallDetails({
|
|
|
6353
6328
|
}) {
|
|
6354
6329
|
const link = shareUrl ?? (typeof location === "undefined" ? "" : location.href);
|
|
6355
6330
|
const qr = shareQr(link);
|
|
6356
|
-
const [details, setDetails] =
|
|
6331
|
+
const [details, setDetails] = useState29(false);
|
|
6357
6332
|
return /* @__PURE__ */ jsxs32("div", { className: "chalk-details", children: [
|
|
6358
6333
|
/* @__PURE__ */ jsxs32("div", { className: "chalk-shell-details-heading", children: [
|
|
6359
6334
|
/* @__PURE__ */ jsx51("h2", { children: spaceName }),
|
|
@@ -6505,8 +6480,8 @@ var SpaceHeader = React14.memo((props) => {
|
|
|
6505
6480
|
const [sounds, setSounds] = useSoundsSetting();
|
|
6506
6481
|
const triggerRef = useRef18(null);
|
|
6507
6482
|
const focusScope = useRef18(null);
|
|
6508
|
-
const [open, setOpen] =
|
|
6509
|
-
const [dialog, setDialog] =
|
|
6483
|
+
const [open, setOpen] = useState30(false);
|
|
6484
|
+
const [dialog, setDialog] = useState30({ kind: "shortcuts", open: false });
|
|
6510
6485
|
const showShortcuts = useCallback6(() => setDialog({ kind: "shortcuts", open: true }), []);
|
|
6511
6486
|
useCallShortcuts(props.shortcuts, showShortcuts);
|
|
6512
6487
|
const phone = useMediaQuery("(max-width: 640px)");
|
|
@@ -6593,16 +6568,16 @@ var SpaceHeader = React14.memo((props) => {
|
|
|
6593
6568
|
SpaceHeader.displayName = "SpaceHeader";
|
|
6594
6569
|
|
|
6595
6570
|
// src/components/composite/ScreenShareView.tsx
|
|
6596
|
-
import { useEffect as useEffect23, useMemo as useMemo11, useRef as useRef19, useState as
|
|
6571
|
+
import { useEffect as useEffect23, useMemo as useMemo11, useRef as useRef19, useState as useState31 } from "react";
|
|
6597
6572
|
import { Fragment as Fragment23, jsx as jsx53, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6598
6573
|
function ScreenSharePresentation({ sharedByName, media, mediaVisible, state, isLocal = false, hasAudio = false, capture: capture2, primary = true, pinned, hidden, style, onClick, onDoubleClick, onStopSharing, onChangeShare, switcher, className }) {
|
|
6599
6574
|
const root = useRef19(null);
|
|
6600
|
-
const [fill, setFill] =
|
|
6601
|
-
const [controlsOpen, setControlsOpen] =
|
|
6602
|
-
const [poppedOut, setPoppedOut] =
|
|
6603
|
-
const [zoom, setZoom] =
|
|
6604
|
-
const [pending, setPending] =
|
|
6605
|
-
const [error, setError] =
|
|
6575
|
+
const [fill, setFill] = useState31(false);
|
|
6576
|
+
const [controlsOpen, setControlsOpen] = useState31(false);
|
|
6577
|
+
const [poppedOut, setPoppedOut] = useState31(false);
|
|
6578
|
+
const [zoom, setZoom] = useState31(false);
|
|
6579
|
+
const [pending, setPending] = useState31(false);
|
|
6580
|
+
const [error, setError] = useState31(null);
|
|
6606
6581
|
const status = state ?? (mediaVisible ? "live" : "connecting");
|
|
6607
6582
|
const name = isLocal ? "Your screen" : `${sharedByName}'s screen`;
|
|
6608
6583
|
const source = capture2?.surface === "window" ? "a window" : capture2?.surface === "browser" ? "a tab" : capture2?.surface === "monitor" ? "your screen" : null;
|
|
@@ -6788,16 +6763,16 @@ function ScreenShareView(props) {
|
|
|
6788
6763
|
}
|
|
6789
6764
|
|
|
6790
6765
|
// src/components/stage/Stage.tsx
|
|
6791
|
-
import { useCallback as useCallback7, useEffect as useEffect24, useLayoutEffect as useLayoutEffect5, useMemo as useMemo12, useRef as useRef22, useState as
|
|
6766
|
+
import { useCallback as useCallback7, useEffect as useEffect24, useLayoutEffect as useLayoutEffect5, useMemo as useMemo12, useRef as useRef22, useState as useState33 } from "react";
|
|
6792
6767
|
import { createPortal as createPortal2 } from "react-dom";
|
|
6793
6768
|
|
|
6794
6769
|
// src/components/stage/useStageDimensions.ts
|
|
6795
|
-
import { useLayoutEffect as useLayoutEffect4, useRef as useRef20, useState as
|
|
6770
|
+
import { useLayoutEffect as useLayoutEffect4, useRef as useRef20, useState as useState32 } from "react";
|
|
6796
6771
|
import { flushSync as flushSync3 } from "react-dom";
|
|
6797
6772
|
function useStageDimensions(fallback3) {
|
|
6798
6773
|
const ref = useRef20(null);
|
|
6799
6774
|
const current = useRef20(fallback3);
|
|
6800
|
-
const [dimensions, setDimensions] =
|
|
6775
|
+
const [dimensions, setDimensions] = useState32(fallback3);
|
|
6801
6776
|
useLayoutEffect4(() => {
|
|
6802
6777
|
const element = ref.current;
|
|
6803
6778
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
@@ -6993,7 +6968,7 @@ function createContentPlacement() {
|
|
|
6993
6968
|
};
|
|
6994
6969
|
}
|
|
6995
6970
|
function PersistentStageContent({ placement, children }) {
|
|
6996
|
-
const [host, setHost] =
|
|
6971
|
+
const [host, setHost] = useState33(null);
|
|
6997
6972
|
useLayoutEffect5(() => {
|
|
6998
6973
|
const element = document.createElement("div");
|
|
6999
6974
|
Object.assign(element.style, TILE_FILL);
|
|
@@ -7018,7 +6993,6 @@ function Stage({
|
|
|
7018
6993
|
pinnedId,
|
|
7019
6994
|
followingId = null,
|
|
7020
6995
|
onFollowChange,
|
|
7021
|
-
clickAction = "pin",
|
|
7022
6996
|
onPinnedChange,
|
|
7023
6997
|
onOverflowClick,
|
|
7024
6998
|
onItemClick,
|
|
@@ -7037,9 +7011,9 @@ function Stage({
|
|
|
7037
7011
|
}) {
|
|
7038
7012
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7039
7013
|
const { ref: boxRef, dimensions: box } = useStageDimensions(FALLBACK_BOX);
|
|
7040
|
-
const [overflowOpen, setOverflowOpen] =
|
|
7041
|
-
const [shareAspects, setShareAspects] =
|
|
7042
|
-
const [uncontrolledPinnedId, setUncontrolledPinnedId] =
|
|
7014
|
+
const [overflowOpen, setOverflowOpen] = useState33(false);
|
|
7015
|
+
const [shareAspects, setShareAspects] = useState33(/* @__PURE__ */ new Map());
|
|
7016
|
+
const [uncontrolledPinnedId, setUncontrolledPinnedId] = useState33(null);
|
|
7043
7017
|
const activePinnedId = pinnedId === void 0 ? uncontrolledPinnedId : pinnedId;
|
|
7044
7018
|
const orderRef = useRef22([]);
|
|
7045
7019
|
const seenAtRef = useRef22(/* @__PURE__ */ new Map());
|
|
@@ -7120,7 +7094,7 @@ function Stage({
|
|
|
7120
7094
|
return /* @__PURE__ */ jsx56(StageContentTile, { item, ...context });
|
|
7121
7095
|
};
|
|
7122
7096
|
const animate = animateOverride ?? !prefersReducedMotion;
|
|
7123
|
-
const [displayed, setDisplayed] =
|
|
7097
|
+
const [displayed, setDisplayed] = useState33({
|
|
7124
7098
|
source: ordered,
|
|
7125
7099
|
geometry,
|
|
7126
7100
|
tiles: ordered.map((item) => ({ item, frame: framesById.get(item.id), leaving: false }))
|
|
@@ -7186,15 +7160,14 @@ function Stage({
|
|
|
7186
7160
|
for (const item of ordered) {
|
|
7187
7161
|
map.set(item.id, {
|
|
7188
7162
|
onClick: () => {
|
|
7189
|
-
|
|
7190
|
-
else togglePin(item);
|
|
7163
|
+
togglePin(item);
|
|
7191
7164
|
onItemClick?.(item);
|
|
7192
7165
|
},
|
|
7193
7166
|
onDoubleClick: onItemDoubleClick ? () => onItemDoubleClick(item) : void 0
|
|
7194
7167
|
});
|
|
7195
7168
|
}
|
|
7196
7169
|
return map;
|
|
7197
|
-
}, [
|
|
7170
|
+
}, [interactive, onItemDoubleClick, onItemClick, ordered, togglePin]);
|
|
7198
7171
|
if (ordered.length === 0) {
|
|
7199
7172
|
return /* @__PURE__ */ jsx56("div", { className: cn("flex h-full w-full items-center justify-center px-6 py-10", className), "data-tour": "video-grid", children: emptyState });
|
|
7200
7173
|
}
|
|
@@ -7219,7 +7192,7 @@ function Stage({
|
|
|
7219
7192
|
aspectRatio: "fill",
|
|
7220
7193
|
primary: frame?.role === "primary",
|
|
7221
7194
|
pinned,
|
|
7222
|
-
|
|
7195
|
+
onFollow: onFollowChange && !item.participant.isLocal ? () => onFollowChange(item.id) : void 0,
|
|
7223
7196
|
following: followingId === item.id,
|
|
7224
7197
|
onClick: click,
|
|
7225
7198
|
onDoubleClick: doubleClick,
|
|
@@ -7280,7 +7253,6 @@ function Stage({
|
|
|
7280
7253
|
setOverflowOpen(false);
|
|
7281
7254
|
},
|
|
7282
7255
|
children: [
|
|
7283
|
-
clickAction === "follow" && !item.participant.isLocal ? `${followingId === item.id ? "Stop following" : "Follow"} ` : "",
|
|
7284
7256
|
item.participant.displayName,
|
|
7285
7257
|
item.participant.isMuted ? " \xB7 Muted" : ""
|
|
7286
7258
|
]
|
|
@@ -7489,7 +7461,7 @@ function SpacePresentation({ colorScheme = "dark", stageBackground, header, stag
|
|
|
7489
7461
|
// src/components/space-view/SpaceView.tsx
|
|
7490
7462
|
import "@q9labsai/chalk-client";
|
|
7491
7463
|
import { DEFAULT_QUICK_REACTIONS as DEFAULT_QUICK_REACTIONS2 } from "@q9labsai/chalk-ui/reactions";
|
|
7492
|
-
import { useCallback as useCallback14, useEffect as useEffect36, useMemo as useMemo18, useRef as useRef29, useState as
|
|
7464
|
+
import { useCallback as useCallback14, useEffect as useEffect36, useMemo as useMemo18, useRef as useRef29, useState as useState44 } from "react";
|
|
7493
7465
|
|
|
7494
7466
|
// src/components/space-header/call-diagnostics.ts
|
|
7495
7467
|
function callDiagnostics(connection, media) {
|
|
@@ -7520,11 +7492,11 @@ function callCountdown(deadline, now, previousSeconds) {
|
|
|
7520
7492
|
}
|
|
7521
7493
|
|
|
7522
7494
|
// src/internal/useEpisodeDuration.ts
|
|
7523
|
-
import { useEffect as useEffect26, useState as
|
|
7495
|
+
import { useEffect as useEffect26, useState as useState34 } from "react";
|
|
7524
7496
|
function useEpisodeDuration() {
|
|
7525
7497
|
const connection = useConnection();
|
|
7526
7498
|
const episodeStart = connection.episode?.startedAt ? Date.parse(connection.episode.startedAt) : null;
|
|
7527
|
-
const [now, setNow] =
|
|
7499
|
+
const [now, setNow] = useState34(() => Date.now());
|
|
7528
7500
|
useEffect26(() => {
|
|
7529
7501
|
if (episodeStart === null || Number.isNaN(episodeStart)) return;
|
|
7530
7502
|
setNow(Date.now());
|
|
@@ -7580,16 +7552,17 @@ function createSoundPlayer({ outputDeviceId } = {}) {
|
|
|
7580
7552
|
const created = !context;
|
|
7581
7553
|
try {
|
|
7582
7554
|
context ??= new AudioContext();
|
|
7555
|
+
if (created && outputDeviceId && "setSinkId" in context && typeof context.setSinkId === "function") void Promise.resolve(context.setSinkId(outputDeviceId)).catch(() => void 0);
|
|
7556
|
+
if (context.state === "suspended") void context.resume().catch(() => void 0);
|
|
7583
7557
|
} catch {
|
|
7584
7558
|
return;
|
|
7585
7559
|
}
|
|
7586
|
-
if (created && outputDeviceId && "setSinkId" in context && typeof context.setSinkId === "function") void Promise.resolve(context.setSinkId(outputDeviceId)).catch(() => void 0);
|
|
7587
|
-
if (context.state === "suspended") void context.resume().catch(() => void 0);
|
|
7588
7560
|
};
|
|
7589
7561
|
if (typeof window !== "undefined") {
|
|
7590
7562
|
window.addEventListener("click", unlock, { capture: true });
|
|
7591
7563
|
window.addEventListener("keydown", unlock, { capture: true });
|
|
7592
7564
|
}
|
|
7565
|
+
unlock();
|
|
7593
7566
|
const tone = (frequency, offset, duration, volume = 0.07, type = "sine", to) => {
|
|
7594
7567
|
if (!context || context.state !== "running") return;
|
|
7595
7568
|
const oscillator = context.createOscillator(), gain = context.createGain(), time = context.currentTime + offset;
|
|
@@ -7628,44 +7601,47 @@ function createSoundPlayer({ outputDeviceId } = {}) {
|
|
|
7628
7601
|
return {
|
|
7629
7602
|
play(cue) {
|
|
7630
7603
|
if (disposed || !context || context.state !== "running") return;
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7604
|
+
try {
|
|
7605
|
+
switch (cue) {
|
|
7606
|
+
case "join":
|
|
7607
|
+
tone(659, 0, 0.16, 0.04);
|
|
7608
|
+
tone(988, 0.08, 0.22, 0.03);
|
|
7609
|
+
break;
|
|
7610
|
+
case "leave":
|
|
7611
|
+
tone(784, 0, 0.2);
|
|
7612
|
+
tone(523, 0.1, 0.3, 0.06);
|
|
7613
|
+
break;
|
|
7614
|
+
case "knock":
|
|
7615
|
+
thud(0);
|
|
7616
|
+
thud(0.17);
|
|
7617
|
+
break;
|
|
7618
|
+
case "message":
|
|
7619
|
+
tone(1175, 0, 0.16, 0.05, "triangle");
|
|
7620
|
+
break;
|
|
7621
|
+
case "hand-raise":
|
|
7622
|
+
tone(1319, 0, 0.32, 0.045);
|
|
7623
|
+
tone(1760, 0.07, 0.4, 0.035);
|
|
7624
|
+
break;
|
|
7625
|
+
case "mute":
|
|
7626
|
+
tone(560, 0, 0.07, 0.06, "triangle", 380);
|
|
7627
|
+
break;
|
|
7628
|
+
case "unmute":
|
|
7629
|
+
tone(420, 0, 0.07, 0.06, "triangle", 640);
|
|
7630
|
+
break;
|
|
7631
|
+
case "recording":
|
|
7632
|
+
tone(587, 0, 0.14);
|
|
7633
|
+
tone(587, 0.18, 0.14);
|
|
7634
|
+
tone(880, 0.36, 0.32, 0.06);
|
|
7635
|
+
break;
|
|
7636
|
+
case "error":
|
|
7637
|
+
tone(392, 0, 0.16, 0.05, "triangle");
|
|
7638
|
+
tone(311, 0.13, 0.24, 0.05, "triangle");
|
|
7639
|
+
break;
|
|
7640
|
+
case "reaction":
|
|
7641
|
+
tone(880, 0, 0.12, 0.035, "triangle");
|
|
7642
|
+
break;
|
|
7643
|
+
}
|
|
7644
|
+
} catch {
|
|
7669
7645
|
}
|
|
7670
7646
|
},
|
|
7671
7647
|
dispose() {
|
|
@@ -7674,7 +7650,7 @@ function createSoundPlayer({ outputDeviceId } = {}) {
|
|
|
7674
7650
|
window.removeEventListener("click", unlock, true);
|
|
7675
7651
|
window.removeEventListener("keydown", unlock, true);
|
|
7676
7652
|
}
|
|
7677
|
-
if (context) void context.close();
|
|
7653
|
+
if (context) void Promise.resolve(context.close()).catch(() => void 0);
|
|
7678
7654
|
}
|
|
7679
7655
|
};
|
|
7680
7656
|
}
|
|
@@ -7705,9 +7681,21 @@ function useSoundCues(enabled, createPlayer = createSoundPlayer) {
|
|
|
7705
7681
|
const player = createPlayerRef.current({ outputDeviceId });
|
|
7706
7682
|
playerRef.current = player;
|
|
7707
7683
|
let previous = client.getSnapshot();
|
|
7684
|
+
const seenParticipants = new Set(previous.participants.roster.map((participant) => participant.participantId));
|
|
7685
|
+
let lastJoinAt = -Infinity;
|
|
7708
7686
|
const unsubscribe = client.subscribe(() => {
|
|
7709
7687
|
const next = client.getSnapshot();
|
|
7710
|
-
|
|
7688
|
+
const hasNewParticipant = next.participants.roster.some((participant) => participant.participantId !== next.self.participantId && !seenParticipants.has(participant.participantId));
|
|
7689
|
+
if (enabledRef.current)
|
|
7690
|
+
for (const cue of diffSoundCues(previous, next)) {
|
|
7691
|
+
if (cue === "join") {
|
|
7692
|
+
const now = performance.now();
|
|
7693
|
+
if (!hasNewParticipant || now - lastJoinAt < 3e3) continue;
|
|
7694
|
+
lastJoinAt = now;
|
|
7695
|
+
}
|
|
7696
|
+
player.play(cue);
|
|
7697
|
+
}
|
|
7698
|
+
for (const participant of next.participants.roster) seenParticipants.add(participant.participantId);
|
|
7711
7699
|
previous = next;
|
|
7712
7700
|
});
|
|
7713
7701
|
const offError = client.on("error", ({ error }) => playFailure(error));
|
|
@@ -7731,14 +7719,14 @@ function useSoundCues(enabled, createPlayer = createSoundPlayer) {
|
|
|
7731
7719
|
}
|
|
7732
7720
|
|
|
7733
7721
|
// src/components/composite/ReactionPicker.tsx
|
|
7734
|
-
import React21, { useMemo as useMemo14, useState as
|
|
7722
|
+
import React21, { useMemo as useMemo14, useState as useState36, useCallback as useCallback10, useEffect as useEffect29, useRef as useRef27 } from "react";
|
|
7735
7723
|
import { DEFAULT_QUICK_REACTIONS, EMOJI_CATEGORIES, EMOJI_KEYWORDS } from "@q9labsai/chalk-ui/reactions";
|
|
7736
7724
|
|
|
7737
7725
|
// src/components/composite/ReactionTray.tsx
|
|
7738
|
-
import { useCallback as useCallback9, useEffect as useEffect28, useLayoutEffect as useLayoutEffect6, useRef as useRef26, useState as
|
|
7726
|
+
import { useCallback as useCallback9, useEffect as useEffect28, useLayoutEffect as useLayoutEffect6, useRef as useRef26, useState as useState35 } from "react";
|
|
7739
7727
|
import { Fragment as Fragment27, jsx as jsx61, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
7740
7728
|
function ReactionTray({ isHandRaised, onToggleHandRaise, reactions, onSelect, onClose, position = "top", className }) {
|
|
7741
|
-
const [more, setMore] =
|
|
7729
|
+
const [more, setMore] = useState35(false);
|
|
7742
7730
|
const returnFocus = useRef26(null);
|
|
7743
7731
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7744
7732
|
const { trigger } = useHaptics();
|
|
@@ -7823,8 +7811,8 @@ import { Fragment as Fragment28, jsx as jsx62, jsxs as jsxs40 } from "react/jsx-
|
|
|
7823
7811
|
var ReactionPicker = React21.memo(({ isHandRaised, onToggleHandRaise, isOpen, onClose, onSelect, recentReactions = [], allowedReactions, position = "top", participantColorSeed, participantGradientPreference, className, size = "default" }) => {
|
|
7824
7812
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7825
7813
|
const { trigger } = useHaptics();
|
|
7826
|
-
const [activeCategory, setActiveCategory] =
|
|
7827
|
-
const [searchQuery, setSearchQuery] =
|
|
7814
|
+
const [activeCategory, setActiveCategory] = useState36("smileys");
|
|
7815
|
+
const [searchQuery, setSearchQuery] = useState36("");
|
|
7828
7816
|
const inputRef = useRef27(null);
|
|
7829
7817
|
const themeVariables = useMemo14(() => getParticipantThemeVariables(participantColorSeed, participantGradientPreference), [participantColorSeed, participantGradientPreference]);
|
|
7830
7818
|
useEffect29(() => {
|
|
@@ -7981,7 +7969,7 @@ var ReactionPicker = React21.memo(({ isHandRaised, onToggleHandRaise, isOpen, on
|
|
|
7981
7969
|
ReactionPicker.displayName = "ReactionPicker";
|
|
7982
7970
|
|
|
7983
7971
|
// src/components/offline-actions/OfflineActions.tsx
|
|
7984
|
-
import { useEffect as useEffect30, useState as
|
|
7972
|
+
import { useEffect as useEffect30, useState as useState37, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
7985
7973
|
import { jsx as jsx63 } from "react/jsx-runtime";
|
|
7986
7974
|
var RECONNECTING_GRACE_MS = 2e3;
|
|
7987
7975
|
function offlineNoticeText(pendingCount, online) {
|
|
@@ -8009,7 +7997,7 @@ function OfflineActions({ reconnecting: requestedReconnecting = false, hasNotice
|
|
|
8009
7997
|
return null;
|
|
8010
7998
|
}
|
|
8011
7999
|
function useTrueFor(value, milliseconds) {
|
|
8012
|
-
const [elapsed, setElapsed] =
|
|
8000
|
+
const [elapsed, setElapsed] = useState37(false);
|
|
8013
8001
|
useEffect30(() => {
|
|
8014
8002
|
setElapsed(false);
|
|
8015
8003
|
if (!value) return;
|
|
@@ -8031,12 +8019,12 @@ function readOnline() {
|
|
|
8031
8019
|
}
|
|
8032
8020
|
|
|
8033
8021
|
// src/components/reconnecting-overlay/ReconnectingOverlay.tsx
|
|
8034
|
-
import { memo as memo3, useEffect as useEffect31, useState as
|
|
8022
|
+
import { memo as memo3, useEffect as useEffect31, useState as useState38 } from "react";
|
|
8035
8023
|
import { jsx as jsx64 } from "react/jsx-runtime";
|
|
8036
8024
|
var RECONNECTING_NOTICE_MS = 2e3;
|
|
8037
8025
|
var ReconnectingOverlay = memo3(function ReconnectingOverlay2({ isVisible, status, onRetry, onLeft, message, showNotice }) {
|
|
8038
8026
|
const reconnecting = isVisible && status === "reconnecting";
|
|
8039
|
-
const [elapsed, setElapsed] =
|
|
8027
|
+
const [elapsed, setElapsed] = useState38(false);
|
|
8040
8028
|
useEffect31(() => {
|
|
8041
8029
|
setElapsed(false);
|
|
8042
8030
|
if (!reconnecting) return;
|
|
@@ -8051,7 +8039,7 @@ var ReconnectingOverlay = memo3(function ReconnectingOverlay2({ isVisible, statu
|
|
|
8051
8039
|
});
|
|
8052
8040
|
|
|
8053
8041
|
// src/components/toast-stack/useCallToasts.ts
|
|
8054
|
-
import { useCallback as useCallback11, useEffect as useEffect32, useRef as useRef28, useState as
|
|
8042
|
+
import { useCallback as useCallback11, useEffect as useEffect32, useRef as useRef28, useState as useState39 } from "react";
|
|
8055
8043
|
|
|
8056
8044
|
// src/components/toast-stack/call-events.tsx
|
|
8057
8045
|
import { Fragment as Fragment29, jsx as jsx65, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
@@ -8148,7 +8136,7 @@ function callEventToasts(previous, next) {
|
|
|
8148
8136
|
// src/components/toast-stack/useCallToasts.ts
|
|
8149
8137
|
function useCallToasts() {
|
|
8150
8138
|
const client = useSpaceClient();
|
|
8151
|
-
const [toasts, setToasts] =
|
|
8139
|
+
const [toasts, setToasts] = useState39([]);
|
|
8152
8140
|
const sequence = useRef28(0);
|
|
8153
8141
|
useEffect32(() => {
|
|
8154
8142
|
setToasts([]);
|
|
@@ -8189,9 +8177,9 @@ function useCallToasts() {
|
|
|
8189
8177
|
}
|
|
8190
8178
|
|
|
8191
8179
|
// src/components/call-limbo/useCallLink.ts
|
|
8192
|
-
import { useEffect as useEffect33, useState as
|
|
8180
|
+
import { useEffect as useEffect33, useState as useState40 } from "react";
|
|
8193
8181
|
function useCallLink(alone) {
|
|
8194
|
-
const [open, setOpen] =
|
|
8182
|
+
const [open, setOpen] = useState40(alone);
|
|
8195
8183
|
useEffect33(() => {
|
|
8196
8184
|
if (!alone) setOpen(false);
|
|
8197
8185
|
}, [alone]);
|
|
@@ -8199,10 +8187,10 @@ function useCallLink(alone) {
|
|
|
8199
8187
|
}
|
|
8200
8188
|
|
|
8201
8189
|
// src/components/toast-stack/NoticeButton.tsx
|
|
8202
|
-
import { useState as
|
|
8190
|
+
import { useState as useState41 } from "react";
|
|
8203
8191
|
import { jsx as jsx66, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
8204
8192
|
function NoticeButton({ toasts, onDismiss }) {
|
|
8205
|
-
const [open, setOpen] =
|
|
8193
|
+
const [open, setOpen] = useState41(false);
|
|
8206
8194
|
if (toasts.length === 0) return null;
|
|
8207
8195
|
const label = toasts.length === 1 ? "1 notice" : `${toasts.length} notices`;
|
|
8208
8196
|
const trigger = /* @__PURE__ */ jsxs42("button", { type: "button", "data-part": "notice-button", className: "chalk-notice-button", "aria-label": `Show ${label}`, children: [
|
|
@@ -8224,7 +8212,7 @@ function NoticeButton({ toasts, onDismiss }) {
|
|
|
8224
8212
|
import { BoardToastContext as BoardToastContext2 } from "@q9labsai/chalk-whiteboard/react";
|
|
8225
8213
|
|
|
8226
8214
|
// src/components/stage/SpaceStage.tsx
|
|
8227
|
-
import { useCallback as useCallback13, useEffect as useEffect34, useMemo as useMemo17, useState as
|
|
8215
|
+
import { useCallback as useCallback13, useEffect as useEffect34, useMemo as useMemo17, useState as useState42 } from "react";
|
|
8228
8216
|
|
|
8229
8217
|
// src/components/board/Board.tsx
|
|
8230
8218
|
import { useContext as useContext3, useMemo as useMemo16 } from "react";
|
|
@@ -8294,31 +8282,43 @@ function Board(props) {
|
|
|
8294
8282
|
|
|
8295
8283
|
// src/components/stage/SpaceStage.tsx
|
|
8296
8284
|
import { jsx as jsx68 } from "react/jsx-runtime";
|
|
8297
|
-
function SpaceStage({ tiles, layout, onLayoutChange, generatedAvatars = true, whiteboard, onOverflowClick, shareCapture, onStopSharing, onChangeShare, colorScheme = "dark", onCloseBoard, className }) {
|
|
8285
|
+
function SpaceStage({ pinnedId, onPinnedChange, tiles, layout, onLayoutChange, generatedAvatars = true, whiteboard, onOverflowClick, shareCapture, onStopSharing, onChangeShare, colorScheme = "dark", onCloseBoard, className }) {
|
|
8298
8286
|
const items = useMemo17(() => buildStageItems(tiles, whiteboard?.isOpen === true), [tiles, whiteboard?.isOpen]);
|
|
8299
|
-
const [selectedShare, setSelectedShare] =
|
|
8300
|
-
const [
|
|
8301
|
-
const
|
|
8287
|
+
const [selectedShare, setSelectedShare] = useState42(null);
|
|
8288
|
+
const [localPin, setLocalPin] = useState42(null);
|
|
8289
|
+
const pin = pinnedId === void 0 ? localPin : pinnedId;
|
|
8290
|
+
const setPin = useCallback13(
|
|
8291
|
+
(id) => {
|
|
8292
|
+
setLocalPin(id);
|
|
8293
|
+
onPinnedChange?.(id);
|
|
8294
|
+
},
|
|
8295
|
+
[onPinnedChange]
|
|
8296
|
+
);
|
|
8297
|
+
const [following, setFollowing] = useState42(void 0);
|
|
8302
8298
|
const boardOpen = whiteboard?.isOpen === true && Boolean(whiteboard.props);
|
|
8303
8299
|
useEffect34(() => {
|
|
8304
|
-
if (!boardOpen) setFollowing(
|
|
8300
|
+
if (!boardOpen) setFollowing(void 0);
|
|
8305
8301
|
}, [boardOpen]);
|
|
8306
8302
|
const canFollow = boardOpen && Boolean(whiteboard?.sendView);
|
|
8307
|
-
const
|
|
8303
|
+
const target = following === void 0 ? whiteboard?.presenterId : following;
|
|
8304
|
+
const followed = canFollow && tiles.some((tile) => tile.id === target && !tile.isLocal) ? target ?? null : null;
|
|
8308
8305
|
const activePin = items.some((item) => item.id === pin) ? pin : null;
|
|
8309
8306
|
const shares = items.filter((item) => item.kind === "screen-share");
|
|
8310
8307
|
const activeShare = selectedShare && shares.some((item) => item.id === selectedShare) ? selectedShare : null;
|
|
8311
8308
|
useEffect34(() => {
|
|
8312
8309
|
if (pin !== activePin) setPin(activePin);
|
|
8313
8310
|
if (selectedShare !== activeShare) setSelectedShare(activeShare);
|
|
8314
|
-
}, [pin, activePin, selectedShare, activeShare]);
|
|
8315
|
-
const follow = useCallback13(
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8311
|
+
}, [pin, activePin, selectedShare, activeShare, setPin]);
|
|
8312
|
+
const follow = useCallback13(
|
|
8313
|
+
(id) => {
|
|
8314
|
+
if (id) {
|
|
8315
|
+
setPin(null);
|
|
8316
|
+
setSelectedShare(null);
|
|
8317
|
+
}
|
|
8318
|
+
setFollowing(id);
|
|
8319
|
+
},
|
|
8320
|
+
[setPin]
|
|
8321
|
+
);
|
|
8322
8322
|
const renderContentTile = useCallback13(
|
|
8323
8323
|
(item, context) => {
|
|
8324
8324
|
if (item.kind === "screen-share")
|
|
@@ -8369,15 +8369,14 @@ function SpaceStage({ tiles, layout, onLayoutChange, generatedAvatars = true, wh
|
|
|
8369
8369
|
Stage,
|
|
8370
8370
|
{
|
|
8371
8371
|
items,
|
|
8372
|
-
layout,
|
|
8372
|
+
layout: activePin ? "focus" : layout,
|
|
8373
8373
|
pinnedId: activePin ?? activeShare ?? (followed ? "whiteboard" : null),
|
|
8374
8374
|
onPinnedChange: setPin,
|
|
8375
|
-
onFollowChange: (id) => follow(followed === id ? null : id),
|
|
8375
|
+
onFollowChange: canFollow ? (id) => follow(followed === id ? null : id) : void 0,
|
|
8376
8376
|
followingId: followed,
|
|
8377
|
-
clickAction: canFollow ? "follow" : "pin",
|
|
8378
8377
|
renderContentTile,
|
|
8379
8378
|
onItemClick: focusContent,
|
|
8380
|
-
onOverflowClick
|
|
8379
|
+
onOverflowClick,
|
|
8381
8380
|
generatedAvatars,
|
|
8382
8381
|
emptyState: /* @__PURE__ */ jsx68(QuietSpace, {}),
|
|
8383
8382
|
className
|
|
@@ -8387,11 +8386,11 @@ function SpaceStage({ tiles, layout, onLayoutChange, generatedAvatars = true, wh
|
|
|
8387
8386
|
SpaceStage.displayName = "SpaceStage";
|
|
8388
8387
|
|
|
8389
8388
|
// src/components/space-view/useDrawerPresence.ts
|
|
8390
|
-
import { useEffect as useEffect35, useState as
|
|
8389
|
+
import { useEffect as useEffect35, useState as useState43 } from "react";
|
|
8391
8390
|
var DRAWER_EXIT_MS = 200;
|
|
8392
8391
|
function useDrawerPresence(panel, exitMs) {
|
|
8393
|
-
const [retained, setRetained] =
|
|
8394
|
-
const [state, setState] =
|
|
8392
|
+
const [retained, setRetained] = useState43(panel);
|
|
8393
|
+
const [state, setState] = useState43(panel === null ? "closed" : "open");
|
|
8395
8394
|
useEffect35(() => {
|
|
8396
8395
|
if (panel !== null) {
|
|
8397
8396
|
setRetained(panel);
|
|
@@ -8441,6 +8440,7 @@ function SpaceView({
|
|
|
8441
8440
|
onEndEpisode,
|
|
8442
8441
|
className
|
|
8443
8442
|
}) {
|
|
8443
|
+
const phone = useIsMobile();
|
|
8444
8444
|
const effectiveShareUrl = inviteLink ?? shareUrl;
|
|
8445
8445
|
const callToasts = useCallToasts();
|
|
8446
8446
|
const [soundsEnabled] = useSoundsSetting();
|
|
@@ -8451,7 +8451,7 @@ function SpaceView({
|
|
|
8451
8451
|
const media = useMedia();
|
|
8452
8452
|
const connection = useConnection();
|
|
8453
8453
|
const offline = useOffline();
|
|
8454
|
-
const [dismissedOfflineNotice, setDismissedOfflineNotice] =
|
|
8454
|
+
const [dismissedOfflineNotice, setDismissedOfflineNotice] = useState44(null);
|
|
8455
8455
|
const offlineNotice = offline.notice && offline.notice !== dismissedOfflineNotice ? offline.notice : null;
|
|
8456
8456
|
const recording = useRecording();
|
|
8457
8457
|
const canPublishScreen = useCan("publishScreen");
|
|
@@ -8462,9 +8462,9 @@ function SpaceView({
|
|
|
8462
8462
|
const canManageRecording = useCan("manageRecording");
|
|
8463
8463
|
const episodeDuration = useEpisodeDuration();
|
|
8464
8464
|
const deadline = connection.episode?.deadline;
|
|
8465
|
-
const [now, setNow] =
|
|
8465
|
+
const [now, setNow] = useState44(Date.now);
|
|
8466
8466
|
const previousCountdown = useRef29(null);
|
|
8467
|
-
const [limitWarning, setLimitWarning] =
|
|
8467
|
+
const [limitWarning, setLimitWarning] = useState44(null);
|
|
8468
8468
|
const countdown = callCountdown(deadline, now);
|
|
8469
8469
|
useEffect36(() => {
|
|
8470
8470
|
if (!deadline) return;
|
|
@@ -8480,13 +8480,14 @@ function SpaceView({
|
|
|
8480
8480
|
if (previous?.deadline !== deadline) setLimitWarning(null);
|
|
8481
8481
|
if (next.warning !== null) setLimitWarning({ id: `time-limit-${deadline}-${next.warning}`, minutes: next.warning });
|
|
8482
8482
|
}, [deadline, now]);
|
|
8483
|
-
const [uncontrolledLayout, setUncontrolledLayout] =
|
|
8484
|
-
const [
|
|
8485
|
-
const [
|
|
8486
|
-
const [
|
|
8487
|
-
const [
|
|
8488
|
-
const [
|
|
8489
|
-
const [
|
|
8483
|
+
const [uncontrolledLayout, setUncontrolledLayout] = useState44(controlledLayout ?? "focus");
|
|
8484
|
+
const [pinnedId, setPinnedId] = useState44(null);
|
|
8485
|
+
const [activePanel, setActivePanel] = useState44(initialPanel);
|
|
8486
|
+
const [isReactionPickerOpen, setReactionPickerOpen] = useState44(false);
|
|
8487
|
+
const [commandError, setCommandError] = useState44(null);
|
|
8488
|
+
const [commandSource, setCommandSource] = useState44();
|
|
8489
|
+
const [commandAction, setCommandAction] = useState44();
|
|
8490
|
+
const [retryCommand, setRetryCommand] = useState44();
|
|
8490
8491
|
const onCommandError = (failure, source, mediaSource, action, command) => {
|
|
8491
8492
|
if (!failure && commandError && typeof commandError === "object") callToasts.dismissFailure(commandError.code);
|
|
8492
8493
|
setCommandError(failure);
|
|
@@ -8521,7 +8522,9 @@ function SpaceView({
|
|
|
8521
8522
|
...feature("whiteboard") && canDrawWhiteboard ? ["whiteboard"] : [],
|
|
8522
8523
|
"leave"
|
|
8523
8524
|
];
|
|
8525
|
+
const headerLayout = pinnedId ? "focus" : layout;
|
|
8524
8526
|
const updateLayout = (nextLayout) => {
|
|
8527
|
+
if (nextLayout === "grid") setPinnedId(null);
|
|
8525
8528
|
setUncontrolledLayout(nextLayout);
|
|
8526
8529
|
onLayoutChange?.(nextLayout);
|
|
8527
8530
|
};
|
|
@@ -8557,7 +8560,7 @@ function SpaceView({
|
|
|
8557
8560
|
};
|
|
8558
8561
|
const mappedFailure = mediaFailureToast(typeof displayedCommandError === "object" ? displayedCommandError : null, displayedCommandSource, externalCommandError != null ? externalCommandAction : commandAction, externalCommandError == null && retryCommand ? () => void retryMedia() : void 0);
|
|
8559
8562
|
const commandToasts = mappedFailure ? [{ id: "space-command-error", ...mappedFailure }] : typeof displayedCommandError === "string" ? [{ id: "space-command-error", message: displayedCommandError, type: "error" }] : [];
|
|
8560
|
-
const [boardToasts, setBoardToasts] =
|
|
8563
|
+
const [boardToasts, setBoardToasts] = useState44([]);
|
|
8561
8564
|
const boardToastCount = useRef29(0);
|
|
8562
8565
|
useEffect36(() => {
|
|
8563
8566
|
if (!whiteboard?.isOpen) setBoardToasts([]);
|
|
@@ -8591,7 +8594,7 @@ function SpaceView({
|
|
|
8591
8594
|
else if (id.startsWith("board-")) setBoardToasts((current) => current.filter((toast) => toast.id !== id));
|
|
8592
8595
|
else callToasts.dismiss(id);
|
|
8593
8596
|
};
|
|
8594
|
-
const [foldedNotices, setFoldedNotices] =
|
|
8597
|
+
const [foldedNotices, setFoldedNotices] = useState44([]);
|
|
8595
8598
|
const folded = toasts.filter((toast) => foldedNotices.includes(toast.id));
|
|
8596
8599
|
return /* @__PURE__ */ jsx69(ParticipantVolumeProvider, { children: /* @__PURE__ */ jsx69(BoardToastContext2.Provider, { value: showBoardToast, children: /* @__PURE__ */ jsx69(
|
|
8597
8600
|
SpacePresentation,
|
|
@@ -8619,7 +8622,7 @@ function SpaceView({
|
|
|
8619
8622
|
onToggleHand: feature("handRaise") && canRaiseHand ? () => void runCommand(() => self.handRaised ? client.participants.lowerHand() : client.participants.raiseHand()) : void 0,
|
|
8620
8623
|
onToggleChat: feature("chat") ? () => setActivePanel((current) => current === "chat" ? null : "chat") : void 0,
|
|
8621
8624
|
onTogglePeople: feature("participants") ? () => setActivePanel((current) => current === "participants" ? null : "participants") : void 0,
|
|
8622
|
-
onToggleLayout: () => updateLayout(
|
|
8625
|
+
onToggleLayout: () => updateLayout(headerLayout === "grid" ? "focus" : "grid"),
|
|
8623
8626
|
onClosePanel: () => setActivePanel(null),
|
|
8624
8627
|
onPushToTalk: (enabled) => {
|
|
8625
8628
|
if (enabled && connection.status !== "live") return;
|
|
@@ -8629,13 +8632,15 @@ function SpaceView({
|
|
|
8629
8632
|
duration: episodeDuration,
|
|
8630
8633
|
timeLeft: countdown.seconds,
|
|
8631
8634
|
isRecording: recording.current?.status === "recording",
|
|
8632
|
-
layout,
|
|
8635
|
+
layout: headerLayout,
|
|
8633
8636
|
onLayoutChange: updateLayout,
|
|
8634
8637
|
notices: folded.length ? /* @__PURE__ */ jsx69(NoticeButton, { toasts: folded, onDismiss: dismissToast }) : void 0
|
|
8635
8638
|
},
|
|
8636
8639
|
stage: /* @__PURE__ */ jsx69(
|
|
8637
8640
|
SpaceStage,
|
|
8638
8641
|
{
|
|
8642
|
+
pinnedId,
|
|
8643
|
+
onPinnedChange: setPinnedId,
|
|
8639
8644
|
tiles,
|
|
8640
8645
|
layout,
|
|
8641
8646
|
onLayoutChange: updateLayout,
|
|
@@ -8691,7 +8696,20 @@ function SpaceView({
|
|
|
8691
8696
|
] }),
|
|
8692
8697
|
sidebar: /* @__PURE__ */ jsxs43(CallCard, { state: drawer.state, panel: drawer.panel, onPanelChange: setActivePanel, peopleCount: participantsSlice.roster.length, participantsEnabled: feature("participants"), chatEnabled: feature("chat"), onClose: () => setActivePanel(null), children: [
|
|
8693
8698
|
drawer.panel === "chat" && feature("chat") ? /* @__PURE__ */ jsx69(ChatPanel, { variant: "mobile", generatedAvatars, onClose: () => setActivePanel(null), pickChatFiles }) : null,
|
|
8694
|
-
drawer.panel === "participants" && feature("participants") ? /* @__PURE__ */ jsx69(
|
|
8699
|
+
drawer.panel === "participants" && feature("participants") ? /* @__PURE__ */ jsx69(
|
|
8700
|
+
ParticipantsPanel,
|
|
8701
|
+
{
|
|
8702
|
+
onParticipantClick: (id) => {
|
|
8703
|
+
setPinnedId((current) => current === id ? null : id);
|
|
8704
|
+
if (phone) setActivePanel(null);
|
|
8705
|
+
},
|
|
8706
|
+
variant: "mobile",
|
|
8707
|
+
admissionEnabled: feature("admission"),
|
|
8708
|
+
generatedAvatars,
|
|
8709
|
+
onCommandError,
|
|
8710
|
+
onClose: () => setActivePanel(null)
|
|
8711
|
+
}
|
|
8712
|
+
) : null,
|
|
8695
8713
|
drawer.panel === "admission" && feature("admission") ? /* @__PURE__ */ jsx69(AdmissionPanel, { className: "h-full w-full rounded-none shadow-none", onClose: () => setActivePanel(null) }) : null
|
|
8696
8714
|
] }),
|
|
8697
8715
|
toasts: /* @__PURE__ */ jsx69(ToastStack, { toasts, onDismiss: dismissToast, onFold: setFoldedNotices }),
|