vue-parley 4.2.0 → 4.3.1

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.
Files changed (60) hide show
  1. package/dist/chat.css +59 -33
  2. package/dist/chunks/{Call-7lGaUPcp.mjs → Call-CPHjSt8T.mjs} +108 -61
  3. package/dist/chunks/Call-CPHjSt8T.mjs.map +1 -0
  4. package/dist/chunks/{Call-D48LfnDv.cjs → Call-DF1buv8M.cjs} +107 -60
  5. package/dist/chunks/Call-DF1buv8M.cjs.map +1 -0
  6. package/dist/chunks/{index-C8N5eSUe.mjs → index-DI5ok4ow.mjs} +150 -145
  7. package/dist/chunks/index-DI5ok4ow.mjs.map +1 -0
  8. package/dist/chunks/{index-DrcpfLUy.cjs → index-DwJwSnRN.cjs} +131 -126
  9. package/dist/chunks/index-DwJwSnRN.cjs.map +1 -0
  10. package/dist/chunks/{session-B8Q7eiUV.mjs → session-BxYnJEOe.mjs} +183 -73
  11. package/dist/chunks/session-BxYnJEOe.mjs.map +1 -0
  12. package/dist/chunks/{session-BwgUu6F3.cjs → session-D2gbmnmM.cjs} +183 -73
  13. package/dist/chunks/session-D2gbmnmM.cjs.map +1 -0
  14. package/dist/index.cjs +1 -1
  15. package/dist/index.mjs +19 -19
  16. package/dist/types/app/components/ChatPage.vue.d.ts.map +1 -1
  17. package/dist/types/app/components/call/Call.vue.d.ts.map +1 -1
  18. package/dist/types/app/components/chat/ChatBubble.vue.d.ts.map +1 -1
  19. package/dist/types/app/components/chat/ChatInput.vue.d.ts.map +1 -1
  20. package/dist/types/app/components/chat/ChatMessages.vue.d.ts.map +1 -1
  21. package/dist/types/app/components/chat/ChatPageBar.vue.d.ts.map +1 -1
  22. package/dist/types/app/components/chat/ChatProfileOverview.vue.d.ts +5 -1
  23. package/dist/types/app/components/chat/ChatProfileOverview.vue.d.ts.map +1 -1
  24. package/dist/types/app/components/chat/ChatView.vue.d.ts.map +1 -1
  25. package/dist/types/app/components/chat/chat-bubbles/BubbleOptions.vue.d.ts.map +1 -1
  26. package/dist/types/app/components/chat/chat-bubbles/MediaViewer.vue.d.ts.map +1 -1
  27. package/dist/types/app/components/chat/chat-input/InputAttachement.vue.d.ts.map +1 -1
  28. package/dist/types/app/components/chat/contact/ChatList.vue.d.ts.map +1 -1
  29. package/dist/types/app/components/chat/messages/FloatingDateHeader.vue.d.ts +0 -1
  30. package/dist/types/app/components/chat/messages/FloatingDateHeader.vue.d.ts.map +1 -1
  31. package/dist/types/app/components/general/ResponsiveDialog.vue.d.ts.map +1 -1
  32. package/dist/types/app/composables/call/media.d.ts +1 -0
  33. package/dist/types/app/composables/call/media.d.ts.map +1 -1
  34. package/dist/types/app/composables/call/peer.d.ts +4 -1
  35. package/dist/types/app/composables/call/peer.d.ts.map +1 -1
  36. package/dist/types/app/composables/call/peers.d.ts +10 -0
  37. package/dist/types/app/composables/call/peers.d.ts.map +1 -1
  38. package/dist/types/app/composables/call/session.d.ts +8 -1
  39. package/dist/types/app/composables/call/session.d.ts.map +1 -1
  40. package/dist/types/app/composables/call/signaling.d.ts +5 -3
  41. package/dist/types/app/composables/call/signaling.d.ts.map +1 -1
  42. package/dist/types/app/composables/call/useCallUi.d.ts +2 -0
  43. package/dist/types/app/composables/call/useCallUi.d.ts.map +1 -1
  44. package/dist/types/app/composables/useCall.d.ts +2 -0
  45. package/dist/types/app/composables/useCall.d.ts.map +1 -1
  46. package/dist/types/app/composables/useFlippedVirtualScroll.d.ts +0 -1
  47. package/dist/types/app/composables/useFlippedVirtualScroll.d.ts.map +1 -1
  48. package/dist/types/app/stores/callStore.d.ts +45 -9
  49. package/dist/types/app/stores/callStore.d.ts.map +1 -1
  50. package/dist/types/app/types/index.d.ts +2 -0
  51. package/dist/types/app/types/index.d.ts.map +1 -1
  52. package/dist/types/i18n/locales/index.d.ts +20 -0
  53. package/dist/types/i18n/locales/index.d.ts.map +1 -1
  54. package/package.json +13 -12
  55. package/dist/chunks/Call-7lGaUPcp.mjs.map +0 -1
  56. package/dist/chunks/Call-D48LfnDv.cjs.map +0 -1
  57. package/dist/chunks/index-C8N5eSUe.mjs.map +0 -1
  58. package/dist/chunks/index-DrcpfLUy.cjs.map +0 -1
  59. package/dist/chunks/session-B8Q7eiUV.mjs.map +0 -1
  60. package/dist/chunks/session-BwgUu6F3.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Call-CPHjSt8T.mjs","sources":["../../app/composables/call/useCallUi.ts","../../app/composables/useCall.ts","../../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}\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 function toggleFullscreen(target: HTMLElement = document.documentElement) {\n if (!document.fullscreenElement) {\n void target.requestFullscreen?.();\n isFullscreen.value = true;\n } else {\n void document.exitFullscreen();\n isFullscreen.value = false;\n }\n }\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 watch(\n [localStream, opts.isMinimized],\n async () => {\n await nextTick();\n if (localStream.value && localVideo.value)\n localVideo.value.srcObject = localStream.value;\n },\n { immediate: true },\n );\n watch(\n [screenStream, opts.isMinimized],\n async () => {\n await nextTick();\n if (localScreen.value) localScreen.value.srcObject = screenStream.value;\n },\n { immediate: true },\n );\n watch(\n [() => ({ ...remoteVideos.value }), opts.isMinimized],\n async () => {\n await nextTick();\n for (const [id, { stream }] of Object.entries(remoteVideos.value))\n attach(remoteRefs.value[id], stream);\n },\n { immediate: true },\n );\n watch(\n [() => ({ ...remoteScreens.value }), opts.isMinimized],\n async () => {\n await nextTick();\n for (const [id, { stream }] of Object.entries(remoteScreens.value))\n attach(remoteScreenRefs.value[id], stream);\n },\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 toggleFullscreen: () => toggleFullscreen(),\n toggleRemote,\n videoPaused,\n toggleVideoPause,\n soundBlocked,\n enableSound,\n detachAll,\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() {\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 });\n\n async function switchCamera(deviceId: string) {\n const stream = await session!.switchCamera(deviceId);\n // Same stream object with a new track: the preview has to be told.\n if (stream && ui.localVideo.value) ui.localVideo.value.srcObject = stream;\n }\n\n return {\n // Call state\n participantCount: session.participantCount,\n tileCount: session.tileCount,\n localStream: media.localStream,\n remoteVideos: peers.remoteVideos,\n remoteScreens: peers.remoteScreens,\n // Local media\n cameras: media.cameras,\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 endCall: callStore.endCall,\n // View\n showCameraModal: ref(false),\n showControls: ui.showControls,\n resetControlsTimeout: ui.resetControlsTimeout,\n isFullscreen: ui.isFullscreen,\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 };\n}\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 { useDraggable, useWindowSize } from \"@vueuse/core\";\nimport { ref, computed, watch, onMounted, nextTick } from \"vue\";\nimport Button from \"primevue/button\";\nimport Listbox from \"primevue/listbox\";\nimport IconButton from \"~/components/general/IconButton.vue\";\nimport ResponsiveDialog from \"~/components/general/ResponsiveDialog.vue\";\n\nconst callStore = useCallStore();\n\n// ارجاع به المان مینیمایز شده برای VueUse\nconst minimizedRef = ref<HTMLElement | null>(null);\nconst bodyRef = ref<HTMLElement | null>(null);\nconst cameraPickerOpen = ref(false);\nconst { t } = useLocalI18n(chat);\nconst { dir } = useDirection();\n\n// Named after whoever is on the other end of the conversation the call belongs to.\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\nconst {\n toggleVideoPause,\n toggleRemote,\n participantCount,\n endCall,\n toggleFullscreen,\n toggleFlashlight,\n toggleScreenShare,\n toggleAudio,\n toggleVideo,\n switchCamera,\n isFlashlightSupported,\n tileCount,\n isAudioOn,\n isVideoOn,\n isFlashlightOn,\n isFullscreen,\n isScreenSharing,\n showControls,\n resetControlsTimeout,\n cameras,\n videoPaused,\n localStream,\n localVideo,\n localScreen,\n remoteParents,\n remoteRefs,\n remoteScreens,\n remoteScreenRefs,\n remoteVideos,\n soundBlocked,\n enableSound,\n} = useCall();\n\nconst pickCamera = (deviceId: string) => {\n cameraPickerOpen.value = false;\n switchCamera(deviceId);\n};\n\n// The call screen is dark whatever the host's colour scheme, so its round controls use fixed\n// translucent tokens instead of the theme's secondary and contrast colours.\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: \"#151823\",\n hoverColor: \"#151823\",\n activeColor: \"#151823\",\n};\nconst callScheme = { root: { secondary: translucent, contrast: lit } };\nconst callButtonDt = { colorScheme: { light: callScheme, dark: callScheme } };\n\nconst footerButton = {\n dt: callButtonDt,\n text: false,\n size: \"large\",\n iconClass: \"size-6\",\n} as const;\n\n// --- PIP BACKGROUND VIDEO ---\n// در حالت مینیمایز، پس‌زمینه PIP یک ویدیوی زنده است: اگر کاربر ریموت فعال باشد\n// استریم آن کاربر نمایش داده می‌شود؛ در غیر این صورت استریم محلی کاربر.\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\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// --- DRAG LOGIC WITH BOUNDARIES & CORNER SNAPPING ---\nconst { width: windowWidth, height: windowHeight } = useWindowSize();\n\nconst PIP_WIDTH = 280; // معادل w-70 در Tailwind\nconst PIP_HEIGHT = 160; // معادل h-40 در Tailwind\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\n// ۱. راه‌اندازی Draggable روی عنصر minimizedRef\nconst { x, y, isDragging } = useDraggable(minimizedRef, {\n initialValue: {\n x:\n typeof window !== \"undefined\"\n ? window.innerWidth - PIP_WIDTH - PADDING\n : PADDING,\n y: PIP_INSET_Y,\n },\n // غیرفعال کردن درگ در صورتی که کامپوننت مینیمایز نباشد\n disabled: computed(() => !callStore.isMinimized),\n});\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\n // پیدا کردن نزدیک‌ترین گوشه بر اساس موقعیت فعلی درگ شده\n const targetX = x.value < windowWidth.value / 2 ? PADDING : maxX;\n const targetY = y.value < windowHeight.value / 2 ? PIP_INSET_Y : maxY;\n\n x.value = targetX;\n y.value = targetY;\n }\n});\n\n// بازنشانی موقعیت به گوشه مناسب در هنگام مینیمایز شدن مجدد\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// ۳. محدود کردن مختصات در محدوده مانیتور و خروجی استایل\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 const safeX = Math.max(PADDING, Math.min(x.value, maxX));\n const safeY = Math.max(PADDING, Math.min(y.value, maxY));\n\n return {\n left: `${safeX}px`,\n top: `${safeY}px`,\n };\n});\n</script>\n\n<template>\n <!-- استفاده از div معمولی به جای motion.div و اعمال پوزیشن با clampedStyle -->\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 w-70 h-40 bg-black-600 rounded-2xl shadow-floating z-9999 overflow-hidden border border-white/10 flex flex-col items-center justify-center cursor-move touch-none\"\n :class=\"[!isDragging ? 'transition-all duration-300 ease-out' : '']\"\n >\n <video\n ref=\"pipVideoRef\"\n muted\n autoplay\n playsinline\n class=\"pointer-events-none absolute inset-0 z-0 h-full w-full object-cover\"\n />\n <div\n class=\"pointer-events-none absolute inset-0 bg-gradient-to-br from-blue-500/5 via-purple-500/5 to-pink-500/5 opacity-0 transition-opacity duration-500 group-hover:opacity-100\"\n />\n <div\n class=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-black/20\"\n />\n\n <div class=\"relative h-full w-full\">\n <div\n class=\"absolute top-3 right-3 left-3 z-10 flex items-center justify-between\"\n >\n <div\n class=\"flex items-center gap-x-2 rounded-full bg-black/40 px-3 py-1.5 backdrop-blur-sm\"\n >\n <div class=\"relative\">\n <div\n class=\"h-2.5 w-2.5 animate-pulse rounded-full bg-diamond-error\"\n />\n <div\n class=\"absolute inset-0 h-2.5 w-2.5 animate-ping rounded-full bg-diamond-error/30\"\n />\n </div>\n <span class=\"text-label-sm text-white/90 select-none\">{{\n t(\"chat.call.active\")\n }}</span>\n <div class=\"flex -space-x-1\">\n <div\n class=\"h-1.5 w-1.5 animate-pulse rounded-full bg-green-400\"\n style=\"animation-delay: 0s\"\n />\n <div\n class=\"h-1.5 w-1.5 animate-pulse rounded-full bg-green-400\"\n style=\"animation-delay: 0.2s\"\n />\n <div\n class=\"h-1.5 w-1.5 animate-pulse rounded-full bg-green-400\"\n style=\"animation-delay: 0.4s\"\n />\n </div>\n </div>\n\n <IconButton\n icon=\"PhPhoneX\"\n :label=\"t('chat.call.controls.endCall')\"\n severity=\"danger\"\n :text=\"false\"\n icon-class=\"size-4\"\n data-testid=\"call-pip-end\"\n @pointerdown.stop\n @click.stop=\"endCall\"\n />\n </div>\n\n <div\n class=\"absolute right-3 bottom-3 left-3 z-10 flex items-center justify-between\"\n >\n <div class=\"flex items-center gap-2\">\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 @pointerdown.stop\n @click.stop=\"cycleRemote\"\n >\n <template #icon>\n <BIcon icon=\"PhUsers\" class=\"size-3\" />\n </template>\n </Button>\n\n <div v-if=\"!isAudioOn || !isVideoOn\" class=\"flex gap-1\">\n <div\n v-if=\"!isAudioOn\"\n class=\"flex h-7 w-7 items-center justify-center rounded-full bg-diamond-error\"\n >\n <BIcon icon=\"PhMicrophoneSlash\" class=\"h-3 w-3 fill-white\" />\n </div>\n <div\n v-if=\"!isVideoOn\"\n class=\"flex h-7 w-7 items-center justify-center rounded-full bg-diamond-error\"\n >\n <BIcon icon=\"PhVideoCameraSlash\" class=\"h-3 w-3 fill-white\" />\n </div>\n </div>\n </div>\n\n <IconButton\n icon=\"PhResize\"\n :label=\"t('chat.call.controls.maximize')\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n data-testid=\"call-maximize\"\n @pointerdown.stop\n @click.stop=\"callStore.maximize()\"\n />\n </div>\n </div>\n </div>\n\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 h-full w-full flex-col bg-diamond-black\"\n >\n <!-- Header -->\n <div\n v-if=\"!callStore.isMinimized\"\n class=\"flex h-16 items-center justify-between px-4 transition-all duration-300 sm:h-20\"\n :class=\"showControls ? 'opacity-100' : 'opacity-0'\"\n @mouseenter=\"resetControlsTimeout\"\n @mousemove=\"resetControlsTimeout\"\n >\n <div class=\"flex items-center gap-x-4\">\n <div class=\"hidden select-none text-label-lg text-white md:block\">\n {{ callTitle }}\n </div>\n <div class=\"flex items-center gap-x-2 text-white text-body-sm\">\n <BIcon icon=\"PhUsers\" class=\"h-4 w-4 fill-white\" />\n <span data-testid=\"call-participants\"\n>{{ t(\"chat.call.participants\", participantCount) }}</span>\n </div>\n </div>\n <div class=\"flex items-center gap-x-4.5\">\n <div\n dir=\"ltr\"\n class=\"flex h-6 items-center justify-center rounded-full bg-white/15 px-2.5 text-body-sm text-white tabular-nums select-none\"\n >\n {{ formatDuration(callStore.elapsedTime) }}\n </div>\n <IconButton\n icon=\"PhCaretDown\"\n :label=\"t('chat.call.controls.minimize')\"\n v-bind=\"footerButton\"\n data-testid=\"call-minimize\"\n @click=\"callStore.minimize\"\n />\n </div>\n </div>\n\n <!-- Main Content -->\n <div\n class=\"relative grid w-full overflow-hidden\"\n :class=\"callStore.isMinimized ? 'h-full p-0' : 'h-full p-4'\"\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=\"secondary\"\n rounded\n data-testid=\"call-enable-sound\"\n class=\"absolute! top-6 left-1/2 z-30 -translate-x-1/2\"\n @click=\"enableSound\"\n >\n <template #icon>\n <BIcon icon=\"PhSpeakerHigh\" class=\"size-4\" />\n </template>\n </Button>\n <div\n v-show=\"tileCount\"\n class=\"grid h-full min-h-0 w-full min-w-0 grid-cols-1 gap-4 md:grid-cols-[repeat(auto-fit,minmax(300px,1fr))]\"\n >\n <div\n v-show=\"isScreenSharing\"\n :ref=\"(el) => (remoteParents[`self_screen`] = el as any)\"\n class=\"group relative flex aspect-video h-full w-full flex-col items-center justify-center overflow-hidden rounded-2xl border-2 border-chat-primary/0 bg-black-600 p-2\"\n >\n <video\n ref=\"localScreen\"\n autoplay\n muted\n playsinline\n class=\"absolute inset-0 z-0 h-full w-full object-cover\"\n />\n\n <div class=\"absolute bottom-3 left-3 z-20 flex items-center gap-x-2\">\n <div\n class=\"rounded bg-black-500 px-2 py-1 text-label-sm text-white select-none\"\n >\n {{ t(\"chat.call.yourPresentation\") }}\n </div>\n <div\n class=\"flex h-10 w-10 items-center justify-center rounded-full bg-black-500\"\n >\n <BIcon icon=\"PhMonitor\" class=\"h-4 w-4 fill-white\" />\n </div>\n <IconButton\n :icon=\"videoPaused['self_screen'] ? 'PhPlay' : 'PhPause'\"\n :label=\"videoPaused['self_screen'] ? t('chat.call.controls.playVideo') : t('chat.call.controls.pauseVideo')\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"toggleVideoPause('self_screen', localScreen as any)\"\n />\n <IconButton\n :icon=\"isFullscreen ? 'PhCornersIn' : 'PhFrameCorners'\"\n :label=\"\n\n isFullscreen\n\n ? t('chat.call.controls.exitFullscreen')\n\n : t('chat.call.controls.fullscreen')\n\n \"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"toggleRemote(`self_screen`)\"\n />\n </div>\n </div>\n <div\n v-for=\"(stream, remoteUserId) in remoteVideos\"\n :key=\"`remote-${remoteUserId}`\"\n data-testid=\"call-remote-video\"\n :ref=\"\n (el) => (remoteParents[`remote_video_${remoteUserId}`] = el as any)\n \"\n class=\"group relative flex aspect-video h-full w-full flex-col items-center justify-center overflow-hidden rounded-2xl border-2 border-chat-primary/0 bg-black-600 p-2\"\n >\n <video\n :ref=\"\n (el) => {\n if (el) remoteRefs[remoteUserId] = el as any;\n }\n \"\n autoplay\n playsinline\n class=\"absolute inset-0 z-0 h-full w-full object-cover\"\n />\n\n <div class=\"absolute bottom-2 left-2 z-20 flex items-center gap-x-1\">\n <div\n class=\"rounded bg-black-500 px-1.5 py-0.5 text-label-sm text-white select-none\"\n >\n {{ stream.name.slice(0, 15) }}\n </div>\n <IconButton\n :icon=\"videoPaused[`remote_video_${remoteUserId}`] ? 'PhPlay' : 'PhPause'\"\n :label=\"\n videoPaused[`remote_video_${remoteUserId}`]\n ? t('chat.call.controls.playVideo')\n : t('chat.call.controls.pauseVideo')\n \"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"\n toggleVideoPause(\n `remote_video_${remoteUserId}`,\n remoteRefs[remoteUserId] as any,\n )\n \"\n />\n <IconButton\n :icon=\"isFullscreen ? 'PhCornersIn' : 'PhFrameCorners'\"\n :label=\"\n\n isFullscreen\n\n ? t('chat.call.controls.exitFullscreen')\n\n : t('chat.call.controls.fullscreen')\n\n \"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"toggleRemote(`remote_video_${remoteUserId}`)\"\n />\n </div>\n </div>\n\n <div\n v-for=\"(stream, remoteUserId) in remoteScreens\"\n :key=\"`remote-screen-${remoteUserId}`\"\n data-testid=\"call-remote-screen\"\n :ref=\"\n (el) => (remoteParents[`remote_screen_${remoteUserId}`] = el as any)\n \"\n class=\"group relative flex aspect-video h-full w-full flex-col items-center justify-center overflow-hidden rounded-2xl border-2 border-chat-primary/0 bg-black-600 p-2\"\n >\n <video\n :ref=\"\n (el) => {\n if (el) remoteScreenRefs[remoteUserId] = el as any;\n }\n \"\n autoplay\n muted\n playsinline\n class=\"absolute inset-0 z-0 h-full w-full object-cover\"\n />\n\n <div class=\"absolute bottom-3 left-3 z-20 flex items-center gap-x-2\">\n <div\n class=\"rounded bg-black-500 px-2 py-1 text-label-sm text-white select-none\"\n >\n {{ t(\"chat.call.presentationOf\", { name: stream.name.slice(0, 15) }) }}\n </div>\n <div\n class=\"flex h-10 w-10 items-center justify-center rounded-full bg-black-500\"\n >\n <BIcon icon=\"PhMonitor\" class=\"h-4 w-4 fill-white\" />\n </div>\n <IconButton\n :icon=\"videoPaused[`remote_screen_${remoteUserId}`] ? 'PhPlay' : 'PhPause'\"\n :label=\"\n videoPaused[`remote_screen_${remoteUserId}`]\n ? t('chat.call.controls.playVideo')\n : t('chat.call.controls.pauseVideo')\n \"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"\n toggleVideoPause(\n `remote_screen_${remoteUserId}`,\n remoteScreenRefs[remoteUserId] || null,\n )\n \"\n />\n <IconButton\n :icon=\"isFullscreen ? 'PhCornersIn' : 'PhFrameCorners'\"\n :label=\"\n\n isFullscreen\n\n ? t('chat.call.controls.exitFullscreen')\n\n : t('chat.call.controls.fullscreen')\n\n \"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"toggleRemote(`remote_screen_${remoteUserId}`)\"\n />\n </div>\n </div>\n </div>\n\n <!-- وب‌کم محلی (وقتی هنوز کارهای دیگر در صفحه فعال است) -->\n <div class=\"flex min-h-0\" :class=\"[tileCount && 'absolute inset-0 m-4']\">\n <div\n v-if=\"!callStore.isMinimized\"\n class=\"relative flex flex-col items-center justify-center overflow-hidden rounded-2xl border-2 border-chat-primary/0 bg-black-600 p-2\"\n :class=\"[\n tileCount ? 'absolute z-10 h-[132px] w-[236px]' : 'h-full w-full',\n ]\"\n >\n <video\n ref=\"localVideo\"\n data-testid=\"call-local-video\"\n autoplay\n muted\n playsinline\n class=\"pointer-events-none absolute inset-0 z-0 h-full w-full object-cover\"\n />\n\n <div\n class=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent\"\n />\n\n <div class=\"absolute bottom-3 left-3 z-20 flex items-center gap-x-2\">\n <div\n class=\"rounded bg-black-500 px-2 py-1 text-label-sm text-white select-none\"\n >\n {{ t(\"chat.call.you\") }}\n </div>\n <div\n v-if=\"!isAudioOn\"\n class=\"flex h-7 w-7 items-center justify-center rounded-full bg-diamond-error\"\n >\n <BIcon icon=\"PhMicrophoneSlash\" class=\"h-3 w-3 fill-white\" />\n </div>\n <IconButton\n :icon=\"videoPaused['self_cam'] ? 'PhPlay' : 'PhPause'\"\n :label=\"videoPaused['self_cam'] ? t('chat.call.controls.playVideo') : t('chat.call.controls.pauseVideo')\"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"toggleVideoPause('self_cam', localVideo as any)\"\n />\n <IconButton\n :icon=\"isFullscreen ? 'PhCornersIn' : 'PhFrameCorners'\"\n :label=\"\n\n isFullscreen\n\n ? t('chat.call.controls.exitFullscreen')\n\n : t('chat.call.controls.fullscreen')\n\n \"\n :dt=\"callButtonDt\"\n :text=\"false\"\n icon-class=\"size-4\"\n @click=\"toggleRemote('self_cam')\"\n />\n </div>\n\n <div\n v-if=\"!isVideoOn\"\n class=\"absolute inset-0 flex items-center justify-center bg-black-600\"\n >\n <div class=\"text-center text-white\">\n <div\n class=\"mx-auto mb-2 flex h-16 w-16 items-center justify-center rounded-full bg-chat-primary\"\n >\n <span class=\"text-title-lg font-semibold\">{{ t(\"chat.call.you\") }}</span>\n </div>\n <p class=\"text-label-md\">{{ t(\"chat.call.cameraIsOff\") }}</p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer Controls -->\n <div\n v-if=\"!callStore.isMinimized\"\n class=\"flex h-21 w-full items-center justify-center gap-x-1.5 border-t border-t-[#2C2C2E] bg-black-600 transition-all duration-300 sm:gap-x-3\"\n :class=\"showControls ? 'opacity-100' : 'opacity-0'\"\n @mouseenter=\"resetControlsTimeout\"\n @mousemove=\"resetControlsTimeout\"\n >\n <IconButton\n :icon=\"isAudioOn ? 'PhMicrophone' : 'PhMicrophoneSlash'\"\n :label=\"isAudioOn ? t('chat.call.controls.mute') : t('chat.call.controls.unmute')\"\n :severity=\"isAudioOn ? 'secondary' : 'contrast'\"\n v-bind=\"footerButton\"\n data-testid=\"call-toggle-audio\"\n :data-active=\"isAudioOn\"\n @click=\"toggleAudio\"\n />\n\n <IconButton\n :icon=\"isVideoOn ? 'PhVideo' : 'PhVideoCameraSlash'\"\n :label=\"isVideoOn ? t('chat.call.controls.cameraOff') : t('chat.call.controls.cameraOn')\"\n :severity=\"isVideoOn ? 'secondary' : 'contrast'\"\n v-bind=\"footerButton\"\n data-testid=\"call-toggle-video\"\n :data-active=\"isVideoOn\"\n @click=\"toggleVideo\"\n />\n\n <template v-if=\"cameras.length > 1\">\n <IconButton\n icon=\"PhCaretUp\"\n :label=\"t('chat.call.controls.chooseCamera')\"\n v-bind=\"footerButton\"\n @click=\"cameraPickerOpen = true\"\n />\n <ResponsiveDialog\n v-model:visible=\"cameraPickerOpen\"\n :header=\"t('chat.call.controls.cameras')\"\n width=\"24rem\"\n >\n <Listbox\n :options=\"cameras\"\n option-value=\"deviceId\"\n :option-label=\"(camera: MediaDeviceInfo) => camera.label || `Camera ${camera.deviceId}`\"\n class=\"w-full\"\n @change=\"(event) => pickCamera(event.value)\"\n />\n </ResponsiveDialog>\n </template>\n\n <IconButton\n icon=\"PhMonitorArrowUp\"\n :label=\"isScreenSharing ? t('chat.call.controls.stopSharing') : t('chat.call.controls.shareScreen')\"\n :severity=\"isScreenSharing ? 'contrast' : 'secondary'\"\n v-bind=\"footerButton\"\n data-testid=\"call-toggle-screen\"\n :data-active=\"isScreenSharing\"\n @click=\"toggleScreenShare\"\n />\n\n <IconButton\n :icon=\"isFullscreen ? 'PhCornersIn' : 'PhFrameCorners'\"\n :label=\"\n\n isFullscreen\n\n ? t('chat.call.controls.exitFullscreen')\n\n : t('chat.call.controls.fullscreen')\n\n \"\n v-bind=\"footerButton\"\n @click=\"toggleFullscreen\"\n />\n\n <IconButton\n v-if=\"isFlashlightSupported\"\n :icon=\"isFlashlightOn ? 'PhLightning' : 'PhLightningSlash'\"\n :label=\"t('chat.call.controls.flashlight')\"\n :severity=\"isFlashlightOn ? 'contrast' : 'secondary'\"\n v-bind=\"footerButton\"\n @click=\"toggleFlashlight\"\n />\n\n <IconButton\n icon=\"PhPhoneX\"\n :label=\"t('chat.call.controls.endCall')\"\n severity=\"danger\"\n :text=\"false\"\n size=\"large\"\n icon-class=\"size-6\"\n data-testid=\"call-end\"\n @click=\"endCall\"\n />\n </div>\n </div>\n</template>\n"],"names":["_unref","_createElementBlock","_normalizeClass","_createElementVNode","_toDisplayString","_createVNode","IconButton","_openBlock","_withModifiers","_mergeProps","_createBlock","_withDirectives","_Fragment","_renderList","ResponsiveDialog","_vShow"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("./index-DrcpfLUy.cjs");
3
+ const index = require("./index-DwJwSnRN.cjs");
4
4
  const vue = require("vue");
5
5
  const core = require("@vueuse/core");
6
6
  const Button = require("primevue/button");
@@ -55,11 +55,29 @@ function useCallUi(opts) {
55
55
  else el.pause();
56
56
  videoPaused.value[tileId] = !videoPaused.value[tileId];
57
57
  }
58
+ const soundBlocked = vue.ref(false);
59
+ async function play(el) {
60
+ try {
61
+ await el.play();
62
+ } catch (err) {
63
+ if ((err == null ? void 0 : err.name) !== "NotAllowedError" || el.muted) return;
64
+ el.muted = true;
65
+ soundBlocked.value = true;
66
+ await el.play().catch((e) => console.error("[vue-chat] Remote video can't play:", e));
67
+ }
68
+ }
69
+ function enableSound() {
70
+ soundBlocked.value = false;
71
+ for (const el of Object.values(remoteRefs.value)) {
72
+ if (!el) continue;
73
+ el.muted = false;
74
+ void play(el);
75
+ }
76
+ }
58
77
  const attach = (el, stream) => {
59
78
  if (!el) return;
60
79
  if (el.srcObject !== stream) el.srcObject = stream;
61
- el.play().catch(() => {
62
- });
80
+ void play(el);
63
81
  };
64
82
  vue.watch(
65
83
  [localStream, opts.isMinimized],
@@ -118,6 +136,8 @@ function useCallUi(opts) {
118
136
  toggleRemote,
119
137
  videoPaused,
120
138
  toggleVideoPause,
139
+ soundBlocked,
140
+ enableSound,
121
141
  detachAll
122
142
  };
123
143
  }
@@ -167,6 +187,8 @@ function useCall() {
167
187
  toggleFullscreen: ui.toggleFullscreen,
168
188
  toggleRemote: ui.toggleRemote,
169
189
  videoPaused: ui.videoPaused,
190
+ soundBlocked: ui.soundBlocked,
191
+ enableSound: ui.enableSound,
170
192
  toggleVideoPause: ui.toggleVideoPause,
171
193
  localVideo: ui.localVideo,
172
194
  localScreen: ui.localScreen,
@@ -175,35 +197,35 @@ function useCall() {
175
197
  remoteParents: ui.remoteParents
176
198
  };
177
199
  }
178
- const _hoisted_1 = { class: "relative h-full w-full" };
179
- const _hoisted_2 = { class: "absolute top-3 right-3 left-3 z-10 flex items-center justify-between" };
180
- const _hoisted_3 = { class: "flex items-center gap-x-2 rounded-full bg-black/40 px-3 py-1.5 backdrop-blur-sm" };
181
- const _hoisted_4 = { class: "text-label-sm text-white/90 select-none" };
182
- const _hoisted_5 = { class: "absolute right-3 bottom-3 left-3 z-10 flex items-center justify-between" };
183
- const _hoisted_6 = { class: "flex items-center gap-2" };
184
- const _hoisted_7 = {
200
+ const _hoisted_1 = ["dir"];
201
+ const _hoisted_2 = { class: "relative h-full w-full" };
202
+ const _hoisted_3 = { class: "absolute top-3 right-3 left-3 z-10 flex items-center justify-between" };
203
+ const _hoisted_4 = { class: "flex items-center gap-x-2 rounded-full bg-black/40 px-3 py-1.5 backdrop-blur-sm" };
204
+ const _hoisted_5 = { class: "text-label-sm text-white/90 select-none" };
205
+ const _hoisted_6 = { class: "absolute right-3 bottom-3 left-3 z-10 flex items-center justify-between" };
206
+ const _hoisted_7 = { class: "flex items-center gap-2" };
207
+ const _hoisted_8 = {
185
208
  key: 0,
186
209
  class: "flex gap-1"
187
210
  };
188
- const _hoisted_8 = {
211
+ const _hoisted_9 = {
189
212
  key: 0,
190
213
  class: "flex h-7 w-7 items-center justify-center rounded-full bg-diamond-error"
191
214
  };
192
- const _hoisted_9 = {
215
+ const _hoisted_10 = {
193
216
  key: 1,
194
217
  class: "flex h-7 w-7 items-center justify-center rounded-full bg-diamond-error"
195
218
  };
196
- const _hoisted_10 = {
197
- "data-testid": "call-view",
198
- class: "vue-chat fixed inset-0 z-[60] flex h-full w-full flex-col bg-diamond-black"
219
+ const _hoisted_11 = ["dir"];
220
+ const _hoisted_12 = { class: "flex items-center gap-x-4" };
221
+ const _hoisted_13 = { class: "hidden select-none text-label-lg text-white md:block" };
222
+ const _hoisted_14 = { class: "flex items-center gap-x-2 text-white text-body-sm" };
223
+ const _hoisted_15 = { "data-testid": "call-participants" };
224
+ const _hoisted_16 = { class: "flex items-center gap-x-4.5" };
225
+ const _hoisted_17 = {
226
+ dir: "ltr",
227
+ class: "flex h-6 items-center justify-center rounded-full bg-white/15 px-2.5 text-body-sm text-white tabular-nums select-none"
199
228
  };
200
- const _hoisted_11 = { class: "flex items-center gap-x-4" };
201
- const _hoisted_12 = { class: "hidden select-none text-label-lg text-white md:block" };
202
- const _hoisted_13 = { class: "flex items-center gap-x-2 text-white text-body-sm" };
203
- const _hoisted_14 = { "data-testid": "call-participants" };
204
- const _hoisted_15 = { class: "flex items-center gap-x-4.5" };
205
- const _hoisted_16 = { class: "flex h-6 items-center justify-center rounded-full bg-diamond-error px-2 text-white select-none" };
206
- const _hoisted_17 = { class: "text-body-sm" };
207
229
  const _hoisted_18 = { class: "grid h-full min-h-0 w-full min-w-0 grid-cols-1 gap-4 md:grid-cols-[repeat(auto-fit,minmax(300px,1fr))]" };
208
230
  const _hoisted_19 = { class: "absolute bottom-3 left-3 z-20 flex items-center gap-x-2" };
209
231
  const _hoisted_20 = { class: "rounded bg-black-500 px-2 py-1 text-label-sm text-white select-none" };
@@ -230,6 +252,7 @@ const _hoisted_34 = { class: "text-label-md" };
230
252
  const PIP_WIDTH = 280;
231
253
  const PIP_HEIGHT = 160;
232
254
  const PADDING = 16;
255
+ const PIP_INSET_Y = 96;
233
256
  const _sfc_main = /* @__PURE__ */ vue.defineComponent({
234
257
  __name: "Call",
235
258
  setup(__props) {
@@ -237,8 +260,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
237
260
  const minimizedRef = vue.ref(null);
238
261
  const bodyRef = vue.ref(null);
239
262
  const cameraPickerOpen = vue.ref(false);
240
- const { t, locale } = index.useLocalI18n(index.chat);
263
+ const { t } = index.useLocalI18n(index.chat);
241
264
  const { dir } = index.useDirection();
265
+ const chatStore = index.useChatStore();
266
+ const callTitle = vue.computed(() => {
267
+ const contact = callStore.channelId ? chatStore.getContactById(callStore.channelId) : null;
268
+ const name = contact ? `${contact.name} ${contact.lastName ?? ""}`.trim() : "";
269
+ return name || t("chat.call.title");
270
+ });
242
271
  const {
243
272
  toggleVideoPause,
244
273
  toggleRemote,
@@ -268,7 +297,9 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
268
297
  remoteRefs,
269
298
  remoteScreens,
270
299
  remoteScreenRefs,
271
- remoteVideos
300
+ remoteVideos,
301
+ soundBlocked,
302
+ enableSound
272
303
  } = useCall();
273
304
  const pickCamera = (deviceId) => {
274
305
  cameraPickerOpen.value = false;
@@ -350,7 +381,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
350
381
  const { x, y, isDragging } = core.useDraggable(minimizedRef, {
351
382
  initialValue: {
352
383
  x: typeof window !== "undefined" ? window.innerWidth - PIP_WIDTH - PADDING : PADDING,
353
- y: typeof window !== "undefined" ? window.innerHeight - PIP_HEIGHT - PADDING : PADDING
384
+ y: PIP_INSET_Y
354
385
  },
355
386
  // غیرفعال کردن درگ در صورتی که کامپوننت مینیمایز نباشد
356
387
  disabled: vue.computed(() => !callStore.isMinimized)
@@ -358,10 +389,9 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
358
389
  vue.watch(isDragging, (dragging) => {
359
390
  if (!dragging && callStore.isMinimized) {
360
391
  const maxX = windowWidth.value - PIP_WIDTH - PADDING;
361
- const maxY = windowHeight.value - PIP_HEIGHT - PADDING;
362
- dir.value === "rtl";
392
+ const maxY = windowHeight.value - PIP_HEIGHT - PIP_INSET_Y;
363
393
  const targetX = x.value < windowWidth.value / 2 ? PADDING : maxX;
364
- const targetY = y.value < windowHeight.value / 2 ? PADDING : maxY;
394
+ const targetY = y.value < windowHeight.value / 2 ? PIP_INSET_Y : maxY;
365
395
  x.value = targetX;
366
396
  y.value = targetY;
367
397
  }
@@ -373,7 +403,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
373
403
  vue.nextTick(() => {
374
404
  const isRtl = dir.value === "rtl";
375
405
  x.value = isRtl ? PADDING : windowWidth.value - PIP_WIDTH - PADDING;
376
- y.value = windowHeight.value - PIP_HEIGHT - PADDING;
406
+ y.value = PIP_INSET_Y;
377
407
  });
378
408
  }
379
409
  },
@@ -399,7 +429,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
399
429
  ref: minimizedRef,
400
430
  "data-testid": "call-pip",
401
431
  style: vue.normalizeStyle(clampedStyle.value),
402
- class: vue.normalizeClass(["vue-chat fixed w-70 h-40 bg-black-600 rounded-2xl shadow-floating z-9999 overflow-hidden border border-white/10 flex flex-col items-center justify-center cursor-move touch-none", [!vue.unref(isDragging) ? "transition-all duration-300 ease-out" : ""]])
432
+ dir: vue.unref(dir),
433
+ class: vue.normalizeClass(["vue-chat font-chat-family fixed w-70 h-40 bg-black-600 rounded-2xl shadow-floating z-9999 overflow-hidden border border-white/10 flex flex-col items-center justify-center cursor-move touch-none", [!vue.unref(isDragging) ? "transition-all duration-300 ease-out" : ""]])
403
434
  }, [
404
435
  vue.createElementVNode("video", {
405
436
  ref_key: "pipVideoRef",
@@ -411,14 +442,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
411
442
  }, null, 512),
412
443
  _cache[18] || (_cache[18] = vue.createElementVNode("div", { class: "pointer-events-none absolute inset-0 bg-gradient-to-br from-blue-500/5 via-purple-500/5 to-pink-500/5 opacity-0 transition-opacity duration-500 group-hover:opacity-100" }, null, -1)),
413
444
  _cache[19] || (_cache[19] = vue.createElementVNode("div", { class: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-black/20" }, null, -1)),
414
- vue.createElementVNode("div", _hoisted_1, [
415
- vue.createElementVNode("div", _hoisted_2, [
416
- vue.createElementVNode("div", _hoisted_3, [
445
+ vue.createElementVNode("div", _hoisted_2, [
446
+ vue.createElementVNode("div", _hoisted_3, [
447
+ vue.createElementVNode("div", _hoisted_4, [
417
448
  _cache[16] || (_cache[16] = vue.createElementVNode("div", { class: "relative" }, [
418
449
  vue.createElementVNode("div", { class: "h-2.5 w-2.5 animate-pulse rounded-full bg-diamond-error" }),
419
450
  vue.createElementVNode("div", { class: "absolute inset-0 h-2.5 w-2.5 animate-ping rounded-full bg-diamond-error/30" })
420
451
  ], -1)),
421
- vue.createElementVNode("span", _hoisted_4, vue.toDisplayString(vue.unref(t)("Call active")), 1),
452
+ vue.createElementVNode("span", _hoisted_5, vue.toDisplayString(vue.unref(t)("chat.call.active")), 1),
422
453
  _cache[17] || (_cache[17] = vue.createElementVNode("div", { class: "flex -space-x-1" }, [
423
454
  vue.createElementVNode("div", {
424
455
  class: "h-1.5 w-1.5 animate-pulse rounded-full bg-green-400",
@@ -446,8 +477,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
446
477
  onClick: vue.withModifiers(vue.unref(endCall), ["stop"])
447
478
  }, null, 8, ["label", "onClick"])
448
479
  ]),
449
- vue.createElementVNode("div", _hoisted_5, [
450
- vue.createElementVNode("div", _hoisted_6, [
480
+ vue.createElementVNode("div", _hoisted_6, [
481
+ vue.createElementVNode("div", _hoisted_7, [
451
482
  vue.createVNode(vue.unref(Button), {
452
483
  label: String(vue.unref(participantCount)),
453
484
  "aria-label": vue.unref(t)("chat.call.controls.nextParticipant"),
@@ -468,14 +499,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
468
499
  ]),
469
500
  _: 1
470
501
  }, 8, ["label", "aria-label", "disabled"]),
471
- !vue.unref(isAudioOn) || !vue.unref(isVideoOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7, [
472
- !vue.unref(isAudioOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8, [
502
+ !vue.unref(isAudioOn) || !vue.unref(isVideoOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8, [
503
+ !vue.unref(isAudioOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_9, [
473
504
  vue.createVNode(_component_BIcon, {
474
505
  icon: "PhMicrophoneSlash",
475
506
  class: "h-3 w-3 fill-white"
476
507
  })
477
508
  ])) : vue.createCommentVNode("", true),
478
- !vue.unref(isVideoOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_9, [
509
+ !vue.unref(isVideoOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_10, [
479
510
  vue.createVNode(_component_BIcon, {
480
511
  icon: "PhVideoCameraSlash",
481
512
  class: "h-3 w-3 fill-white"
@@ -496,8 +527,12 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
496
527
  }, null, 8, ["label"])
497
528
  ])
498
529
  ])
499
- ], 6)) : vue.createCommentVNode("", true),
500
- vue.withDirectives(vue.createElementVNode("div", _hoisted_10, [
530
+ ], 14, _hoisted_1)) : vue.createCommentVNode("", true),
531
+ vue.withDirectives(vue.createElementVNode("div", {
532
+ "data-testid": "call-view",
533
+ dir: vue.unref(dir),
534
+ class: "vue-chat font-chat-family fixed inset-0 z-[60] flex h-full w-full flex-col bg-diamond-black"
535
+ }, [
501
536
  !vue.unref(callStore).isMinimized ? (vue.openBlock(), vue.createElementBlock("div", {
502
537
  key: 0,
503
538
  class: vue.normalizeClass(["flex h-16 items-center justify-between px-4 transition-all duration-300 sm:h-20", vue.unref(showControls) ? "opacity-100" : "opacity-0"]),
@@ -506,24 +541,18 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
506
541
  onMousemove: _cache[5] || (_cache[5] = //@ts-ignore
507
542
  (...args) => vue.unref(resetControlsTimeout) && vue.unref(resetControlsTimeout)(...args))
508
543
  }, [
509
- vue.createElementVNode("div", _hoisted_11, [
510
- vue.createElementVNode("div", _hoisted_12, vue.toDisplayString(vue.unref(t)("Behayand Meeting")), 1),
511
- vue.createElementVNode("div", _hoisted_13, [
544
+ vue.createElementVNode("div", _hoisted_12, [
545
+ vue.createElementVNode("div", _hoisted_13, vue.toDisplayString(callTitle.value), 1),
546
+ vue.createElementVNode("div", _hoisted_14, [
512
547
  vue.createVNode(_component_BIcon, {
513
548
  icon: "PhUsers",
514
549
  class: "h-4 w-4 fill-white"
515
550
  }),
516
- vue.createElementVNode("span", _hoisted_14, vue.toDisplayString(vue.unref(participantCount)) + " " + vue.toDisplayString(vue.unref(participantCount) > 1 ? vue.unref(t)("participants") : vue.unref(t)("participant")), 1)
551
+ vue.createElementVNode("span", _hoisted_15, vue.toDisplayString(vue.unref(t)("chat.call.participants", vue.unref(participantCount))), 1)
517
552
  ])
518
553
  ]),
519
- vue.createElementVNode("div", _hoisted_15, [
520
- vue.createElementVNode("div", _hoisted_16, [
521
- vue.createElementVNode("div", _hoisted_17, vue.toDisplayString((/* @__PURE__ */ new Date()).toLocaleTimeString(vue.unref(locale), {
522
- hour: "2-digit",
523
- minute: "2-digit",
524
- hour12: true
525
- })), 1)
526
- ]),
554
+ vue.createElementVNode("div", _hoisted_16, [
555
+ vue.createElementVNode("div", _hoisted_17, vue.toDisplayString(vue.unref(index.formatDuration)(vue.unref(callStore).elapsedTime)), 1),
527
556
  vue.createVNode(index._sfc_main, vue.mergeProps({
528
557
  icon: "PhCaretDown",
529
558
  label: vue.unref(t)("chat.call.controls.minimize")
@@ -538,6 +567,24 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
538
567
  onMousemove: _cache[10] || (_cache[10] = //@ts-ignore
539
568
  (...args) => vue.unref(resetControlsTimeout) && vue.unref(resetControlsTimeout)(...args))
540
569
  }, [
570
+ vue.unref(soundBlocked) ? (vue.openBlock(), vue.createBlock(vue.unref(Button), {
571
+ key: 0,
572
+ label: vue.unref(t)("chat.call.controls.enableSound"),
573
+ dt: callButtonDt,
574
+ severity: "secondary",
575
+ rounded: "",
576
+ "data-testid": "call-enable-sound",
577
+ class: "absolute! top-6 left-1/2 z-30 -translate-x-1/2",
578
+ onClick: vue.unref(enableSound)
579
+ }, {
580
+ icon: vue.withCtx(() => [
581
+ vue.createVNode(_component_BIcon, {
582
+ icon: "PhSpeakerHigh",
583
+ class: "size-4"
584
+ })
585
+ ]),
586
+ _: 1
587
+ }, 8, ["label", "onClick"])) : vue.createCommentVNode("", true),
541
588
  vue.withDirectives(vue.createElementVNode("div", _hoisted_18, [
542
589
  vue.withDirectives(vue.createElementVNode("div", {
543
590
  ref: (el) => vue.unref(remoteParents)[`self_screen`] = el,
@@ -552,7 +599,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
552
599
  class: "absolute inset-0 z-0 h-full w-full object-cover"
553
600
  }, null, 512),
554
601
  vue.createElementVNode("div", _hoisted_19, [
555
- vue.createElementVNode("div", _hoisted_20, vue.toDisplayString(vue.unref(t)("Your Presentation")), 1),
602
+ vue.createElementVNode("div", _hoisted_20, vue.toDisplayString(vue.unref(t)("chat.call.yourPresentation")), 1),
556
603
  vue.createElementVNode("div", _hoisted_21, [
557
604
  vue.createVNode(_component_BIcon, {
558
605
  icon: "PhMonitor",
@@ -639,7 +686,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
639
686
  class: "absolute inset-0 z-0 h-full w-full object-cover"
640
687
  }, null, 512),
641
688
  vue.createElementVNode("div", _hoisted_24, [
642
- vue.createElementVNode("div", _hoisted_25, vue.toDisplayString(vue.unref(t)("Presentation of")) + " " + vue.toDisplayString(stream.name.slice(0, 15)), 1),
689
+ vue.createElementVNode("div", _hoisted_25, vue.toDisplayString(vue.unref(t)("chat.call.presentationOf", { name: stream.name.slice(0, 15) })), 1),
643
690
  vue.createElementVNode("div", _hoisted_26, [
644
691
  vue.createVNode(_component_BIcon, {
645
692
  icon: "PhMonitor",
@@ -691,7 +738,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
691
738
  }, null, 512),
692
739
  _cache[20] || (_cache[20] = vue.createElementVNode("div", { class: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" }, null, -1)),
693
740
  vue.createElementVNode("div", _hoisted_27, [
694
- vue.createElementVNode("div", _hoisted_28, vue.toDisplayString(vue.unref(t)("You")), 1),
741
+ vue.createElementVNode("div", _hoisted_28, vue.toDisplayString(vue.unref(t)("chat.call.you")), 1),
695
742
  !vue.unref(isAudioOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_29, [
696
743
  vue.createVNode(_component_BIcon, {
697
744
  icon: "PhMicrophoneSlash",
@@ -718,9 +765,9 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
718
765
  !vue.unref(isVideoOn) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_30, [
719
766
  vue.createElementVNode("div", _hoisted_31, [
720
767
  vue.createElementVNode("div", _hoisted_32, [
721
- vue.createElementVNode("span", _hoisted_33, vue.toDisplayString(vue.unref(t)("You")), 1)
768
+ vue.createElementVNode("span", _hoisted_33, vue.toDisplayString(vue.unref(t)("chat.call.you")), 1)
722
769
  ]),
723
- vue.createElementVNode("p", _hoisted_34, vue.toDisplayString(vue.unref(t)("Camera is off")), 1)
770
+ vue.createElementVNode("p", _hoisted_34, vue.toDisplayString(vue.unref(t)("chat.call.cameraIsOff")), 1)
724
771
  ])
725
772
  ])) : vue.createCommentVNode("", true)
726
773
  ], 2)) : vue.createCommentVNode("", true)
@@ -807,7 +854,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
807
854
  onClick: vue.unref(endCall)
808
855
  }, null, 8, ["label", "onClick"])
809
856
  ], 34)) : vue.createCommentVNode("", true)
810
- ], 512), [
857
+ ], 8, _hoisted_11), [
811
858
  [vue.vShow, vue.unref(callStore).isActive && !vue.unref(callStore).isMinimized]
812
859
  ])
813
860
  ], 64);
@@ -815,4 +862,4 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
815
862
  }
816
863
  });
817
864
  exports.default = _sfc_main;
818
- //# sourceMappingURL=Call-D48LfnDv.cjs.map
865
+ //# sourceMappingURL=Call-DF1buv8M.cjs.map