vue-parley 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{Call-CQpSxbDL.mjs → Call-DfAAePMJ.mjs} +48 -31
- package/dist/chunks/Call-DfAAePMJ.mjs.map +1 -0
- package/dist/chunks/{Call-4KBqhFK6.cjs → Call-w4VQ-iRu.cjs} +48 -31
- package/dist/chunks/Call-w4VQ-iRu.cjs.map +1 -0
- package/dist/chunks/{index-B89wAtdh.mjs → index-BdXnFhTL.mjs} +4 -4
- package/dist/chunks/{index-B89wAtdh.mjs.map → index-BdXnFhTL.mjs.map} +1 -1
- package/dist/chunks/{index-jw7O-NMe.cjs → index-BtxDzcig.cjs} +4 -4
- package/dist/chunks/{index-jw7O-NMe.cjs.map → index-BtxDzcig.cjs.map} +1 -1
- package/dist/chunks/{session-Ij2decwl.cjs → session-BBh6YzVv.cjs} +2 -2
- package/dist/chunks/{session-Ij2decwl.cjs.map → session-BBh6YzVv.cjs.map} +1 -1
- package/dist/chunks/{session-CAv8AIQt.mjs → session-yLg7UVs_.mjs} +2 -2
- package/dist/chunks/{session-CAv8AIQt.mjs.map → session-yLg7UVs_.mjs.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/types/app/components/call/Call.vue.d.ts.map +1 -1
- package/dist/types/app/composables/call/useCallUi.d.ts +1 -0
- package/dist/types/app/composables/call/useCallUi.d.ts.map +1 -1
- package/dist/types/app/composables/useCall.d.ts +1 -0
- package/dist/types/app/composables/useCall.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/Call-4KBqhFK6.cjs.map +0 -1
- package/dist/chunks/Call-CQpSxbDL.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref, onMounted, onUnmounted, watch, nextTick, reactive, onBeforeUnmount, computed, defineComponent, openBlock, createElementBlock, createBlock, unref, mergeProps, withCtx, createVNode, normalizeClass, createElementVNode, normalizeStyle, createSlots, toDisplayString, createCommentVNode, withDirectives, Fragment, useModel, renderList, createTextVNode, mergeModels, withModifiers, Transition, vShow } from "vue";
|
|
2
|
-
import { u as useCallStore, a as useLocalI18n, c as chat, n as nameInitials, b as avatarToneStyle, _ as _sfc_main$5, d as useDirection, e as useChatStore, f as formatDuration } from "./index-
|
|
2
|
+
import { u as useCallStore, a as useLocalI18n, c as chat, n as nameInitials, b as avatarToneStyle, _ as _sfc_main$5, d as useDirection, e as useChatStore, f as formatDuration } from "./index-BdXnFhTL.mjs";
|
|
3
3
|
import { useElementSize, useEventListener, useWindowSize, useDraggable } from "@vueuse/core";
|
|
4
4
|
import Button from "primevue/button";
|
|
5
5
|
import Menu from "primevue/menu";
|
|
@@ -35,16 +35,15 @@ function useCallUi(opts) {
|
|
|
35
35
|
detachAll();
|
|
36
36
|
});
|
|
37
37
|
const isFullscreen = ref(false);
|
|
38
|
+
const canFullscreen = typeof document !== "undefined" && !!document.fullscreenEnabled;
|
|
39
|
+
const syncFullscreen = () => isFullscreen.value = !!document.fullscreenElement;
|
|
38
40
|
function toggleFullscreen(target = document.documentElement) {
|
|
39
41
|
var _a;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
isFullscreen.value = true;
|
|
43
|
-
} else {
|
|
44
|
-
void document.exitFullscreen();
|
|
45
|
-
isFullscreen.value = false;
|
|
46
|
-
}
|
|
42
|
+
const change = document.fullscreenElement ? document.exitFullscreen() : (_a = target.requestFullscreen) == null ? void 0 : _a.call(target);
|
|
43
|
+
void (change == null ? void 0 : change.then(syncFullscreen, syncFullscreen));
|
|
47
44
|
}
|
|
45
|
+
onMounted(() => document.addEventListener("fullscreenchange", syncFullscreen));
|
|
46
|
+
onUnmounted(() => document.removeEventListener("fullscreenchange", syncFullscreen));
|
|
48
47
|
const toggleRemote = (tileId, el) => {
|
|
49
48
|
const container = el ?? remoteParents.value[tileId];
|
|
50
49
|
if (container) toggleFullscreen(container);
|
|
@@ -124,6 +123,7 @@ function useCallUi(opts) {
|
|
|
124
123
|
showControls,
|
|
125
124
|
resetControlsTimeout,
|
|
126
125
|
isFullscreen,
|
|
126
|
+
canFullscreen,
|
|
127
127
|
toggleFullscreen: () => toggleFullscreen(),
|
|
128
128
|
toggleRemote,
|
|
129
129
|
videoPaused,
|
|
@@ -199,6 +199,7 @@ function useCall({ layoutKey } = {}) {
|
|
|
199
199
|
showControls: ui.showControls,
|
|
200
200
|
resetControlsTimeout: ui.resetControlsTimeout,
|
|
201
201
|
isFullscreen: ui.isFullscreen,
|
|
202
|
+
canFullscreen: ui.canFullscreen,
|
|
202
203
|
toggleFullscreen: ui.toggleFullscreen,
|
|
203
204
|
toggleRemote: ui.toggleRemote,
|
|
204
205
|
videoPaused: ui.videoPaused,
|
|
@@ -1032,6 +1033,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1032
1033
|
isVideoOn,
|
|
1033
1034
|
isFlashlightOn,
|
|
1034
1035
|
isFullscreen,
|
|
1036
|
+
canFullscreen,
|
|
1035
1037
|
isScreenSharing,
|
|
1036
1038
|
showControls,
|
|
1037
1039
|
resetControlsTimeout,
|
|
@@ -1164,11 +1166,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1164
1166
|
]);
|
|
1165
1167
|
const moreMenu = ref(null);
|
|
1166
1168
|
const moreItems = computed(() => [
|
|
1167
|
-
{
|
|
1168
|
-
label: fullscreenLabel.value,
|
|
1169
|
-
callIcon: isFullscreen.value ? "fullscreenExit" : "fullscreen",
|
|
1170
|
-
command: () => toggleFullscreen()
|
|
1171
|
-
},
|
|
1172
1169
|
...isFlashlightSupported.value ? [
|
|
1173
1170
|
{
|
|
1174
1171
|
label: isFlashlightOn.value ? t("chat.call.controls.flashlightOff") : t("chat.call.controls.flashlightOn"),
|
|
@@ -1305,10 +1302,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1305
1302
|
playsinline: "",
|
|
1306
1303
|
class: "pointer-events-none absolute inset-0 size-full object-cover"
|
|
1307
1304
|
}, null, 512),
|
|
1308
|
-
_cache[
|
|
1305
|
+
_cache[18] || (_cache[18] = createElementVNode("div", { class: "pointer-events-none absolute inset-0 bg-linear-to-t from-black/60 via-transparent to-black/30" }, null, -1)),
|
|
1309
1306
|
createElementVNode("div", _hoisted_2, [
|
|
1310
1307
|
createElementVNode("div", _hoisted_3, [
|
|
1311
|
-
_cache[
|
|
1308
|
+
_cache[17] || (_cache[17] = createElementVNode("span", { class: "relative flex size-2.5" }, [
|
|
1312
1309
|
createElementVNode("span", { class: "absolute inline-flex size-full animate-ping rounded-full bg-red-500/60 motion-reduce:animate-none" }),
|
|
1313
1310
|
createElementVNode("span", { class: "relative inline-flex size-2.5 rounded-full bg-red-500" })
|
|
1314
1311
|
], -1)),
|
|
@@ -1386,12 +1383,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1386
1383
|
createElementVNode("div", {
|
|
1387
1384
|
"data-testid": "call-top-bar",
|
|
1388
1385
|
class: normalizeClass(["flex h-14 shrink-0 items-center gap-x-3 px-3 transition-opacity duration-300 motion-reduce:transition-none md:h-16 md:px-6", unref(showControls) ? "opacity-100" : "opacity-0"]),
|
|
1389
|
-
onMouseenter: _cache[
|
|
1386
|
+
onMouseenter: _cache[6] || (_cache[6] = //@ts-ignore
|
|
1390
1387
|
(...args) => unref(resetControlsTimeout) && unref(resetControlsTimeout)(...args))
|
|
1391
1388
|
}, [
|
|
1392
1389
|
createElementVNode("div", _hoisted_10, [
|
|
1393
1390
|
createElementVNode("h1", _hoisted_11, toDisplayString(callTitle.value), 1),
|
|
1394
|
-
_cache[
|
|
1391
|
+
_cache[19] || (_cache[19] = createElementVNode("span", {
|
|
1395
1392
|
"aria-hidden": "true",
|
|
1396
1393
|
class: "h-4 w-px shrink-0 bg-white/30"
|
|
1397
1394
|
}, null, -1)),
|
|
@@ -1425,6 +1422,25 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1425
1422
|
{ bottom: true }
|
|
1426
1423
|
]
|
|
1427
1424
|
]),
|
|
1425
|
+
unref(canFullscreen) ? withDirectives((openBlock(), createBlock(_sfc_main$3, {
|
|
1426
|
+
key: 0,
|
|
1427
|
+
icon: unref(isFullscreen) ? "fullscreenExit" : "fullscreen",
|
|
1428
|
+
label: fullscreenLabel.value,
|
|
1429
|
+
dt: unref(callButtonDt),
|
|
1430
|
+
text: false,
|
|
1431
|
+
"icon-class": "size-5",
|
|
1432
|
+
class: normalizeClass(["size-11!", unref(focusRing)]),
|
|
1433
|
+
"data-testid": "call-fullscreen",
|
|
1434
|
+
"data-active": unref(isFullscreen),
|
|
1435
|
+
onClick: _cache[5] || (_cache[5] = ($event) => unref(toggleFullscreen)())
|
|
1436
|
+
}, null, 8, ["icon", "label", "dt", "class", "data-active"])), [
|
|
1437
|
+
[
|
|
1438
|
+
unref(vTooltip),
|
|
1439
|
+
unref(tip)(fullscreenLabel.value),
|
|
1440
|
+
void 0,
|
|
1441
|
+
{ bottom: true }
|
|
1442
|
+
]
|
|
1443
|
+
]) : createCommentVNode("", true),
|
|
1428
1444
|
withDirectives(createVNode(_sfc_main$3, {
|
|
1429
1445
|
icon: "pictureInPicture",
|
|
1430
1446
|
label: unref(t)("chat.call.controls.minimize"),
|
|
@@ -1449,7 +1465,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1449
1465
|
ref: stageRef,
|
|
1450
1466
|
class: "relative min-h-0 flex-1 px-2 pb-2 md:px-4 md:pb-4",
|
|
1451
1467
|
style: { "--call-gap": "0.5rem" },
|
|
1452
|
-
onMousemove: _cache[
|
|
1468
|
+
onMousemove: _cache[11] || (_cache[11] = //@ts-ignore
|
|
1453
1469
|
(...args) => unref(resetControlsTimeout) && unref(resetControlsTimeout)(...args))
|
|
1454
1470
|
}, [
|
|
1455
1471
|
unref(soundBlocked) ? (openBlock(), createBlock(unref(Button), {
|
|
@@ -1496,9 +1512,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1496
1512
|
}, tileProps(selfTile.value), {
|
|
1497
1513
|
hint: unref(t)("chat.call.cameraIsOff"),
|
|
1498
1514
|
class: "size-full",
|
|
1499
|
-
onVideo: _cache[
|
|
1500
|
-
onPause: _cache[
|
|
1501
|
-
onFullscreen: _cache[
|
|
1515
|
+
onVideo: _cache[7] || (_cache[7] = (el, prev) => bindVideo(selfTile.value, el, prev)),
|
|
1516
|
+
onPause: _cache[8] || (_cache[8] = (el) => togglePause(selfTile.value, el)),
|
|
1517
|
+
onFullscreen: _cache[9] || (_cache[9] = (el) => toggleTileFullscreen(selfTile.value, el))
|
|
1502
1518
|
}), null, 16, ["hint"])),
|
|
1503
1519
|
showWaiting.value ? (openBlock(), createElementBlock("div", _hoisted_17, [
|
|
1504
1520
|
createElementVNode("div", _hoisted_18, [
|
|
@@ -1524,7 +1540,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1524
1540
|
}, tileProps(selfTile.value, true), {
|
|
1525
1541
|
"can-pin": false,
|
|
1526
1542
|
class: "absolute! end-5 bottom-4 z-10 aspect-video w-36 shadow-xl outline outline-white/25 sm:w-56 md:end-6 md:bottom-6 md:w-64",
|
|
1527
|
-
onVideo: _cache[
|
|
1543
|
+
onVideo: _cache[10] || (_cache[10] = (el, prev) => bindVideo(selfTile.value, el, prev))
|
|
1528
1544
|
}), null, 16))
|
|
1529
1545
|
], 64)) : unref(layout).mode.value === "grid" ? (openBlock(), createElementBlock("div", {
|
|
1530
1546
|
key: 3,
|
|
@@ -1579,9 +1595,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1579
1595
|
], 544),
|
|
1580
1596
|
createElementVNode("div", {
|
|
1581
1597
|
class: normalizeClass(["flex h-20 shrink-0 items-center justify-center px-3 transition-opacity duration-300 motion-reduce:transition-none md:px-6", unref(showControls) ? "opacity-100" : "opacity-0"]),
|
|
1582
|
-
onMouseenter: _cache[
|
|
1598
|
+
onMouseenter: _cache[14] || (_cache[14] = //@ts-ignore
|
|
1583
1599
|
(...args) => unref(resetControlsTimeout) && unref(resetControlsTimeout)(...args)),
|
|
1584
|
-
onMousemove: _cache[
|
|
1600
|
+
onMousemove: _cache[15] || (_cache[15] = //@ts-ignore
|
|
1585
1601
|
(...args) => unref(resetControlsTimeout) && unref(resetControlsTimeout)(...args))
|
|
1586
1602
|
}, [
|
|
1587
1603
|
createElementVNode("div", _hoisted_21, [
|
|
@@ -1615,7 +1631,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1615
1631
|
"icon-class": "size-6",
|
|
1616
1632
|
class: normalizeClass(["h-12! w-8! rounded-e-none! ps-1!", unref(focusRing)]),
|
|
1617
1633
|
"aria-haspopup": "true",
|
|
1618
|
-
onClick: _cache[
|
|
1634
|
+
onClick: _cache[12] || (_cache[12] = ($event) => {
|
|
1619
1635
|
var _a;
|
|
1620
1636
|
return (_a = cameraMenu.value) == null ? void 0 : _a.toggle($event);
|
|
1621
1637
|
})
|
|
@@ -1679,25 +1695,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1679
1695
|
{ top: true }
|
|
1680
1696
|
]
|
|
1681
1697
|
]) : createCommentVNode("", true),
|
|
1682
|
-
withDirectives(
|
|
1698
|
+
moreItems.value.length ? withDirectives((openBlock(), createBlock(_sfc_main$3, mergeProps({
|
|
1699
|
+
key: 2,
|
|
1683
1700
|
icon: "moreVert",
|
|
1684
1701
|
label: unref(t)("chat.call.controls.more")
|
|
1685
1702
|
}, barButton, {
|
|
1686
1703
|
class: "h-12! w-10! sm:w-12!",
|
|
1687
1704
|
"aria-haspopup": "true",
|
|
1688
1705
|
"data-testid": "call-more",
|
|
1689
|
-
onClick: _cache[
|
|
1706
|
+
onClick: _cache[13] || (_cache[13] = ($event) => {
|
|
1690
1707
|
var _a;
|
|
1691
1708
|
return (_a = moreMenu.value) == null ? void 0 : _a.toggle($event);
|
|
1692
1709
|
})
|
|
1693
|
-
}), null, 16, ["label"]), [
|
|
1710
|
+
}), null, 16, ["label"])), [
|
|
1694
1711
|
[
|
|
1695
1712
|
unref(vTooltip),
|
|
1696
1713
|
unref(tip)(unref(t)("chat.call.controls.more")),
|
|
1697
1714
|
void 0,
|
|
1698
1715
|
{ top: true }
|
|
1699
1716
|
]
|
|
1700
|
-
]),
|
|
1717
|
+
]) : createCommentVNode("", true),
|
|
1701
1718
|
withDirectives(createVNode(_sfc_main$3, {
|
|
1702
1719
|
icon: "callEnd",
|
|
1703
1720
|
label: unref(t)("chat.call.controls.endCall"),
|
|
@@ -1721,7 +1738,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1721
1738
|
], 34),
|
|
1722
1739
|
createVNode(_sfc_main$1, {
|
|
1723
1740
|
visible: peopleOpen.value,
|
|
1724
|
-
"onUpdate:visible": _cache[
|
|
1741
|
+
"onUpdate:visible": _cache[16] || (_cache[16] = ($event) => peopleOpen.value = $event),
|
|
1725
1742
|
participants: unref(participants)
|
|
1726
1743
|
}, null, 8, ["visible", "participants"]),
|
|
1727
1744
|
createVNode(unref(Menu), {
|
|
@@ -1769,4 +1786,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1769
1786
|
export {
|
|
1770
1787
|
_sfc_main as default
|
|
1771
1788
|
};
|
|
1772
|
-
//# sourceMappingURL=Call-
|
|
1789
|
+
//# sourceMappingURL=Call-DfAAePMJ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Call-DfAAePMJ.mjs","sources":["../../app/composables/call/useCallUi.ts","../../app/composables/useCall.ts","../../app/composables/call/useSpeaking.ts","../../app/composables/call/useCallLayout.ts","../../app/composables/call/useCallNotices.ts","../../app/components/call/CallIcon.vue","../../app/components/call/CallButton.vue","../../app/components/call/tokens.ts","../../app/components/call/CallTile.vue","../../app/components/call/CallParticipants.vue","../../app/components/call/Call.vue"],"sourcesContent":["import { nextTick, onMounted, onUnmounted, ref, watch, type Ref } from \"vue\";\nimport type { RemoteStream } from \"./peers\";\n\nexport interface CallUiOptions {\n localStream: Ref<MediaStream | null>;\n screenStream: Ref<MediaStream | null>;\n remoteVideos: Ref<Record<string, RemoteStream>>;\n remoteScreens: Ref<Record<string, RemoteStream>>;\n /** Re-attach streams when this changes: minimizing swaps the <video> elements. */\n isMinimized: () => boolean;\n /** Re-attach streams when this changes: tiles moving between grid, stage and strip remount. */\n layoutKey?: () => string;\n}\n\nconst CONTROLS_HIDE_AFTER_MS = 3000;\n\n/** The call screen's view state, and keeping each <video> element showing the right stream. */\nexport function useCallUi(opts: CallUiOptions) {\n const { localStream, screenStream, remoteVideos, remoteScreens } = opts;\n\n // Template refs, bound by Call.vue.\n const localVideo = ref<HTMLVideoElement | null>(null);\n const localScreen = ref<HTMLVideoElement | null>(null);\n const remoteRefs = ref<Record<string, HTMLVideoElement | null>>({});\n const remoteScreenRefs = ref<Record<string, HTMLVideoElement | undefined>>({});\n const remoteParents = ref<Record<string, HTMLElement>>({});\n\n // --- Controls fade out after a few seconds without input ---\n const showControls = ref(true);\n let controlsTimeout: ReturnType<typeof setTimeout> | undefined;\n function resetControlsTimeout() {\n showControls.value = true;\n clearTimeout(controlsTimeout);\n controlsTimeout = setTimeout(\n () => (showControls.value = false),\n CONTROLS_HIDE_AFTER_MS,\n );\n }\n const inputEvents = [\"mousemove\", \"click\", \"keydown\"] as const;\n onMounted(() => {\n resetControlsTimeout();\n inputEvents.forEach((e) => document.addEventListener(e, resetControlsTimeout));\n });\n onUnmounted(() => {\n inputEvents.forEach((e) => document.removeEventListener(e, resetControlsTimeout));\n clearTimeout(controlsTimeout);\n // The call goes on; only this view lets go of its elements.\n detachAll();\n });\n\n // --- Fullscreen: the whole call, or a single tile ---\n const isFullscreen = ref(false);\n // Browsers without the Fullscreen API on elements (iPhone Safari) get no button for it.\n const canFullscreen = typeof document !== \"undefined\" && !!document.fullscreenEnabled;\n // Read back from the document, not assumed: a request can be refused, and Esc or the browser's\n // own controls leave fullscreen without going through the toggle.\n const syncFullscreen = () => (isFullscreen.value = !!document.fullscreenElement);\n function toggleFullscreen(target: HTMLElement = document.documentElement) {\n const change = document.fullscreenElement\n ? document.exitFullscreen()\n : target.requestFullscreen?.();\n void change?.then(syncFullscreen, syncFullscreen);\n }\n onMounted(() => document.addEventListener(\"fullscreenchange\", syncFullscreen));\n onUnmounted(() => document.removeEventListener(\"fullscreenchange\", syncFullscreen));\n const toggleRemote = (tileId: string, el?: HTMLElement) => {\n const container = el ?? remoteParents.value[tileId];\n if (container) toggleFullscreen(container);\n };\n\n // --- Pausing a single tile ---\n const videoPaused = ref<Record<string, boolean>>({});\n function toggleVideoPause(tileId: string, el: HTMLVideoElement | null | undefined) {\n if (!(el instanceof HTMLVideoElement)) return;\n if (videoPaused.value[tileId]) void el.play();\n else el.pause();\n videoPaused.value[tileId] = !videoPaused.value[tileId];\n }\n\n // --- Keep each <video> showing its stream ---\n /** The browser refused to play a remote participant with sound until the user taps something. */\n const soundBlocked = ref(false);\n\n async function play(el: HTMLVideoElement) {\n try {\n await el.play();\n } catch (err) {\n if ((err as DOMException)?.name !== \"NotAllowedError\" || el.muted) return;\n // Mobile browsers (and desktop ones without prior interaction) refuse unmuted playback\n // that doesn't follow a tap, which would leave the tile black. Show the video muted and\n // offer a button to turn the sound on.\n el.muted = true;\n soundBlocked.value = true;\n await el.play().catch((e) => console.error(\"[vue-chat] Remote video can't play:\", e));\n }\n }\n\n /** Unmutes the remote participants; must run from a user gesture. */\n function enableSound() {\n soundBlocked.value = false;\n for (const el of Object.values(remoteRefs.value)) {\n if (!el) continue;\n el.muted = false;\n void play(el);\n }\n }\n\n const attach = (el: HTMLVideoElement | null | undefined, stream: MediaStream) => {\n if (!el) return;\n if (el.srcObject !== stream) el.srcObject = stream;\n void play(el);\n };\n\n /** Points every <video> at its stream: after a stream changes, or tiles moved and remounted. */\n async function reattach() {\n await nextTick();\n if (localStream.value && localVideo.value && localVideo.value.srcObject !== localStream.value)\n localVideo.value.srcObject = localStream.value;\n if (localScreen.value && localScreen.value.srcObject !== screenStream.value)\n localScreen.value.srcObject = screenStream.value;\n for (const [id, { stream }] of Object.entries(remoteVideos.value))\n attach(remoteRefs.value[id], stream);\n for (const [id, { stream }] of Object.entries(remoteScreens.value))\n attach(remoteScreenRefs.value[id], stream);\n }\n\n watch(\n [\n localStream,\n screenStream,\n () => ({ ...remoteVideos.value }),\n () => ({ ...remoteScreens.value }),\n opts.isMinimized,\n () => opts.layoutKey?.(),\n ],\n reattach,\n { immediate: true },\n );\n\n /** Detaches every <video>, so no element keeps a stopped stream alive. */\n function detachAll() {\n const all = [\n localVideo.value,\n localScreen.value,\n ...Object.values(remoteRefs.value),\n ...Object.values(remoteScreenRefs.value),\n ];\n for (const el of all) if (el) el.srcObject = null;\n }\n\n return {\n localVideo,\n localScreen,\n remoteRefs,\n remoteScreenRefs,\n remoteParents,\n showControls,\n resetControlsTimeout,\n isFullscreen,\n canFullscreen,\n toggleFullscreen: () => toggleFullscreen(),\n toggleRemote,\n videoPaused,\n toggleVideoPause,\n soundBlocked,\n enableSound,\n detachAll,\n reattach,\n };\n}\n","import { ref } from \"vue\";\nimport { useCallStore } from \"~/stores/callStore\";\nimport { useCallUi } from \"./call/useCallUi\";\n\n/**\n * The view side of the running call, for Call.vue. The call itself (signalling, peers, media)\n * lives in the call store, so unmounting this view doesn't end it.\n */\nexport default function useCall({ layoutKey }: { layoutKey?: () => string } = {}) {\n const callStore = useCallStore();\n const session = callStore.session;\n if (!session) {\n throw new Error(\"[vue-chat] useCall() needs a running call: callStore.startCall() first\");\n }\n const { media, peers } = session;\n\n const ui = useCallUi({\n localStream: media.localStream,\n screenStream: media.screenStream,\n remoteVideos: peers.remoteVideos,\n remoteScreens: peers.remoteScreens,\n isMinimized: () => callStore.isMinimized,\n layoutKey,\n });\n\n async function switchCamera(deviceId: string) {\n refreshPreview(await session!.switchCamera(deviceId));\n }\n\n async function flipCamera() {\n refreshPreview(await session!.flipCamera());\n }\n\n function refreshPreview(stream: MediaStream | null) {\n // Same stream object with a new track: the preview has to be told, and Safari only listens\n // when srcObject actually changes.\n const el = ui.localVideo.value;\n if (stream && el) {\n el.srcObject = null;\n el.srcObject = stream;\n el.play().catch(() => {});\n }\n }\n\n return {\n // Call state\n participantCount: session.participantCount,\n tileCount: session.tileCount,\n participants: session.participants,\n phase: session.phase,\n hadOthers: session.hadOthers,\n maxParticipants: session.maxParticipants,\n remoteMedia: peers.remoteMedia,\n peerStatus: peers.peerStatus,\n remoteNames: peers.remoteNames,\n localStream: media.localStream,\n remoteVideos: peers.remoteVideos,\n remoteScreens: peers.remoteScreens,\n // Local media\n cameras: media.cameras,\n facingMode: media.facingMode,\n canFlipCamera: media.canFlipCamera,\n isAudioOn: media.isAudioOn,\n isVideoOn: media.isVideoOn,\n isScreenSharing: media.isScreenSharing,\n isFlashlightOn: media.isFlashlightOn,\n isFlashlightSupported: media.isFlashlightSupported,\n toggleAudio: media.toggleAudio,\n toggleVideo: media.toggleVideo,\n toggleFlashlight: media.toggleFlashlight,\n toggleScreenShare: session.toggleScreenShare,\n switchCamera,\n flipCamera,\n endCall: callStore.endCall,\n // View\n showCameraModal: ref(false),\n showControls: ui.showControls,\n resetControlsTimeout: ui.resetControlsTimeout,\n isFullscreen: ui.isFullscreen,\n canFullscreen: ui.canFullscreen,\n toggleFullscreen: ui.toggleFullscreen,\n toggleRemote: ui.toggleRemote,\n videoPaused: ui.videoPaused,\n soundBlocked: ui.soundBlocked,\n enableSound: ui.enableSound,\n toggleVideoPause: ui.toggleVideoPause,\n localVideo: ui.localVideo,\n localScreen: ui.localScreen,\n remoteRefs: ui.remoteRefs,\n remoteScreenRefs: ui.remoteScreenRefs,\n remoteParents: ui.remoteParents,\n reattach: ui.reattach,\n retryPeer: session.retryPeer,\n };\n}\n","import { onBeforeUnmount, reactive, watch } from \"vue\";\n\n// RMS of the waveform (0–1) above which a voice counts as speaking, and how long it stays lit\n// after dropping below, so the ring doesn't flicker between words.\nconst THRESHOLD = 0.04;\nconst HOLD_MS = 400;\nconst POLL_MS = 120;\n\ninterface Meter {\n stream: MediaStream;\n source: MediaStreamAudioSourceNode;\n analyser: AnalyserNode;\n buffer: Uint8Array<ArrayBuffer>;\n lastLoud: number;\n}\n\n/**\n * Who is speaking, per tile id: a level meter on each stream's audio, through one shared\n * AudioContext. Ids whose stream is null, or has no audio track, are never speaking.\n */\nexport function useSpeaking(streams: () => Record<string, MediaStream | null | undefined>) {\n const speaking = reactive<Record<string, boolean>>({});\n const meters = new Map<string, Meter>();\n let context: AudioContext | null = null;\n let timer: ReturnType<typeof setInterval> | undefined;\n\n const drop = (id: string) => {\n const meter = meters.get(id);\n if (!meter) return;\n meter.source.disconnect();\n meters.delete(id);\n delete speaking[id];\n };\n\n const poll = () => {\n const now = performance.now();\n for (const [id, meter] of meters) {\n meter.analyser.getByteTimeDomainData(meter.buffer);\n let sum = 0;\n for (const sample of meter.buffer) {\n const centred = (sample - 128) / 128;\n sum += centred * centred;\n }\n if (Math.sqrt(sum / meter.buffer.length) > THRESHOLD) meter.lastLoud = now;\n const lit = now - meter.lastLoud < HOLD_MS;\n if (speaking[id] !== lit) speaking[id] = lit;\n }\n };\n\n watch(\n streams,\n (current) => {\n for (const id of [...meters.keys()]) {\n if (current[id] !== meters.get(id)!.stream) drop(id);\n }\n\n for (const [id, stream] of Object.entries(current)) {\n if (!stream || meters.has(id) || !stream.getAudioTracks().length) continue;\n if (typeof AudioContext === \"undefined\") return;\n context ??= new AudioContext();\n // Created after the call was started by a click, so it is normally running already.\n if (context.state === \"suspended\") void context.resume().catch(() => {});\n\n const source = context.createMediaStreamSource(stream);\n const analyser = context.createAnalyser();\n analyser.fftSize = 512;\n // Only measured, never routed to the speakers: the <video> elements play the sound.\n source.connect(analyser);\n meters.set(id, {\n stream,\n source,\n analyser,\n buffer: new Uint8Array(analyser.fftSize),\n lastLoud: 0,\n });\n }\n\n if (meters.size && !timer) timer = setInterval(poll, POLL_MS);\n if (!meters.size && timer) {\n clearInterval(timer);\n timer = undefined;\n }\n },\n { immediate: true, deep: 1 },\n );\n\n onBeforeUnmount(() => {\n clearInterval(timer);\n for (const id of [...meters.keys()]) drop(id);\n void context?.close().catch(() => {});\n });\n\n return speaking;\n}\n","import { computed, ref, watch, type Ref } from \"vue\";\nimport type { Participant } from \"./session\";\n\n/** One tile on the call screen: someone's camera (the user's own is `self`), or a screen share. */\nexport interface CallTileInfo {\n /** Stable per tile: `self_cam`, `self_screen`, `remote_video_<id>`, `remote_screen_<id>`. */\n id: string;\n kind: \"camera\" | \"screen\" | \"self\";\n participantId: string;\n}\n\n/**\n * How the call screen arranges its tiles (research R7):\n * - `solo`: alone, the user's own camera fills the stage;\n * - `pair`: one other person fills it, the user's camera floats in a corner (as in 5.0);\n * - `grid`: two or three others, everyone a tile of a 2×2 grid;\n * - `stage`: a screen share or a pinned tile takes the stage, the rest sit in a strip.\n */\nexport type CallLayoutMode = \"solo\" | \"pair\" | \"grid\" | \"stage\";\n\nexport interface CallLayoutOptions {\n participants: Ref<Participant[]>;\n /** The call view's own size, which decides where the strip goes. */\n width: Ref<number>;\n height: Ref<number>;\n}\n\nexport function useCallLayout({ participants, width, height }: CallLayoutOptions) {\n const cameraTile = (p: Participant): CallTileInfo =>\n p.isSelf\n ? { id: \"self_cam\", kind: \"self\", participantId: p.id }\n : { id: `remote_video_${p.id}`, kind: \"camera\", participantId: p.id };\n const screenTile = (p: Participant): CallTileInfo => ({\n id: p.isSelf ? \"self_screen\" : `remote_screen_${p.id}`,\n kind: \"screen\",\n participantId: p.id,\n });\n\n const cameraTiles = computed(() => participants.value.map(cameraTile));\n const screenTiles = computed(() =>\n participants.value.filter((p) => p.screen).map(screenTile),\n );\n /** Every tile, each participant's camera followed by their screen. */\n const tiles = computed(() =>\n participants.value.flatMap((p) => (p.screen ? [cameraTile(p), screenTile(p)] : [cameraTile(p)])),\n );\n\n // When each screen share first showed, so the newest one takes the stage.\n const screenSince = new Map<string, number>();\n let screenOrder = 0;\n const newestScreen = ref<string | null>(null);\n watch(\n screenTiles,\n (current) => {\n const ids = new Set(current.map((t) => t.id));\n for (const id of [...screenSince.keys()]) if (!ids.has(id)) screenSince.delete(id);\n for (const id of ids) if (!screenSince.has(id)) screenSince.set(id, ++screenOrder);\n // The user's own share comes last: they know what they are showing.\n const ranked = [...ids].sort(\n (a, b) =>\n Number(a === \"self_screen\") - Number(b === \"self_screen\") ||\n screenSince.get(b)! - screenSince.get(a)!,\n );\n newestScreen.value = ranked[0] ?? null;\n },\n { immediate: true },\n );\n\n const pinnedId = ref<string | null>(null);\n function togglePin(tileId: string) {\n pinnedId.value = pinnedId.value === tileId ? null : tileId;\n }\n // A pinned participant who leaves, or a pinned share that stops, lets go of the stage.\n watch(tiles, (current) => {\n if (pinnedId.value && !current.some((t) => t.id === pinnedId.value)) pinnedId.value = null;\n });\n\n const remoteCount = computed(() => participants.value.length - 1);\n\n const mode = computed<CallLayoutMode>(() => {\n if (pinnedId.value || newestScreen.value) return \"stage\";\n if (remoteCount.value <= 0) return \"solo\";\n if (remoteCount.value === 1) return \"pair\";\n return \"grid\";\n });\n\n const stageTile = computed<CallTileInfo | null>(() => {\n if (mode.value !== \"stage\") return null;\n const id = pinnedId.value ?? newestScreen.value;\n return tiles.value.find((t) => t.id === id) ?? null;\n });\n const stripTiles = computed(() =>\n mode.value === \"stage\" ? tiles.value.filter((t) => t.id !== stageTile.value?.id) : [],\n );\n const gridTiles = computed(() => (mode.value === \"grid\" ? cameraTiles.value : []));\n\n const orientation = computed<\"portrait\" | \"landscape\">(() =>\n height.value > width.value ? \"portrait\" : \"landscape\",\n );\n\n /**\n * The grid is always 2×2, so a phone's tiles stay large enough to recognise a face (SC-006).\n * With three tiles the last row holds one, centred, at the width of one cell.\n */\n const gridClass = \"grid size-full grid-cols-2 grid-rows-2 gap-(--call-gap)\";\n const cellClass = (index: number) =>\n gridTiles.value.length === 3 && index === 2\n ? \"col-span-2 w-[calc(50%-var(--call-gap)/2)] justify-self-center\"\n : \"\";\n\n /** Changes whenever tiles move between the stage, grid and strip (their <video> remounts). */\n const key = computed(\n () => `${mode.value}|${stageTile.value?.id ?? \"\"}|${tiles.value.map((t) => t.id).join()}`,\n );\n\n return {\n mode,\n tiles,\n gridTiles,\n stageTile,\n stripTiles,\n pinnedId,\n togglePin,\n orientation,\n gridClass,\n cellClass,\n key,\n };\n}\n\nexport type CallLayout = ReturnType<typeof useCallLayout>;\n","import { onBeforeUnmount, ref, watch, type Ref } from \"vue\";\nimport type { Participant } from \"./session\";\n\n/** How long a notice shows, and the window in which joins and leaves merge into it. */\nconst NOTICE_MS = 3_000;\n\nexport interface CallNotice {\n text: string;\n /** Changes with every new notice, so a view can restart its transition. */\n id: number;\n}\n\n/**\n * \"Sara joined\", \"Nima left\": a short notice when someone joins or leaves, with changes that come\n * close together merged into one (\"Sara and Nima joined\"). The people already there when the view\n * mounts are not announced. `liveText` carries the same words for an `aria-live` region.\n */\nexport function useCallNotices(\n participants: Ref<Participant[]>,\n t: (key: string, params: Record<string, unknown>, plural: number) => string,\n and: () => string,\n locale: () => string,\n) {\n const current = ref<CallNotice | null>(null);\n const liveText = ref(\"\");\n\n let joined: string[] = [];\n let left: string[] = [];\n let timer: ReturnType<typeof setTimeout> | undefined;\n let counter = 0;\n\n const list = (names: string[]) => {\n if (names.length <= 1) return names[0] ?? \"\";\n const comma = locale().startsWith(\"fa\") || locale().startsWith(\"ar\") ? \"، \" : \", \";\n return `${names.slice(0, -1).join(comma)} ${and()} ${names[names.length - 1]}`;\n };\n\n function show() {\n const parts = [\n joined.length ? t(\"chat.call.joined\", { names: list(joined) }, joined.length) : \"\",\n left.length ? t(\"chat.call.left\", { names: list(left) }, left.length) : \"\",\n ].filter(Boolean);\n if (!parts.length) return;\n const text = parts.join(\" · \");\n current.value = { text, id: ++counter };\n liveText.value = text;\n clearTimeout(timer);\n timer = setTimeout(() => {\n current.value = null;\n joined = [];\n left = [];\n }, NOTICE_MS);\n }\n\n watch(\n () => participants.value.filter((p) => !p.isSelf).map((p) => [p.id, p.name] as const),\n (now, before) => {\n if (!before) return; // whoever was already there when the view mounted\n const was = new Map(before);\n const is = new Map(now);\n let changed = false;\n for (const [id, name] of is) {\n if (was.has(id)) continue;\n // Back within the window (a dropped connection rebuilt): no news.\n const i = left.indexOf(name);\n if (i >= 0) left.splice(i, 1);\n else joined.push(name);\n changed = true;\n }\n for (const [id, name] of was) {\n if (is.has(id)) continue;\n // Joined and gone again within the window: only the leaving is news now.\n const i = joined.indexOf(name);\n if (i >= 0) joined.splice(i, 1);\n left.push(name);\n changed = true;\n }\n if (changed) {\n if (joined.length || left.length) show();\n else current.value = null;\n }\n },\n { immediate: true },\n );\n\n onBeforeUnmount(() => clearTimeout(timer));\n\n return { current, liveText };\n}\n","<script setup lang=\"ts\">\n/**\n * The call screen's icons: Google's Material Symbols (Rounded, weight 400), the set Google Meet\n * uses, so the controls read the way people already know them. Only the icons the call needs are\n * inlined, as SVG paths, so the library takes no icon dependency for them.\n *\n * Material Symbols: Copyright Google LLC, Apache License 2.0\n * (https://github.com/google/material-design-icons/blob/master/LICENSE).\n */\nconst ICONS = {\n mic:\n \"<path fill=\\\"currentColor\\\" d=\\\"M9.875 13.125Q9 12.25 9 11V5q0-1.25.875-2.125T12 2t2.125.875T15 5v6q0 1.25-.875 2.125T12 14t-2.125-.875M11 20v-2.075q-2.3-.325-3.937-1.95t-1.988-3.95q-.05-.425.225-.725T6 11t.713.288T7.1 12q.35 1.75 1.738 2.875T12 16q1.8 0 3.175-1.137T16.9 12q.1-.425.388-.712T18 11t.7.3t.225.725q-.35 2.275-1.975 3.925T13 17.925V20q0 .425-.288.713T12 21t-.712-.288T11 20\\\"/>\",\n micOff:\n \"<path fill=\\\"currentColor\\\" d=\\\"M16.8 14.575q-.35-.2-.45-.612t.1-.763q.175-.275.288-.587t.162-.638q.1-.425.388-.7T18 11t.7.3t.225.725q-.075.575-.262 1.125t-.488 1.05q-.2.35-.612.463t-.763-.088m-3.5-4.125L9.575 6.725Q9.3 6.45 9.15 6.088T9 5.325V5q0-1.25.875-2.125T12 2t2.125.875T15 5v4.725q0 .675-.612.938T13.3 10.45M11 20v-2.1q-2.3-.3-3.937-1.925t-1.988-3.95q-.05-.425.225-.725T6 11t.713.288T7.1 12q.35 1.75 1.738 2.875T12 16q.85 0 1.613-.262T15 15l1.425 1.425q-.725.575-1.588.963T13 17.9V20q0 .425-.288.713T12 21t-.712-.288T11 20m8.1 1.9l-17-17q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l17 17q.275.275.275.7t-.275.7t-.7.275t-.7-.275\\\"/>\",\n videocam:\n \"<path fill=\\\"currentColor\\\" d=\\\"M4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h12q.825 0 1.413.588T18 6v4.5l3.15-3.15q.25-.25.55-.125t.3.475v8.6q0 .35-.3.475t-.55-.125L18 13.5V18q0 .825-.587 1.413T16 20z\\\"/>\",\n videocamOff:\n \"<path fill=\\\"currentColor\\\" d=\\\"m18 10.5l3.15-3.15q.25-.25.55-.125t.3.475v8.6q0 .35-.3.475t-.55-.125l-3.325-3.325q-.25.35-.712.425t-.813-.275L8.525 5.7q-.25-.25-.288-.525t.088-.55t.35-.45T9.25 4H16q.825 0 1.413.588T18 6zm1.85 12.15L1.35 4.15q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l18.5 18.5q.275.275.275.7t-.275.7t-.7.275t-.7-.275M4 4l14 14q0 .825-.587 1.413T16 20H4q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4\\\"/>\",\n presentToAll:\n \"<path fill=\\\"currentColor\\\" d=\\\"M11 11.825V15q0 .425.288.713T12 16t.713-.288T13 15v-3.15l.9.875q.3.275.7.288t.7-.288t.3-.712t-.3-.713l-2.6-2.6q-.3-.3-.7-.3t-.7.3l-2.6 2.6q-.3.3-.287.7t.312.7q.3.275.7.288t.7-.288zM4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h16q.825 0 1.413.588T22 6v12q0 .825-.587 1.413T20 20z\\\"/>\",\n cancelPresentation:\n \"<path fill=\\\"currentColor\\\" d=\\\"m10.6 12l-1.9 1.9q-.275.275-.275.7t.275.7t.7.275t.7-.275l1.9-1.9l1.9 1.9q.275.275.7.275t.7-.275t.275-.7t-.275-.7L13.4 12l1.9-1.9q.275-.275.275-.7t-.275-.7t-.7-.275t-.7.275L12 10.6l-1.9-1.9q-.275-.275-.7-.275t-.7.275t-.275.7t.275.7zM4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h16q.825 0 1.413.588T22 6v12q0 .825-.587 1.413T20 20z\\\"/>\",\n callEnd:\n \"<path fill=\\\"currentColor\\\" d=\\\"M12 8q2.95 0 5.813 1.188T22.9 12.75q.3.3.3.7t-.3.7l-2.3 2.25q-.275.275-.638.3t-.662-.2l-2.9-2.2q-.2-.15-.3-.35t-.1-.45v-2.85q-.95-.3-1.95-.475T12 10t-2.05.175T8 10.65v2.85q0 .25-.1.45t-.3.35l-2.9 2.2q-.3.225-.663.2t-.637-.3l-2.3-2.25q-.3-.3-.3-.7t.3-.7q2.2-2.375 5.075-3.562T12 8\\\"/>\",\n fullscreen:\n \"<path fill=\\\"currentColor\\\" d=\\\"M5 19h2q.425 0 .713.288T8 20t-.288.713T7 21H4q-.425 0-.712-.288T3 20v-3q0-.425.288-.712T4 16t.713.288T5 17zm14 0v-2q0-.425.288-.712T20 16t.713.288T21 17v3q0 .425-.288.713T20 21h-3q-.425 0-.712-.288T16 20t.288-.712T17 19zM5 5v2q0 .425-.288.713T4 8t-.712-.288T3 7V4q0-.425.288-.712T4 3h3q.425 0 .713.288T8 4t-.288.713T7 5zm14 0h-2q-.425 0-.712-.288T16 4t.288-.712T17 3h3q.425 0 .713.288T21 4v3q0 .425-.288.713T20 8t-.712-.288T19 7z\\\"/>\",\n fullscreenExit:\n \"<path fill=\\\"currentColor\\\" d=\\\"M6 18H4q-.425 0-.712-.288T3 17t.288-.712T4 16h3q.425 0 .713.288T8 17v3q0 .425-.288.713T7 21t-.712-.288T6 20zm12 0v2q0 .425-.288.713T17 21t-.712-.288T16 20v-3q0-.425.288-.712T17 16h3q.425 0 .713.288T21 17t-.288.713T20 18zM6 6V4q0-.425.288-.712T7 3t.713.288T8 4v3q0 .425-.288.713T7 8H4q-.425 0-.712-.288T3 7t.288-.712T4 6zm12 0h2q.425 0 .713.288T21 7t-.288.713T20 8h-3q-.425 0-.712-.288T16 7V4q0-.425.288-.712T17 3t.713.288T18 4z\\\"/>\",\n flashlightOn:\n \"<path fill=\\\"currentColor\\\" d=\\\"M6 5V4q0-.825.588-1.412T8 2h8q.825 0 1.413.588T18 4v1zm7.063 10.063q.437-.438.437-1.063t-.437-1.062T12 12.5t-1.062.438T10.5 14t.438 1.063T12 15.5t1.063-.437M8 20v-9L6.325 8.5q-.175-.25-.25-.525T6 7.4V7h12v.4q0 .3-.075.575t-.25.525L16 11v9q0 .825-.587 1.413T14 22h-4q-.825 0-1.412-.587T8 20\\\"/>\",\n flashlightOff:\n \"<path fill=\\\"currentColor\\\" d=\\\"M8 20v-9.2L2.1 4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l17 17q.275.275.275.7t-.275.7t-.7.275t-.7-.275L16 18.8V20q0 .825-.587 1.413T14 22h-4q-.825 0-1.412-.587T8 20M7.85 5l-1.7-1.7q.2-.575.7-.937T8 2h8q.825 0 1.413.588T18 4v1zM16 13.15L9.85 7H18v.4q0 .3-.075.575t-.25.525L16 11z\\\"/>\",\n pause:\n \"<path fill=\\\"currentColor\\\" d=\\\"M16 19q-.825 0-1.412-.587T14 17V7q0-.825.588-1.412T16 5t1.413.588T18 7v10q0 .825-.587 1.413T16 19m-8 0q-.825 0-1.412-.587T6 17V7q0-.825.588-1.412T8 5t1.413.588T10 7v10q0 .825-.587 1.413T8 19\\\"/>\",\n play:\n \"<path fill=\\\"currentColor\\\" d=\\\"M8 17.175V6.825q0-.425.3-.713t.7-.287q.125 0 .263.037t.262.113l8.15 5.175q.225.15.338.375t.112.475t-.112.475t-.338.375l-8.15 5.175q-.125.075-.262.113T9 18.175q-.4 0-.7-.288t-.3-.712\\\"/>\",\n group:\n \"<path fill=\\\"currentColor\\\" d=\\\"M1 17.2q0-.85.438-1.562T2.6 14.55q1.55-.775 3.15-1.162T9 13t3.25.388t3.15 1.162q.725.375 1.163 1.088T17 17.2v.8q0 .825-.587 1.413T15 20H3q-.825 0-1.412-.587T1 18zM18.45 20q.275-.45.413-.962T19 18v-1q0-1.1-.612-2.113T16.65 13.15q1.275.15 2.4.513t2.1.887q.9.5 1.375 1.112T23 17v1q0 .825-.587 1.413T21 20zM6.175 10.825Q5 9.65 5 8t1.175-2.825T9 4t2.825 1.175T13 8t-1.175 2.825T9 12t-2.825-1.175m11.65 0Q16.65 12 15 12q-.275 0-.7-.062t-.7-.138q.675-.8 1.038-1.775T15 8t-.362-2.025T13.6 4.2q.35-.125.7-.163T15 4q1.65 0 2.825 1.175T19 8t-1.175 2.825\\\"/>\",\n pictureInPicture:\n \"<path fill=\\\"currentColor\\\" d=\\\"M4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h16q.825 0 1.413.588T22 6v12q0 .825-.587 1.413T20 20zm8-3h6q.425 0 .713-.288T19 16v-4q0-.425-.288-.712T18 11h-6q-.425 0-.712.288T11 12v4q0 .425.288.713T12 17m3-3\\\"/>\",\n openInFull:\n \"<path fill=\\\"currentColor\\\" d=\\\"M4 21q-.425 0-.712-.288T3 20v-6q0-.425.288-.712T4 13t.713.288T5 14v3.6L17.6 5H14q-.425 0-.712-.288T13 4t.288-.712T14 3h6q.425 0 .713.288T21 4v6q0 .425-.288.713T20 11t-.712-.288T19 10V6.4L6.4 19H10q.425 0 .713.288T11 20t-.288.713T10 21z\\\"/>\",\n volumeUp:\n \"<path fill=\\\"currentColor\\\" d=\\\"M19 11.975q0-2.075-1.1-3.787t-2.95-2.563q-.375-.175-.55-.537t-.05-.738q.15-.4.538-.575t.787 0Q18.1 4.85 19.55 7.063T21 11.974t-1.45 4.913t-3.875 3.287q-.4.175-.788 0t-.537-.575q-.125-.375.05-.737t.55-.538q1.85-.85 2.95-2.562t1.1-3.788M7 15H4q-.425 0-.712-.288T3 14v-4q0-.425.288-.712T4 9h3l3.3-3.3q.475-.475 1.088-.213t.612.938v11.15q0 .675-.612.938T10.3 18.3zm9.5-3q0 1.05-.475 1.988t-1.25 1.537q-.25.15-.513.013T14 15.1V8.85q0-.3.263-.437t.512.012q.775.625 1.25 1.575t.475 2\\\"/>\",\n cameraSwitch:\n \"<path fill=\\\"currentColor\\\" d=\\\"M8 17q-.825 0-1.412-.587T6 15V9q0-.825.588-1.412T8 7h1l.7-.7q.15-.15.338-.225T10.425 6h3.15q.2 0 .388.075t.337.225l.7.7h1q.825 0 1.412.588T18 9v6q0 .825-.587 1.413T16 17zm4-3q.825 0 1.413-.587T14 12t-.587-1.412T12 10t-1.412.588T10 12t.588 1.413T12 14m0 10q-4.4 0-7.712-2.762T.174 14.275Q.1 13.85.337 13.5T1 13.1t.75.213t.4.687q.65 3.275 3.113 5.475T11.1 21.95l-.85-.85q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l3.3 3.3q.175.175.113.4t-.288.275q-.675.175-1.362.25T12 24m0-24q4.4 0 7.713 2.75t4.112 6.975q.075.425-.162.775t-.663.4t-.75-.213t-.4-.687q-.65-3.275-3.113-5.475T12.9 2.05l.85.85q.275.275.275.7t-.275.7t-.7.275t-.7-.275L9.05 1Q8.875.825 8.938.6t.287-.275Q9.9.15 10.588.075T12 0\\\"/>\",\n arrowDropUp:\n \"<path fill=\\\"currentColor\\\" d=\\\"M8.2 14q-.225 0-.362-.15T7.7 13.5q0-.05.15-.35l3.625-3.625q.125-.125.25-.175T12 9.3t.275.05t.25.175l3.625 3.625q.075.075.113.163t.037.187q0 .2-.137.35T15.8 14z\\\"/>\",\n moreVert:\n \"<path fill=\\\"currentColor\\\" d=\\\"M12 20q-.825 0-1.412-.587T10 18t.588-1.412T12 16t1.413.588T14 18t-.587 1.413T12 20m0-6q-.825 0-1.412-.587T10 12t.588-1.412T12 10t1.413.588T14 12t-.587 1.413T12 14m0-6q-.825 0-1.412-.587T10 6t.588-1.412T12 4t1.413.588T14 6t-.587 1.413T12 8\\\"/>\",\n check:\n \"<path fill=\\\"currentColor\\\" d=\\\"m9.55 15.15l8.475-8.475q.3-.3.7-.3t.7.3t.3.713t-.3.712l-9.175 9.2q-.3.3-.7.3t-.7-.3L4.55 13q-.3-.3-.288-.712t.313-.713t.713-.3t.712.3z\\\"/>\",\n keep:\n \"<path fill=\\\"currentColor\\\" d=\\\"M16 5v7l1.7 1.7q.15.15.225.338t.075.387V15q0 .425-.288.712T17 16h-4v5.85q0 .425-.288.713T12 22.85t-.712-.288T11 21.85V16H7q-.425 0-.712-.288T6 15v-.575q0-.2.075-.387T6.3 13.7L8 12V5q-.425 0-.712-.288T7 4t.288-.712T8 3h8q.425 0 .713.288T17 4t-.288.713T16 5\\\"/>\",\n keepOff:\n \"<path fill=\\\"currentColor\\\" d=\\\"m14.3 11.475l-7.05-7.05q-.125-.125-.187-.275T7 3.85q0-.325.225-.588t.6-.262H16q.425 0 .713.287T17 4q0 .4-.363.563T16 5v5.75q0 .675-.612.938t-1.088-.213M11 22v-6H7.4q-.625 0-1-.437t-.375-.988q0-.275.113-.55T6.5 13.5L8 12v-1.15L2.1 4.9q-.275-.275-.288-.687T2.1 3.5q.275-.275.7-.275t.7.275l16.975 16.975q.3.3.288.713t-.313.712q-.3.275-.7.288t-.7-.288l-5.9-5.9H13v6q0 .425-.288.713T12 23t-.712-.288T11 22\\\"/>\",\n close:\n \"<path fill=\\\"currentColor\\\" d=\\\"m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z\\\"/>\",\n refresh:\n \"<path fill=\\\"currentColor\\\" d=\\\"M12 20q-3.35 0-5.675-2.325T4 12t2.325-5.675T12 4q1.725 0 3.3.712T18 6.75V5q0-.425.288-.712T19 4t.713.288T20 5v5q0 .425-.288.713T19 11h-5q-.425 0-.712-.288T13 10t.288-.712T14 9h3.2q-.8-1.4-2.187-2.2T12 6Q9.5 6 7.75 7.75T6 12t1.75 4.25T12 18q1.7 0 3.113-.862t2.187-2.313q.2-.35.563-.487t.737-.013q.4.125.575.525t-.025.75q-1.025 2-2.925 3.2T12 20\\\"/>\",\n} as const;\n\nexport type CallIconName = keyof typeof ICONS;\n\ndefineProps<{ name: CallIconName }>();\n</script>\n\n<template>\n <!-- eslint-disable-next-line vue/no-v-html -- static paths from ICONS above, never user input -->\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\" v-html=\"ICONS[name]\" />\n</template>\n","<script setup lang=\"ts\">\n/**\n * IconButton for the call screen: an icon-only, round PrimeVue Button showing a Material Symbol\n * (CallIcon). Any Button prop (severity, size, dt...) and listener passes through.\n */\nimport Button from \"primevue/button\";\nimport CallIcon, { type CallIconName } from \"./CallIcon.vue\";\n\ndefineOptions({ inheritAttrs: false });\n\nwithDefaults(\n defineProps<{\n icon: CallIconName;\n /** Accessible name; the button has no visible text. */\n label: string;\n iconClass?: string;\n }>(),\n { iconClass: \"size-5\" },\n);\n</script>\n\n<template>\n <Button rounded text severity=\"secondary\" v-bind=\"$attrs\" :aria-label=\"label\">\n <template #icon>\n <CallIcon :name=\"icon\" :class=\"iconClass\" />\n </template>\n </Button>\n</template>\n","// The call screen is dark whatever the host's colour scheme, so its controls use fixed tokens\n// instead of the theme's: translucent white at rest, white when a feature is on (Meet's \"lit\"),\n// red when the microphone or camera is off. Shared by Call.vue and the tiles and drawer in it.\n\nconst translucent = {\n background: \"rgb(255 255 255 / 0.12)\",\n hoverBackground: \"rgb(255 255 255 / 0.2)\",\n activeBackground: \"rgb(255 255 255 / 0.28)\",\n borderColor: \"transparent\",\n hoverBorderColor: \"transparent\",\n activeBorderColor: \"transparent\",\n color: \"#ffffff\",\n hoverColor: \"#ffffff\",\n activeColor: \"#ffffff\",\n};\nconst lit = {\n background: \"#ffffff\",\n hoverBackground: \"rgb(255 255 255 / 0.9)\",\n activeBackground: \"rgb(255 255 255 / 0.8)\",\n borderColor: \"#ffffff\",\n hoverBorderColor: \"#ffffff\",\n activeBorderColor: \"#ffffff\",\n color: \"#171717\",\n hoverColor: \"#171717\",\n activeColor: \"#171717\",\n};\n// Tailwind's red-500 to red-700.\nconst off = {\n background: \"#ef4444\",\n hoverBackground: \"#dc2626\",\n activeBackground: \"#b91c1c\",\n borderColor: \"transparent\",\n hoverBorderColor: \"transparent\",\n activeBorderColor: \"transparent\",\n color: \"#ffffff\",\n hoverColor: \"#ffffff\",\n activeColor: \"#ffffff\",\n};\nconst callScheme = { root: { secondary: translucent, contrast: lit, danger: off } };\nexport const callButtonDt = { colorScheme: { light: callScheme, dark: callScheme } };\n\n// Its menus are dark too, Tailwind's neutral-800 under white text, in either host scheme.\nexport const callMenuDt = {\n root: { background: \"#262626\", borderColor: \"rgb(255 255 255 / 0.1)\", color: \"#f5f5f5\" },\n item: {\n focusBackground: \"rgb(255 255 255 / 0.1)\",\n color: \"#f5f5f5\",\n focusColor: \"#ffffff\",\n icon: { color: \"#a3a3a3\", focusColor: \"#ffffff\" },\n },\n submenuLabel: { background: \"transparent\", color: \"#a3a3a3\" },\n};\n\n// The participant drawer, in the same dark palette as the menus.\nexport const callDrawerDt = {\n root: { background: \"#262626\", borderColor: \"rgb(255 255 255 / 0.1)\", color: \"#f5f5f5\" },\n header: { padding: \"1rem 1rem 0.5rem\" },\n content: { padding: \"0 0.5rem 1rem\" },\n};\n\n// Tile actions sit on the video: small round buttons, shown on hover or focus where there is a\n// pointer that hovers, always on touch screens, where they grow to a 44px target.\nexport const tileButton = {\n dt: callButtonDt,\n text: false,\n size: \"small\",\n iconClass: \"size-4.5\",\n class: \"size-9! [@media(hover:none)]:size-11!\",\n} as const;\nexport const tileActions =\n \"absolute end-2 bottom-2 z-20 flex items-center gap-x-1.5 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 motion-reduce:transition-none [@media(hover:none)]:opacity-100\";\nexport const nameChip =\n \"min-w-0 truncate rounded-md bg-black/60 px-2 py-0.5 text-label-sm text-white backdrop-blur-sm select-none\";\n/** A focus ring that shows on the dark stage. */\nexport const focusRing =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-900\";\n\n// Tooltips are appended to <body>, outside the chat, so they take its font and reset with them.\nexport const tip = (value: string) => ({ value, class: \"vue-chat font-chat-family\" });\n","<script setup lang=\"ts\">\n/**\n * One tile of the call screen: someone's camera, the user's own, or a screen share. It shows the\n * video with the person's name, a mic-off badge, their initial when the camera is off (FR-009),\n * the speaking ring, and a \"can't connect\" state with Retry (FR-022). The <video> stays mounted\n * whatever shows over it: it also plays the person's sound.\n */\nimport { computed, onBeforeUnmount, onMounted, ref } from \"vue\";\nimport Avatar from \"primevue/avatar\";\nimport BIcon from \"~/components/global/BIcon.vue\";\nimport Button from \"primevue/button\";\nimport Tooltip from \"primevue/tooltip\";\nimport useLocalI18n from \"~/composables/useLocalI18n\";\nimport { chat } from \"@i18n/locales\";\nimport type { Participant } from \"~/composables/call/session\";\nimport type { CallTileInfo } from \"~/composables/call/useCallLayout\";\nimport CallButton from \"./CallButton.vue\";\nimport CallIcon from \"./CallIcon.vue\";\nimport { callButtonDt, focusRing, nameChip, tileActions, tileButton, tip } from \"./tokens\";\nimport { avatarToneStyle, nameInitials } from \"~/utils/avatar\";\n\nconst vTooltip = Tooltip;\n\nconst props = withDefaults(\n defineProps<{\n tile: CallTileInfo;\n participant: Participant;\n stream?: MediaStream | null;\n speaking?: boolean;\n pinned?: boolean;\n /** Pinning only makes sense once there is someone else to show. */\n canPin?: boolean;\n /** A strip tile: smaller avatar, fewer actions. */\n compact?: boolean;\n paused?: boolean;\n isFullscreen?: boolean;\n /** Flips the video left to right, for the user's own front camera. */\n mirrored?: boolean;\n /** A line under the avatar when the camera is off, such as \"Camera is off\". */\n hint?: string;\n }>(),\n { stream: null, speaking: false, pinned: false, canPin: false, compact: false, paused: false, isFullscreen: false, mirrored: false },\n);\n\nconst emit = defineEmits<{\n pin: [];\n pause: [video: HTMLVideoElement | null];\n fullscreen: [root: HTMLElement | null];\n retry: [];\n /** The tile's <video> mounted (`el`) or went away (`null`, with the one that did). */\n video: [el: HTMLVideoElement | null, previous: HTMLVideoElement | null];\n}>();\n\nconst { t } = useLocalI18n(chat);\n\nconst root = ref<HTMLElement | null>(null);\nconst videoEl = ref<HTMLVideoElement | null>(null);\nonMounted(() => emit(\"video\", videoEl.value, null));\nonBeforeUnmount(() => emit(\"video\", null, videoEl.value));\ndefineExpose({ videoEl, root });\n\nconst isSelf = computed(() => props.participant.isSelf);\nconst isScreen = computed(() => props.tile.kind === \"screen\");\nconst status = computed(() => props.participant.status);\n\nconst name = computed(() => props.participant.name || (isSelf.value ? t(\"chat.call.you\") : \"\"));\nconst label = computed(() => {\n if (isScreen.value)\n return isSelf.value ? t(\"chat.call.yourPresentation\") : t(\"chat.call.presentationOf\", { name: name.value });\n return isSelf.value ? t(\"chat.call.you\") : name.value;\n});\n// The call screen is always dark, so its avatars take the dark tones.\nconst initials = computed(() => nameInitials(props.participant.name));\nconst toneStyle = computed(() => avatarToneStyle(props.participant.name, null, \"dark\"));\n\nconst hasVideo = computed(() => !!props.stream?.getVideoTracks().length);\n/** Camera off, or none sent at all: the person's initial instead of a black frame. */\nconst showAvatar = computed(\n () => !isScreen.value && (props.participant.media?.video === false || !hasVideo.value),\n);\nconst muted = computed(() => !isScreen.value && props.participant.media?.audio === false);\nconst unreachable = computed(() => !isSelf.value && status.value === \"unreachable\");\nconst statusText = computed(() => {\n if (isSelf.value) return props.hint;\n if (status.value === \"connecting\") return t(\"chat.call.connecting\");\n if (status.value === \"recovering\") return t(\"chat.call.reconnecting\");\n return props.hint;\n});\n\n// The ids hosts' tests already use: remote camera tiles with a stream, and remote screens.\nconst innerTestId = computed(() => {\n if (isSelf.value) return undefined;\n if (isScreen.value) return \"call-remote-screen\";\n return props.stream ? \"call-remote-video\" : undefined;\n});\n\nconst pinLabel = computed(() =>\n props.pinned ? t(\"chat.call.controls.unpin\") : t(\"chat.call.controls.pin\"),\n);\nconst pauseLabel = computed(() =>\n props.paused ? t(\"chat.call.controls.playVideo\") : t(\"chat.call.controls.pauseVideo\"),\n);\nconst fullscreenLabel = computed(() =>\n props.isFullscreen ? t(\"chat.call.controls.exitFullscreen\") : t(\"chat.call.controls.fullscreen\"),\n);\n</script>\n\n<template>\n <div\n ref=\"root\"\n data-testid=\"call-tile\"\n :data-participant-id=\"participant.id\"\n :data-kind=\"tile.kind\"\n class=\"group relative min-h-0 min-w-0 overflow-hidden rounded-2xl bg-neutral-800 ring-3 ring-inset transition-shadow [clip-path:inset(0_round_var(--radius-2xl))] motion-reduce:transition-none\"\n :class=\"speaking && !isScreen ? 'ring-sky-400' : 'ring-transparent'\"\n >\n <div class=\"absolute inset-0\" :data-testid=\"innerTestId\">\n <video\n ref=\"videoEl\"\n :data-testid=\"tile.kind === 'self' ? 'call-local-video' : undefined\"\n autoplay\n playsinline\n :muted=\"isSelf || isScreen\"\n class=\"absolute inset-0 size-full rounded-[inherit]\"\n :class=\"[\n isScreen ? 'object-contain' : 'object-cover',\n tile.kind === 'self' && 'pointer-events-none',\n mirrored && '-scale-x-100',\n ]\"\n />\n\n <!-- Camera off or not (yet) sent: the person's initial. -->\n <div\n v-if=\"showAvatar\"\n data-testid=\"call-tile-avatar\"\n class=\"absolute inset-0 flex flex-col items-center justify-center gap-y-2 bg-neutral-800 px-2 text-center\"\n >\n <Avatar\n :label=\"initials || undefined\"\n shape=\"circle\"\n :size=\"compact ? 'large' : 'xlarge'\"\n class=\"font-semibold select-none\"\n :style=\"toneStyle\"\n >\n <template v-if=\"!initials\" #icon><BIcon icon=\"PhUser\" class=\"size-1/2\" /></template>\n </Avatar>\n <p v-if=\"statusText && !compact\" class=\"text-label-md text-neutral-300 select-none\">\n {{ statusText }}\n </p>\n </div>\n\n <!-- Rebuilding this pair kept failing: say so, and let the user try again. -->\n <div\n v-if=\"unreachable\"\n data-testid=\"call-tile-unreachable\"\n role=\"status\"\n class=\"absolute inset-0 z-30 flex flex-col items-center justify-center gap-y-3 bg-neutral-900/85 px-3 text-center\"\n >\n <p class=\"text-label-md text-neutral-100\" :class=\"compact && 'sr-only'\">\n {{ t(\"chat.call.cantConnect\", { name }) }}\n </p>\n <Button\n :label=\"compact ? undefined : t('chat.call.controls.retry')\"\n :aria-label=\"t('chat.call.controls.retry')\"\n :dt=\"callButtonDt\"\n severity=\"contrast\"\n rounded\n size=\"small\"\n data-testid=\"call-tile-retry\"\n :class=\"['min-h-11 min-w-11', focusRing]\"\n @click=\"emit('retry')\"\n >\n <template #icon>\n <CallIcon name=\"refresh\" class=\"size-5\" />\n </template>\n </Button>\n </div>\n\n <!-- Clear of the actions at the end: the pin alone on a strip tile, three otherwise. -->\n <div\n class=\"absolute start-2 bottom-2 z-20 flex items-center gap-x-1.5\"\n :class=\"compact ? 'max-w-[calc(100%-3.5rem)]' : 'max-w-[60%]'\"\n >\n <span\n v-if=\"isScreen\"\n class=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-black/60 backdrop-blur-sm\"\n >\n <CallIcon name=\"presentToAll\" class=\"size-4\" />\n </span>\n <span\n v-if=\"muted\"\n data-testid=\"call-tile-muted\"\n role=\"img\"\n :aria-label=\"t('chat.call.muted')\"\n class=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-red-500 text-white\"\n >\n <CallIcon name=\"micOff\" class=\"size-4\" />\n </span>\n <span :class=\"nameChip\"><bdi>{{ label }}</bdi></span>\n </div>\n\n <div v-if=\"!unreachable\" :class=\"tileActions\">\n <CallButton\n v-if=\"canPin\"\n v-tooltip.top=\"tip(pinLabel)\"\n :icon=\"pinned ? 'keepOff' : 'keep'\"\n :label=\"pinLabel\"\n :aria-pressed=\"pinned\"\n v-bind=\"tileButton\"\n :class=\"focusRing\"\n data-testid=\"call-pin\"\n @click=\"emit('pin')\"\n />\n <template v-if=\"!compact && !showAvatar\">\n <CallButton\n v-tooltip.top=\"tip(pauseLabel)\"\n :icon=\"paused ? 'play' : 'pause'\"\n :label=\"pauseLabel\"\n v-bind=\"tileButton\"\n :class=\"focusRing\"\n @click=\"emit('pause', videoEl)\"\n />\n <CallButton\n v-tooltip.top=\"tip(fullscreenLabel)\"\n :icon=\"isFullscreen ? 'fullscreenExit' : 'fullscreen'\"\n :label=\"fullscreenLabel\"\n v-bind=\"tileButton\"\n :class=\"focusRing\"\n @click=\"emit('fullscreen', root)\"\n />\n </template>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Everyone in the call, in a drawer from the inline end (the right, or the left in RTL): their\n * initial, name, microphone and camera, and whether they can't be reached (FR-013).\n */\nimport { computed } from \"vue\";\nimport Avatar from \"primevue/avatar\";\nimport BIcon from \"~/components/global/BIcon.vue\";\nimport Drawer from \"primevue/drawer\";\nimport useLocalI18n, { useDirection } from \"~/composables/useLocalI18n\";\nimport { chat } from \"@i18n/locales\";\nimport type { Participant } from \"~/composables/call/session\";\nimport CallButton from \"./CallButton.vue\";\nimport CallIcon from \"./CallIcon.vue\";\nimport { callButtonDt, callDrawerDt, focusRing } from \"./tokens\";\nimport { avatarToneStyle, nameInitials } from \"~/utils/avatar\";\n\ndefineProps<{ participants: Participant[] }>();\nconst visible = defineModel<boolean>(\"visible\", { default: false });\n\nconst { t } = useLocalI18n(chat);\nconst { dir } = useDirection();\nconst position = computed(() => (dir.value === \"rtl\" ? \"left\" : \"right\"));\n\nconst nameOf = (p: Participant) => p.name || (p.isSelf ? t(\"chat.call.you\") : \"\");\n// No name (yourself, before your profile loads): no initials, the person icon.\nconst initialsOf = (p: Participant) => nameInitials(p.name);\nconst statusOf = (p: Participant) =>\n p.isSelf\n ? \"\"\n : p.status === \"unreachable\"\n ? t(\"chat.call.cantConnect\", { name: nameOf(p) })\n : p.status === \"recovering\"\n ? t(\"chat.call.reconnecting\")\n : p.status === \"connecting\"\n ? t(\"chat.call.connecting\")\n : \"\";\n</script>\n\n<template>\n <Drawer\n v-model:visible=\"visible\"\n :position=\"position\"\n :dt=\"callDrawerDt\"\n :show-close-icon=\"false\"\n :dir=\"dir\"\n class=\"vue-chat font-chat-family w-full! sm:w-80!\"\n data-testid=\"call-people-list\"\n >\n <template #header>\n <div class=\"flex w-full items-center justify-between gap-x-2\">\n <h2 class=\"text-title-md text-white\">\n {{ t(\"chat.call.people\") }}\n <span class=\"ms-1 text-neutral-400\">({{ participants.length }})</span>\n </h2>\n <CallButton\n icon=\"close\"\n :label=\"t('chat.call.controls.closePeople')\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-5\"\n :class=\"['size-11!', focusRing]\"\n data-testid=\"call-people-close\"\n @click=\"visible = false\"\n />\n </div>\n </template>\n\n <ul class=\"flex flex-col\">\n <li\n v-for=\"p in participants\"\n :key=\"p.id\"\n data-testid=\"call-participant\"\n :data-participant-id=\"p.id\"\n class=\"flex min-h-14 items-center gap-x-3 rounded-xl px-2 py-2\"\n >\n <Avatar\n :label=\"initialsOf(p) || undefined\"\n shape=\"circle\"\n class=\"shrink-0 font-semibold select-none\"\n :style=\"avatarToneStyle(p.name, null, 'dark')\"\n >\n <template v-if=\"!initialsOf(p)\" #icon><BIcon icon=\"PhUser\" class=\"size-1/2\" /></template>\n </Avatar>\n <div class=\"min-w-0 flex-1\">\n <p class=\"truncate text-body-md text-neutral-100\">\n <bdi>{{ nameOf(p) }}</bdi>\n <span v-if=\"p.isSelf\" class=\"text-neutral-400\"> ({{ t(\"chat.call.you\") }})</span>\n </p>\n <p\n v-if=\"statusOf(p)\"\n :data-testid=\"p.status === 'unreachable' ? 'call-participant-unreachable' : undefined\"\n class=\"truncate text-label-sm\"\n :class=\"p.status === 'unreachable' ? 'text-red-400' : 'text-neutral-400'\"\n >\n {{ statusOf(p) }}\n </p>\n </div>\n <!-- Unknown for clients too old to say: no icon rather than a wrong one. -->\n <span v-if=\"p.media\" class=\"flex shrink-0 items-center gap-x-1.5 text-neutral-300\">\n <span\n role=\"img\"\n :aria-label=\"p.media.audio ? t('chat.call.micOn') : t('chat.call.muted')\"\n :class=\"!p.media.audio && 'text-red-400'\"\n >\n <CallIcon :name=\"p.media.audio ? 'mic' : 'micOff'\" class=\"size-5\" />\n </span>\n <span\n role=\"img\"\n :aria-label=\"p.media.video ? t('chat.call.cameraOn') : t('chat.call.cameraOff')\"\n :class=\"!p.media.video && 'text-red-400'\"\n >\n <CallIcon :name=\"p.media.video ? 'videocam' : 'videocamOff'\" class=\"size-5\" />\n </span>\n </span>\n </li>\n </ul>\n </Drawer>\n</template>\n","<script setup lang=\"ts\">\nimport { useCallStore } from \"~/stores/callStore\";\nimport { useChatStore } from \"~/stores/chatStore\";\nimport { formatDuration } from \"~/utils/format\";\nimport useLocalI18n, { useDirection } from \"~/composables/useLocalI18n\";\nimport { chat } from \"@i18n/locales\";\nimport useCall from \"~/composables/useCall\";\nimport { useSpeaking } from \"~/composables/call/useSpeaking\";\nimport { useCallLayout, type CallTileInfo } from \"~/composables/call/useCallLayout\";\nimport { useCallNotices } from \"~/composables/call/useCallNotices\";\nimport type { Participant } from \"~/composables/call/session\";\nimport { useDraggable, useElementSize, useEventListener, useWindowSize } from \"@vueuse/core\";\nimport { ref, computed, watch, onMounted, nextTick, onBeforeUnmount } from \"vue\";\nimport Button from \"primevue/button\";\nimport Menu from \"primevue/menu\";\nimport Tooltip from \"primevue/tooltip\";\nimport type { MenuItem } from \"primevue/menuitem\";\nimport CallButton from \"./CallButton.vue\";\nimport CallIcon from \"./CallIcon.vue\";\nimport CallTile from \"./CallTile.vue\";\nimport CallParticipants from \"./CallParticipants.vue\";\nimport { callButtonDt, callMenuDt, focusRing, tip } from \"./tokens\";\n\nconst vTooltip = Tooltip;\n\nconst callStore = useCallStore();\nconst minimizedRef = ref<HTMLElement | null>(null);\nconst bodyRef = ref<HTMLElement | null>(null);\n\nconst { t, locale } = useLocalI18n(chat);\nconst { dir } = useDirection();\n\n// Named after the conversation the call belongs to: the other person, or the group.\nconst chatStore = useChatStore();\nconst callTitle = computed(() => {\n const contact = callStore.channelId ? chatStore.getContactById(callStore.channelId) : null;\n const name = contact ? `${contact.name} ${contact.lastName ?? \"\"}`.trim() : \"\";\n return name || t(\"chat.call.title\");\n});\n\n// Tiles move between the grid, the stage and the strip, remounting their <video>: the streams\n// are attached again whenever the arrangement changes.\nconst layoutKey = ref(\"\");\n\nconst {\n toggleVideoPause,\n toggleRemote,\n participantCount,\n participants,\n phase,\n hadOthers,\n endCall,\n toggleFullscreen,\n toggleFlashlight,\n toggleScreenShare,\n toggleAudio,\n toggleVideo,\n switchCamera,\n flipCamera,\n canFlipCamera,\n facingMode,\n isFlashlightSupported,\n isAudioOn,\n isVideoOn,\n isFlashlightOn,\n isFullscreen,\n canFullscreen,\n isScreenSharing,\n showControls,\n resetControlsTimeout,\n cameras,\n videoPaused,\n localStream,\n localVideo,\n localScreen,\n remoteRefs,\n remoteScreenRefs,\n remoteVideos,\n soundBlocked,\n enableSound,\n reattach,\n retryPeer,\n} = useCall({ layoutKey: () => layoutKey.value });\n\n// --- Layout ---\n\nconst stageRef = ref<HTMLElement | null>(null);\nconst { width: stageWidth, height: stageHeight } = useElementSize(stageRef);\nconst layout = useCallLayout({ participants, width: stageWidth, height: stageHeight });\nwatch(layout.key, (key) => (layoutKey.value = key), { immediate: true });\nconst portrait = computed(() => layout.orientation.value === \"portrait\");\n\nconst participantById = computed(\n () => new Map(participants.value.map((p) => [p.id, p] as const)),\n);\nconst participantOf = (tile: CallTileInfo) => participantById.value.get(tile.participantId)!;\nconst streamOf = (tile: CallTileInfo) => {\n const p = participantOf(tile);\n return (tile.kind === \"screen\" ? p?.screen : p?.camera) ?? null;\n};\nconst speakingOf = (tile: CallTileInfo) =>\n tile.kind === \"self\" ? !!speaking.self : tile.kind === \"camera\" && !!speaking[tile.participantId];\n\n// The tile on the other end in a one-to-one call, and the user's own.\nconst pairRemote = computed(() => layout.tiles.value.find((t) => t.kind === \"camera\") ?? null);\nconst selfTile = computed(() => layout.tiles.value.find((t) => t.kind === \"self\")!);\nconst canPin = computed(() => participants.value.length > 1 || isScreenSharing.value);\n\n/** Keeps the view's <video> refs pointing at whichever tile currently shows each stream. */\nfunction bindVideo(tile: CallTileInfo, el: HTMLVideoElement | null, previous: HTMLVideoElement | null) {\n const pid = tile.participantId;\n // A tile going away only clears the ref if no newer tile has taken it over already.\n const next = <T,>(current: T) => (el ?? (current === previous ? null : current)) as T;\n if (tile.kind === \"self\") localVideo.value = next(localVideo.value);\n else if (tile.id === \"self_screen\") localScreen.value = next(localScreen.value);\n else if (tile.kind === \"camera\") remoteRefs.value[pid] = next(remoteRefs.value[pid] ?? null);\n else remoteScreenRefs.value[pid] = next(remoteScreenRefs.value[pid] ?? null) ?? undefined;\n if (el) void reattach();\n}\n\nconst togglePause = (tile: CallTileInfo, el: HTMLVideoElement | null) => toggleVideoPause(tile.id, el);\nconst toggleTileFullscreen = (tile: CallTileInfo, el: HTMLElement | null) => {\n if (el) toggleRemote(tile.id, el);\n};\n\n// --- Waiting, notices, people ---\n\nconst waitingText = computed(() =>\n hadOthers.value ? t(\"chat.call.everyoneLeft\") : t(\"chat.call.waiting\"),\n);\nconst showWaiting = computed(() => layout.mode.value === \"solo\" && phase.value === \"waiting\");\n\nconst notices = useCallNotices(\n participants,\n (key, params, plural) => t(key, params, plural),\n () => t(\"chat.call.andJoin\"),\n () => String(locale.value),\n);\n\nconst peopleOpen = ref(false);\nconst peopleLabel = computed(\n () => `${t(\"chat.call.controls.people\")} (${t(\"chat.call.participants\", participantCount.value)})`,\n);\n\n// --- Controls ---\n\n// Pills, as in Google Meet: wider than tall, so the bar reads as one row of controls.\nconst barButton = {\n dt: callButtonDt,\n text: false,\n size: \"large\",\n iconClass: \"size-6\",\n class: `h-12! w-12! sm:w-14! ${focusRing}`,\n} as const;\n\n// Meet's shortcuts, on the tooltip and in the keyboard: Ctrl+D the microphone, Ctrl+E the camera.\nconst isMac = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\nconst keys = (key: string) => (isMac ? `⌘ ${key}` : `Ctrl + ${key}`);\nconst withKeys = (label: string, key: string) => `${label} (${keys(key)})`;\n\nconst audioLabel = computed(() =>\n isAudioOn.value ? t(\"chat.call.controls.mute\") : t(\"chat.call.controls.unmute\"),\n);\nconst videoLabel = computed(() =>\n isVideoOn.value ? t(\"chat.call.controls.cameraOff\") : t(\"chat.call.controls.cameraOn\"),\n);\nconst shareLabel = computed(() =>\n isScreenSharing.value\n ? t(\"chat.call.controls.stopSharing\")\n : t(\"chat.call.controls.shareScreen\"),\n);\n// Names where the flip goes, so a screen reader hears more than \"switch\".\nconst flipLabel = computed(() =>\n facingMode.value === \"environment\"\n ? t(\"chat.call.controls.frontCamera\")\n : t(\"chat.call.controls.backCamera\"),\n);\nconst showCameraPicker = computed(() => cameras.value.length > 1 && !canFlipCamera.value);\n\n// One flip at a time: a second tap mid-flip would race the first for the camera.\nconst isFlipping = ref(false);\nconst flip = async () => {\n if (isFlipping.value) return;\n isFlipping.value = true;\n try {\n await flipCamera();\n } finally {\n isFlipping.value = false;\n }\n};\n\nconst fullscreenLabel = computed(() =>\n isFullscreen.value\n ? t(\"chat.call.controls.exitFullscreen\")\n : t(\"chat.call.controls.fullscreen\"),\n);\n\nuseEventListener(window, \"keydown\", (event: KeyboardEvent) => {\n if (!callStore.isActive || callStore.isMinimized) return;\n if (!(isMac ? event.metaKey : event.ctrlKey) || event.altKey || event.shiftKey) return;\n const key = event.key.toLowerCase();\n if (key !== \"d\" && key !== \"e\") return;\n // Both are browser shortcuts too (bookmark, search), which the call takes over while it's open.\n event.preventDefault();\n if (key === \"d\") toggleAudio();\n else toggleVideo();\n});\n\n// The camera in use: read off the track when the call starts, then whatever was picked.\nconst currentCameraId = ref<string | null>(null);\nwatch(\n localStream,\n (stream) => {\n currentCameraId.value = stream?.getVideoTracks()[0]?.getSettings().deviceId ?? null;\n },\n { immediate: true },\n);\n\nconst cameraMenu = ref<InstanceType<typeof Menu> | null>(null);\nconst cameraItems = computed<MenuItem[]>(() => [\n {\n label: t(\"chat.call.controls.cameras\"),\n items: cameras.value.map((camera, index) => ({\n label: camera.label || `${t(\"chat.call.controls.chooseCamera\")} ${index + 1}`,\n callIcon: camera.deviceId === currentCameraId.value ? \"check\" : undefined,\n command: async () => {\n currentCameraId.value = camera.deviceId;\n await switchCamera(camera.deviceId);\n // A failed switch falls back to the previous camera.\n currentCameraId.value =\n localStream.value?.getVideoTracks()[0]?.getSettings().deviceId ?? null;\n },\n })),\n },\n]);\n\nconst moreMenu = ref<InstanceType<typeof Menu> | null>(null);\nconst moreItems = computed<MenuItem[]>(() => [\n ...(isFlashlightSupported.value\n ? [\n {\n label: isFlashlightOn.value\n ? t(\"chat.call.controls.flashlightOff\")\n : t(\"chat.call.controls.flashlightOn\"),\n callIcon: isFlashlightOn.value ? \"flashlightOff\" : \"flashlightOn\",\n command: () => toggleFlashlight(),\n },\n ]\n : []),\n]);\n\n// --- Speaking ---\n\nconst speaking = useSpeaking(() => ({\n self: isAudioOn.value ? localStream.value : null,\n ...Object.fromEntries(\n Object.entries(remoteVideos.value).map(([id, remote]) => [id, remote.stream]),\n ),\n}));\n\n// --- Picture-in-picture ---\n\n// Minimized, the call plays live behind its controls: whoever is speaking (or the one picked with\n// the count button), or the user's own camera when nobody else is there.\nconst pipVideoRef = ref<HTMLVideoElement | null>(null);\nconst activeRemoteIndex = ref(0);\n\nconst remoteVideoEntries = computed(() => Object.entries(remoteVideos.value));\nconst hasRemoteVideos = computed(() => remoteVideoEntries.value.length > 0);\nconst activeRemoteUserId = computed<string | null>(() => {\n const entries = remoteVideoEntries.value;\n if (entries.length === 0) return null;\n return entries[activeRemoteIndex.value % entries.length]![0];\n});\n\nconst pipStream = computed<MediaStream | null>(() => {\n if (hasRemoteVideos.value) {\n const id = activeRemoteUserId.value;\n return id ? (remoteVideos.value[id]?.stream ?? null) : null;\n }\n return localStream.value ?? null;\n});\n\nfunction cycleRemote() {\n const count = remoteVideoEntries.value.length;\n if (count === 0) return;\n activeRemoteIndex.value = (activeRemoteIndex.value + 1) % count;\n}\n\n// Follows whoever speaks, after a moment, so a cough doesn't flip the picture back and forth.\nconst speakerIndex = computed(() =>\n remoteVideoEntries.value.findIndex(([id]) => speaking[id]),\n);\nlet speakerTimer: ReturnType<typeof setTimeout> | undefined;\nwatch(speakerIndex, (index) => {\n clearTimeout(speakerTimer);\n if (index < 0 || index === activeRemoteIndex.value % remoteVideoEntries.value.length) return;\n speakerTimer = setTimeout(() => (activeRemoteIndex.value = index), 1_500);\n});\nonBeforeUnmount(() => clearTimeout(speakerTimer));\n\nwatch(\n [pipStream, () => callStore.isMinimized],\n async () => {\n await nextTick();\n const el = pipVideoRef.value;\n if (!el) return;\n const stream = pipStream.value;\n if (stream && el.srcObject !== stream) {\n el.srcObject = stream;\n el.play().catch(() => {});\n } else if (!stream && el.srcObject) {\n el.srcObject = null;\n }\n },\n { immediate: true },\n);\n\nonMounted(() => {\n bodyRef.value = document.body;\n});\n\n// Dragged anywhere, then snapped to the nearest corner on release.\nconst { width: windowWidth, height: windowHeight } = useWindowSize();\n\nconst PIP_WIDTH = 280; // w-70\nconst PIP_HEIGHT = 160; // h-40\nconst PADDING = 16;\n// Top and bottom corners stay this far from the edges, clear of the chat header and the composer.\nconst PIP_INSET_Y = 96;\n\nconst { x, y, isDragging } = useDraggable(minimizedRef, {\n initialValue: {\n x: typeof window !== \"undefined\" ? window.innerWidth - PIP_WIDTH - PADDING : PADDING,\n y: PIP_INSET_Y,\n },\n disabled: computed(() => !callStore.isMinimized),\n});\n\nwatch(isDragging, (dragging) => {\n if (!dragging && callStore.isMinimized) {\n const maxX = windowWidth.value - PIP_WIDTH - PADDING;\n const maxY = windowHeight.value - PIP_HEIGHT - PIP_INSET_Y;\n x.value = x.value < windowWidth.value / 2 ? PADDING : maxX;\n y.value = y.value < windowHeight.value / 2 ? PIP_INSET_Y : maxY;\n }\n});\n\n// Each time it is minimized it starts in the top corner on the reading end.\nwatch(\n () => callStore.isMinimized,\n (isMinimized) => {\n if (isMinimized) {\n nextTick(() => {\n const isRtl = dir.value === \"rtl\";\n x.value = isRtl ? PADDING : windowWidth.value - PIP_WIDTH - PADDING;\n // The top corner, where it covers older messages rather than the composer.\n y.value = PIP_INSET_Y;\n });\n }\n },\n { immediate: true },\n);\n\n// Kept on screen whatever the window does.\nconst clampedStyle = computed(() => {\n if (!callStore.isMinimized) return {};\n\n const maxX = windowWidth.value - PIP_WIDTH - PADDING;\n const maxY = windowHeight.value - PIP_HEIGHT - PADDING;\n\n return {\n left: `${Math.max(PADDING, Math.min(x.value, maxX))}px`,\n top: `${Math.max(PADDING, Math.min(y.value, maxY))}px`,\n };\n});\n\n/** What every CallTile on the stage gets, apart from its layout classes. */\nconst tileProps = (tile: CallTileInfo, compact = false) => ({\n tile,\n participant: participantOf(tile) as Participant,\n stream: streamOf(tile),\n speaking: speakingOf(tile),\n pinned: layout.pinnedId.value === tile.id,\n canPin: canPin.value,\n compact,\n paused: !!videoPaused.value[tile.id],\n isFullscreen: isFullscreen.value,\n // The user's own camera shows as a mirror, as people expect; the back one shows the world as is.\n mirrored: tile.kind === \"self\" && facingMode.value !== \"environment\",\n});\n</script>\n\n<template>\n <!-- Picture-in-picture: the call shrunk to a draggable window over the app. -->\n <div\n v-if=\"callStore.isActive && callStore.isMinimized\"\n ref=\"minimizedRef\"\n data-testid=\"call-pip\"\n :style=\"clampedStyle\"\n :dir=\"dir\"\n class=\"vue-chat font-chat-family fixed z-9999 h-40 w-70 cursor-move touch-none overflow-hidden rounded-2xl bg-neutral-900 shadow-2xl ring-1 ring-white/10\"\n :class=\"[!isDragging && 'transition-all duration-300 ease-out motion-reduce:transition-none']\"\n >\n <video\n ref=\"pipVideoRef\"\n muted\n autoplay\n playsinline\n class=\"pointer-events-none absolute inset-0 size-full object-cover\"\n />\n <div\n class=\"pointer-events-none absolute inset-0 bg-linear-to-t from-black/60 via-transparent to-black/30\"\n />\n\n <div class=\"absolute inset-x-3 top-3 flex items-center justify-between\">\n <div\n class=\"flex items-center gap-x-2 rounded-full bg-black/45 px-3 py-1.5 text-label-sm text-white backdrop-blur-sm select-none\"\n >\n <span class=\"relative flex size-2.5\">\n <span class=\"absolute inline-flex size-full animate-ping rounded-full bg-red-500/60 motion-reduce:animate-none\" />\n <span class=\"relative inline-flex size-2.5 rounded-full bg-red-500\" />\n </span>\n <span dir=\"ltr\" class=\"tabular-nums\">{{ formatDuration(callStore.elapsedTime) }}</span>\n </div>\n\n <CallButton\n icon=\"callEnd\"\n :label=\"t('chat.call.controls.endCall')\"\n severity=\"danger\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-5\"\n class=\"h-9! w-12!\"\n data-testid=\"call-pip-end\"\n @pointerdown.stop\n @click.stop=\"endCall\"\n />\n </div>\n\n <div class=\"absolute inset-x-3 bottom-3 flex items-center justify-between\">\n <div class=\"flex items-center gap-1.5\">\n <Button\n :label=\"String(participantCount)\"\n :aria-label=\"t('chat.call.controls.nextParticipant')\"\n :disabled=\"!hasRemoteVideos\"\n :dt=\"callButtonDt\"\n severity=\"secondary\"\n size=\"small\"\n rounded\n class=\"h-8!\"\n @pointerdown.stop\n @click.stop=\"cycleRemote\"\n >\n <template #icon>\n <CallIcon name=\"group\" class=\"size-4\" />\n </template>\n </Button>\n\n <span\n v-if=\"!isAudioOn\"\n class=\"flex size-8 items-center justify-center rounded-full bg-red-500 text-white\"\n >\n <CallIcon name=\"micOff\" class=\"size-4\" />\n </span>\n <span\n v-if=\"!isVideoOn\"\n class=\"flex size-8 items-center justify-center rounded-full bg-red-500 text-white\"\n >\n <CallIcon name=\"videocamOff\" class=\"size-4\" />\n </span>\n </div>\n\n <CallButton\n icon=\"openInFull\"\n :label=\"t('chat.call.controls.maximize')\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4.5\"\n class=\"size-9!\"\n data-testid=\"call-maximize\"\n @pointerdown.stop\n @click.stop=\"callStore.maximize()\"\n />\n </div>\n </div>\n\n <!-- The full call screen. -->\n <div\n v-show=\"callStore.isActive && !callStore.isMinimized\"\n data-testid=\"call-view\"\n :dir=\"dir\"\n class=\"vue-chat font-chat-family fixed inset-0 z-60 flex size-full flex-col bg-neutral-900 text-white\"\n >\n <!-- Top bar: what the call is, how long it has run, and who is in it. -->\n <div\n data-testid=\"call-top-bar\"\n class=\"flex h-14 shrink-0 items-center gap-x-3 px-3 transition-opacity duration-300 motion-reduce:transition-none md:h-16 md:px-6\"\n :class=\"showControls ? 'opacity-100' : 'opacity-0'\"\n @mouseenter=\"resetControlsTimeout\"\n >\n <div class=\"flex min-w-0 flex-1 items-center gap-x-3 select-none\">\n <h1 class=\"truncate text-title-sm text-white\">{{ callTitle }}</h1>\n <span aria-hidden=\"true\" class=\"h-4 w-px shrink-0 bg-white/30\" />\n <span dir=\"ltr\" class=\"shrink-0 text-body-md text-neutral-300 tabular-nums\">\n {{ formatDuration(callStore.elapsedTime) }}\n </span>\n </div>\n\n <div data-testid=\"call-participants\" class=\"flex shrink-0 items-center gap-x-2\">\n <Button\n v-tooltip.bottom=\"tip(peopleLabel)\"\n :aria-label=\"peopleLabel\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"peopleOpen\"\n :dt=\"callButtonDt\"\n severity=\"secondary\"\n rounded\n data-testid=\"call-people-button\"\n :class=\"['h-11! gap-x-1.5! px-3.5!', focusRing]\"\n @click=\"peopleOpen = true\"\n >\n <CallIcon name=\"group\" class=\"size-5\" />\n <span data-testid=\"call-participant-count\" aria-hidden=\"true\" class=\"text-label-md tabular-nums\">\n {{ participantCount }}\n </span>\n </Button>\n <CallButton\n v-if=\"canFullscreen\"\n v-tooltip.bottom=\"tip(fullscreenLabel)\"\n :icon=\"isFullscreen ? 'fullscreenExit' : 'fullscreen'\"\n :label=\"fullscreenLabel\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-5\"\n :class=\"['size-11!', focusRing]\"\n data-testid=\"call-fullscreen\"\n :data-active=\"isFullscreen\"\n @click=\"toggleFullscreen()\"\n />\n <CallButton\n v-tooltip.bottom=\"tip(t('chat.call.controls.minimize'))\"\n icon=\"pictureInPicture\"\n :label=\"t('chat.call.controls.minimize')\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-5\"\n :class=\"['size-11!', focusRing]\"\n data-testid=\"call-minimize\"\n @click=\"callStore.minimize\"\n />\n </div>\n </div>\n\n <!-- Stage -->\n <div\n ref=\"stageRef\"\n class=\"relative min-h-0 flex-1 px-2 pb-2 md:px-4 md:pb-4\"\n style=\"--call-gap: 0.5rem\"\n @mousemove=\"resetControlsTimeout\"\n >\n <!-- The browser blocked the others' sound until a tap: they play muted until then. -->\n <Button\n v-if=\"soundBlocked\"\n :label=\"t('chat.call.controls.enableSound')\"\n :dt=\"callButtonDt\"\n severity=\"contrast\"\n rounded\n data-testid=\"call-enable-sound\"\n class=\"absolute! top-4 left-1/2 z-40 -translate-x-1/2 shadow-lg\"\n @click=\"enableSound\"\n >\n <template #icon>\n <CallIcon name=\"volumeUp\" class=\"size-5\" />\n </template>\n </Button>\n\n <!-- Someone joined or left. Read out too, without moving focus. -->\n <Transition\n enter-active-class=\"transition duration-200 motion-reduce:transition-none\"\n enter-from-class=\"opacity-0 -translate-y-2\"\n leave-active-class=\"transition duration-200 motion-reduce:transition-none\"\n leave-to-class=\"opacity-0\"\n >\n <div\n v-if=\"notices.current.value && !soundBlocked\"\n :key=\"notices.current.value.id\"\n data-testid=\"call-notice\"\n class=\"pointer-events-none absolute inset-x-0 top-3 z-40 flex justify-center px-4\"\n >\n <span class=\"max-w-full truncate rounded-full bg-black/70 px-4 py-1.5 text-label-md text-white shadow-lg backdrop-blur-sm\">\n <bdi>{{ notices.current.value.text }}</bdi>\n </span>\n </div>\n </Transition>\n <span class=\"sr-only\" aria-live=\"polite\">{{ notices.liveText.value }}</span>\n\n <!-- Alone: the user's own camera, with what the call is waiting for. -->\n <template v-if=\"layout.mode.value === 'solo'\">\n <CallTile\n :key=\"selfTile.id\"\n v-bind=\"tileProps(selfTile)\"\n :hint=\"t('chat.call.cameraIsOff')\"\n class=\"size-full\"\n @video=\"(el, prev) => bindVideo(selfTile, el, prev)\"\n @pause=\"(el) => togglePause(selfTile, el)\"\n @fullscreen=\"(el) => toggleTileFullscreen(selfTile, el)\"\n />\n <div\n v-if=\"showWaiting\"\n data-testid=\"call-waiting\"\n role=\"status\"\n class=\"pointer-events-none absolute inset-x-0 top-8 z-30 flex justify-center px-4\"\n >\n <div class=\"max-w-full rounded-2xl bg-black/65 px-5 py-3 text-center shadow-lg backdrop-blur-sm\">\n <p class=\"truncate text-title-sm text-white\">{{ callTitle }}</p>\n <p class=\"mt-0.5 text-label-md text-neutral-200\">{{ waitingText }}</p>\n </div>\n </div>\n </template>\n\n <!-- One other person: they fill the stage, the user's own camera floats in a corner. -->\n <!-- Handlers take the tile from the loop, not the computed: a tile's last events come as it\n unmounts, after the computed has moved on. -->\n <template v-else-if=\"layout.mode.value === 'pair' && pairRemote\">\n <CallTile\n v-for=\"tile in [pairRemote]\"\n :key=\"tile.id\"\n v-bind=\"tileProps(tile)\"\n class=\"size-full\"\n @pin=\"layout.togglePin(tile.id)\"\n @retry=\"retryPeer(tile.participantId)\"\n @video=\"(el, prev) => bindVideo(tile, el, prev)\"\n @pause=\"(el) => togglePause(tile, el)\"\n @fullscreen=\"(el) => toggleTileFullscreen(tile, el)\"\n />\n <CallTile\n :key=\"selfTile.id\"\n v-bind=\"tileProps(selfTile, true)\"\n :can-pin=\"false\"\n class=\"absolute! end-5 bottom-4 z-10 aspect-video w-36 shadow-xl outline outline-white/25 sm:w-56 md:end-6 md:bottom-6 md:w-64\"\n @video=\"(el, prev) => bindVideo(selfTile, el, prev)\"\n />\n </template>\n\n <!-- Two or three others: everyone a tile of a 2×2 grid. -->\n <div v-else-if=\"layout.mode.value === 'grid'\" :class=\"layout.gridClass\">\n <CallTile\n v-for=\"(tile, index) in layout.gridTiles.value\"\n :key=\"tile.id\"\n v-bind=\"tileProps(tile)\"\n :class=\"['size-full', layout.cellClass(index)]\"\n @pin=\"layout.togglePin(tile.id)\"\n @retry=\"retryPeer(tile.participantId)\"\n @video=\"(el, prev) => bindVideo(tile, el, prev)\"\n @pause=\"(el) => togglePause(tile, el)\"\n @fullscreen=\"(el) => toggleTileFullscreen(tile, el)\"\n />\n </div>\n\n <!-- A screen share or a pinned tile on the stage, everyone else in a strip: along the\n bottom on a tall screen, along the inline end on a wide one. -->\n <div\n v-else-if=\"layout.stageTile.value\"\n class=\"flex size-full gap-(--call-gap)\"\n :class=\"portrait ? 'flex-col' : 'flex-row'\"\n >\n <CallTile\n v-for=\"tile in [layout.stageTile.value]\"\n :key=\"tile.id\"\n v-bind=\"tileProps(tile)\"\n data-stage=\"true\"\n class=\"min-h-0 min-w-0 flex-1\"\n @pin=\"layout.togglePin(tile.id)\"\n @retry=\"retryPeer(tile.participantId)\"\n @video=\"(el, prev) => bindVideo(tile, el, prev)\"\n @pause=\"(el) => togglePause(tile, el)\"\n @fullscreen=\"(el) => toggleTileFullscreen(tile, el)\"\n />\n <div\n v-if=\"layout.stripTiles.value.length\"\n data-testid=\"call-strip\"\n class=\"hide-scrollbar flex shrink-0 gap-(--call-gap)\"\n :class=\"portrait ? 'h-24 flex-row overflow-x-auto sm:h-28' : 'w-40 flex-col overflow-y-auto lg:w-56'\"\n >\n <CallTile\n v-for=\"tile in layout.stripTiles.value\"\n :key=\"tile.id\"\n v-bind=\"tileProps(tile, true)\"\n class=\"aspect-video shrink-0\"\n :class=\"portrait ? 'h-full' : 'w-full'\"\n @pin=\"layout.togglePin(tile.id)\"\n @retry=\"retryPeer(tile.participantId)\"\n @video=\"(el, prev) => bindVideo(tile, el, prev)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Control bar -->\n <div\n class=\"flex h-20 shrink-0 items-center justify-center px-3 transition-opacity duration-300 motion-reduce:transition-none md:px-6\"\n :class=\"showControls ? 'opacity-100' : 'opacity-0'\"\n @mouseenter=\"resetControlsTimeout\"\n @mousemove=\"resetControlsTimeout\"\n >\n <div class=\"flex items-center justify-center gap-x-2 sm:gap-x-3\">\n <CallButton\n v-tooltip.top=\"tip(withKeys(audioLabel, 'D'))\"\n :icon=\"isAudioOn ? 'mic' : 'micOff'\"\n :label=\"audioLabel\"\n :severity=\"isAudioOn ? 'secondary' : 'danger'\"\n :aria-keyshortcuts=\"isMac ? 'Meta+D' : 'Control+D'\"\n v-bind=\"barButton\"\n data-testid=\"call-toggle-audio\"\n :data-active=\"isAudioOn\"\n @click=\"toggleAudio\"\n />\n\n <!-- The camera, with Meet's caret for picking which one when there are several (a phone\n flips between its two sides instead, with the button after this one). -->\n <div class=\"flex items-center rounded-full\" :class=\"showCameraPicker && 'bg-white/12'\">\n <CallButton\n v-if=\"showCameraPicker\"\n v-tooltip.top=\"tip(t('chat.call.controls.chooseCamera'))\"\n icon=\"arrowDropUp\"\n :label=\"t('chat.call.controls.chooseCamera')\"\n :dt=\"callButtonDt\"\n text\n severity=\"secondary\"\n icon-class=\"size-6\"\n :class=\"['h-12! w-8! rounded-e-none! ps-1!', focusRing]\"\n aria-haspopup=\"true\"\n @click=\"cameraMenu?.toggle($event)\"\n />\n <CallButton\n v-tooltip.top=\"tip(withKeys(videoLabel, 'E'))\"\n :icon=\"isVideoOn ? 'videocam' : 'videocamOff'\"\n :label=\"videoLabel\"\n :severity=\"isVideoOn ? 'secondary' : 'danger'\"\n :aria-keyshortcuts=\"isMac ? 'Meta+E' : 'Control+E'\"\n v-bind=\"barButton\"\n data-testid=\"call-toggle-video\"\n :data-active=\"isVideoOn\"\n @click=\"toggleVideo\"\n />\n </div>\n\n <CallButton\n v-if=\"canFlipCamera\"\n v-tooltip.top=\"tip(flipLabel)\"\n icon=\"cameraSwitch\"\n :label=\"flipLabel\"\n :disabled=\"!isVideoOn || isFlipping\"\n v-bind=\"barButton\"\n data-testid=\"call-flip-camera\"\n :data-facing=\"facingMode ?? undefined\"\n @click=\"flip\"\n />\n\n <CallButton\n v-if=\"callStore.canShareScreen\"\n v-tooltip.top=\"tip(shareLabel)\"\n :icon=\"isScreenSharing ? 'cancelPresentation' : 'presentToAll'\"\n :label=\"shareLabel\"\n :severity=\"isScreenSharing ? 'contrast' : 'secondary'\"\n v-bind=\"barButton\"\n data-testid=\"call-toggle-screen\"\n :data-active=\"isScreenSharing\"\n @click=\"toggleScreenShare\"\n />\n\n <!-- Only the flashlight is left in it: no menu where the device has none. -->\n <CallButton\n v-if=\"moreItems.length\"\n v-tooltip.top=\"tip(t('chat.call.controls.more'))\"\n icon=\"moreVert\"\n :label=\"t('chat.call.controls.more')\"\n v-bind=\"barButton\"\n class=\"h-12! w-10! sm:w-12!\"\n aria-haspopup=\"true\"\n data-testid=\"call-more\"\n @click=\"moreMenu?.toggle($event)\"\n />\n\n <CallButton\n v-tooltip.top=\"tip(t('chat.call.controls.endCall'))\"\n icon=\"callEnd\"\n :label=\"t('chat.call.controls.endCall')\"\n severity=\"danger\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n size=\"large\"\n icon-class=\"size-6\"\n :class=\"['h-12! w-16! sm:w-18!', focusRing]\"\n data-testid=\"call-end\"\n @click=\"endCall\"\n />\n </div>\n </div>\n\n <CallParticipants v-model:visible=\"peopleOpen\" :participants=\"participants\" />\n\n <Menu ref=\"cameraMenu\" :model=\"cameraItems\" popup :dir=\"dir\" :dt=\"callMenuDt\" class=\"vue-chat\">\n <template #itemicon=\"{ item }\">\n <CallIcon v-if=\"item.callIcon\" :name=\"item.callIcon\" class=\"size-5 text-sky-400\" />\n <span v-else class=\"size-5\" />\n </template>\n </Menu>\n <Menu ref=\"moreMenu\" :model=\"moreItems\" popup :dir=\"dir\" :dt=\"callMenuDt\" class=\"vue-chat\">\n <template #itemicon=\"{ item }\">\n <CallIcon :name=\"item.callIcon\" class=\"size-5 text-neutral-400\" />\n </template>\n </Menu>\n </div>\n</template>\n"],"names":["lit","_createElementBlock","_openBlock","_createBlock","_unref","_mergeProps","$attrs","_createVNode","CallIcon","_normalizeClass","_createElementVNode","_hoisted_4","BIcon","_hoisted_5","_toDisplayString","_hoisted_6","_hoisted_7","_withDirectives","CallButton","_Fragment","_useModel","_hoisted_1","_hoisted_2","_createTextVNode","_hoisted_3","_renderList","_normalizeStyle","_hoisted_8","_hoisted_9","_hoisted_10","t","_withModifiers","_Transition","CallTile","CallParticipants","_withCtx","_vShow"],"mappings":"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"}
|