vue-parley 4.1.0 → 4.2.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/README.md +20 -0
- package/dist/chat.css +61 -12
- package/dist/chunks/{Call-9LZHOptu.mjs → Call-7lGaUPcp.mjs} +2 -2
- package/dist/chunks/{Call-9LZHOptu.mjs.map → Call-7lGaUPcp.mjs.map} +1 -1
- package/dist/chunks/{Call-Cke0WQnu.cjs → Call-D48LfnDv.cjs} +2 -2
- package/dist/chunks/{Call-Cke0WQnu.cjs.map → Call-D48LfnDv.cjs.map} +1 -1
- package/dist/chunks/{index-C665OZSn.mjs → index-C8N5eSUe.mjs} +238 -84
- package/dist/chunks/index-C8N5eSUe.mjs.map +1 -0
- package/dist/chunks/{index-B85RXr7I.cjs → index-DrcpfLUy.cjs} +236 -82
- package/dist/chunks/index-DrcpfLUy.cjs.map +1 -0
- package/dist/chunks/{session-DesCGje_.mjs → session-B8Q7eiUV.mjs} +2 -2
- package/dist/chunks/{session-DesCGje_.mjs.map → session-B8Q7eiUV.mjs.map} +1 -1
- package/dist/chunks/{session-D025EMzU.cjs → session-BwgUu6F3.cjs} +2 -2
- package/dist/chunks/{session-D025EMzU.cjs.map → session-BwgUu6F3.cjs.map} +1 -1
- package/dist/fakes.cjs +14 -3
- package/dist/fakes.cjs.map +1 -1
- package/dist/fakes.mjs +14 -3
- package/dist/fakes.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/types/app/components/chat/ChatMessages.vue.d.ts.map +1 -1
- package/dist/types/app/components/chat/chat-bubbles/BubbleOptions.vue.d.ts.map +1 -1
- package/dist/types/app/components/chat/contact/ContactAvatar.vue.d.ts +1 -1
- package/dist/types/app/components/chat/contact/ContactAvatar.vue.d.ts.map +1 -1
- package/dist/types/app/components/global/BIcon.vue.d.ts.map +1 -1
- package/dist/types/app/stores/messageStores.d.ts +11 -2
- package/dist/types/app/stores/messageStores.d.ts.map +1 -1
- package/dist/types/app/types/index.d.ts +24 -2
- package/dist/types/app/types/index.d.ts.map +1 -1
- package/dist/types/fakes/backend.d.ts +6 -1
- package/dist/types/fakes/backend.d.ts.map +1 -1
- package/dist/types/i18n/locales/index.d.ts +6 -0
- package/dist/types/i18n/locales/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/index-B85RXr7I.cjs.map +0 -1
- package/dist/chunks/index-C665OZSn.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Formerly `@yonus_amire01/chat`. To switch, replace that name with `vue-parley` i
|
|
|
19
19
|
- [Nuxt 3 / 4](#nuxt-3--4)
|
|
20
20
|
- [Customising the page](#customising-the-page)
|
|
21
21
|
- [Photos and videos](#photos-and-videos)
|
|
22
|
+
- [Read receipts](#read-receipts)
|
|
22
23
|
- [Calls outside the chat page](#calls-outside-the-chat-page)
|
|
23
24
|
- [Fake backend](#fake-backend)
|
|
24
25
|
- [What `createChat()` does](#what-createchat-does)
|
|
@@ -135,6 +136,25 @@ To build a different layout, use the exported building blocks instead: `ChatList
|
|
|
135
136
|
|
|
136
137
|
A round video note recorded in the chat is different: it is `type: "video"` with `videoUrl`, and plays in its bubble.
|
|
137
138
|
|
|
139
|
+
### Read receipts
|
|
140
|
+
|
|
141
|
+
Your own messages show one tick when sent and two once someone has read them (`isRead`). With a `fetchReaders` handler, the message menu also says **who** read one of your messages: the reader and when in a one-to-one chat, or "Seen by N" opening the list of readers in a group.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
const messages: MessagesHandlers = {
|
|
145
|
+
// …
|
|
146
|
+
// The conversation is open and read up to lastMessageId (when a message is loaded). Called when
|
|
147
|
+
// it opens, and again as messages from others arrive while it is on screen.
|
|
148
|
+
async markRead(conversationId, lastMessageId) {},
|
|
149
|
+
// The other participants who have read one of the viewer's own messages.
|
|
150
|
+
async fetchReaders(message): Promise<MessageReader[]> {
|
|
151
|
+
return [{ id: "u2", name: "Sara", lastName: "Ahmadi", imageUrl: "", readAt: new Date() }];
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`readAt` is when the reader last caught up on the conversation, which a host tracking a per-member "read up to" pointer may only know for the newest message they reached. When a read receipt arrives in real time, call `useMessagesStore().markSeenUpTo(conversationId, messageId)` with the newest loaded message the reader has reached: your messages up to it turn read.
|
|
157
|
+
|
|
138
158
|
### Calls outside the chat page
|
|
139
159
|
|
|
140
160
|
A call belongs to the call store, not to a component, so it keeps running when the chat page unmounts. To keep it **on screen** while the user navigates, render the call view once near the app root and turn off the chat page's own:
|
package/dist/chat.css
CHANGED
|
@@ -951,6 +951,10 @@
|
|
|
951
951
|
max-height: calc(var(--spacing) * 60);
|
|
952
952
|
}
|
|
953
953
|
|
|
954
|
+
:where(.vue-chat, .vue-chat *).max-h-72\! {
|
|
955
|
+
max-height: calc(var(--spacing) * 72) !important;
|
|
956
|
+
}
|
|
957
|
+
|
|
954
958
|
:where(.vue-chat, .vue-chat *).max-h-109 {
|
|
955
959
|
max-height: calc(var(--spacing) * 109);
|
|
956
960
|
}
|
|
@@ -1163,6 +1167,10 @@
|
|
|
1163
1167
|
min-width: calc(var(--spacing) * 20);
|
|
1164
1168
|
}
|
|
1165
1169
|
|
|
1170
|
+
:where(.vue-chat, .vue-chat *).min-w-64\! {
|
|
1171
|
+
min-width: calc(var(--spacing) * 64) !important;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1166
1174
|
:where(.vue-chat, .vue-chat *).flex-1 {
|
|
1167
1175
|
flex: 1;
|
|
1168
1176
|
}
|
|
@@ -1430,6 +1438,10 @@
|
|
|
1430
1438
|
column-gap: calc(var(--spacing) * 2.5);
|
|
1431
1439
|
}
|
|
1432
1440
|
|
|
1441
|
+
:where(.vue-chat, .vue-chat *).gap-x-2\.5\! {
|
|
1442
|
+
column-gap: calc(var(--spacing) * 2.5) !important;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1433
1445
|
:where(.vue-chat, .vue-chat *).gap-x-3 {
|
|
1434
1446
|
column-gap: calc(var(--spacing) * 3);
|
|
1435
1447
|
}
|
|
@@ -1456,6 +1468,12 @@
|
|
|
1456
1468
|
margin-inline-end: calc(calc(var(--spacing) * -1) * calc(1 - var(--tw-space-x-reverse)));
|
|
1457
1469
|
}
|
|
1458
1470
|
|
|
1471
|
+
:where(.vue-chat, .vue-chat *):where(.-space-x-2 > :not(:last-child)) {
|
|
1472
|
+
--tw-space-x-reverse: 0;
|
|
1473
|
+
margin-inline-start: calc(calc(var(--spacing) * -2) * var(--tw-space-x-reverse));
|
|
1474
|
+
margin-inline-end: calc(calc(var(--spacing) * -2) * calc(1 - var(--tw-space-x-reverse)));
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1459
1477
|
:where(.vue-chat, .vue-chat *).gap-y-0\.5 {
|
|
1460
1478
|
row-gap: calc(var(--spacing) * .5);
|
|
1461
1479
|
}
|
|
@@ -1518,6 +1536,10 @@
|
|
|
1518
1536
|
overflow-y: auto;
|
|
1519
1537
|
}
|
|
1520
1538
|
|
|
1539
|
+
:where(.vue-chat, .vue-chat *).overflow-y-auto\! {
|
|
1540
|
+
overflow-y: auto !important;
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1521
1543
|
:where(.vue-chat, .vue-chat *).\!rounded {
|
|
1522
1544
|
border-radius: .25rem !important;
|
|
1523
1545
|
}
|
|
@@ -1600,6 +1622,11 @@
|
|
|
1600
1622
|
border-width: 1px;
|
|
1601
1623
|
}
|
|
1602
1624
|
|
|
1625
|
+
:where(.vue-chat, .vue-chat *).border\! {
|
|
1626
|
+
border-style: var(--tw-border-style) !important;
|
|
1627
|
+
border-width: 1px !important;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1603
1630
|
:where(.vue-chat, .vue-chat *).border-0\! {
|
|
1604
1631
|
border-style: var(--tw-border-style) !important;
|
|
1605
1632
|
border-width: 0 !important;
|
|
@@ -1791,6 +1818,16 @@
|
|
|
1791
1818
|
}
|
|
1792
1819
|
}
|
|
1793
1820
|
|
|
1821
|
+
:where(.vue-chat, .vue-chat *).bg-chat-background\/95\! {
|
|
1822
|
+
background-color: #fffffff2 !important;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1826
|
+
:where(.vue-chat, .vue-chat *).bg-chat-background\/95\! {
|
|
1827
|
+
background-color: color-mix(in oklab, var(--color-chat-background) 95%, transparent) !important;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1794
1831
|
:where(.vue-chat, .vue-chat *).bg-chat-bubble {
|
|
1795
1832
|
background-color: var(--color-chat-bubble);
|
|
1796
1833
|
}
|
|
@@ -2728,6 +2765,10 @@
|
|
|
2728
2765
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
2729
2766
|
}
|
|
2730
2767
|
|
|
2768
|
+
:where(.vue-chat, .vue-chat *).ring-chat-background {
|
|
2769
|
+
--tw-ring-color: var(--color-chat-background);
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2731
2772
|
:where(.vue-chat, .vue-chat *).ring-white {
|
|
2732
2773
|
--tw-ring-color: var(--color-white);
|
|
2733
2774
|
}
|
|
@@ -3229,10 +3270,18 @@
|
|
|
3229
3270
|
rotate: 0deg;
|
|
3230
3271
|
}
|
|
3231
3272
|
|
|
3273
|
+
:where(.vue-chat, .vue-chat *).rtl\:rotate-180:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
|
|
3274
|
+
rotate: 180deg;
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3232
3277
|
:where(.vue-chat, .vue-chat *).rtl\:flex-row\!:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
|
|
3233
3278
|
flex-direction: row !important;
|
|
3234
3279
|
}
|
|
3235
3280
|
|
|
3281
|
+
:where(.vue-chat, .vue-chat *):where(.rtl\:space-x-reverse:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) > :not(:last-child)) {
|
|
3282
|
+
--tw-space-x-reverse: 1;
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3236
3285
|
:where(.vue-chat, .vue-chat *).rtl\:border-l:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
|
|
3237
3286
|
border-left-style: var(--tw-border-style);
|
|
3238
3287
|
border-left-width: 1px;
|
|
@@ -3760,15 +3809,15 @@
|
|
|
3760
3809
|
}
|
|
3761
3810
|
|
|
3762
3811
|
/* Styles remain exactly the same */
|
|
3763
|
-
:where(.vue-chat, .vue-chat *).flip-vertical[data-v-
|
|
3812
|
+
:where(.vue-chat, .vue-chat *).flip-vertical[data-v-01ea74e6] {
|
|
3764
3813
|
transform: scaleY(-1);
|
|
3765
3814
|
will-change: transform;
|
|
3766
3815
|
}
|
|
3767
|
-
:where(.vue-chat, .vue-chat *)[data-index][data-v-
|
|
3816
|
+
:where(.vue-chat, .vue-chat *)[data-index][data-v-01ea74e6] {
|
|
3768
3817
|
will-change: transform;
|
|
3769
3818
|
backface-visibility: hidden;
|
|
3770
3819
|
}
|
|
3771
|
-
@keyframes slide-in-right-
|
|
3820
|
+
@keyframes slide-in-right-01ea74e6 {
|
|
3772
3821
|
0% {
|
|
3773
3822
|
opacity: 0;
|
|
3774
3823
|
transform: scaleY(-1) translateX(30px);
|
|
@@ -3778,7 +3827,7 @@
|
|
|
3778
3827
|
transform: scaleY(-1) translateX(0);
|
|
3779
3828
|
}
|
|
3780
3829
|
}
|
|
3781
|
-
@keyframes slide-in-left-
|
|
3830
|
+
@keyframes slide-in-left-01ea74e6 {
|
|
3782
3831
|
0% {
|
|
3783
3832
|
opacity: 0;
|
|
3784
3833
|
transform: scaleY(-1) translateX(-30px);
|
|
@@ -3788,23 +3837,23 @@
|
|
|
3788
3837
|
transform: scaleY(-1) translateX(0);
|
|
3789
3838
|
}
|
|
3790
3839
|
}
|
|
3791
|
-
:where(.vue-chat, .vue-chat *).animate-slide-right[data-v-
|
|
3792
|
-
animation: slide-in-right-
|
|
3840
|
+
:where(.vue-chat, .vue-chat *).animate-slide-right[data-v-01ea74e6] {
|
|
3841
|
+
animation: slide-in-right-01ea74e6 300ms ease-out forwards;
|
|
3793
3842
|
will-change: transform, opacity;
|
|
3794
3843
|
}
|
|
3795
|
-
:where(.vue-chat, .vue-chat *).animate-slide-left[data-v-
|
|
3796
|
-
animation: slide-in-left-
|
|
3844
|
+
:where(.vue-chat, .vue-chat *).animate-slide-left[data-v-01ea74e6] {
|
|
3845
|
+
animation: slide-in-left-01ea74e6 300ms ease-out forwards;
|
|
3797
3846
|
will-change: transform, opacity;
|
|
3798
3847
|
}
|
|
3799
|
-
:where(.vue-chat, .vue-chat *)#list[data-v-
|
|
3848
|
+
:where(.vue-chat, .vue-chat *)#list[data-v-01ea74e6] {
|
|
3800
3849
|
will-change: padding-top;
|
|
3801
3850
|
}
|
|
3802
|
-
:where(.vue-chat, .vue-chat *).animate-request-in[data-v-
|
|
3803
|
-
animation: request-in-
|
|
3851
|
+
:where(.vue-chat, .vue-chat *).animate-request-in[data-v-01ea74e6] {
|
|
3852
|
+
animation: request-in-01ea74e6 0.4s ease-out forwards;
|
|
3804
3853
|
overflow: hidden;
|
|
3805
3854
|
transform: scaleY(-1);
|
|
3806
3855
|
}
|
|
3807
|
-
@keyframes request-in-
|
|
3856
|
+
@keyframes request-in-01ea74e6 {
|
|
3808
3857
|
0% {
|
|
3809
3858
|
opacity: 0;
|
|
3810
3859
|
max-height: 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as useCallStore, a as useLocalI18n, c as chat, b as useDirection, _ as _sfc_main$1, d as _sfc_main$2, e as _sfc_main$3 } from "./index-
|
|
1
|
+
import { u as useCallStore, a as useLocalI18n, c as chat, b as useDirection, _ as _sfc_main$1, d as _sfc_main$2, e as _sfc_main$3 } from "./index-C8N5eSUe.mjs";
|
|
2
2
|
import { ref, onMounted, onUnmounted, watch, nextTick, defineComponent, computed, openBlock, createElementBlock, Fragment, unref, normalizeClass, normalizeStyle, createElementVNode, toDisplayString, createVNode, withModifiers, withCtx, createCommentVNode, withDirectives, mergeProps, vShow, renderList, createBlock } from "vue";
|
|
3
3
|
import { useWindowSize, useDraggable } from "@vueuse/core";
|
|
4
4
|
import Button from "primevue/button";
|
|
@@ -815,4 +815,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
815
815
|
export {
|
|
816
816
|
_sfc_main as default
|
|
817
817
|
};
|
|
818
|
-
//# sourceMappingURL=Call-
|
|
818
|
+
//# sourceMappingURL=Call-7lGaUPcp.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Call-9LZHOptu.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 const attach = (el: HTMLVideoElement | null | undefined, stream: MediaStream) => {\n if (!el) return;\n if (el.srcObject !== stream) el.srcObject = stream;\n el.play().catch(() => {});\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 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 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 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, locale } = useLocalI18n(chat);\nconst { dir } = useDirection();\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} = 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\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:\n typeof window !== \"undefined\"\n ? window.innerHeight - PIP_HEIGHT - PADDING\n : PADDING,\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 - PADDING;\n\n // جهت RTL روی گوشه پیشفرض اولیه تاثیر میگذارد\n const isRtl = dir.value === \"rtl\";\n\n // پیدا کردن نزدیکترین گوشه بر اساس موقعیت فعلی درگ شده\n const targetX = x.value < windowWidth.value / 2 ? PADDING : maxX;\n const targetY = y.value < windowHeight.value / 2 ? PADDING : 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 y.value = windowHeight.value - PIP_HEIGHT - PADDING;\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 class=\"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\"\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(\"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 class=\"vue-chat 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 {{ t(\"Behayand Meeting\") }}\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 >{{ participantCount }}\n {{\n participantCount > 1 ? t(\"participants\") : t(\"participant\")\n }}</span\n >\n </div>\n </div>\n <div class=\"flex items-center gap-x-4.5\">\n <div\n class=\"flex h-6 items-center justify-center rounded-full bg-diamond-error px-2 text-white select-none\"\n >\n <div class=\"text-body-sm\">\n {{\n new Date().toLocaleTimeString(locale, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: true,\n })\n }}\n </div>\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 <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(\"Your Presentation\") }}\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(\"Presentation of\") }} {{ 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(\"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(\"You\") }}</span>\n </div>\n <p class=\"text-label-md\">{{ t(\"Camera is off\") }}</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","_withDirectives","_mergeProps","_Fragment","_renderList","ResponsiveDialog","_createBlock","_vShow"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Call-7lGaUPcp.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 const attach = (el: HTMLVideoElement | null | undefined, stream: MediaStream) => {\n if (!el) return;\n if (el.srcObject !== stream) el.srcObject = stream;\n el.play().catch(() => {});\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 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 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 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, locale } = useLocalI18n(chat);\nconst { dir } = useDirection();\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} = 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\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:\n typeof window !== \"undefined\"\n ? window.innerHeight - PIP_HEIGHT - PADDING\n : PADDING,\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 - PADDING;\n\n // جهت RTL روی گوشه پیشفرض اولیه تاثیر میگذارد\n const isRtl = dir.value === \"rtl\";\n\n // پیدا کردن نزدیکترین گوشه بر اساس موقعیت فعلی درگ شده\n const targetX = x.value < windowWidth.value / 2 ? PADDING : maxX;\n const targetY = y.value < windowHeight.value / 2 ? PADDING : 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 y.value = windowHeight.value - PIP_HEIGHT - PADDING;\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 class=\"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\"\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(\"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 class=\"vue-chat 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 {{ t(\"Behayand Meeting\") }}\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 >{{ participantCount }}\n {{\n participantCount > 1 ? t(\"participants\") : t(\"participant\")\n }}</span\n >\n </div>\n </div>\n <div class=\"flex items-center gap-x-4.5\">\n <div\n class=\"flex h-6 items-center justify-center rounded-full bg-diamond-error px-2 text-white select-none\"\n >\n <div class=\"text-body-sm\">\n {{\n new Date().toLocaleTimeString(locale, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: true,\n })\n }}\n </div>\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 <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(\"Your Presentation\") }}\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(\"Presentation of\") }} {{ 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(\"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(\"You\") }}</span>\n </div>\n <p class=\"text-label-md\">{{ t(\"Camera is off\") }}</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","_withDirectives","_mergeProps","_Fragment","_renderList","ResponsiveDialog","_createBlock","_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-
|
|
3
|
+
const index = require("./index-DrcpfLUy.cjs");
|
|
4
4
|
const vue = require("vue");
|
|
5
5
|
const core = require("@vueuse/core");
|
|
6
6
|
const Button = require("primevue/button");
|
|
@@ -815,4 +815,4 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
815
815
|
}
|
|
816
816
|
});
|
|
817
817
|
exports.default = _sfc_main;
|
|
818
|
-
//# sourceMappingURL=Call-
|
|
818
|
+
//# sourceMappingURL=Call-D48LfnDv.cjs.map
|