@arbidocs/blocks 0.4.108 → 0.4.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{NativeDocxEditor-UAZUKZ77.js → NativeDocxEditor-4PY4YZYC.js} +3 -3
- package/dist/{NativeDocxEditor-UAZUKZ77.js.map → NativeDocxEditor-4PY4YZYC.js.map} +1 -1
- package/dist/{NativeDocxEditor-YX7B7OFH.cjs → NativeDocxEditor-WODZAURG.cjs} +7 -7
- package/dist/{NativeDocxEditor-YX7B7OFH.cjs.map → NativeDocxEditor-WODZAURG.cjs.map} +1 -1
- package/dist/agents/index.cjs +286 -286
- package/dist/agents/index.js +10 -10
- package/dist/agents/tasks/ConversationListView.d.ts +5 -1
- package/dist/agents/tasks/TaskActivityTimeline.d.ts +5 -1
- package/dist/calendar/EventDetails.d.ts +1 -1
- package/dist/calendar/index.cjs +13 -0
- package/dist/calendar/index.cjs.map +1 -1
- package/dist/calendar/index.js +13 -0
- package/dist/calendar/index.js.map +1 -1
- package/dist/calendar/types.d.ts +3 -0
- package/dist/calls/CallSidePanel.d.ts +17 -0
- package/dist/calls/CallStage.d.ts +57 -0
- package/dist/calls/ControlBar.d.ts +91 -0
- package/dist/calls/ControlButton.d.ts +44 -0
- package/dist/calls/PreJoin.d.ts +31 -0
- package/dist/calls/cards.d.ts +54 -0
- package/dist/calls/hooks.d.ts +20 -0
- package/dist/calls/index.cjs +1853 -0
- package/dist/calls/index.cjs.map +1 -0
- package/dist/calls/index.d.ts +20 -0
- package/dist/calls/index.js +1737 -0
- package/dist/calls/index.js.map +1 -0
- package/dist/calls/join-choices.d.ts +11 -0
- package/dist/calls/layout.d.ts +106 -0
- package/dist/calls/panels.d.ts +55 -0
- package/dist/calls/status.d.ts +69 -0
- package/dist/calls/tiles.d.ts +59 -0
- package/dist/chat/Message.d.ts +17 -2
- package/dist/chat/TranscriptLine.d.ts +50 -0
- package/dist/chat/index.cjs +147 -126
- package/dist/chat/index.d.ts +3 -1
- package/dist/chat/index.js +5 -4
- package/dist/chat/transcript-runs.d.ts +6 -0
- package/dist/{chunk-QT6EGMAJ.cjs → chunk-2NIL2ASF.cjs} +38 -294
- package/dist/chunk-2NIL2ASF.cjs.map +1 -0
- package/dist/{chunk-XMBYDLZQ.cjs → chunk-2UAJVK3C.cjs} +4 -4
- package/dist/{chunk-XMBYDLZQ.cjs.map → chunk-2UAJVK3C.cjs.map} +1 -1
- package/dist/{chunk-TTXK62YI.cjs → chunk-54WBIVHV.cjs} +5 -5
- package/dist/{chunk-TTXK62YI.cjs.map → chunk-54WBIVHV.cjs.map} +1 -1
- package/dist/{chunk-7C35WXYB.js → chunk-5HFPRI3W.js} +5 -5
- package/dist/chunk-5HFPRI3W.js.map +1 -0
- package/dist/{chunk-S7RHJI5Q.js → chunk-6RHHMBZ5.js} +158 -5
- package/dist/chunk-6RHHMBZ5.js.map +1 -0
- package/dist/{chunk-3Y6NQIDE.js → chunk-A35KT2II.js} +37 -19
- package/dist/chunk-A35KT2II.js.map +1 -0
- package/dist/{chunk-PGDL26TQ.js → chunk-AY32GGKU.js} +10 -4
- package/dist/{chunk-PGDL26TQ.js.map → chunk-AY32GGKU.js.map} +1 -1
- package/dist/{chunk-IXALYQT7.cjs → chunk-C2CWWEHO.cjs} +2 -2
- package/dist/chunk-C2CWWEHO.cjs.map +1 -0
- package/dist/{chunk-S55VDTX3.js → chunk-CECWAIHL.js} +3 -3
- package/dist/{chunk-S55VDTX3.js.map → chunk-CECWAIHL.js.map} +1 -1
- package/dist/{chunk-XQDM6T6C.js → chunk-CXZ7FPTQ.js} +3 -3
- package/dist/{chunk-XQDM6T6C.js.map → chunk-CXZ7FPTQ.js.map} +1 -1
- package/dist/{chunk-C2HRZSAT.cjs → chunk-DJM7DLCT.cjs} +5 -5
- package/dist/chunk-DJM7DLCT.cjs.map +1 -0
- package/dist/{chunk-XQKGYGCJ.js → chunk-DQCYCEDR.js} +3 -3
- package/dist/{chunk-XQKGYGCJ.js.map → chunk-DQCYCEDR.js.map} +1 -1
- package/dist/{chunk-ZYSY4L5L.cjs → chunk-ELDUWTRR.cjs} +4 -4
- package/dist/{chunk-ZYSY4L5L.cjs.map → chunk-ELDUWTRR.cjs.map} +1 -1
- package/dist/{chunk-A2MN2ZLX.js → chunk-GKDWQLVU.js} +13 -274
- package/dist/chunk-GKDWQLVU.js.map +1 -0
- package/dist/{chunk-24ND4S6Y.cjs → chunk-HBBJYRGI.cjs} +162 -5
- package/dist/{chunk-S7RHJI5Q.js.map → chunk-HBBJYRGI.cjs.map} +1 -1
- package/dist/{chunk-P2KPDPFF.js → chunk-IXTQYFIF.js} +23 -15
- package/dist/chunk-IXTQYFIF.js.map +1 -0
- package/dist/{chunk-JQVPGMLU.js → chunk-JB32KYAH.js} +3 -3
- package/dist/{chunk-JQVPGMLU.js.map → chunk-JB32KYAH.js.map} +1 -1
- package/dist/{chunk-PBS5MFIY.cjs → chunk-JK45LSIH.cjs} +3 -3
- package/dist/{chunk-PBS5MFIY.cjs.map → chunk-JK45LSIH.cjs.map} +1 -1
- package/dist/chunk-MWDW5UBW.cjs +199 -0
- package/dist/chunk-MWDW5UBW.cjs.map +1 -0
- package/dist/{chunk-ZPLG7QYF.js → chunk-N5YEF3LC.js} +2 -2
- package/dist/chunk-N5YEF3LC.js.map +1 -0
- package/dist/{chunk-EWSEQEPL.js → chunk-NRUPUDWB.js} +17 -7
- package/dist/chunk-NRUPUDWB.js.map +1 -0
- package/dist/{chunk-DDF5GPIJ.js → chunk-P5ST47VY.js} +3 -3
- package/dist/{chunk-DDF5GPIJ.js.map → chunk-P5ST47VY.js.map} +1 -1
- package/dist/{chunk-EGDWNEAG.js → chunk-PEHLUB52.js} +3 -3
- package/dist/{chunk-EGDWNEAG.js.map → chunk-PEHLUB52.js.map} +1 -1
- package/dist/{chunk-W7NZRZ54.js → chunk-SQNAJPNR.js} +4 -4
- package/dist/{chunk-W7NZRZ54.js.map → chunk-SQNAJPNR.js.map} +1 -1
- package/dist/{chunk-DTBSGG36.cjs → chunk-U6MPHCEB.cjs} +24 -16
- package/dist/chunk-U6MPHCEB.cjs.map +1 -0
- package/dist/{chunk-MP6FK43E.cjs → chunk-VP4KJ4LK.cjs} +17 -6
- package/dist/chunk-VP4KJ4LK.cjs.map +1 -0
- package/dist/{chunk-LLFW2T6S.cjs → chunk-VZKBI2KJ.cjs} +85 -67
- package/dist/chunk-VZKBI2KJ.cjs.map +1 -0
- package/dist/{chunk-5YXG342J.cjs → chunk-W7ZDBPJ3.cjs} +4 -4
- package/dist/{chunk-5YXG342J.cjs.map → chunk-W7ZDBPJ3.cjs.map} +1 -1
- package/dist/{chunk-SKSE4OT6.cjs → chunk-WPVIOGDG.cjs} +5 -5
- package/dist/{chunk-SKSE4OT6.cjs.map → chunk-WPVIOGDG.cjs.map} +1 -1
- package/dist/{chunk-3US5OIDQ.cjs → chunk-XSUOEJB3.cjs} +9 -3
- package/dist/chunk-XSUOEJB3.cjs.map +1 -0
- package/dist/chunk-Z3AZ7Q5X.js +177 -0
- package/dist/chunk-Z3AZ7Q5X.js.map +1 -0
- package/dist/{chunk-Z5VUZ6YD.cjs → chunk-ZV3BKLFY.cjs} +3 -3
- package/dist/{chunk-Z5VUZ6YD.cjs.map → chunk-ZV3BKLFY.cjs.map} +1 -1
- package/dist/citations/index.cjs +10 -10
- package/dist/citations/index.js +1 -1
- package/dist/collaboration/index.cjs +57 -57
- package/dist/collaboration/index.js +3 -3
- package/dist/connect/docx.cjs +6 -6
- package/dist/connect/docx.js +4 -4
- package/dist/connect/index.cjs +87 -87
- package/dist/connect/index.js +16 -16
- package/dist/databases/index.cjs +2 -2
- package/dist/databases/index.js +1 -1
- package/dist/docx/definitions/fragment.d.ts +2 -6
- package/dist/docx/definitions/port.d.ts +2 -57
- package/dist/docx/index.cjs +46 -46
- package/dist/docx/index.js +3 -3
- package/dist/docx/references/commands.d.ts +3 -31
- package/dist/docx/references/numbering.d.ts +3 -47
- package/dist/facts/index.cjs +5 -5
- package/dist/facts/index.js +4 -4
- package/dist/files/GridView.d.ts +4 -1
- package/dist/files/TagPassagePanel.d.ts +2 -0
- package/dist/files/index.cjs +89 -79
- package/dist/files/index.cjs.map +1 -1
- package/dist/files/index.js +88 -78
- package/dist/files/index.js.map +1 -1
- package/dist/home/index.cjs +17 -17
- package/dist/home/index.js +3 -3
- package/dist/index.cjs +739 -718
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -21
- package/dist/index.js.map +1 -1
- package/dist/retrieval/index.cjs +1 -1
- package/dist/retrieval/index.js +1 -1
- package/dist/settings/FirmPool.d.ts +45 -0
- package/dist/settings/index.cjs +134 -37
- package/dist/settings/index.cjs.map +1 -1
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.js +100 -6
- package/dist/settings/index.js.map +1 -1
- package/dist/shell/index.cjs +12 -12
- package/dist/shell/index.js +4 -4
- package/dist/site/index.cjs +5 -5
- package/dist/site/index.js +1 -1
- package/dist/studio/index.cjs +5 -5
- package/dist/studio/index.js +4 -4
- package/dist/workflow-canvas/index.cjs +53 -53
- package/dist/workflow-canvas/index.js +10 -10
- package/dist/workspaces/index.cjs +3 -3
- package/dist/workspaces/index.cjs.map +1 -1
- package/dist/workspaces/index.js +3 -3
- package/dist/workspaces/index.js.map +1 -1
- package/node_modules/@arbidocs/coedit/dist/commands.cjs +356 -0
- package/node_modules/@arbidocs/coedit/dist/commands.cjs.map +1 -0
- package/node_modules/@arbidocs/coedit/dist/commands.d.cts +235 -0
- package/node_modules/@arbidocs/coedit/dist/commands.d.ts +235 -0
- package/node_modules/@arbidocs/coedit/dist/commands.js +338 -0
- package/node_modules/@arbidocs/coedit/dist/commands.js.map +1 -0
- package/node_modules/@arbidocs/coedit/package.json +6 -1
- package/package.json +15 -5
- package/src/calls/calls.css +157 -0
- package/dist/chunk-24ND4S6Y.cjs.map +0 -1
- package/dist/chunk-3US5OIDQ.cjs.map +0 -1
- package/dist/chunk-3Y6NQIDE.js.map +0 -1
- package/dist/chunk-7C35WXYB.js.map +0 -1
- package/dist/chunk-A2MN2ZLX.js.map +0 -1
- package/dist/chunk-C2HRZSAT.cjs.map +0 -1
- package/dist/chunk-DTBSGG36.cjs.map +0 -1
- package/dist/chunk-EWSEQEPL.js.map +0 -1
- package/dist/chunk-IXALYQT7.cjs.map +0 -1
- package/dist/chunk-LLFW2T6S.cjs.map +0 -1
- package/dist/chunk-MP6FK43E.cjs.map +0 -1
- package/dist/chunk-P2KPDPFF.js.map +0 -1
- package/dist/chunk-QT6EGMAJ.cjs.map +0 -1
- package/dist/chunk-ZPLG7QYF.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/calls/ControlButton.tsx","../../src/calls/hooks.ts","../../src/calls/tiles.tsx","../../src/calls/status.tsx","../../src/calls/ControlBar.tsx","../../src/calls/CallStage.tsx","../../src/calls/CallSidePanel.tsx","../../src/calls/panels.tsx","../../src/calls/cards.tsx","../../src/calls/join-choices.ts","../../src/calls/PreJoin.tsx"],"names":["CallControlButton","forwardRef","CallTile","jsxs","cn","jsx","Tooltip","TooltipTrigger","MicOff","TooltipContent","useState","useEffect","useRef","Mic","Button","Fragment","AudioLines","Video","VideoOff","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","Phone","PhoneOff","Loader2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The one button style of the call controls: an ARBI `Button` (36 px, 44 px on touch) with a\n * tooltip naming the action and its shortcut. Three tones:\n * neutral — a plain control (share, chat, more);\n * active — a control whose thing is on or open (captions on, chat open);\n * off — a device the user turned off (mic / camera), red-tinted, not a giant block.\n * The status chips of the header (`CallStatusChip`) live here too, so all call chrome shares\n * one source of sizes and colours.\n */\n\nimport { forwardRef, type ReactElement, type ReactNode } from 'react'\nimport {\n Button,\n cn,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n type ButtonProps,\n} from '@arbidocs/react/ui'\n\nexport type ControlTone = 'neutral' | 'active' | 'off' | 'danger'\n\nconst TONE: Record<ControlTone, string> = {\n neutral: 'bg-muted text-foreground hover:bg-accent',\n // Solid: a control whose thing is on reads as on at a glance (CC on, chat open, sharing).\n active: 'bg-primary text-primary-foreground hover:bg-primary/90',\n off: 'bg-red-bg text-red-text hover:bg-red-bg/80',\n danger: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n}\n\nexport interface CallControlButtonProps extends Omit<ButtonProps, 'variant'> {\n /** What the button does now (\"Turn off microphone\"). Also its accessible name. */\n label: string\n /** Shown in the tooltip after the label, e.g. \"M\". */\n shortcut?: string\n tone?: ControlTone\n /** Tooltip side (default above: the bar sits at the bottom). */\n side?: 'top' | 'bottom'\n /** False for a menu trigger: the open menu says it all, and a tip would sit on top of it. */\n tooltip?: boolean\n}\n\nexport const CallControlButton = forwardRef<HTMLButtonElement, CallControlButtonProps>(\n function CallControlButton(\n {\n label,\n shortcut,\n tone = 'neutral',\n side = 'top',\n tooltip = true,\n className,\n children,\n ...props\n },\n ref\n ) {\n const button = (\n <Button\n ref={ref}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n className={cn('relative shrink-0 [&_svg]:size-[18px]', TONE[tone], className)}\n {...props}\n >\n {children}\n </Button>\n )\n if (!tooltip) return button\n return (\n <Tooltip>\n {/* The tooltip binds to a wrapper so the button keeps its own ref (a menu trigger needs it). */}\n <TooltipTrigger asChild>\n <span className=\"inline-flex shrink-0\">{button}</span>\n </TooltipTrigger>\n <TooltipContent side={side}>\n {label}\n {shortcut && (\n <kbd className=\"ml-2 rounded-sm border border-border px-1 font-sans text-[11px] text-muted-foreground\">\n {shortcut}\n </kbd>\n )}\n </TooltipContent>\n </Tooltip>\n )\n }\n)\n\n/** A count on a control's corner: unread messages (red, top) or how many people (quiet, bottom). */\nexport function ControlBadge({\n count,\n tone = 'alert',\n testId,\n}: {\n count: number\n tone?: 'alert' | 'quiet'\n testId?: string\n}): ReactElement {\n return (\n <span\n className={cn(\n 'pointer-events-none absolute -right-1 min-w-[1.125rem] rounded-full px-1 text-center text-[10px] font-semibold leading-[1.125rem]',\n tone === 'alert'\n ? '-top-1 bg-destructive text-destructive-foreground ring-2 ring-background'\n : '-bottom-1 bg-background text-muted-foreground ring-1 ring-border'\n )}\n data-testid={testId}\n >\n {count > 99 ? '99+' : count}\n </span>\n )\n}\n\n/** A small quiet status chip for the call header (recording, transcription, encryption). */\nexport function CallStatusChip({\n tone,\n icon,\n label,\n compact = false,\n pulse = false,\n title,\n children,\n className,\n testId,\n ...rest\n}: {\n tone: 'red' | 'green' | 'yellow' | 'neutral'\n icon?: ReactNode\n /** Visible text (hidden when compact; the accessible text stays). */\n label: ReactNode\n compact?: boolean\n /** A pulsing dot in front (live capture). */\n pulse?: boolean\n title?: string\n children?: ReactNode\n className?: string\n testId?: string\n} & Omit<React.HTMLAttributes<HTMLSpanElement>, 'title'>): ReactElement {\n const tones = {\n red: 'border-red-border bg-red-bg text-red-text',\n green: 'border-green-border bg-green-bg text-green-text',\n yellow: 'border-yellow-border bg-yellow-bg text-yellow-text',\n neutral: 'border-border bg-muted text-muted-foreground',\n }\n return (\n <span\n className={cn(\n 'inline-flex h-6 shrink-0 items-center gap-1.5 rounded-md border px-2 text-xs font-medium',\n tones[tone],\n className\n )}\n title={title}\n data-testid={testId}\n {...rest}\n >\n {pulse && (\n <span className=\"relative flex size-2 shrink-0\" aria-hidden>\n <span className=\"absolute inline-flex size-full animate-ping rounded-full bg-red-solid opacity-60 motion-reduce:hidden\" />\n <span className=\"relative inline-flex size-2 rounded-full bg-red-solid\" />\n </span>\n )}\n {icon}\n <span className={cn('min-w-0 truncate', compact && 'sr-only')}>{label}</span>\n {children}\n </span>\n )\n}\n","/** Small hooks of the call blocks. */\n\nimport { useEffect, useMemo, useRef, useState, type RefObject } from 'react'\nimport { NOTICE_MS } from './layout'\n\n/** Size of an element, kept current with a ResizeObserver. */\nexport function useElementSize<T extends HTMLElement>(): [\n (el: T | null) => void,\n { width: number; height: number },\n] {\n const [size, setSize] = useState({ width: 0, height: 0 })\n const observer = useRef<ResizeObserver | null>(null)\n const ref = useMemo(\n () => (el: T | null) => {\n observer.current?.disconnect()\n observer.current = null\n if (!el || typeof ResizeObserver === 'undefined') return\n const ro = new ResizeObserver((entries) => {\n const r = entries[0]?.contentRect\n if (!r) return\n setSize((s) =>\n s.width === r.width && s.height === r.height ? s : { width: r.width, height: r.height }\n )\n })\n ro.observe(el)\n observer.current = ro\n },\n []\n )\n useEffect(() => () => observer.current?.disconnect(), [])\n return [ref, size]\n}\n\n/**\n * A notice that is spelled out on mount (when `announce`) and folds after `ms`; `onFolded` runs\n * once it folds, so the app can avoid spelling it out again on the next mount.\n */\nexport function useBriefNotice(announce = true, onFolded?: () => void, ms = NOTICE_MS): boolean {\n const [expanded, setExpanded] = useState(announce)\n const folded = useRef(onFolded)\n folded.current = onFolded\n useEffect(() => {\n if (!expanded) return\n const id = setTimeout(() => {\n setExpanded(false)\n folded.current?.()\n }, ms)\n return () => clearTimeout(id)\n }, [expanded, ms])\n return expanded\n}\n\n/** Is the keyboard event typed into a field (where a shortcut letter is just a letter)? */\nfunction typing(e: KeyboardEvent): boolean {\n const el = e.target as HTMLElement | null\n return !!el?.closest?.('input, textarea, select, [contenteditable=\"true\"], [role=\"textbox\"]')\n}\n\n/**\n * Single-key shortcuts inside `ref`: a control marked `data-call-shortcut=\"m\"` is clicked by the M\n * key while `enabled` and nobody is typing (or holding a modifier).\n */\nexport function useShortcutKeys(ref: RefObject<HTMLElement | null>, enabled: boolean): void {\n useEffect(() => {\n if (!enabled) return\n const onKey = (e: KeyboardEvent) => {\n if (e.repeat || e.ctrlKey || e.metaKey || e.altKey || typing(e)) return\n const key = e.key.toLowerCase()\n if (!/^[a-z]$/.test(key)) return\n const button = ref.current?.querySelector<HTMLButtonElement>(\n `[data-call-shortcut=\"${key}\"]:not(:disabled)`\n )\n if (!button) return\n e.preventDefault()\n button.click()\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [ref, enabled])\n}\n","/**\n * The call stage's tiles: one participant tile (with a voice-level ring, so it is plain who is\n * talking), the gallery grid (fills the stage: 1, 2 side by side, 2 + 1, 2 × 2, 3 + 2, …), and the\n * spotlight layout — the speaker (or a shared screen) large, everyone else in a filmstrip.\n *\n * Media-library free: the app hands each tile its `<video>` (or nothing, for initials) and its\n * state. Extra props (data attributes the app's recorder reads, say) land on the tile's root.\n * Styles: `@arbidocs/blocks/calls.css`.\n */\n\nimport {\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { AudioLines, MicOff, MonitorUp, SignalLow, Users } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { useElementSize } from './hooks'\nimport { gridLayout, gridSlots, spotlightBox } from './layout'\n\nexport interface CallTileProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /**\n * The name, once, at the bottom left: a node (the app's person pill, say), or a string shown in\n * a small dark chip.\n */\n name: ReactNode\n /** Shown large while there is no video (camera off). */\n initials: string\n /** The `<video>` element; omit while the camera is off. */\n video?: ReactNode\n source?: 'camera' | 'screen'\n /** My own tile: the name says \"(me)\". */\n local?: boolean\n /** Mirror the video (my own camera, as a selfie). Only the <video> flips; labels never do. */\n mirror?: boolean\n /** Talking now: a ring (thicker with `level`) and a sound icon by the name — never colour alone. */\n speaking?: boolean\n /** Voice level 0..1, updated fast (~60 ms): drives the ring's size. */\n level?: number\n micMuted?: boolean\n poorConnection?: boolean\n /** Small tiles (filmstrip, picture-in-picture) use a smaller avatar. */\n size?: 'normal' | 'small'\n /** Text after my own name when `name` is a string (a pill says \"(me)\" itself). */\n youLabel?: string\n}\n\n/** One participant (or screen-share) tile. */\nexport const CallTile = forwardRef<HTMLDivElement, CallTileProps>(function CallTile(\n {\n name,\n initials,\n video,\n source = 'camera',\n local = false,\n mirror = false,\n speaking = false,\n level = 0,\n micMuted = false,\n poorConnection = false,\n size = 'normal',\n youLabel,\n className,\n style,\n ...rest\n },\n ref\n) {\n const screen = source === 'screen'\n const ring = speaking && !screen ? Math.min(1, Math.max(0, level)) : 0\n return (\n <div\n ref={ref}\n className={cn('call-tile', className)}\n data-call-tile=\"\"\n data-source={source}\n data-local={local}\n data-mirror={mirror && source === 'camera' && !!video}\n data-speaking={speaking && !screen}\n style={{ '--call-level': ring.toFixed(2), ...style } as CSSProperties}\n {...rest}\n >\n {video ?? (\n <div className=\"call-tile-placeholder\" aria-hidden>\n <span className={cn('call-tile-avatar', size === 'small' && 'call-tile-avatar-sm')}>\n {initials}\n </span>\n </div>\n )}\n <div className=\"call-tile-name\">\n {typeof name === 'string' ? (\n <span className=\"call-tile-chip min-w-0\">\n <span className=\"truncate\">{name}</span>\n {local && !screen && youLabel && (\n <span className=\"shrink-0 opacity-80\">{youLabel}</span>\n )}\n </span>\n ) : (\n <span className=\"call-tile-chip min-w-0 overflow-hidden py-0.5 pl-0.5\">{name}</span>\n )}\n {(screen || micMuted || speaking) && (\n <span className=\"call-tile-chip shrink-0\">\n {screen && <MonitorUp className=\"size-3.5\" aria-label=\"Screen\" />}\n {!screen && micMuted && <MicOff className=\"size-3.5\" aria-label=\"Microphone off\" />}\n {speaking && !screen && (\n <AudioLines className=\"call-tile-speaking size-3.5\" aria-label=\"Speaking\" />\n )}\n </span>\n )}\n </div>\n {poorConnection && (\n <span className=\"call-tile-signal\" title=\"Poor connection\">\n <SignalLow className=\"size-3.5\" aria-label=\"Poor connection\" />\n </span>\n )}\n </div>\n )\n})\n\nconst GRID_GAP = 8\n\n/** The adaptive grid. Tiles keep 16:9 and the largest size the stage allows. */\nexport function CallGrid<T>({\n items,\n getKey,\n renderTile,\n moreLabel = (n: number) => `${n} more`,\n className,\n}: {\n items: T[]\n getKey(item: T): string\n /** The tile for one item; it fills a box the grid sizes. */\n renderTile(item: T): ReactElement\n moreLabel?(hidden: number): string\n className?: string\n}): ReactElement {\n const [ref, size] = useElementSize<HTMLDivElement>()\n const { shown, hidden } = gridSlots(items)\n const count = shown.length + (hidden ? 1 : 0)\n // The 16:9 maths picks rows × columns and the largest 16:9 tile that fits; tiles keep the\n // camera's shape (never stretched into portrait), the grid sits at the top of the stage.\n const layout = gridLayout(count, size.width, size.height, GRID_GAP)\n const box = { width: layout.tileWidth, height: layout.tileHeight }\n const rows: number[][] = []\n let next = 0\n for (const n of layout.rowCounts) rows.push(Array.from({ length: n }, () => next++))\n return (\n <div\n ref={ref}\n className={cn('flex size-full min-h-0 flex-col items-center', className)}\n style={{ gap: GRID_GAP }}\n data-testid=\"call-grid\"\n data-cols={layout.cols}\n >\n {layout.tileWidth > 0 &&\n rows.map((row, r) => (\n <div key={r} className=\"flex justify-center\" style={{ gap: GRID_GAP }}>\n {row.map((i) =>\n i < shown.length ? (\n <div key={getKey(shown[i])} className=\"call-tile-box\" style={box}>\n {renderTile(shown[i])}\n </div>\n ) : (\n <div key=\"more\" className=\"call-tile call-tile-more\" style={box}>\n <Users className=\"size-5\" aria-hidden />\n <span>{moreLabel(hidden)}</span>\n </div>\n )\n )}\n </div>\n ))}\n </div>\n )\n}\n\n/**\n * Spotlight: one tile large (the speaker, or a shared screen), everyone else in a filmstrip\n * beside it — below it on a narrow stage such as the docked call panel.\n */\nexport function CallFocus<T>({\n focus,\n others,\n getKey,\n renderTile,\n className,\n testId = 'call-focus',\n}: {\n focus: T\n others: T[]\n getKey(item: T): string\n renderTile(item: T, size: 'normal' | 'small'): ReactElement\n className?: string\n testId?: string\n}): ReactElement {\n const [ref, size] = useElementSize<HTMLDivElement>()\n const narrow = size.width > 0 && size.width < 640\n const box = spotlightBox(size.width, size.height, others.length, narrow)\n return (\n <div\n ref={ref}\n className={cn(\n 'flex size-full min-h-0 gap-2',\n narrow ? 'flex-col items-center' : 'flex-row items-start justify-center',\n className\n )}\n data-testid={testId}\n >\n {/* The large tile keeps 16:9 at the top: a camera is never cropped into portrait. */}\n <div\n key={getKey(focus)}\n className=\"call-tile-box shrink-0\"\n style={{ width: box.width, height: box.height }}\n data-testid=\"call-spotlight\"\n >\n {box.width > 0 && renderTile(focus, 'normal')}\n </div>\n {others.length > 0 && (\n <div\n className={cn(\n 'grid shrink-0 gap-2',\n narrow ? 'w-full grid-cols-3 content-start' : 'w-60 grid-cols-1 overflow-y-auto'\n )}\n style={narrow ? { width: box.width } : undefined}\n data-testid=\"call-filmstrip\"\n >\n {others.map((t) => (\n <div key={getKey(t)} className=\"call-tile-box aspect-video w-full min-w-0\">\n {renderTile(t, 'small')}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n","/**\n * The call's status, each shown once in the header (or on the minimised card): recording,\n * transcription and encryption chips, and the live captions strip below the tiles.\n *\n * Recording and transcription chips first spell out who started them (\"Recording (Audio) —\n * started by Ada\"), then fold to a short label after {@link NOTICE_MS}; the full sentence stays\n * available to screen readers and as the tooltip.\n */\n\nimport { useEffect, useState, type ReactElement, type ReactNode } from 'react'\nimport { Captions, Lock, LockOpen, Mic, MicOff } from 'lucide-react'\nimport { cn, Tooltip, TooltipContent, TooltipTrigger } from '@arbidocs/react/ui'\nimport { CallStatusChip } from './ControlButton'\nimport { CAPTION_LINES, CAPTION_TTL_MS, speakerAccent } from './layout'\nimport { useBriefNotice } from './hooks'\n\nfunction FoldingLabel({\n sentence,\n short,\n expanded,\n}: {\n sentence: string\n short: string\n expanded: boolean\n}): ReactElement {\n return (\n <>\n <span className={cn(!expanded && 'sr-only')}>{sentence}</span>\n {!expanded && <span aria-hidden>{short}</span>}\n </>\n )\n}\n\n/** \"Recording\" with a pulsing dot. */\nexport function RecordingStatusChip({\n sentence,\n short = 'Recording',\n compact = false,\n announce = true,\n onAnnounced,\n className,\n ...rest\n}: {\n /** Spell the sentence out first (false once it has been, e.g. after a re-mount). */\n announce?: boolean\n onAnnounced?(): void\n /** e.g. \"Recording (Audio + video) — started by you\". */\n sentence: string\n short?: string\n /** Dot only once folded (a narrow header, the minimised card). */\n compact?: boolean\n className?: string\n} & Omit<React.HTMLAttributes<HTMLSpanElement>, 'title'>): ReactElement {\n const expanded = useBriefNotice(announce, onAnnounced)\n return (\n <CallStatusChip\n tone=\"red\"\n pulse\n role=\"status\"\n aria-live=\"polite\"\n label={<FoldingLabel sentence={sentence} short={short} expanded={expanded} />}\n compact={compact && !expanded}\n title={sentence}\n className={className}\n data-expanded={expanded}\n {...rest}\n />\n )\n}\n\n/** \"Transcribing\", with my own \"stop sending my voice\" switch in it. */\nexport function TranscriptionStatusChip({\n sentence,\n announce = true,\n onAnnounced,\n short = 'Transcribing',\n detail,\n muted,\n onMutedChange,\n muteLabel,\n unmuteLabel,\n compact = false,\n className,\n ...rest\n}: {\n /** e.g. \"Transcription on — started by Ada\". */\n sentence: string\n announce?: boolean\n onAnnounced?(): void\n short?: string\n /** Tooltip after the sentence (what transcription does). */\n detail?: string\n muted: boolean\n onMutedChange(muted: boolean): void\n muteLabel: string\n unmuteLabel: string\n compact?: boolean\n className?: string\n} & Omit<React.HTMLAttributes<HTMLSpanElement>, 'title'>): ReactElement {\n const expanded = useBriefNotice(announce, onAnnounced)\n const label = muted ? unmuteLabel : muteLabel\n return (\n <CallStatusChip\n tone=\"red\"\n role=\"status\"\n aria-live=\"polite\"\n icon={<Captions className=\"size-3.5 shrink-0\" aria-hidden />}\n label={<FoldingLabel sentence={sentence} short={short} expanded={expanded} />}\n compact={compact && !expanded}\n title={detail ? `${sentence}. ${detail}` : sentence}\n className={cn('pr-0.5', className)}\n data-expanded={expanded}\n {...rest}\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n // `!`: a header section may force its buttons to a toolbar size.\n className=\"inline-flex h-5! w-5! shrink-0 items-center justify-center rounded-sm p-0! hover:bg-red-text/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-pressed={muted}\n aria-label={label}\n onClick={() => onMutedChange(!muted)}\n data-testid=\"transcription-mute\"\n >\n {muted ? (\n <MicOff className=\"size-3.5\" aria-hidden />\n ) : (\n <Mic className=\"size-3.5\" aria-hidden />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{label}</TooltipContent>\n </Tooltip>\n </CallStatusChip>\n )\n}\n\n/** Whether the media is end-to-end encrypted. */\nexport function EncryptionStatusChip({\n state,\n compact = false,\n labels = {\n on: 'Encrypted',\n pending: 'Encrypting…',\n off: 'Not encrypted',\n onTitle: 'Media is end-to-end encrypted; the media server only sees ciphertext.',\n offTitle: 'This call is not end-to-end encrypted.',\n },\n}: {\n state: 'on' | 'pending' | 'off'\n compact?: boolean\n labels?: { on: string; pending: string; off: string; onTitle: string; offTitle: string }\n}): ReactElement {\n const on = state === 'on'\n return (\n <CallStatusChip\n tone={on ? 'neutral' : 'yellow'}\n icon={\n on ? (\n <Lock className=\"size-3.5 shrink-0\" aria-hidden />\n ) : (\n <LockOpen className=\"size-3.5 shrink-0\" aria-hidden />\n )\n }\n label={on ? labels.on : state === 'pending' ? labels.pending : labels.off}\n compact={compact}\n title={on ? labels.onTitle : labels.offTitle}\n data-testid=\"call-encryption-badge\"\n data-state={state}\n />\n )\n}\n\n/** One caption: a speaker's latest segment. */\nexport interface CaptionEntry {\n id: string\n speakerId: string\n name: string\n text: string\n /** Local receipt time, ms (drives the fade). */\n receivedAt: number\n}\n\n/**\n * Live captions in a strip below the tiles (never over a face): at most two lines, the newest at\n * the bottom, each speaker's name in their own accent. With `reserve` the strip keeps its height\n * while empty, so the tiles do not jump each time someone starts or stops talking.\n */\nexport function CaptionsStrip({\n captions,\n reserve = false,\n waitingText = 'Captions appear here as people speak.',\n className,\n}: {\n captions: CaptionEntry[]\n reserve?: boolean\n waitingText?: ReactNode\n className?: string\n}): ReactElement | null {\n const [now, setNow] = useState(() => Date.now())\n const visible = captions.filter((c) => now - c.receivedAt < CAPTION_TTL_MS).slice(-CAPTION_LINES)\n const showing = visible.length > 0\n const newest = captions[captions.length - 1]?.receivedAt\n useEffect(() => {\n setNow(Date.now())\n }, [newest])\n useEffect(() => {\n if (!showing) return\n const id = setInterval(() => setNow(Date.now()), 1000)\n return () => clearInterval(id)\n }, [showing])\n if (!showing && !reserve) return null\n return (\n <div\n className={cn(\n 'shrink-0 rounded-md bg-muted px-3 py-2 text-sm leading-5 text-foreground',\n className\n )}\n aria-live=\"polite\"\n data-testid=\"captions-overlay\"\n >\n {/* Two lines in all. Each caption is its speaker's name (never clipped) beside the tail of\n what they said: the text is bottom-aligned in a clip, so a long caption loses its start,\n not its speaker. One caption gets both lines; two get one each. */}\n <div className=\"flex h-10 flex-col justify-end overflow-hidden\">\n {!showing && (\n <p className=\"truncate text-muted-foreground\" data-testid=\"captions-waiting\">\n {waitingText}\n </p>\n )}\n {visible.map((c) => (\n <p\n key={`${c.speakerId}:${c.id}`}\n className=\"flex min-w-0 shrink-0 gap-1.5\"\n data-testid=\"caption-line\"\n data-speaker={c.speakerId}\n >\n <span\n className={cn(\n 'max-w-[40%] shrink-0 truncate font-semibold',\n speakerAccent(c.speakerId)\n )}\n >\n {c.name}\n </span>\n <span className=\"sr-only\">: </span>\n <span\n className=\"flex min-w-0 flex-1 flex-col justify-end overflow-hidden\"\n style={{ height: `${(visible.length > 1 ? 1 : CAPTION_LINES) * 1.25}rem` }}\n >\n <span className=\"break-words\">{c.text}</span>\n </span>\n </p>\n ))}\n </div>\n </div>\n )\n}\n","/**\n * The call's control bar: one row, three columns. Left, the elapsed time (and any warning);\n * centre, the controls in groups; right, Leave. Controls are `CallControlButton`s; Record carries\n * its label, so its state is never a guess.\n * Press-shortcuts: a control marked `data-call-shortcut=\"m\"` is clicked by the M key while\n * `shortcuts` is on and nobody is typing.\n */\n\nimport { useEffect, useRef, useState, type ReactElement, type ReactNode } from 'react'\nimport {\n ChevronUp,\n Circle,\n Loader2,\n Mic,\n MicOff,\n MoreHorizontal,\n PhoneOff,\n Video,\n VideoOff,\n} from 'lucide-react'\nimport {\n Button,\n cn,\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Separator,\n} from '@arbidocs/react/ui'\nimport { CallControlButton } from './ControlButton'\nimport { useShortcutKeys } from './hooks'\nimport { formatElapsed } from './layout'\n\nexport function CallControlBar({\n left,\n right,\n children,\n shortcuts = false,\n className,\n}: {\n left?: ReactNode\n right?: ReactNode\n /** The centre controls (use `ControlGroup` / `ControlDivider`). */\n children: ReactNode\n /** Single-key shortcuts on (the call is on screen). */\n shortcuts?: boolean\n className?: string\n}): ReactElement {\n const ref = useRef<HTMLDivElement>(null)\n useShortcutKeys(ref, shortcuts)\n return (\n <div\n ref={ref}\n className={cn(\n 'grid h-16 shrink-0 grid-cols-[1fr_auto_1fr] items-center gap-2 border-t border-border bg-background px-3 sm:px-4',\n className\n )}\n data-testid=\"call-controls\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">{left}</div>\n <div className=\"flex items-center gap-2\">{children}</div>\n <div className=\"flex items-center justify-end gap-2\">{right}</div>\n </div>\n )\n}\n\nexport function ControlGroup({ children }: { children: ReactNode }): ReactElement {\n return <div className=\"flex items-center gap-2\">{children}</div>\n}\n\nexport function ControlDivider(): ReactElement {\n return <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n}\n\n/** `m:ss` since `since`, ticking every second. */\nexport function ElapsedTime({ since, title }: { since: number; title?: string }): ReactElement {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n const id = setInterval(() => setNow(Date.now()), 1000)\n return () => clearInterval(id)\n }, [])\n return (\n <span className=\"text-sm tabular-nums text-muted-foreground\" title={title}>\n {formatElapsed(now - since)}\n </span>\n )\n}\n\nexport interface MediaDevice {\n deviceId: string\n label: string\n}\n\n/** Microphone or camera: one toggle with an attached caret that opens the device list. */\nexport function MediaControl({\n kind,\n enabled,\n pending = false,\n onToggle,\n devices,\n activeDeviceId,\n onSelectDevice,\n shortcut,\n testId,\n options = [],\n}: {\n kind: 'microphone' | 'camera'\n enabled: boolean\n pending?: boolean\n onToggle(): void\n devices: MediaDevice[]\n activeDeviceId?: string\n onSelectDevice(deviceId: string): void\n shortcut?: string\n testId: string\n /** On/off settings under the device list (e.g. \"Mirror my video\"). */\n options?: { label: string; checked: boolean; onChange(checked: boolean): void; testId?: string }[]\n}): ReactElement {\n const mic = kind === 'microphone'\n const label = enabled ? `Turn off ${kind}` : `Turn on ${kind}`\n const Icon = mic ? (enabled ? Mic : MicOff) : enabled ? Video : VideoOff\n const title = mic ? 'Microphone' : 'Camera'\n return (\n <div className=\"flex shrink-0 items-center\" role=\"group\" aria-label={title}>\n <CallControlButton\n label={label}\n shortcut={shortcut}\n tone={enabled ? 'neutral' : 'off'}\n aria-pressed={enabled}\n disabled={pending}\n onClick={onToggle}\n className=\"rounded-r-none\"\n data-testid={testId}\n data-call-shortcut={shortcut?.toLowerCase()}\n data-enabled={enabled}\n >\n <Icon aria-hidden />\n </CallControlButton>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n aria-label={`Choose ${kind}`}\n title={`Choose ${kind}`}\n className={cn(\n 'h-9 w-6 shrink-0 rounded-l-none border-l px-0 pointer-coarse:h-11! pointer-coarse:w-8',\n enabled\n ? 'border-background bg-muted text-muted-foreground hover:bg-accent hover:text-foreground'\n : 'border-background bg-red-bg text-red-text hover:bg-red-bg/80'\n )}\n data-testid={`${testId}-devices`}\n >\n <ChevronUp className=\"size-3.5\" aria-hidden />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent side=\"top\" align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"text-xs font-medium text-muted-foreground\">\n {title}\n </DropdownMenuLabel>\n {devices.length === 0 ? (\n <DropdownMenuItem disabled>No {kind} found</DropdownMenuItem>\n ) : (\n <DropdownMenuRadioGroup value={activeDeviceId} onValueChange={onSelectDevice}>\n {devices.map((d, i) => (\n <DropdownMenuRadioItem key={d.deviceId} value={d.deviceId}>\n <span className=\"truncate\">{d.label || `${title} ${i + 1}`}</span>\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n )}\n {options.length > 0 && <DropdownMenuSeparator />}\n {options.map((o) => (\n <DropdownMenuCheckboxItem\n key={o.label}\n checked={o.checked}\n onCheckedChange={(c) => o.onChange(c === true)}\n data-testid={o.testId}\n >\n {o.label}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )\n}\n\nexport interface RecordMode<M extends string = string> {\n mode: M\n label: string\n description: string\n testId?: string\n}\n\n/**\n * The host's record button: off, it opens the mode choice; on, it stops (red). A plain menu\n * rather than a portal so the choice stays next to its button.\n */\nexport function RecordControl<M extends string>({\n on,\n busy = false,\n modes,\n note,\n onStart,\n onStop,\n}: {\n on: boolean\n busy?: boolean\n modes: RecordMode<M>[]\n /** One line above the modes (how recording works). */\n note?: string\n onStart(mode: M): void\n onStop(): void\n}): ReactElement {\n const [choosing, setChoosing] = useState(false)\n const menuRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!choosing) return\n const onDown = (e: PointerEvent) => {\n if (!menuRef.current?.contains(e.target as Node)) setChoosing(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setChoosing(false)\n }\n document.addEventListener('pointerdown', onDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('pointerdown', onDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [choosing])\n // Labelled, so its state is never a guess: \"Record\" (red dot) or \"Stop recording\" (pulsing).\n const base = 'h-9 shrink-0 gap-2 px-3 pointer-coarse:h-11!'\n if (on) {\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n className={cn(base, 'bg-red-bg text-red-text hover:bg-red-bg/80')}\n disabled={busy}\n onClick={onStop}\n data-testid=\"recording-stop\"\n >\n {busy ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <span className=\"relative flex size-2.5\" aria-hidden>\n <span className=\"absolute inline-flex size-full animate-ping rounded-full bg-red-solid opacity-60 motion-reduce:hidden\" />\n <span className=\"relative inline-flex size-2.5 rounded-full bg-red-solid\" />\n </span>\n )}\n Stop recording\n </Button>\n )\n }\n return (\n <div ref={menuRef} className=\"relative\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n className={cn(base, 'bg-muted text-foreground hover:bg-accent')}\n disabled={busy}\n aria-expanded={choosing}\n aria-haspopup=\"menu\"\n onClick={() => setChoosing((c) => !c)}\n data-testid=\"recording-start\"\n >\n {busy ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <Circle className=\"size-3 fill-red-solid text-red-solid\" aria-hidden />\n )}\n Record\n </Button>\n {choosing && (\n <div\n role=\"menu\"\n aria-label=\"Record\"\n className=\"absolute bottom-full left-1/2 z-50 mb-2 w-64 -translate-x-1/2 rounded-md border bg-popover p-1 text-popover-foreground shadow-lg\"\n >\n {note && <p className=\"px-2 py-1.5 text-xs text-muted-foreground\">{note}</p>}\n {modes.map((m) => (\n <button\n key={m.mode}\n type=\"button\"\n role=\"menuitem\"\n className=\"flex w-full flex-col items-start rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent focus-visible:bg-accent pointer-coarse:min-h-11\"\n onClick={() => {\n setChoosing(false)\n onStart(m.mode)\n }}\n data-testid={m.testId}\n >\n <span className=\"font-medium\">{m.label}</span>\n <span className=\"text-xs text-muted-foreground\">{m.description}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n/** Leave: the one filled red control, at the right end. */\nexport function LeaveButton({\n onLeave,\n compact = false,\n label = 'Leave',\n title = 'Leave call',\n}: {\n onLeave(): void\n compact?: boolean\n label?: string\n title?: string\n}): ReactElement {\n return (\n <Button\n type=\"button\"\n variant=\"destructive\"\n size={compact ? 'icon' : 'default'}\n className={cn('shrink-0', !compact && 'px-4')}\n aria-label={title}\n title={title}\n onClick={onLeave}\n data-testid=\"call-leave\"\n >\n <PhoneOff className=\"size-4\" aria-hidden />\n {!compact && label}\n </Button>\n )\n}\n\nexport interface MoreMenuItem {\n key: string\n label: ReactNode\n icon?: ReactNode\n onSelect(): void\n disabled?: boolean\n /** Right-aligned extra (a count). */\n trailing?: ReactNode\n testId?: string\n}\n\n/** \"More\": a details header, then groups of items separated by hairlines. */\nexport function MoreMenu({\n details,\n groups,\n label = 'More options',\n}: {\n details?: ReactNode\n groups: MoreMenuItem[][]\n label?: string\n}): ReactElement {\n const shown = groups.filter((g) => g.length > 0)\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <CallControlButton label={label} tooltip={false} data-testid=\"call-more\">\n <MoreHorizontal aria-hidden />\n </CallControlButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent side=\"top\" align=\"end\" className=\"w-72\" data-testid=\"call-more-menu\">\n {details && (\n <>\n <DropdownMenuLabel className=\"flex flex-col gap-1 font-normal\">\n {details}\n </DropdownMenuLabel>\n {shown.length > 0 && <DropdownMenuSeparator />}\n </>\n )}\n {shown.map((group, i) => (\n <div key={group[0].key} role=\"none\">\n {i > 0 && <DropdownMenuSeparator />}\n {group.map((item) => (\n <DropdownMenuItem\n key={item.key}\n onSelect={item.onSelect}\n disabled={item.disabled}\n data-testid={item.testId}\n >\n {item.icon}\n <span className=\"min-w-0 flex-1 truncate\">{item.label}</span>\n {item.trailing}\n </DropdownMenuItem>\n ))}\n </div>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n","/**\n * The call panel, docked beside the call's conversation like the document viewer: the app's\n * header (`TabHeader`: one tab with the call's title; status chips, the view switch and\n * \"Minimise\" on the right), a \"Speaking: …\" line, the stage (tiles, or a side panel over them)\n * and the control bar. Normal app surfaces in both themes; only the tiles are dark.\n */\n\nimport type { ReactElement, ReactNode } from 'react'\nimport { useElementSize } from './hooks'\nimport { AudioLines, LayoutGrid, PictureInPicture2, Phone, UserRound } from 'lucide-react'\nimport { Button, cn, Tooltip, TooltipContent, TooltipTrigger } from '@arbidocs/react/ui'\nimport { TabHeader } from '../shell/TabHeader'\n\nexport type CallView = 'speaker' | 'gallery'\n\nfunction HeaderIconButton({\n label,\n onClick,\n children,\n testId,\n pressed,\n}: {\n label: string\n onClick(): void\n children: ReactNode\n testId?: string\n pressed?: boolean\n}): ReactElement {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"text-muted-foreground hover:text-foreground\"\n aria-label={label}\n aria-pressed={pressed}\n onClick={onClick}\n data-testid={testId}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{label}</TooltipContent>\n </Tooltip>\n )\n}\n\nexport function CallHeader({\n title,\n icon,\n status,\n view,\n onViewChange,\n onMinimise,\n minimiseLabel = 'Minimise — keep working while the call goes on',\n}: {\n title: string\n icon?: ReactNode\n /** The status chips; given `compact` on a narrow header. */\n status?: ReactNode | ((compact: boolean) => ReactNode)\n /** Speaker (the talker large) or gallery (everyone equal): one switch. */\n view?: CallView\n onViewChange?(view: CallView): void\n onMinimise?(): void\n minimiseLabel?: string\n}): ReactElement {\n return (\n <div className=\"@container\">\n <TabHeader\n tabs={[\n {\n id: 'call',\n label: (\n <Tooltip>\n {/* Sized by the header's width (a container): the status chips and buttons keep\n their room; the title truncates with an ellipsis only when it must. */}\n <TooltipTrigger asChild showWithText>\n <span\n className=\"block min-w-0 max-w-[calc(100cqw-16rem)] truncate\"\n data-testid=\"call-title\"\n >\n {title}\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{title}</TooltipContent>\n </Tooltip>\n ),\n icon: icon ?? <Phone className=\"size-4\" />,\n },\n ]}\n activeTabId=\"call\"\n onTabChange={() => undefined}\n testId=\"call-header\"\n // The hairline is the header's lower edge, flush with the panel below it.\n className=\"pb-0\"\n rightContent={(compact: boolean) => (\n <>\n {typeof status === 'function' ? status(compact) : status}\n {view && onViewChange && (\n <HeaderIconButton\n label={\n view === 'speaker'\n ? 'Gallery view (everyone equal)'\n : 'Speaker view (who talks, large)'\n }\n onClick={() => onViewChange(view === 'speaker' ? 'gallery' : 'speaker')}\n testId=\"call-view-toggle\"\n >\n {view === 'speaker' ? (\n <LayoutGrid className=\"size-4\" />\n ) : (\n <UserRound className=\"size-4\" />\n )}\n </HeaderIconButton>\n )}\n {onMinimise && (\n <HeaderIconButton\n label={minimiseLabel}\n onClick={onMinimise}\n testId=\"call-dock-toggle\"\n >\n <PictureInPicture2 className=\"size-4\" />\n </HeaderIconButton>\n )}\n </>\n )}\n />\n </div>\n )\n}\n\n/**\n * \"Speaking: Ada, Bo\" — who is talking right now, in words (the tile rings say it in colour and\n * motion). Polite live region, so a screen reader hears changes without being flooded.\n */\nexport function SpeakingNow({\n names,\n idleText = 'No one is speaking',\n className,\n}: {\n /** Who is talking (person pills, or plain names). */\n names: ReactNode[]\n idleText?: string\n className?: string\n}): ReactElement {\n const talking = names.length > 0\n return (\n <p\n className={cn(\n 'flex min-w-0 items-center gap-1.5 text-sm',\n talking ? 'text-foreground' : 'text-muted-foreground',\n className\n )}\n aria-live=\"polite\"\n data-testid=\"call-speaking-now\"\n >\n <AudioLines\n className={cn(\n 'size-4 shrink-0',\n talking ? 'text-theme-cyan motion-safe:animate-pulse' : 'text-muted-foreground'\n )}\n aria-hidden\n />\n {talking ? (\n <span className=\"flex min-w-0 items-center gap-1 overflow-hidden\">\n <span className=\"shrink-0 text-muted-foreground\">Speaking:</span>\n {names.map((n, i) => (\n <span key={i} className=\"flex min-w-0 shrink-0 items-center\">\n {n}\n </span>\n ))}\n </span>\n ) : (\n <span className=\"min-w-0 truncate\">{idleText}</span>\n )}\n </p>\n )\n}\n\n/**\n * A short-lived line under the header (\"Transcription on — started by Ada\"): the notice gets its\n * own line, so it never takes the title's room; the header keeps only the short chip.\n */\nexport function CallNotice({ children }: { children: ReactNode }): ReactElement {\n return (\n <p\n className=\"flex min-w-0 items-center gap-1.5 text-sm text-red-text motion-safe:animate-in motion-safe:fade-in-0\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"call-notice\"\n >\n <span className=\"size-2 shrink-0 rounded-full bg-red-solid\" aria-hidden />\n <span className=\"min-w-0 truncate\">{children}</span>\n </p>\n )\n}\n\n/**\n * The panel frame: header, a slim line under it (\"Speaking: …\", notices), the video stage, the\n * participant list under the video, and the control bar. `stageHeight` sizes the video to its\n * tiles (they keep 16:9 at the top) so the rest of the panel goes to the list rather than to blank\n * space; without it, or with a `compact` list, the stage takes the room.\n */\nexport function CallStageFrame({\n header,\n subheader,\n stage,\n stageRef,\n stageOverlay,\n people,\n stageHeight,\n controls,\n className,\n}: {\n header: ReactNode\n /** A slim line under the header (\"Speaking: …\"). */\n subheader?: ReactNode\n stage: ReactNode\n stageRef?: React.Ref<HTMLDivElement>\n /** Floating over the tiles' top-left corner (lobby requests, connection state). */\n stageOverlay?: ReactNode\n /** The participant list, under the video. */\n people?: ReactNode\n /** The video's natural height for a stage `width` wide and at most `maxHeight` tall. */\n stageHeight?(width: number, maxHeight: number): number\n controls: ReactNode\n className?: string\n}): ReactElement {\n const [bodyRef, body] = useElementSize<HTMLDivElement>()\n // Padding of the stage box (px-3 + pb-3).\n const PAD_X = 24\n const PAD_B = 12\n const sized =\n !!people && !!stageHeight && body.width > 0 && body.height > 0\n ? Math.ceil(stageHeight(body.width - PAD_X, Math.round(body.height * 0.62)) + PAD_B)\n : null\n return (\n <div className={cn('flex size-full min-h-0 flex-col bg-background text-foreground', className)}>\n {header}\n {subheader && (\n <div className=\"flex min-h-9 shrink-0 flex-col justify-center gap-0.5 px-3 py-1\">\n {subheader}\n </div>\n )}\n <div ref={bodyRef} className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n className={cn('flex min-h-0 flex-col px-3 pb-3', sized == null ? 'flex-1' : 'shrink-0')}\n style={sized == null ? undefined : { height: sized }}\n >\n <div ref={stageRef} className=\"relative min-h-0 flex-1\" data-testid=\"call-stage\">\n {stage}\n {stageOverlay}\n </div>\n </div>\n {people}\n </div>\n {controls}\n </div>\n )\n}\n","/**\n * A side panel inside the call (chat, participants): the same header as the app's docked panels\n * (FloatingPanel: title in the brand colour, hairline below, a ghost close button), on the normal\n * background, beside the tiles rather than over them.\n */\n\nimport type { ReactElement, ReactNode } from 'react'\nimport { X } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\n\nexport function CallSidePanel({\n title,\n icon,\n actions,\n onClose,\n closeLabel,\n closeTestId,\n children,\n className,\n ...rest\n}: {\n title: string\n icon?: ReactNode\n /** Extra header actions, left of the close button. */\n actions?: ReactNode\n onClose(): void\n closeLabel: string\n closeTestId?: string\n children: ReactNode\n className?: string\n} & React.HTMLAttributes<HTMLElement>): ReactElement {\n return (\n <aside\n className={cn('flex min-h-0 flex-col bg-background text-foreground', className)}\n aria-label={title}\n {...rest}\n >\n <div className=\"flex h-12 shrink-0 items-center gap-2 border-b border-border pl-3 pr-1.5\">\n <span className=\"flex min-w-0 flex-1 items-center gap-2 text-base font-semibold text-primary\">\n {icon}\n <span className=\"truncate\">{title}</span>\n </span>\n {actions}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 text-muted-foreground hover:text-foreground\"\n aria-label={closeLabel}\n title={closeLabel}\n onClick={onClose}\n data-testid={closeTestId}\n >\n <X className=\"size-4\" />\n </Button>\n </div>\n {children}\n </aside>\n )\n}\n","/**\n * The call panel's participant list and the lobby requests. Presentational: the app supplies the people\n * and the actions. (Chat happens in the call's conversation, beside the panel.)\n */\n\nimport { useState, type ReactElement, type ReactNode } from 'react'\nimport { MicOff, MoreHorizontal, UserX, Video, VideoOff } from 'lucide-react'\nimport {\n Button,\n cn,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@arbidocs/react/ui'\nimport { initialsOf } from './layout'\n\nexport interface CallPerson {\n id: string\n name: string\n isLocal: boolean\n micMuted?: boolean\n /** Publishing an unmuted camera (the host may turn it off). */\n cameraOn?: boolean\n /** Talking now, and how loud (0..1): the live speaker list. */\n speaking?: boolean\n level?: number\n /** Extra state after the name (e.g. \"Presenting\"). */\n note?: ReactNode\n /** The person as the app shows people (a pill); else initials and `name`. */\n entity?: ReactNode\n}\n\n/** A small live voice meter: five bars lit by level; \"muted\" when the mic is off. */\nexport function VoiceMeter({\n level,\n muted = false,\n className,\n}: {\n level: number\n muted?: boolean\n className?: string\n}): ReactElement {\n if (muted) {\n return (\n <span className={cn('flex items-center text-red-text', className)} title=\"Microphone off\">\n <MicOff className=\"size-4\" aria-label=\"Microphone off\" />\n </span>\n )\n }\n const lit = Math.round(Math.min(1, Math.max(0, level)) * 5)\n return (\n <span\n className={cn('flex h-4 items-end gap-0.5', className)}\n role=\"meter\"\n aria-label=\"Voice level\"\n aria-valuemin={0}\n aria-valuemax={5}\n aria-valuenow={lit}\n >\n {[0.35, 0.55, 0.75, 0.9, 1].map((h, i) => (\n <span\n key={i}\n className={cn('w-1 rounded-sm', i < lit ? 'bg-theme-cyan' : 'bg-muted-foreground/30')}\n style={{ height: `${h * 100}%` }}\n />\n ))}\n </span>\n )\n}\n\n/** One participant row: pill, live voice meter, mic / camera state, and the host's \"…\" actions. */\nfunction PersonRow({\n p,\n canRemove,\n removingId,\n onRemove,\n onAskToMute,\n onMute,\n}: {\n p: CallPerson\n canRemove: boolean\n removingId?: string | null\n onRemove(person: CallPerson): void\n onAskToMute?(person: CallPerson): void\n onMute?(person: CallPerson, track: 'audio' | 'video'): void\n}): ReactElement {\n const hasActions =\n !p.isLocal && (canRemove || ((onAskToMute || onMute) && !p.micMuted) || (onMute && p.cameraOn))\n return (\n <li\n className=\"flex h-10 items-center gap-2 rounded-md px-2 hover:bg-muted\"\n data-testid={`call-person-${p.id}`}\n data-speaking={p.speaking || undefined}\n >\n <span className=\"flex min-w-0 flex-1 items-center gap-1.5 text-sm\">\n {p.entity ? (\n // The ring hugs the person's pill, not the whole row.\n <span\n className={cn(\n 'inline-flex min-w-0 rounded-full',\n p.speaking && 'ring-2 ring-theme-cyan ring-offset-2 ring-offset-background'\n )}\n >\n {p.entity}\n </span>\n ) : (\n <>\n <span\n className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary\"\n aria-hidden\n >\n {initialsOf(p.name)}\n </span>\n <span className=\"min-w-0 truncate\">\n {p.name}\n {p.isLocal && <span className=\"text-muted-foreground\"> (me)</span>}\n </span>\n </>\n )}\n {p.speaking && <span className=\"sr-only\"> — speaking</span>}\n {p.note && <span className=\"text-xs text-muted-foreground\">{p.note}</span>}\n </span>\n <VoiceMeter level={p.level ?? 0} muted={p.micMuted} />\n <span\n className={cn(\n 'flex w-4 justify-center',\n p.cameraOn ? 'text-muted-foreground' : 'text-red-text'\n )}\n title={p.cameraOn ? 'Camera on' : 'Camera off'}\n >\n {p.cameraOn ? (\n <Video className=\"size-4\" aria-label=\"Camera on\" />\n ) : (\n <VideoOff className=\"size-4\" aria-label=\"Camera off\" />\n )}\n </span>\n {hasActions ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 text-muted-foreground hover:text-foreground\"\n aria-label={`Actions for ${p.name}`}\n data-testid={`call-person-menu-${p.id}`}\n >\n <MoreHorizontal className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {onAskToMute && !p.micMuted && (\n <DropdownMenuItem\n onSelect={() => onAskToMute(p)}\n data-testid={`call-ask-mute-${p.id}`}\n >\n <MicOff aria-hidden />\n Ask to mute\n </DropdownMenuItem>\n )}\n {onMute && !p.micMuted && (\n <DropdownMenuItem\n onSelect={() => onMute(p, 'audio')}\n data-testid={`call-mute-${p.id}`}\n >\n <MicOff aria-hidden />\n Mute\n </DropdownMenuItem>\n )}\n {onMute && p.cameraOn && (\n <DropdownMenuItem\n onSelect={() => onMute(p, 'video')}\n data-testid={`call-camera-off-${p.id}`}\n >\n <VideoOff aria-hidden />\n Turn off camera\n </DropdownMenuItem>\n )}\n {canRemove && (\n <DropdownMenuItem\n onSelect={() => onRemove(p)}\n disabled={removingId === p.id}\n className=\"text-destructive focus:text-destructive\"\n data-testid={`call-remove-${p.id}`}\n >\n <UserX aria-hidden />\n Remove from call\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n // Keeps every row's meter and icons in the same column.\n <span className=\"size-8 shrink-0\" aria-hidden />\n )}\n </li>\n )\n}\n\n/**\n * Who is in the call, always on show under the video in the call panel: a live speaker list (the\n * app orders it, talkers first), each row with the person's pill, voice meter, mic and camera\n * state, and — for the host — mute / ask to mute / remove in its \"…\". Scrolls when long. In a\n * short panel (`compact`) it folds to one strip — who is talking, and \"Show all (N)\".\n */\nexport function CallParticipants({\n people,\n canRemove,\n removingId,\n onRemove,\n onAskToMute,\n onMute,\n compact = false,\n className,\n}: {\n people: CallPerson[]\n canRemove: boolean\n removingId?: string | null\n onRemove(person: CallPerson): void\n /** Shown for others whose mic is on (the host). */\n onAskToMute?(person: CallPerson): void\n /** The host's force-mute of a mic (`audio`, shown while it is on) or a camera (`video`, while on). */\n onMute?(person: CallPerson, track: 'audio' | 'video'): void\n compact?: boolean\n className?: string\n}): ReactElement {\n const [expanded, setExpanded] = useState(false)\n const rows = (\n <ul className=\"min-h-0 flex-1 overflow-y-auto px-1 pb-2\" data-testid=\"call-people-list\">\n {people.map((p) => (\n <PersonRow\n key={p.id}\n p={p}\n canRemove={canRemove}\n removingId={removingId}\n onRemove={onRemove}\n onAskToMute={onAskToMute}\n onMute={onMute}\n />\n ))}\n </ul>\n )\n const heading = (\n <span className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n People ({people.length})\n </span>\n )\n if (compact && !expanded) {\n const talking = people.filter((p) => p.speaking)\n return (\n <section\n className={cn(\n 'flex h-11 shrink-0 items-center gap-2 border-t border-border px-3',\n className\n )}\n aria-label=\"People\"\n data-testid=\"call-people\"\n data-compact=\"\"\n >\n {heading}\n <span className=\"flex min-w-0 flex-1 items-center gap-1 overflow-hidden\">\n {talking.map((p) => (\n <span key={p.id} className=\"flex shrink-0 items-center\">\n {p.entity ?? p.name}\n </span>\n ))}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 shrink-0\"\n aria-expanded={false}\n onClick={() => setExpanded(true)}\n data-testid=\"call-people-show-all\"\n >\n Show all ({people.length})\n </Button>\n </section>\n )\n }\n return (\n <section\n className={cn(\n 'flex min-h-0 flex-col border-t border-border',\n compact && 'absolute inset-x-0 bottom-0 z-20 max-h-[80%] bg-background shadow-lg',\n className\n )}\n aria-label=\"People\"\n data-testid=\"call-people\"\n >\n <div className=\"flex h-9 shrink-0 items-center justify-between px-3\">\n {heading}\n {compact && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7\"\n aria-expanded\n onClick={() => setExpanded(false)}\n data-testid=\"call-people-show-less\"\n >\n Show less\n </Button>\n )}\n </div>\n {rows}\n </section>\n )\n}\n\nexport interface LobbyRequest {\n id: string\n name: string\n /** The person as the app shows people (a pill); else `name`. */\n entity?: ReactNode\n}\n\n/** People asking to join, as cards over the stage's top-left corner. */\nexport function LobbyRequests({\n requests,\n onDecide,\n}: {\n requests: LobbyRequest[]\n onDecide(id: string, admit: boolean): void\n}): ReactElement | null {\n if (!requests.length) return null\n return (\n <div\n className=\"absolute left-3 top-3 z-10 flex w-72 max-w-[calc(100%-1.5rem)] flex-col gap-2\"\n role=\"region\"\n aria-label=\"Lobby\"\n data-testid=\"call-lobby\"\n >\n {requests.map((k) => (\n <div\n key={k.id}\n className=\"flex items-center gap-3 rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg\"\n data-testid=\"call-lobby-knock\"\n >\n <span className=\"flex min-w-0 flex-1 flex-wrap items-center gap-1\">\n {k.entity ?? <span className=\"font-medium\">{k.name}</span>}\n <span>wants to join.</span>\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8\"\n onClick={() => onDecide(k.id, false)}\n data-testid=\"call-lobby-deny\"\n >\n Deny\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"h-8\"\n onClick={() => onDecide(k.id, true)}\n data-testid=\"call-lobby-admit\"\n >\n Admit\n </Button>\n </div>\n ))}\n </div>\n )\n}\n","/**\n * The call's small cards: the minimised call (picture-in-picture, so the user keeps working),\n * the incoming-call card, and the waiting / connecting states. Same surfaces as the app's popovers.\n */\n\nimport { useRef, type ReactElement, type ReactNode } from 'react'\nimport {\n Bell,\n BellOff,\n Loader2,\n Maximize2,\n Mic,\n MicOff,\n Phone,\n PhoneOff,\n Video,\n VideoOff,\n} from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { CallControlButton } from './ControlButton'\nimport { useShortcutKeys } from './hooks'\n\n/**\n * The minimised call: the current speaker (their tile, with its voice ring), \"Speaking: …\", the\n * status chips, and my microphone and camera, back to the call, leave.\n */\nexport function MinimisedCall({\n title,\n video,\n status,\n speaking,\n micEnabled,\n onToggleMic,\n cameraEnabled,\n onToggleCamera,\n onRestore,\n onLeave,\n restoreLabel = 'Back to the call',\n shortcuts = true,\n className,\n}: {\n title: string\n /** M / V work on the card too. */\n shortcuts?: boolean\n /** The current speaker's tile; omitted (before the call connects), a phone placeholder. */\n video?: ReactNode\n status?: ReactNode\n /** \"Speaking: …\" (a `SpeakingNow`), shown instead of the title while someone talks. */\n speaking?: ReactNode\n /** Omit (with the toggle) before the call connects. */\n micEnabled?: boolean\n onToggleMic?(): void\n cameraEnabled?: boolean\n onToggleCamera?(): void\n onRestore(): void\n onLeave(): void\n restoreLabel?: string\n className?: string\n}): ReactElement {\n const ref = useRef<HTMLDivElement>(null)\n useShortcutKeys(ref, shortcuts)\n return (\n <div ref={ref} className={cn('flex flex-col', className)} data-testid=\"call-minimised\">\n <button\n type=\"button\"\n className=\"group relative aspect-video w-full overflow-hidden rounded-t-md bg-hero focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\"\n onClick={onRestore}\n aria-label={restoreLabel}\n data-testid=\"call-minimised-restore\"\n >\n <span className=\"call-tile-box absolute inset-0\">\n {video ?? (\n <span className=\"call-tile\">\n <span className=\"call-tile-placeholder\">\n <span className=\"call-tile-avatar call-tile-avatar-sm\">\n <Phone className=\"size-4\" aria-hidden />\n </span>\n </span>\n </span>\n )}\n </span>\n </button>\n <div className=\"flex flex-col gap-2 px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\" title={title}>\n {title}\n </span>\n {status && <span className=\"flex shrink-0 items-center gap-1\">{status}</span>}\n </div>\n {speaking}\n <div className=\"flex items-center gap-2\">\n {onToggleMic && micEnabled !== undefined && (\n <CallControlButton\n label={micEnabled ? 'Turn off microphone' : 'Turn on microphone'}\n shortcut=\"M\"\n tone={micEnabled ? 'neutral' : 'off'}\n aria-pressed={micEnabled}\n onClick={onToggleMic}\n className=\"size-8\"\n data-testid=\"call-minimised-mic\"\n data-call-shortcut=\"m\"\n >\n {micEnabled ? <Mic aria-hidden /> : <MicOff aria-hidden />}\n </CallControlButton>\n )}\n {onToggleCamera && cameraEnabled !== undefined && (\n <CallControlButton\n label={cameraEnabled ? 'Turn off camera' : 'Turn on camera'}\n shortcut=\"V\"\n tone={cameraEnabled ? 'neutral' : 'off'}\n aria-pressed={cameraEnabled}\n onClick={onToggleCamera}\n className=\"size-8\"\n data-testid=\"call-minimised-camera\"\n data-call-shortcut=\"v\"\n >\n {cameraEnabled ? <Video aria-hidden /> : <VideoOff aria-hidden />}\n </CallControlButton>\n )}\n <span className=\"flex-1\" />\n <CallControlButton\n label={restoreLabel}\n onClick={onRestore}\n className=\"size-8\"\n data-testid=\"call-dock-expand\"\n >\n <Maximize2 aria-hidden />\n </CallControlButton>\n <CallControlButton\n label=\"Leave call\"\n tone=\"danger\"\n onClick={onLeave}\n className=\"size-8\"\n data-testid=\"call-dock-leave\"\n >\n <PhoneOff aria-hidden />\n </CallControlButton>\n </div>\n </div>\n </div>\n )\n}\n\n/** A ring: who calls, in what context, accept / decline, and the ringtone switch. */\nexport function IncomingCallCard({\n callerName,\n caller,\n context,\n busy = false,\n muted,\n onMutedChange,\n onAccept,\n onDecline,\n className,\n}: {\n callerName: string\n /** The caller as the app shows people (a pill); else `callerName`. */\n caller?: ReactNode\n /** \"is calling you\", \"invites you to a group call\", … */\n context: string\n busy?: boolean\n muted: boolean\n onMutedChange(muted: boolean): void\n onAccept(): void\n onDecline(): void\n className?: string\n}): ReactElement {\n return (\n <div\n role=\"alertdialog\"\n aria-labelledby=\"incoming-call-title\"\n aria-describedby=\"incoming-call-desc\"\n data-testid=\"incoming-call-dialog\"\n className={cn(\n 'w-80 max-w-[calc(100vw-2rem)] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-xl motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-top-2',\n className\n )}\n >\n <div className=\"flex items-start gap-3\">\n <span className=\"relative flex size-10 shrink-0\" aria-hidden>\n <span className=\"absolute inset-0 rounded-full bg-primary/20 motion-safe:animate-ping\" />\n <span className=\"relative flex size-10 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Phone className=\"size-5\" />\n </span>\n </span>\n <div className=\"min-w-0 flex-1 pt-0.5\">\n <div id=\"incoming-call-title\" className=\"flex min-w-0 text-sm font-semibold\">\n {caller ?? <span className=\"truncate\">{callerName}</span>}\n {caller && <span className=\"sr-only\">{callerName}</span>}\n </div>\n <p id=\"incoming-call-desc\" className=\"text-xs text-muted-foreground\">\n {context}\n </p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"-mr-1 -mt-1 size-8 shrink-0 text-muted-foreground hover:text-foreground\"\n aria-pressed={muted}\n aria-label={muted ? 'Unmute ringtone' : 'Mute ringtone'}\n title={muted ? 'Unmute ringtone' : 'Mute ringtone'}\n onClick={() => onMutedChange(!muted)}\n data-testid=\"incoming-call-mute\"\n >\n {muted ? <BellOff className=\"size-4\" /> : <Bell className=\"size-4\" />}\n </Button>\n </div>\n <div className=\"mt-4 grid grid-cols-2 gap-2\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={onDecline}\n disabled={busy}\n data-testid=\"incoming-call-decline\"\n >\n <PhoneOff className=\"size-4\" aria-hidden />\n Decline\n </Button>\n <Button\n type=\"button\"\n onClick={onAccept}\n disabled={busy}\n data-testid=\"incoming-call-accept\"\n autoFocus\n >\n {busy ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <Phone className=\"size-4\" aria-hidden />\n )}\n Accept\n </Button>\n </div>\n </div>\n )\n}\n\n/** A centred state on the stage (waiting in the lobby, connecting). */\nexport function CallStateMessage({\n title,\n description,\n spinner = true,\n action,\n testId,\n}: {\n title: string\n description?: string\n spinner?: boolean\n action?: ReactNode\n testId?: string\n}): ReactElement {\n return (\n <div\n className=\"flex size-full flex-col items-center justify-center gap-3 p-6 text-center\"\n data-testid={testId}\n >\n {spinner && <Loader2 className=\"size-6 animate-spin text-muted-foreground\" aria-hidden />}\n <p className=\"text-base font-semibold\">{title}</p>\n {description && <p className=\"max-w-sm text-sm text-muted-foreground\">{description}</p>}\n {action}\n </div>\n )\n}\n\n/** Covers the tiles while (re)connecting. */\nexport function ConnectionOverlay({ label }: { label: string }): ReactElement {\n return (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center rounded-md bg-background/70 text-sm text-muted-foreground\">\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n {label}\n </div>\n )\n}\n","/** What the pre-join hands the call: microphone / camera on or off, and which devices. */\nexport interface JoinChoices {\n audioEnabled: boolean\n videoEnabled: boolean\n audioDeviceId?: string\n videoDeviceId?: string\n}\n\nexport const DEFAULT_JOIN_CHOICES: JoinChoices = { audioEnabled: true, videoEnabled: false }\n\nexport type MediaKind = 'camera' | 'microphone'\n\n/** A readable sentence for a getUserMedia failure (the app may pass a richer one). */\nexport function describeMediaError(err: unknown, kind: MediaKind): string {\n const Kind = kind === 'camera' ? 'Camera' : 'Microphone'\n const name = (err as { name?: string } | null)?.name\n if (name === 'NotAllowedError' || name === 'SecurityError')\n return `${Kind} access is blocked. Allow it in the browser's site settings and try again.`\n if (name === 'NotFoundError' || name === 'OverconstrainedError') return `No ${kind} was found.`\n if (name === 'NotReadableError') return `${Kind} is in use by another app.`\n return `${Kind} could not start${(err as Error)?.message ? `: ${(err as Error).message}` : '.'}`\n}\n","/**\n * PreJoin — device check before entering a call: camera preview, microphone level meter, camera /\n * microphone pickers and on/off toggles. Used when starting a call, joining a scheduled call or a\n * call link. (Answering a ring skips it and joins straight away, microphone on.)\n *\n * Plain getUserMedia — no media library — so it is cheap to show. The preview tracks are stopped on\n * join / unmount; the call opens its own with the chosen devices. Wide: preview left, choices\n * right; narrow: stacked.\n */\n\nimport { useEffect, useRef, useState, type ReactElement, type ReactNode } from 'react'\nimport { Loader2, Mic, MicOff, Video, VideoOff } from 'lucide-react'\nimport {\n Button,\n cn,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@arbidocs/react/ui'\nimport { CallControlButton } from './ControlButton'\nimport {\n DEFAULT_JOIN_CHOICES,\n describeMediaError,\n type JoinChoices,\n type MediaKind,\n} from './join-choices'\n\nexport interface PreJoinProps {\n /** The call's name, shown above the choices. */\n title?: string | null\n /** Heading of the choices (default \"Ready to join?\"). */\n heading?: string\n /** Extra fields above the join button (optional). */\n children?: ReactNode\n joinLabel?: string\n busy?: boolean\n /** Shown under the controls (e.g. a join error). */\n error?: string | null\n onJoin(choices: JoinChoices): void\n onCancel?(): void\n /** Mirror the camera preview (a selfie view, the default; only the <video> flips). */\n mirror?: boolean\n /** Turns a device error into a sentence (defaults to {@link describeMediaError}). */\n describeError?(err: unknown, kind: MediaKind): string\n className?: string\n}\n\ntype Kind = 'audioinput' | 'videoinput'\n\nfunction useDevices(kind: Kind, refreshKey: unknown): MediaDeviceInfo[] {\n const [devices, setDevices] = useState<MediaDeviceInfo[]>([])\n useEffect(() => {\n const md = navigator.mediaDevices\n if (!md?.enumerateDevices) return\n let cancelled = false\n const load = () =>\n md\n .enumerateDevices()\n .then((all) => {\n if (!cancelled) setDevices(all.filter((d) => d.kind === kind && d.deviceId))\n })\n .catch(() => {})\n void load()\n md.addEventListener?.('devicechange', load)\n return () => {\n cancelled = true\n md.removeEventListener?.('devicechange', load)\n }\n }, [kind, refreshKey])\n return devices\n}\n\n/** A live preview track for one device kind while `enabled`; errors are reported, not thrown. */\nfunction usePreviewStream(\n kind: Kind,\n enabled: boolean,\n deviceId: string | undefined,\n describe: (err: unknown, kind: MediaKind) => string\n) {\n const [stream, setStream] = useState<MediaStream | null>(null)\n const [error, setError] = useState<string | null>(null)\n const describeRef = useRef(describe)\n describeRef.current = describe\n useEffect(() => {\n if (!enabled) {\n setStream(null)\n return\n }\n const md = navigator.mediaDevices\n if (!md?.getUserMedia) {\n setError(\n window.isSecureContext\n ? 'This browser cannot access the camera or microphone.'\n : 'Camera and microphone need HTTPS (or localhost).'\n )\n return\n }\n let cancelled = false\n let opened: MediaStream | null = null\n const constraint: MediaTrackConstraints | boolean = deviceId\n ? { deviceId: { exact: deviceId } }\n : true\n md.getUserMedia(kind === 'videoinput' ? { video: constraint } : { audio: constraint })\n .then((s) => {\n opened = s\n if (cancelled) s.getTracks().forEach((t) => t.stop())\n else {\n setError(null)\n setStream(s)\n }\n })\n .catch((err: unknown) => {\n if (!cancelled)\n setError(describeRef.current(err, kind === 'videoinput' ? 'camera' : 'microphone'))\n })\n return () => {\n cancelled = true\n opened?.getTracks().forEach((t) => t.stop())\n setStream(null)\n }\n }, [kind, enabled, deviceId])\n return { stream, error }\n}\n\n/** 0..1 input level from an AnalyserNode, sampled every animation frame. */\nfunction useAudioLevel(stream: MediaStream | null): number {\n const [level, setLevel] = useState(0)\n useEffect(() => {\n if (!stream || typeof AudioContext === 'undefined') {\n setLevel(0)\n return\n }\n let ctx: AudioContext\n try {\n ctx = new AudioContext()\n } catch {\n return\n }\n const analyser = ctx.createAnalyser()\n analyser.fftSize = 512\n ctx.createMediaStreamSource(stream).connect(analyser)\n const buf = new Uint8Array(analyser.fftSize)\n let frame = 0\n const tick = () => {\n analyser.getByteTimeDomainData(buf)\n let peak = 0\n for (const v of buf) peak = Math.max(peak, Math.abs(v - 128))\n setLevel(Math.min(1, peak / 64))\n frame = requestAnimationFrame(tick)\n }\n void ctx.resume().catch(() => {})\n tick()\n return () => {\n cancelAnimationFrame(frame)\n void ctx.close().catch(() => {})\n }\n }, [stream])\n return level\n}\n\nfunction DeviceSelect({\n devices,\n value,\n onChange,\n label,\n icon,\n disabled,\n testId,\n}: {\n devices: MediaDeviceInfo[]\n value: string | undefined\n onChange(id: string): void\n label: string\n icon: ReactNode\n disabled?: boolean\n testId: string\n}): ReactElement {\n const current = value ?? devices[0]?.deviceId\n return (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n <span className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground [&_svg]:size-3.5\">\n {icon}\n {label}\n </span>\n <Select value={current} onValueChange={onChange} disabled={disabled || devices.length < 2}>\n <SelectTrigger aria-label={label} className=\"h-9 min-w-0 text-sm\" data-testid={testId}>\n <SelectValue placeholder={`Default ${label.toLowerCase()}`} />\n </SelectTrigger>\n <SelectContent>\n {devices.map((d, i) => (\n <SelectItem key={d.deviceId} value={d.deviceId}>\n {d.label || `${label} ${i + 1}`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )\n}\n\nexport function PreJoin({\n title,\n heading = 'Ready to join?',\n children,\n joinLabel = 'Join',\n busy = false,\n error,\n onJoin,\n onCancel,\n describeError = describeMediaError,\n mirror = true,\n className,\n}: PreJoinProps): ReactElement {\n const [choices, setChoices] = useState<JoinChoices>(DEFAULT_JOIN_CHOICES)\n const video = usePreviewStream(\n 'videoinput',\n choices.videoEnabled,\n choices.videoDeviceId,\n describeError\n )\n const audio = usePreviewStream(\n 'audioinput',\n choices.audioEnabled,\n choices.audioDeviceId,\n describeError\n )\n const level = useAudioLevel(audio.stream)\n // Labels appear only after permission is granted: re-enumerate once a stream opens.\n const cameras = useDevices('videoinput', video.stream)\n const mics = useDevices('audioinput', audio.stream)\n const videoRef = useRef<HTMLVideoElement>(null)\n\n useEffect(() => {\n if (videoRef.current) videoRef.current.srcObject = video.stream\n }, [video.stream])\n\n const set = (patch: Partial<JoinChoices>) => setChoices((c) => ({ ...c, ...patch }))\n const deviceError = video.error ?? audio.error\n\n return (\n <div className={cn('@container flex w-full', className)} data-testid=\"call-prejoin\">\n <div className=\"mx-auto grid w-full max-w-4xl items-center gap-6 @2xl:grid-cols-[3fr_2fr] @2xl:gap-8\">\n <div className=\"flex flex-col gap-3\">\n <div className=\"relative aspect-video w-full overflow-hidden rounded-md bg-hero\">\n {choices.videoEnabled && video.stream ? (\n <video\n ref={videoRef}\n autoPlay\n muted\n playsInline\n className={cn('size-full object-cover', mirror && '-scale-x-100')}\n data-testid=\"call-prejoin-video\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center text-sm text-white/80\">\n {choices.videoEnabled ? (\n <Loader2 className=\"size-5 animate-spin\" aria-label=\"Starting camera\" />\n ) : (\n 'Camera is off'\n )}\n </div>\n )}\n </div>\n <div className=\"flex items-center justify-center gap-3\">\n <CallControlButton\n label={choices.audioEnabled ? 'Turn off microphone' : 'Turn on microphone'}\n tone={choices.audioEnabled ? 'neutral' : 'off'}\n aria-pressed={choices.audioEnabled}\n onClick={() => set({ audioEnabled: !choices.audioEnabled })}\n data-testid=\"call-prejoin-mic-toggle\"\n >\n {choices.audioEnabled ? <Mic aria-hidden /> : <MicOff aria-hidden />}\n </CallControlButton>\n <CallControlButton\n label={choices.videoEnabled ? 'Turn off camera' : 'Turn on camera'}\n tone={choices.videoEnabled ? 'neutral' : 'off'}\n aria-pressed={choices.videoEnabled}\n onClick={() => set({ videoEnabled: !choices.videoEnabled })}\n data-testid=\"call-prejoin-camera-toggle\"\n >\n {choices.videoEnabled ? <Video aria-hidden /> : <VideoOff aria-hidden />}\n </CallControlButton>\n </div>\n </div>\n\n <div className=\"flex min-w-0 flex-col gap-4\">\n <div className=\"flex flex-col gap-1\">\n <h2 className=\"text-xl font-semibold\">{heading}</h2>\n {title && <p className=\"truncate text-sm text-muted-foreground\">{title}</p>}\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <DeviceSelect\n devices={mics}\n value={choices.audioDeviceId}\n onChange={(id) => set({ audioDeviceId: id })}\n label=\"Microphone\"\n icon={<Mic />}\n disabled={!choices.audioEnabled}\n testId=\"call-prejoin-mic-select\"\n />\n <div\n className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\"\n role=\"meter\"\n aria-label=\"Microphone level\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={Math.round(level * 100)}\n data-testid=\"call-prejoin-mic-level\"\n >\n <div\n className=\"h-full bg-primary transition-[width] duration-75 motion-reduce:transition-none\"\n style={{ width: `${Math.round(level * 100)}%` }}\n />\n </div>\n <DeviceSelect\n devices={cameras}\n value={choices.videoDeviceId}\n onChange={(id) => set({ videoDeviceId: id })}\n label=\"Camera\"\n icon={<Video />}\n disabled={!choices.videoEnabled}\n testId=\"call-prejoin-camera-select\"\n />\n </div>\n\n {children}\n\n {(error || deviceError) && (\n <p role=\"alert\" className=\"text-sm text-destructive\" data-testid=\"call-prejoin-error\">\n {error ?? deviceError}\n </p>\n )}\n\n <div className=\"flex gap-2\">\n <Button\n type=\"button\"\n className=\"flex-1\"\n disabled={busy}\n onClick={() => onJoin(choices)}\n data-testid=\"call-prejoin-join\"\n >\n {busy && <Loader2 className=\"size-4 animate-spin\" aria-hidden />}\n {joinLabel}\n </Button>\n {onCancel && (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onCancel}\n data-testid=\"call-prejoin-cancel\"\n >\n Cancel\n </Button>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** What the pre-join hands the call: microphone / camera on or off, and which devices. */
|
|
2
|
+
export interface JoinChoices {
|
|
3
|
+
audioEnabled: boolean;
|
|
4
|
+
videoEnabled: boolean;
|
|
5
|
+
audioDeviceId?: string;
|
|
6
|
+
videoDeviceId?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const DEFAULT_JOIN_CHOICES: JoinChoices;
|
|
9
|
+
export type MediaKind = 'camera' | 'microphone';
|
|
10
|
+
/** A readable sentence for a getUserMedia failure (the app may pass a richer one). */
|
|
11
|
+
export declare function describeMediaError(err: unknown, kind: MediaKind): string;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure layout helpers for the call stage: the adaptive tile grid, the per-speaker caption accent,
|
|
3
|
+
* the picture-in-picture corner and the elapsed-time label. No React, no LiveKit: unit-tested on
|
|
4
|
+
* their own.
|
|
5
|
+
*/
|
|
6
|
+
/** Tiles are 16:9, like the cameras they show. */
|
|
7
|
+
export declare const TILE_ASPECT: number;
|
|
8
|
+
/** How long a status notice ("Recording — started by X") stays spelled out before it folds. */
|
|
9
|
+
export declare const NOTICE_MS = 6000;
|
|
10
|
+
/** How long a caption stays on screen. */
|
|
11
|
+
export declare const CAPTION_TTL_MS = 8000;
|
|
12
|
+
/** Caption lines shown at once (two lines, the newest at the bottom). */
|
|
13
|
+
export declare const CAPTION_LINES = 2;
|
|
14
|
+
/** Tiles shown in the grid before the rest fold into a "+N" tile. */
|
|
15
|
+
export declare const MAX_GRID_TILES = 9;
|
|
16
|
+
export interface GridLayout {
|
|
17
|
+
cols: number;
|
|
18
|
+
rows: number;
|
|
19
|
+
/** Tiles per row, top to bottom (a short last row is centred: 3 → [2, 1]). */
|
|
20
|
+
rowCounts: number[];
|
|
21
|
+
tileWidth: number;
|
|
22
|
+
tileHeight: number;
|
|
23
|
+
/** The cell a tile fills when the grid fills the whole stage (the layout's rows × columns). */
|
|
24
|
+
cellWidth: number;
|
|
25
|
+
cellHeight: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The grid that gives `count` tiles of a fixed aspect the largest size inside `width × height`
|
|
29
|
+
* with `gap` between them, preferring a row-first layout when it is nearly as large.
|
|
30
|
+
*/
|
|
31
|
+
export declare function gridLayout(count: number, width: number, height: number, gap?: number, aspect?: number): GridLayout;
|
|
32
|
+
/** Spread `count` tiles over rows of at most `cols`, the fuller rows first: 5 in 3 → [3, 2]. */
|
|
33
|
+
export declare function rowCounts(count: number, cols: number): number[];
|
|
34
|
+
/** What the grid shows: up to {@link MAX_GRID_TILES}; past that, one slot becomes "+N more". */
|
|
35
|
+
export declare function gridSlots<T>(items: T[], max?: number): {
|
|
36
|
+
shown: T[];
|
|
37
|
+
hidden: number;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Speaker accents for captions: semantic text tokens that meet AA contrast on the muted surface
|
|
41
|
+
* in both themes. The same identity always gets the same colour.
|
|
42
|
+
*/
|
|
43
|
+
export declare const SPEAKER_ACCENTS: readonly ["text-blue-text-strong", "text-purple-text-strong", "text-green-text-strong", "text-yellow-text-strong", "text-red-text-strong"];
|
|
44
|
+
export declare function speakerAccent(identity: string): (typeof SPEAKER_ACCENTS)[number];
|
|
45
|
+
/** The same speaker's colour as a border (the live transcript line). */
|
|
46
|
+
export declare const SPEAKER_BORDERS: readonly ["border-blue-text-strong", "border-purple-text-strong", "border-green-text-strong", "border-yellow-text-strong", "border-red-text-strong"];
|
|
47
|
+
export declare function speakerBorder(identity: string): (typeof SPEAKER_BORDERS)[number];
|
|
48
|
+
/** The speaker's colour as an inset ring (the line being spoken). */
|
|
49
|
+
export declare const SPEAKER_RINGS: readonly ["ring-blue-text-strong/40", "ring-purple-text-strong/40", "ring-green-text-strong/40", "ring-yellow-text-strong/40", "ring-red-text-strong/40"];
|
|
50
|
+
export declare function speakerRing(identity: string): (typeof SPEAKER_RINGS)[number];
|
|
51
|
+
/** The speaker's colour as a fill (the "is speaking" dots). */
|
|
52
|
+
export declare const SPEAKER_DOTS: readonly ["bg-blue-text-strong", "bg-purple-text-strong", "bg-green-text-strong", "bg-yellow-text-strong", "bg-red-text-strong"];
|
|
53
|
+
export declare function speakerDot(identity: string): (typeof SPEAKER_DOTS)[number];
|
|
54
|
+
export type PipCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
55
|
+
/** The viewport corner nearest to a point (where a dragged picture-in-picture card settles). */
|
|
56
|
+
export declare function nearestCorner(x: number, y: number, width: number, height: number): PipCorner;
|
|
57
|
+
/** `m:ss`, or `h:mm:ss` past an hour. */
|
|
58
|
+
export declare function formatElapsed(ms: number): string;
|
|
59
|
+
/** Up to two initials for a camera-off tile: "Alice Morgan" → "AM", "usr-1a2b" → "U". */
|
|
60
|
+
export declare function initialsOf(name: string): string;
|
|
61
|
+
/** Who has the spotlight (speaker view), and who is waiting to take it. */
|
|
62
|
+
export interface SpotlightState {
|
|
63
|
+
id: string | null;
|
|
64
|
+
/** A louder voice that must stay dominant for `holdMs` before it takes over. */
|
|
65
|
+
candidate: string | null;
|
|
66
|
+
since: number;
|
|
67
|
+
}
|
|
68
|
+
export declare const INITIAL_SPOTLIGHT: SpotlightState;
|
|
69
|
+
/** A voice at or above this level (0..1) counts as speaking. */
|
|
70
|
+
export declare const SPEAKING_LEVEL = 0.08;
|
|
71
|
+
/**
|
|
72
|
+
* The speaker view's spotlight, with hysteresis: a new voice takes the spotlight only after it has
|
|
73
|
+
* dominated (`margin` × louder than the current one, above `threshold`) for `holdMs`, so a cough
|
|
74
|
+
* does not flick the view; while several talk at once and nobody dominates, it stays put. With
|
|
75
|
+
* nobody in the spotlight yet, the first voice takes it at once. `exclude` (my own identity) never
|
|
76
|
+
* takes the spotlight: nobody needs to watch themselves large (Meet / Zoom behaviour).
|
|
77
|
+
*/
|
|
78
|
+
export declare function nextSpotlight(state: SpotlightState, levels: Record<string, number>, now: number, { threshold, holdMs, margin, exclude }?: {
|
|
79
|
+
threshold?: number | undefined;
|
|
80
|
+
holdMs?: number | undefined;
|
|
81
|
+
margin?: number | undefined;
|
|
82
|
+
exclude?: readonly string[] | undefined;
|
|
83
|
+
}): SpotlightState;
|
|
84
|
+
/**
|
|
85
|
+
* Who fills the speaker view's large slot: the spotlight if it is someone else in the call, else
|
|
86
|
+
* the first other person, else me (alone in the call). Never me while anyone else is there.
|
|
87
|
+
*/
|
|
88
|
+
export declare function pickSpotlight(people: readonly {
|
|
89
|
+
id: string;
|
|
90
|
+
local: boolean;
|
|
91
|
+
}[], spotlightId: string | null): string | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* The speaker view's large tile: the biggest 16:9 box that fits, leaving room for the filmstrip
|
|
94
|
+
* (below it on a narrow stage — a row of three 16:9 thumbnails per line — or a 15rem column beside
|
|
95
|
+
* it). It never takes a portrait shape: spare height stays blank under the filmstrip.
|
|
96
|
+
*/
|
|
97
|
+
export declare function spotlightBox(width: number, height: number, others: number, narrow: boolean, gap?: number, aspect?: number): {
|
|
98
|
+
width: number;
|
|
99
|
+
height: number;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* How tall the call stage's tiles are, for a stage `width` wide and at most `maxHeight` tall:
|
|
103
|
+
* speaker view (`focus`: the large 16:9 tile, plus the filmstrip under it on a narrow stage) or
|
|
104
|
+
* gallery (`grid`). The panel gives the rest of its height to the participant list.
|
|
105
|
+
*/
|
|
106
|
+
export declare function stageContentHeight(view: 'focus' | 'grid', width: number, maxHeight: number, count: number, gap?: number, aspect?: number): number;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The call panel's participant list and the lobby requests. Presentational: the app supplies the people
|
|
3
|
+
* and the actions. (Chat happens in the call's conversation, beside the panel.)
|
|
4
|
+
*/
|
|
5
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
6
|
+
export interface CallPerson {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
isLocal: boolean;
|
|
10
|
+
micMuted?: boolean;
|
|
11
|
+
/** Publishing an unmuted camera (the host may turn it off). */
|
|
12
|
+
cameraOn?: boolean;
|
|
13
|
+
/** Talking now, and how loud (0..1): the live speaker list. */
|
|
14
|
+
speaking?: boolean;
|
|
15
|
+
level?: number;
|
|
16
|
+
/** Extra state after the name (e.g. "Presenting"). */
|
|
17
|
+
note?: ReactNode;
|
|
18
|
+
/** The person as the app shows people (a pill); else initials and `name`. */
|
|
19
|
+
entity?: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
/** A small live voice meter: five bars lit by level; "muted" when the mic is off. */
|
|
22
|
+
export declare function VoiceMeter({ level, muted, className, }: {
|
|
23
|
+
level: number;
|
|
24
|
+
muted?: boolean;
|
|
25
|
+
className?: string;
|
|
26
|
+
}): ReactElement;
|
|
27
|
+
/**
|
|
28
|
+
* Who is in the call, always on show under the video in the call panel: a live speaker list (the
|
|
29
|
+
* app orders it, talkers first), each row with the person's pill, voice meter, mic and camera
|
|
30
|
+
* state, and — for the host — mute / ask to mute / remove in its "…". Scrolls when long. In a
|
|
31
|
+
* short panel (`compact`) it folds to one strip — who is talking, and "Show all (N)".
|
|
32
|
+
*/
|
|
33
|
+
export declare function CallParticipants({ people, canRemove, removingId, onRemove, onAskToMute, onMute, compact, className, }: {
|
|
34
|
+
people: CallPerson[];
|
|
35
|
+
canRemove: boolean;
|
|
36
|
+
removingId?: string | null;
|
|
37
|
+
onRemove(person: CallPerson): void;
|
|
38
|
+
/** Shown for others whose mic is on (the host). */
|
|
39
|
+
onAskToMute?(person: CallPerson): void;
|
|
40
|
+
/** The host's force-mute of a mic (`audio`, shown while it is on) or a camera (`video`, while on). */
|
|
41
|
+
onMute?(person: CallPerson, track: 'audio' | 'video'): void;
|
|
42
|
+
compact?: boolean;
|
|
43
|
+
className?: string;
|
|
44
|
+
}): ReactElement;
|
|
45
|
+
export interface LobbyRequest {
|
|
46
|
+
id: string;
|
|
47
|
+
name: string;
|
|
48
|
+
/** The person as the app shows people (a pill); else `name`. */
|
|
49
|
+
entity?: ReactNode;
|
|
50
|
+
}
|
|
51
|
+
/** People asking to join, as cards over the stage's top-left corner. */
|
|
52
|
+
export declare function LobbyRequests({ requests, onDecide, }: {
|
|
53
|
+
requests: LobbyRequest[];
|
|
54
|
+
onDecide(id: string, admit: boolean): void;
|
|
55
|
+
}): ReactElement | null;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The call's status, each shown once in the header (or on the minimised card): recording,
|
|
3
|
+
* transcription and encryption chips, and the live captions strip below the tiles.
|
|
4
|
+
*
|
|
5
|
+
* Recording and transcription chips first spell out who started them ("Recording (Audio) —
|
|
6
|
+
* started by Ada"), then fold to a short label after {@link NOTICE_MS}; the full sentence stays
|
|
7
|
+
* available to screen readers and as the tooltip.
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
10
|
+
/** "Recording" with a pulsing dot. */
|
|
11
|
+
export declare function RecordingStatusChip({ sentence, short, compact, announce, onAnnounced, className, ...rest }: {
|
|
12
|
+
/** Spell the sentence out first (false once it has been, e.g. after a re-mount). */
|
|
13
|
+
announce?: boolean;
|
|
14
|
+
onAnnounced?(): void;
|
|
15
|
+
/** e.g. "Recording (Audio + video) — started by you". */
|
|
16
|
+
sentence: string;
|
|
17
|
+
short?: string;
|
|
18
|
+
/** Dot only once folded (a narrow header, the minimised card). */
|
|
19
|
+
compact?: boolean;
|
|
20
|
+
className?: string;
|
|
21
|
+
} & Omit<React.HTMLAttributes<HTMLSpanElement>, 'title'>): ReactElement;
|
|
22
|
+
/** "Transcribing", with my own "stop sending my voice" switch in it. */
|
|
23
|
+
export declare function TranscriptionStatusChip({ sentence, announce, onAnnounced, short, detail, muted, onMutedChange, muteLabel, unmuteLabel, compact, className, ...rest }: {
|
|
24
|
+
/** e.g. "Transcription on — started by Ada". */
|
|
25
|
+
sentence: string;
|
|
26
|
+
announce?: boolean;
|
|
27
|
+
onAnnounced?(): void;
|
|
28
|
+
short?: string;
|
|
29
|
+
/** Tooltip after the sentence (what transcription does). */
|
|
30
|
+
detail?: string;
|
|
31
|
+
muted: boolean;
|
|
32
|
+
onMutedChange(muted: boolean): void;
|
|
33
|
+
muteLabel: string;
|
|
34
|
+
unmuteLabel: string;
|
|
35
|
+
compact?: boolean;
|
|
36
|
+
className?: string;
|
|
37
|
+
} & Omit<React.HTMLAttributes<HTMLSpanElement>, 'title'>): ReactElement;
|
|
38
|
+
/** Whether the media is end-to-end encrypted. */
|
|
39
|
+
export declare function EncryptionStatusChip({ state, compact, labels, }: {
|
|
40
|
+
state: 'on' | 'pending' | 'off';
|
|
41
|
+
compact?: boolean;
|
|
42
|
+
labels?: {
|
|
43
|
+
on: string;
|
|
44
|
+
pending: string;
|
|
45
|
+
off: string;
|
|
46
|
+
onTitle: string;
|
|
47
|
+
offTitle: string;
|
|
48
|
+
};
|
|
49
|
+
}): ReactElement;
|
|
50
|
+
/** One caption: a speaker's latest segment. */
|
|
51
|
+
export interface CaptionEntry {
|
|
52
|
+
id: string;
|
|
53
|
+
speakerId: string;
|
|
54
|
+
name: string;
|
|
55
|
+
text: string;
|
|
56
|
+
/** Local receipt time, ms (drives the fade). */
|
|
57
|
+
receivedAt: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Live captions in a strip below the tiles (never over a face): at most two lines, the newest at
|
|
61
|
+
* the bottom, each speaker's name in their own accent. With `reserve` the strip keeps its height
|
|
62
|
+
* while empty, so the tiles do not jump each time someone starts or stops talking.
|
|
63
|
+
*/
|
|
64
|
+
export declare function CaptionsStrip({ captions, reserve, waitingText, className, }: {
|
|
65
|
+
captions: CaptionEntry[];
|
|
66
|
+
reserve?: boolean;
|
|
67
|
+
waitingText?: ReactNode;
|
|
68
|
+
className?: string;
|
|
69
|
+
}): ReactElement | null;
|