@q9labsai/chalk-react 5.2.2 → 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-YLP43HHE.js → chunk-34SIWIY5.js} +349 -319
- package/dist/{chunk-NYP6LNZF.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) => {
|
|
@@ -5423,11 +5409,12 @@ ParticipantsPanel.displayName = "ParticipantsPanel";
|
|
|
5423
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
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";
|
|
5426
5413
|
const copy = {
|
|
5427
5414
|
entering: { title: `Joining ${callName}\u2026`, detail: "" },
|
|
5428
5415
|
left: { title: `You left ${callName}`, detail: "" },
|
|
5429
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: "" },
|
|
5430
|
-
failed: { title: `Couldn\u2019t connect to ${callName}`, detail: getConnectionFailureDetail({ code: errorCode, sync }) },
|
|
5417
|
+
failed: { title: connectionLost ? "Connection lost" : `Couldn\u2019t connect to ${callName}`, detail: getConnectionFailureDetail({ code: errorCode, sync }) },
|
|
5431
5418
|
removed: { title: `You were removed from ${callName}`, detail: "The host removed you from this call." },
|
|
5432
5419
|
full: { title: "This call is full", detail: `${callName} has reached 100 people. Ask the host to make room, then try again.` },
|
|
5433
5420
|
elsewhere: { title: "You joined from another tab", detail: `${callName} is open in another tab or window. Use it here instead?` }
|
|
@@ -5455,7 +5442,7 @@ function StatusSurface({ phase, callName = "the call", reason, episodeEndReason,
|
|
|
5455
5442
|
] }) : null,
|
|
5456
5443
|
/* @__PURE__ */ jsxs29("div", { "data-part": "status-actions", className: "mt-5 flex gap-7", children: [
|
|
5457
5444
|
phase === "episode-ended" && episodeEndReason === "maximum_duration" && endAction ? /* @__PURE__ */ jsx47(StatusAction, { icon: /* @__PURE__ */ jsx47(StatusIcon, { retry: true }), label: endAction.label, onClick: endAction.onClick }) : null,
|
|
5458
|
-
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,
|
|
5459
5446
|
phase !== "entering" && onHome ? /* @__PURE__ */ jsx47(StatusAction, { icon: /* @__PURE__ */ jsx47(StatusIcon, {}), label: "Home", onClick: onHome }) : null
|
|
5460
5447
|
] }),
|
|
5461
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
|
|
@@ -5486,7 +5473,7 @@ function StatusAction({ icon, label, onClick, disabled }) {
|
|
|
5486
5473
|
}
|
|
5487
5474
|
|
|
5488
5475
|
// src/components/call-limbo/CallReady.tsx
|
|
5489
|
-
import { useEffect as useEffect19, useId, useRef as useRef14, useState as
|
|
5476
|
+
import { useEffect as useEffect19, useId, useRef as useRef14, useState as useState25 } from "react";
|
|
5490
5477
|
|
|
5491
5478
|
// src/components/call-limbo/qr-code.ts
|
|
5492
5479
|
function inviteQR(text) {
|
|
@@ -5629,13 +5616,13 @@ function inviteQR(text) {
|
|
|
5629
5616
|
// src/components/call-limbo/CallReady.tsx
|
|
5630
5617
|
import { Fragment as Fragment19, jsx as jsx48, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5631
5618
|
function CallReady({ open, onClose, link = typeof location === "undefined" ? "" : location.href }) {
|
|
5632
|
-
const [showQR, setShowQR] =
|
|
5619
|
+
const [showQR, setShowQR] = useState25(false);
|
|
5633
5620
|
const qrRef = useRef14(null);
|
|
5634
5621
|
const cardRef = useRef14(null);
|
|
5635
5622
|
const phone = useIsMobile();
|
|
5636
5623
|
const reducedMotion = usePrefersReducedMotion();
|
|
5637
|
-
const [entered, setEntered] =
|
|
5638
|
-
const [present, setPresent] =
|
|
5624
|
+
const [entered, setEntered] = useState25(false);
|
|
5625
|
+
const [present, setPresent] = useState25(open);
|
|
5639
5626
|
const id = useId();
|
|
5640
5627
|
const qr = showQR ? inviteQR(link) : null;
|
|
5641
5628
|
const close = () => {
|
|
@@ -5716,11 +5703,11 @@ function CallReady({ open, onClose, link = typeof location === "undefined" ? ""
|
|
|
5716
5703
|
}
|
|
5717
5704
|
|
|
5718
5705
|
// src/components/toast-stack/ToastStack.tsx
|
|
5719
|
-
import { memo, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as
|
|
5706
|
+
import { memo, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as useState27 } from "react";
|
|
5720
5707
|
import { flushSync as flushSync2 } from "react-dom";
|
|
5721
5708
|
|
|
5722
5709
|
// src/components/toast-stack/useToastCapacity.ts
|
|
5723
|
-
import { isValidElement as isValidElement2, useLayoutEffect as useLayoutEffect2, useState as
|
|
5710
|
+
import { isValidElement as isValidElement2, useLayoutEffect as useLayoutEffect2, useState as useState26 } from "react";
|
|
5724
5711
|
import { flushSync } from "react-dom";
|
|
5725
5712
|
|
|
5726
5713
|
// src/components/toast-stack/toast-layout-snapshot.ts
|
|
@@ -5765,7 +5752,7 @@ function measureToastLayout(stack, snapshot) {
|
|
|
5765
5752
|
|
|
5766
5753
|
// src/components/toast-stack/useToastCapacity.ts
|
|
5767
5754
|
function useToastCapacity(stack, candidates, enabled, ownedIds) {
|
|
5768
|
-
const [fit, setFit] =
|
|
5755
|
+
const [fit, setFit] = useState26(null);
|
|
5769
5756
|
let count = candidates.length;
|
|
5770
5757
|
if (enabled) {
|
|
5771
5758
|
count = 0;
|
|
@@ -5859,7 +5846,7 @@ var ToastStack = memo(function ToastStack2({ toasts, onDismiss, maxVisible = 3,
|
|
|
5859
5846
|
const stack = useRef15(null);
|
|
5860
5847
|
const short = useShortCall(stack, onFold !== void 0);
|
|
5861
5848
|
const candidates = maxVisible > 0 ? toasts.slice(-maxVisible) : [];
|
|
5862
|
-
const [ownedIds, setOwnedIds] =
|
|
5849
|
+
const [ownedIds, setOwnedIds] = useState27([]);
|
|
5863
5850
|
const fold = useRef15(onFold);
|
|
5864
5851
|
const capacity = useToastCapacity(stack, candidates, onFold !== void 0 && short === false, ownedIds);
|
|
5865
5852
|
const selected = onFold !== void 0 && short !== false ? [] : candidates.slice(candidates.length - capacity.count);
|
|
@@ -5868,7 +5855,7 @@ var ToastStack = memo(function ToastStack2({ toasts, onDismiss, maxVisible = 3,
|
|
|
5868
5855
|
const foldedIds = folded.map((toast) => toast.id);
|
|
5869
5856
|
const announced = useRef15(/* @__PURE__ */ new Map());
|
|
5870
5857
|
const wasAnnounced = (toast) => announced.current.get(toast.id) === noticeIdentity(toast);
|
|
5871
|
-
const [unheard, setUnheard] =
|
|
5858
|
+
const [unheard, setUnheard] = useState27([]);
|
|
5872
5859
|
const reported = useRef15([]);
|
|
5873
5860
|
const reporting = useRef15(false);
|
|
5874
5861
|
useLayoutEffect3(() => {
|
|
@@ -5915,7 +5902,7 @@ var ToastStack = memo(function ToastStack2({ toasts, onDismiss, maxVisible = 3,
|
|
|
5915
5902
|
] });
|
|
5916
5903
|
});
|
|
5917
5904
|
function useShortCall(stack, enabled) {
|
|
5918
|
-
const [short, setShort] =
|
|
5905
|
+
const [short, setShort] = useState27(null);
|
|
5919
5906
|
useLayoutEffect3(() => {
|
|
5920
5907
|
if (!enabled) {
|
|
5921
5908
|
setShort(null);
|
|
@@ -5936,7 +5923,7 @@ function sameIds(a, b) {
|
|
|
5936
5923
|
}
|
|
5937
5924
|
|
|
5938
5925
|
// src/internal/call-motion.ts
|
|
5939
|
-
import { useEffect as useEffect20, useState as
|
|
5926
|
+
import { useEffect as useEffect20, useState as useState28 } from "react";
|
|
5940
5927
|
var moves = /* @__PURE__ */ new WeakMap();
|
|
5941
5928
|
function captureFlip(elements) {
|
|
5942
5929
|
const previous = Array.from(elements, (element) => ({ element, box: element.getBoundingClientRect() }));
|
|
@@ -5964,7 +5951,7 @@ function playFlip(previous) {
|
|
|
5964
5951
|
}
|
|
5965
5952
|
var ACTIVE_LAYERS = '[role="menu"],[role="dialog"],[data-part="toast"],[data-part="notice-button"],[data-chalk-drawer]';
|
|
5966
5953
|
function useIdleChrome(root, enabled) {
|
|
5967
|
-
const [idle, setIdle] =
|
|
5954
|
+
const [idle, setIdle] = useState28(false);
|
|
5968
5955
|
const fine = useMediaQuery("(pointer:fine) and (min-width:641px)");
|
|
5969
5956
|
useEffect20(() => {
|
|
5970
5957
|
const element = root.current;
|
|
@@ -5996,7 +5983,7 @@ function useIdleChrome(root, enabled) {
|
|
|
5996
5983
|
}
|
|
5997
5984
|
|
|
5998
5985
|
// src/components/space-header/SpaceHeader.tsx
|
|
5999
|
-
import React14, { useCallback as useCallback6, useRef as useRef18, useState as
|
|
5986
|
+
import React14, { useCallback as useCallback6, useRef as useRef18, useState as useState30 } from "react";
|
|
6000
5987
|
|
|
6001
5988
|
// src/internal/useSoundsSetting.ts
|
|
6002
5989
|
import { useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
@@ -6048,7 +6035,7 @@ function LayoutMenu({ layout, onLayoutChange }) {
|
|
|
6048
6035
|
|
|
6049
6036
|
// src/components/space-header/CallDetails.tsx
|
|
6050
6037
|
import { Dialog as Dialog2 } from "@base-ui/react/dialog";
|
|
6051
|
-
import { useEffect as useEffect21, useRef as useRef16, useState as
|
|
6038
|
+
import { useEffect as useEffect21, useRef as useRef16, useState as useState29 } from "react";
|
|
6052
6039
|
|
|
6053
6040
|
// src/components/space-header/share-qr.ts
|
|
6054
6041
|
function shareQr(text) {
|
|
@@ -6203,10 +6190,10 @@ function CallDialog({
|
|
|
6203
6190
|
const container = useRef16(null);
|
|
6204
6191
|
const reportInput = useRef16(null);
|
|
6205
6192
|
const reportOpener = useRef16(null);
|
|
6206
|
-
const [text, setText] =
|
|
6207
|
-
const [includeDiagnostics, setIncludeDiagnostics] =
|
|
6208
|
-
const [status, setStatus] =
|
|
6209
|
-
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("");
|
|
6210
6197
|
useEffect21(() => {
|
|
6211
6198
|
if (open && kind === "report") {
|
|
6212
6199
|
setText("");
|
|
@@ -6341,7 +6328,7 @@ function CallDetails({
|
|
|
6341
6328
|
}) {
|
|
6342
6329
|
const link = shareUrl ?? (typeof location === "undefined" ? "" : location.href);
|
|
6343
6330
|
const qr = shareQr(link);
|
|
6344
|
-
const [details, setDetails] =
|
|
6331
|
+
const [details, setDetails] = useState29(false);
|
|
6345
6332
|
return /* @__PURE__ */ jsxs32("div", { className: "chalk-details", children: [
|
|
6346
6333
|
/* @__PURE__ */ jsxs32("div", { className: "chalk-shell-details-heading", children: [
|
|
6347
6334
|
/* @__PURE__ */ jsx51("h2", { children: spaceName }),
|
|
@@ -6493,8 +6480,8 @@ var SpaceHeader = React14.memo((props) => {
|
|
|
6493
6480
|
const [sounds, setSounds] = useSoundsSetting();
|
|
6494
6481
|
const triggerRef = useRef18(null);
|
|
6495
6482
|
const focusScope = useRef18(null);
|
|
6496
|
-
const [open, setOpen] =
|
|
6497
|
-
const [dialog, setDialog] =
|
|
6483
|
+
const [open, setOpen] = useState30(false);
|
|
6484
|
+
const [dialog, setDialog] = useState30({ kind: "shortcuts", open: false });
|
|
6498
6485
|
const showShortcuts = useCallback6(() => setDialog({ kind: "shortcuts", open: true }), []);
|
|
6499
6486
|
useCallShortcuts(props.shortcuts, showShortcuts);
|
|
6500
6487
|
const phone = useMediaQuery("(max-width: 640px)");
|
|
@@ -6581,16 +6568,16 @@ var SpaceHeader = React14.memo((props) => {
|
|
|
6581
6568
|
SpaceHeader.displayName = "SpaceHeader";
|
|
6582
6569
|
|
|
6583
6570
|
// src/components/composite/ScreenShareView.tsx
|
|
6584
|
-
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";
|
|
6585
6572
|
import { Fragment as Fragment23, jsx as jsx53, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6586
6573
|
function ScreenSharePresentation({ sharedByName, media, mediaVisible, state, isLocal = false, hasAudio = false, capture: capture2, primary = true, pinned, hidden, style, onClick, onDoubleClick, onStopSharing, onChangeShare, switcher, className }) {
|
|
6587
6574
|
const root = useRef19(null);
|
|
6588
|
-
const [fill, setFill] =
|
|
6589
|
-
const [controlsOpen, setControlsOpen] =
|
|
6590
|
-
const [poppedOut, setPoppedOut] =
|
|
6591
|
-
const [zoom, setZoom] =
|
|
6592
|
-
const [pending, setPending] =
|
|
6593
|
-
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);
|
|
6594
6581
|
const status = state ?? (mediaVisible ? "live" : "connecting");
|
|
6595
6582
|
const name = isLocal ? "Your screen" : `${sharedByName}'s screen`;
|
|
6596
6583
|
const source = capture2?.surface === "window" ? "a window" : capture2?.surface === "browser" ? "a tab" : capture2?.surface === "monitor" ? "your screen" : null;
|
|
@@ -6776,16 +6763,16 @@ function ScreenShareView(props) {
|
|
|
6776
6763
|
}
|
|
6777
6764
|
|
|
6778
6765
|
// src/components/stage/Stage.tsx
|
|
6779
|
-
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";
|
|
6780
6767
|
import { createPortal as createPortal2 } from "react-dom";
|
|
6781
6768
|
|
|
6782
6769
|
// src/components/stage/useStageDimensions.ts
|
|
6783
|
-
import { useLayoutEffect as useLayoutEffect4, useRef as useRef20, useState as
|
|
6770
|
+
import { useLayoutEffect as useLayoutEffect4, useRef as useRef20, useState as useState32 } from "react";
|
|
6784
6771
|
import { flushSync as flushSync3 } from "react-dom";
|
|
6785
6772
|
function useStageDimensions(fallback3) {
|
|
6786
6773
|
const ref = useRef20(null);
|
|
6787
6774
|
const current = useRef20(fallback3);
|
|
6788
|
-
const [dimensions, setDimensions] =
|
|
6775
|
+
const [dimensions, setDimensions] = useState32(fallback3);
|
|
6789
6776
|
useLayoutEffect4(() => {
|
|
6790
6777
|
const element = ref.current;
|
|
6791
6778
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
@@ -6981,7 +6968,7 @@ function createContentPlacement() {
|
|
|
6981
6968
|
};
|
|
6982
6969
|
}
|
|
6983
6970
|
function PersistentStageContent({ placement, children }) {
|
|
6984
|
-
const [host, setHost] =
|
|
6971
|
+
const [host, setHost] = useState33(null);
|
|
6985
6972
|
useLayoutEffect5(() => {
|
|
6986
6973
|
const element = document.createElement("div");
|
|
6987
6974
|
Object.assign(element.style, TILE_FILL);
|
|
@@ -7006,7 +6993,6 @@ function Stage({
|
|
|
7006
6993
|
pinnedId,
|
|
7007
6994
|
followingId = null,
|
|
7008
6995
|
onFollowChange,
|
|
7009
|
-
clickAction = "pin",
|
|
7010
6996
|
onPinnedChange,
|
|
7011
6997
|
onOverflowClick,
|
|
7012
6998
|
onItemClick,
|
|
@@ -7025,9 +7011,9 @@ function Stage({
|
|
|
7025
7011
|
}) {
|
|
7026
7012
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7027
7013
|
const { ref: boxRef, dimensions: box } = useStageDimensions(FALLBACK_BOX);
|
|
7028
|
-
const [overflowOpen, setOverflowOpen] =
|
|
7029
|
-
const [shareAspects, setShareAspects] =
|
|
7030
|
-
const [uncontrolledPinnedId, setUncontrolledPinnedId] =
|
|
7014
|
+
const [overflowOpen, setOverflowOpen] = useState33(false);
|
|
7015
|
+
const [shareAspects, setShareAspects] = useState33(/* @__PURE__ */ new Map());
|
|
7016
|
+
const [uncontrolledPinnedId, setUncontrolledPinnedId] = useState33(null);
|
|
7031
7017
|
const activePinnedId = pinnedId === void 0 ? uncontrolledPinnedId : pinnedId;
|
|
7032
7018
|
const orderRef = useRef22([]);
|
|
7033
7019
|
const seenAtRef = useRef22(/* @__PURE__ */ new Map());
|
|
@@ -7108,7 +7094,7 @@ function Stage({
|
|
|
7108
7094
|
return /* @__PURE__ */ jsx56(StageContentTile, { item, ...context });
|
|
7109
7095
|
};
|
|
7110
7096
|
const animate = animateOverride ?? !prefersReducedMotion;
|
|
7111
|
-
const [displayed, setDisplayed] =
|
|
7097
|
+
const [displayed, setDisplayed] = useState33({
|
|
7112
7098
|
source: ordered,
|
|
7113
7099
|
geometry,
|
|
7114
7100
|
tiles: ordered.map((item) => ({ item, frame: framesById.get(item.id), leaving: false }))
|
|
@@ -7174,15 +7160,14 @@ function Stage({
|
|
|
7174
7160
|
for (const item of ordered) {
|
|
7175
7161
|
map.set(item.id, {
|
|
7176
7162
|
onClick: () => {
|
|
7177
|
-
|
|
7178
|
-
else togglePin(item);
|
|
7163
|
+
togglePin(item);
|
|
7179
7164
|
onItemClick?.(item);
|
|
7180
7165
|
},
|
|
7181
7166
|
onDoubleClick: onItemDoubleClick ? () => onItemDoubleClick(item) : void 0
|
|
7182
7167
|
});
|
|
7183
7168
|
}
|
|
7184
7169
|
return map;
|
|
7185
|
-
}, [
|
|
7170
|
+
}, [interactive, onItemDoubleClick, onItemClick, ordered, togglePin]);
|
|
7186
7171
|
if (ordered.length === 0) {
|
|
7187
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 });
|
|
7188
7173
|
}
|
|
@@ -7207,7 +7192,7 @@ function Stage({
|
|
|
7207
7192
|
aspectRatio: "fill",
|
|
7208
7193
|
primary: frame?.role === "primary",
|
|
7209
7194
|
pinned,
|
|
7210
|
-
|
|
7195
|
+
onFollow: onFollowChange && !item.participant.isLocal ? () => onFollowChange(item.id) : void 0,
|
|
7211
7196
|
following: followingId === item.id,
|
|
7212
7197
|
onClick: click,
|
|
7213
7198
|
onDoubleClick: doubleClick,
|
|
@@ -7268,7 +7253,6 @@ function Stage({
|
|
|
7268
7253
|
setOverflowOpen(false);
|
|
7269
7254
|
},
|
|
7270
7255
|
children: [
|
|
7271
|
-
clickAction === "follow" && !item.participant.isLocal ? `${followingId === item.id ? "Stop following" : "Follow"} ` : "",
|
|
7272
7256
|
item.participant.displayName,
|
|
7273
7257
|
item.participant.isMuted ? " \xB7 Muted" : ""
|
|
7274
7258
|
]
|
|
@@ -7477,7 +7461,7 @@ function SpacePresentation({ colorScheme = "dark", stageBackground, header, stag
|
|
|
7477
7461
|
// src/components/space-view/SpaceView.tsx
|
|
7478
7462
|
import "@q9labsai/chalk-client";
|
|
7479
7463
|
import { DEFAULT_QUICK_REACTIONS as DEFAULT_QUICK_REACTIONS2 } from "@q9labsai/chalk-ui/reactions";
|
|
7480
|
-
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";
|
|
7481
7465
|
|
|
7482
7466
|
// src/components/space-header/call-diagnostics.ts
|
|
7483
7467
|
function callDiagnostics(connection, media) {
|
|
@@ -7508,11 +7492,11 @@ function callCountdown(deadline, now, previousSeconds) {
|
|
|
7508
7492
|
}
|
|
7509
7493
|
|
|
7510
7494
|
// src/internal/useEpisodeDuration.ts
|
|
7511
|
-
import { useEffect as useEffect26, useState as
|
|
7495
|
+
import { useEffect as useEffect26, useState as useState34 } from "react";
|
|
7512
7496
|
function useEpisodeDuration() {
|
|
7513
7497
|
const connection = useConnection();
|
|
7514
7498
|
const episodeStart = connection.episode?.startedAt ? Date.parse(connection.episode.startedAt) : null;
|
|
7515
|
-
const [now, setNow] =
|
|
7499
|
+
const [now, setNow] = useState34(() => Date.now());
|
|
7516
7500
|
useEffect26(() => {
|
|
7517
7501
|
if (episodeStart === null || Number.isNaN(episodeStart)) return;
|
|
7518
7502
|
setNow(Date.now());
|
|
@@ -7568,16 +7552,17 @@ function createSoundPlayer({ outputDeviceId } = {}) {
|
|
|
7568
7552
|
const created = !context;
|
|
7569
7553
|
try {
|
|
7570
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);
|
|
7571
7557
|
} catch {
|
|
7572
7558
|
return;
|
|
7573
7559
|
}
|
|
7574
|
-
if (created && outputDeviceId && "setSinkId" in context && typeof context.setSinkId === "function") void Promise.resolve(context.setSinkId(outputDeviceId)).catch(() => void 0);
|
|
7575
|
-
if (context.state === "suspended") void context.resume().catch(() => void 0);
|
|
7576
7560
|
};
|
|
7577
7561
|
if (typeof window !== "undefined") {
|
|
7578
7562
|
window.addEventListener("click", unlock, { capture: true });
|
|
7579
7563
|
window.addEventListener("keydown", unlock, { capture: true });
|
|
7580
7564
|
}
|
|
7565
|
+
unlock();
|
|
7581
7566
|
const tone = (frequency, offset, duration, volume = 0.07, type = "sine", to) => {
|
|
7582
7567
|
if (!context || context.state !== "running") return;
|
|
7583
7568
|
const oscillator = context.createOscillator(), gain = context.createGain(), time = context.currentTime + offset;
|
|
@@ -7616,44 +7601,47 @@ function createSoundPlayer({ outputDeviceId } = {}) {
|
|
|
7616
7601
|
return {
|
|
7617
7602
|
play(cue) {
|
|
7618
7603
|
if (disposed || !context || context.state !== "running") return;
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
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
|
-
|
|
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 {
|
|
7657
7645
|
}
|
|
7658
7646
|
},
|
|
7659
7647
|
dispose() {
|
|
@@ -7662,7 +7650,7 @@ function createSoundPlayer({ outputDeviceId } = {}) {
|
|
|
7662
7650
|
window.removeEventListener("click", unlock, true);
|
|
7663
7651
|
window.removeEventListener("keydown", unlock, true);
|
|
7664
7652
|
}
|
|
7665
|
-
if (context) void context.close();
|
|
7653
|
+
if (context) void Promise.resolve(context.close()).catch(() => void 0);
|
|
7666
7654
|
}
|
|
7667
7655
|
};
|
|
7668
7656
|
}
|
|
@@ -7693,9 +7681,21 @@ function useSoundCues(enabled, createPlayer = createSoundPlayer) {
|
|
|
7693
7681
|
const player = createPlayerRef.current({ outputDeviceId });
|
|
7694
7682
|
playerRef.current = player;
|
|
7695
7683
|
let previous = client.getSnapshot();
|
|
7684
|
+
const seenParticipants = new Set(previous.participants.roster.map((participant) => participant.participantId));
|
|
7685
|
+
let lastJoinAt = -Infinity;
|
|
7696
7686
|
const unsubscribe = client.subscribe(() => {
|
|
7697
7687
|
const next = client.getSnapshot();
|
|
7698
|
-
|
|
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);
|
|
7699
7699
|
previous = next;
|
|
7700
7700
|
});
|
|
7701
7701
|
const offError = client.on("error", ({ error }) => playFailure(error));
|
|
@@ -7719,14 +7719,14 @@ function useSoundCues(enabled, createPlayer = createSoundPlayer) {
|
|
|
7719
7719
|
}
|
|
7720
7720
|
|
|
7721
7721
|
// src/components/composite/ReactionPicker.tsx
|
|
7722
|
-
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";
|
|
7723
7723
|
import { DEFAULT_QUICK_REACTIONS, EMOJI_CATEGORIES, EMOJI_KEYWORDS } from "@q9labsai/chalk-ui/reactions";
|
|
7724
7724
|
|
|
7725
7725
|
// src/components/composite/ReactionTray.tsx
|
|
7726
|
-
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";
|
|
7727
7727
|
import { Fragment as Fragment27, jsx as jsx61, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
7728
7728
|
function ReactionTray({ isHandRaised, onToggleHandRaise, reactions, onSelect, onClose, position = "top", className }) {
|
|
7729
|
-
const [more, setMore] =
|
|
7729
|
+
const [more, setMore] = useState35(false);
|
|
7730
7730
|
const returnFocus = useRef26(null);
|
|
7731
7731
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7732
7732
|
const { trigger } = useHaptics();
|
|
@@ -7811,8 +7811,8 @@ import { Fragment as Fragment28, jsx as jsx62, jsxs as jsxs40 } from "react/jsx-
|
|
|
7811
7811
|
var ReactionPicker = React21.memo(({ isHandRaised, onToggleHandRaise, isOpen, onClose, onSelect, recentReactions = [], allowedReactions, position = "top", participantColorSeed, participantGradientPreference, className, size = "default" }) => {
|
|
7812
7812
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7813
7813
|
const { trigger } = useHaptics();
|
|
7814
|
-
const [activeCategory, setActiveCategory] =
|
|
7815
|
-
const [searchQuery, setSearchQuery] =
|
|
7814
|
+
const [activeCategory, setActiveCategory] = useState36("smileys");
|
|
7815
|
+
const [searchQuery, setSearchQuery] = useState36("");
|
|
7816
7816
|
const inputRef = useRef27(null);
|
|
7817
7817
|
const themeVariables = useMemo14(() => getParticipantThemeVariables(participantColorSeed, participantGradientPreference), [participantColorSeed, participantGradientPreference]);
|
|
7818
7818
|
useEffect29(() => {
|
|
@@ -7969,7 +7969,7 @@ var ReactionPicker = React21.memo(({ isHandRaised, onToggleHandRaise, isOpen, on
|
|
|
7969
7969
|
ReactionPicker.displayName = "ReactionPicker";
|
|
7970
7970
|
|
|
7971
7971
|
// src/components/offline-actions/OfflineActions.tsx
|
|
7972
|
-
import { useEffect as useEffect30, useState as
|
|
7972
|
+
import { useEffect as useEffect30, useState as useState37, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
7973
7973
|
import { jsx as jsx63 } from "react/jsx-runtime";
|
|
7974
7974
|
var RECONNECTING_GRACE_MS = 2e3;
|
|
7975
7975
|
function offlineNoticeText(pendingCount, online) {
|
|
@@ -7997,7 +7997,7 @@ function OfflineActions({ reconnecting: requestedReconnecting = false, hasNotice
|
|
|
7997
7997
|
return null;
|
|
7998
7998
|
}
|
|
7999
7999
|
function useTrueFor(value, milliseconds) {
|
|
8000
|
-
const [elapsed, setElapsed] =
|
|
8000
|
+
const [elapsed, setElapsed] = useState37(false);
|
|
8001
8001
|
useEffect30(() => {
|
|
8002
8002
|
setElapsed(false);
|
|
8003
8003
|
if (!value) return;
|
|
@@ -8019,12 +8019,12 @@ function readOnline() {
|
|
|
8019
8019
|
}
|
|
8020
8020
|
|
|
8021
8021
|
// src/components/reconnecting-overlay/ReconnectingOverlay.tsx
|
|
8022
|
-
import { memo as memo3, useEffect as useEffect31, useState as
|
|
8022
|
+
import { memo as memo3, useEffect as useEffect31, useState as useState38 } from "react";
|
|
8023
8023
|
import { jsx as jsx64 } from "react/jsx-runtime";
|
|
8024
8024
|
var RECONNECTING_NOTICE_MS = 2e3;
|
|
8025
8025
|
var ReconnectingOverlay = memo3(function ReconnectingOverlay2({ isVisible, status, onRetry, onLeft, message, showNotice }) {
|
|
8026
8026
|
const reconnecting = isVisible && status === "reconnecting";
|
|
8027
|
-
const [elapsed, setElapsed] =
|
|
8027
|
+
const [elapsed, setElapsed] = useState38(false);
|
|
8028
8028
|
useEffect31(() => {
|
|
8029
8029
|
setElapsed(false);
|
|
8030
8030
|
if (!reconnecting) return;
|
|
@@ -8039,7 +8039,7 @@ var ReconnectingOverlay = memo3(function ReconnectingOverlay2({ isVisible, statu
|
|
|
8039
8039
|
});
|
|
8040
8040
|
|
|
8041
8041
|
// src/components/toast-stack/useCallToasts.ts
|
|
8042
|
-
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";
|
|
8043
8043
|
|
|
8044
8044
|
// src/components/toast-stack/call-events.tsx
|
|
8045
8045
|
import { Fragment as Fragment29, jsx as jsx65, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
@@ -8136,7 +8136,7 @@ function callEventToasts(previous, next) {
|
|
|
8136
8136
|
// src/components/toast-stack/useCallToasts.ts
|
|
8137
8137
|
function useCallToasts() {
|
|
8138
8138
|
const client = useSpaceClient();
|
|
8139
|
-
const [toasts, setToasts] =
|
|
8139
|
+
const [toasts, setToasts] = useState39([]);
|
|
8140
8140
|
const sequence = useRef28(0);
|
|
8141
8141
|
useEffect32(() => {
|
|
8142
8142
|
setToasts([]);
|
|
@@ -8177,9 +8177,9 @@ function useCallToasts() {
|
|
|
8177
8177
|
}
|
|
8178
8178
|
|
|
8179
8179
|
// src/components/call-limbo/useCallLink.ts
|
|
8180
|
-
import { useEffect as useEffect33, useState as
|
|
8180
|
+
import { useEffect as useEffect33, useState as useState40 } from "react";
|
|
8181
8181
|
function useCallLink(alone) {
|
|
8182
|
-
const [open, setOpen] =
|
|
8182
|
+
const [open, setOpen] = useState40(alone);
|
|
8183
8183
|
useEffect33(() => {
|
|
8184
8184
|
if (!alone) setOpen(false);
|
|
8185
8185
|
}, [alone]);
|
|
@@ -8187,10 +8187,10 @@ function useCallLink(alone) {
|
|
|
8187
8187
|
}
|
|
8188
8188
|
|
|
8189
8189
|
// src/components/toast-stack/NoticeButton.tsx
|
|
8190
|
-
import { useState as
|
|
8190
|
+
import { useState as useState41 } from "react";
|
|
8191
8191
|
import { jsx as jsx66, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
8192
8192
|
function NoticeButton({ toasts, onDismiss }) {
|
|
8193
|
-
const [open, setOpen] =
|
|
8193
|
+
const [open, setOpen] = useState41(false);
|
|
8194
8194
|
if (toasts.length === 0) return null;
|
|
8195
8195
|
const label = toasts.length === 1 ? "1 notice" : `${toasts.length} notices`;
|
|
8196
8196
|
const trigger = /* @__PURE__ */ jsxs42("button", { type: "button", "data-part": "notice-button", className: "chalk-notice-button", "aria-label": `Show ${label}`, children: [
|
|
@@ -8212,7 +8212,7 @@ function NoticeButton({ toasts, onDismiss }) {
|
|
|
8212
8212
|
import { BoardToastContext as BoardToastContext2 } from "@q9labsai/chalk-whiteboard/react";
|
|
8213
8213
|
|
|
8214
8214
|
// src/components/stage/SpaceStage.tsx
|
|
8215
|
-
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";
|
|
8216
8216
|
|
|
8217
8217
|
// src/components/board/Board.tsx
|
|
8218
8218
|
import { useContext as useContext3, useMemo as useMemo16 } from "react";
|
|
@@ -8282,31 +8282,43 @@ function Board(props) {
|
|
|
8282
8282
|
|
|
8283
8283
|
// src/components/stage/SpaceStage.tsx
|
|
8284
8284
|
import { jsx as jsx68 } from "react/jsx-runtime";
|
|
8285
|
-
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 }) {
|
|
8286
8286
|
const items = useMemo17(() => buildStageItems(tiles, whiteboard?.isOpen === true), [tiles, whiteboard?.isOpen]);
|
|
8287
|
-
const [selectedShare, setSelectedShare] =
|
|
8288
|
-
const [
|
|
8289
|
-
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);
|
|
8290
8298
|
const boardOpen = whiteboard?.isOpen === true && Boolean(whiteboard.props);
|
|
8291
8299
|
useEffect34(() => {
|
|
8292
|
-
if (!boardOpen) setFollowing(
|
|
8300
|
+
if (!boardOpen) setFollowing(void 0);
|
|
8293
8301
|
}, [boardOpen]);
|
|
8294
8302
|
const canFollow = boardOpen && Boolean(whiteboard?.sendView);
|
|
8295
|
-
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;
|
|
8296
8305
|
const activePin = items.some((item) => item.id === pin) ? pin : null;
|
|
8297
8306
|
const shares = items.filter((item) => item.kind === "screen-share");
|
|
8298
8307
|
const activeShare = selectedShare && shares.some((item) => item.id === selectedShare) ? selectedShare : null;
|
|
8299
8308
|
useEffect34(() => {
|
|
8300
8309
|
if (pin !== activePin) setPin(activePin);
|
|
8301
8310
|
if (selectedShare !== activeShare) setSelectedShare(activeShare);
|
|
8302
|
-
}, [pin, activePin, selectedShare, activeShare]);
|
|
8303
|
-
const follow = useCallback13(
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
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
|
+
);
|
|
8310
8322
|
const renderContentTile = useCallback13(
|
|
8311
8323
|
(item, context) => {
|
|
8312
8324
|
if (item.kind === "screen-share")
|
|
@@ -8357,15 +8369,14 @@ function SpaceStage({ tiles, layout, onLayoutChange, generatedAvatars = true, wh
|
|
|
8357
8369
|
Stage,
|
|
8358
8370
|
{
|
|
8359
8371
|
items,
|
|
8360
|
-
layout,
|
|
8372
|
+
layout: activePin ? "focus" : layout,
|
|
8361
8373
|
pinnedId: activePin ?? activeShare ?? (followed ? "whiteboard" : null),
|
|
8362
8374
|
onPinnedChange: setPin,
|
|
8363
|
-
onFollowChange: (id) => follow(followed === id ? null : id),
|
|
8375
|
+
onFollowChange: canFollow ? (id) => follow(followed === id ? null : id) : void 0,
|
|
8364
8376
|
followingId: followed,
|
|
8365
|
-
clickAction: canFollow ? "follow" : "pin",
|
|
8366
8377
|
renderContentTile,
|
|
8367
8378
|
onItemClick: focusContent,
|
|
8368
|
-
onOverflowClick
|
|
8379
|
+
onOverflowClick,
|
|
8369
8380
|
generatedAvatars,
|
|
8370
8381
|
emptyState: /* @__PURE__ */ jsx68(QuietSpace, {}),
|
|
8371
8382
|
className
|
|
@@ -8375,11 +8386,11 @@ function SpaceStage({ tiles, layout, onLayoutChange, generatedAvatars = true, wh
|
|
|
8375
8386
|
SpaceStage.displayName = "SpaceStage";
|
|
8376
8387
|
|
|
8377
8388
|
// src/components/space-view/useDrawerPresence.ts
|
|
8378
|
-
import { useEffect as useEffect35, useState as
|
|
8389
|
+
import { useEffect as useEffect35, useState as useState43 } from "react";
|
|
8379
8390
|
var DRAWER_EXIT_MS = 200;
|
|
8380
8391
|
function useDrawerPresence(panel, exitMs) {
|
|
8381
|
-
const [retained, setRetained] =
|
|
8382
|
-
const [state, setState] =
|
|
8392
|
+
const [retained, setRetained] = useState43(panel);
|
|
8393
|
+
const [state, setState] = useState43(panel === null ? "closed" : "open");
|
|
8383
8394
|
useEffect35(() => {
|
|
8384
8395
|
if (panel !== null) {
|
|
8385
8396
|
setRetained(panel);
|
|
@@ -8429,6 +8440,7 @@ function SpaceView({
|
|
|
8429
8440
|
onEndEpisode,
|
|
8430
8441
|
className
|
|
8431
8442
|
}) {
|
|
8443
|
+
const phone = useIsMobile();
|
|
8432
8444
|
const effectiveShareUrl = inviteLink ?? shareUrl;
|
|
8433
8445
|
const callToasts = useCallToasts();
|
|
8434
8446
|
const [soundsEnabled] = useSoundsSetting();
|
|
@@ -8439,7 +8451,7 @@ function SpaceView({
|
|
|
8439
8451
|
const media = useMedia();
|
|
8440
8452
|
const connection = useConnection();
|
|
8441
8453
|
const offline = useOffline();
|
|
8442
|
-
const [dismissedOfflineNotice, setDismissedOfflineNotice] =
|
|
8454
|
+
const [dismissedOfflineNotice, setDismissedOfflineNotice] = useState44(null);
|
|
8443
8455
|
const offlineNotice = offline.notice && offline.notice !== dismissedOfflineNotice ? offline.notice : null;
|
|
8444
8456
|
const recording = useRecording();
|
|
8445
8457
|
const canPublishScreen = useCan("publishScreen");
|
|
@@ -8450,9 +8462,9 @@ function SpaceView({
|
|
|
8450
8462
|
const canManageRecording = useCan("manageRecording");
|
|
8451
8463
|
const episodeDuration = useEpisodeDuration();
|
|
8452
8464
|
const deadline = connection.episode?.deadline;
|
|
8453
|
-
const [now, setNow] =
|
|
8465
|
+
const [now, setNow] = useState44(Date.now);
|
|
8454
8466
|
const previousCountdown = useRef29(null);
|
|
8455
|
-
const [limitWarning, setLimitWarning] =
|
|
8467
|
+
const [limitWarning, setLimitWarning] = useState44(null);
|
|
8456
8468
|
const countdown = callCountdown(deadline, now);
|
|
8457
8469
|
useEffect36(() => {
|
|
8458
8470
|
if (!deadline) return;
|
|
@@ -8468,13 +8480,14 @@ function SpaceView({
|
|
|
8468
8480
|
if (previous?.deadline !== deadline) setLimitWarning(null);
|
|
8469
8481
|
if (next.warning !== null) setLimitWarning({ id: `time-limit-${deadline}-${next.warning}`, minutes: next.warning });
|
|
8470
8482
|
}, [deadline, now]);
|
|
8471
|
-
const [uncontrolledLayout, setUncontrolledLayout] =
|
|
8472
|
-
const [
|
|
8473
|
-
const [
|
|
8474
|
-
const [
|
|
8475
|
-
const [
|
|
8476
|
-
const [
|
|
8477
|
-
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();
|
|
8478
8491
|
const onCommandError = (failure, source, mediaSource, action, command) => {
|
|
8479
8492
|
if (!failure && commandError && typeof commandError === "object") callToasts.dismissFailure(commandError.code);
|
|
8480
8493
|
setCommandError(failure);
|
|
@@ -8509,7 +8522,9 @@ function SpaceView({
|
|
|
8509
8522
|
...feature("whiteboard") && canDrawWhiteboard ? ["whiteboard"] : [],
|
|
8510
8523
|
"leave"
|
|
8511
8524
|
];
|
|
8525
|
+
const headerLayout = pinnedId ? "focus" : layout;
|
|
8512
8526
|
const updateLayout = (nextLayout) => {
|
|
8527
|
+
if (nextLayout === "grid") setPinnedId(null);
|
|
8513
8528
|
setUncontrolledLayout(nextLayout);
|
|
8514
8529
|
onLayoutChange?.(nextLayout);
|
|
8515
8530
|
};
|
|
@@ -8545,7 +8560,7 @@ function SpaceView({
|
|
|
8545
8560
|
};
|
|
8546
8561
|
const mappedFailure = mediaFailureToast(typeof displayedCommandError === "object" ? displayedCommandError : null, displayedCommandSource, externalCommandError != null ? externalCommandAction : commandAction, externalCommandError == null && retryCommand ? () => void retryMedia() : void 0);
|
|
8547
8562
|
const commandToasts = mappedFailure ? [{ id: "space-command-error", ...mappedFailure }] : typeof displayedCommandError === "string" ? [{ id: "space-command-error", message: displayedCommandError, type: "error" }] : [];
|
|
8548
|
-
const [boardToasts, setBoardToasts] =
|
|
8563
|
+
const [boardToasts, setBoardToasts] = useState44([]);
|
|
8549
8564
|
const boardToastCount = useRef29(0);
|
|
8550
8565
|
useEffect36(() => {
|
|
8551
8566
|
if (!whiteboard?.isOpen) setBoardToasts([]);
|
|
@@ -8579,7 +8594,7 @@ function SpaceView({
|
|
|
8579
8594
|
else if (id.startsWith("board-")) setBoardToasts((current) => current.filter((toast) => toast.id !== id));
|
|
8580
8595
|
else callToasts.dismiss(id);
|
|
8581
8596
|
};
|
|
8582
|
-
const [foldedNotices, setFoldedNotices] =
|
|
8597
|
+
const [foldedNotices, setFoldedNotices] = useState44([]);
|
|
8583
8598
|
const folded = toasts.filter((toast) => foldedNotices.includes(toast.id));
|
|
8584
8599
|
return /* @__PURE__ */ jsx69(ParticipantVolumeProvider, { children: /* @__PURE__ */ jsx69(BoardToastContext2.Provider, { value: showBoardToast, children: /* @__PURE__ */ jsx69(
|
|
8585
8600
|
SpacePresentation,
|
|
@@ -8607,7 +8622,7 @@ function SpaceView({
|
|
|
8607
8622
|
onToggleHand: feature("handRaise") && canRaiseHand ? () => void runCommand(() => self.handRaised ? client.participants.lowerHand() : client.participants.raiseHand()) : void 0,
|
|
8608
8623
|
onToggleChat: feature("chat") ? () => setActivePanel((current) => current === "chat" ? null : "chat") : void 0,
|
|
8609
8624
|
onTogglePeople: feature("participants") ? () => setActivePanel((current) => current === "participants" ? null : "participants") : void 0,
|
|
8610
|
-
onToggleLayout: () => updateLayout(
|
|
8625
|
+
onToggleLayout: () => updateLayout(headerLayout === "grid" ? "focus" : "grid"),
|
|
8611
8626
|
onClosePanel: () => setActivePanel(null),
|
|
8612
8627
|
onPushToTalk: (enabled) => {
|
|
8613
8628
|
if (enabled && connection.status !== "live") return;
|
|
@@ -8617,13 +8632,15 @@ function SpaceView({
|
|
|
8617
8632
|
duration: episodeDuration,
|
|
8618
8633
|
timeLeft: countdown.seconds,
|
|
8619
8634
|
isRecording: recording.current?.status === "recording",
|
|
8620
|
-
layout,
|
|
8635
|
+
layout: headerLayout,
|
|
8621
8636
|
onLayoutChange: updateLayout,
|
|
8622
8637
|
notices: folded.length ? /* @__PURE__ */ jsx69(NoticeButton, { toasts: folded, onDismiss: dismissToast }) : void 0
|
|
8623
8638
|
},
|
|
8624
8639
|
stage: /* @__PURE__ */ jsx69(
|
|
8625
8640
|
SpaceStage,
|
|
8626
8641
|
{
|
|
8642
|
+
pinnedId,
|
|
8643
|
+
onPinnedChange: setPinnedId,
|
|
8627
8644
|
tiles,
|
|
8628
8645
|
layout,
|
|
8629
8646
|
onLayoutChange: updateLayout,
|
|
@@ -8679,7 +8696,20 @@ function SpaceView({
|
|
|
8679
8696
|
] }),
|
|
8680
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: [
|
|
8681
8698
|
drawer.panel === "chat" && feature("chat") ? /* @__PURE__ */ jsx69(ChatPanel, { variant: "mobile", generatedAvatars, onClose: () => setActivePanel(null), pickChatFiles }) : null,
|
|
8682
|
-
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,
|
|
8683
8713
|
drawer.panel === "admission" && feature("admission") ? /* @__PURE__ */ jsx69(AdmissionPanel, { className: "h-full w-full rounded-none shadow-none", onClose: () => setActivePanel(null) }) : null
|
|
8684
8714
|
] }),
|
|
8685
8715
|
toasts: /* @__PURE__ */ jsx69(ToastStack, { toasts, onDismiss: dismissToast, onFold: setFoldedNotices }),
|