@webitel/ui-sdk 26.4.78 → 26.6.2

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 (89) hide show
  1. package/README.md +10 -0
  2. package/dist/{contacts-eFuSbv3m.js → contacts-DuiejYmg.js} +1551 -802
  3. package/dist/{index-CaY0ocAF.js → index-D_Bvqjjy.js} +1 -1
  4. package/dist/{index-TiiXs7ZO.js → index-ofJZWfBt.js} +1 -1
  5. package/dist/{install-Bd5HfFTV.js → install-rysuPEjF.js} +38 -38
  6. package/dist/{isObject-BV09j4E1.js → isObject-C5JdCKnH.js} +1 -1
  7. package/dist/ui-sdk.css +1 -1
  8. package/dist/ui-sdk.js +1 -1
  9. package/dist/ui-sdk.umd.cjs +187 -188
  10. package/dist/{useVidstackSrc-BGxC2kR5.js → useVidstackSrc-C6hUWIuE.js} +1 -1
  11. package/dist/{vidstack-Bq6c3Bam-jeTFOXk6.js → vidstack-Bq6c3Bam-D6M5GPTI.js} +3 -3
  12. package/dist/{vidstack-D2pY00kU-I-LJsKk8.js → vidstack-D2pY00kU-CRo5Kvyt.js} +3 -3
  13. package/dist/{vidstack-DDXt6fpN-W_Ix9vbH.js → vidstack-DDXt6fpN-QgRuASyL.js} +2 -2
  14. package/dist/{vidstack-D_-9AA6_-27F2Mv_5.js → vidstack-D_-9AA6_-BQB6UUD-.js} +2 -2
  15. package/dist/{vidstack-DqAw8m9J-BxfLqlFs.js → vidstack-DqAw8m9J-0B90hhJB.js} +1 -1
  16. package/dist/{vidstack-audio-CvjDPPuQ.js → vidstack-audio-BML-tyCz.js} +2 -2
  17. package/dist/{vidstack-dash-rV4ryZh2.js → vidstack-dash-BwVTHD5j.js} +4 -4
  18. package/dist/{vidstack-google-cast-Cb8t34m4.js → vidstack-google-cast-CvoUE_Qj.js} +4 -4
  19. package/dist/{vidstack-hls-C2zZ7COz.js → vidstack-hls-BgbWYqKl.js} +4 -4
  20. package/dist/{vidstack-video-DzItbHtm.js → vidstack-video-D6tVAa-p.js} +3 -3
  21. package/dist/{vidstack-vimeo-BpKsHwp4.js → vidstack-vimeo-CMino7JB.js} +4 -4
  22. package/dist/{vidstack-youtube--6zpNJz6.js → vidstack-youtube-DLE3pyNu.js} +3 -3
  23. package/dist/{wt-action-bar-Df57KUsc.js → wt-action-bar-BwAQUnPp.js} +1 -1
  24. package/dist/{wt-button-select-ymdOC5NH.js → wt-button-select-D8-D18E4.js} +1 -1
  25. package/dist/{wt-call-media-action-D4CP3oZl.js → wt-call-media-action-B-AEoxjt.js} +1 -1
  26. package/dist/{wt-chat-emoji-CUjHxdzV.js → wt-chat-emoji-D_4QMhH7.js} +2 -2
  27. package/dist/{wt-confirm-dialog-CNwpPdgE.js → wt-confirm-dialog-BQVImEga.js} +1 -1
  28. package/dist/{wt-context-menu-CToKHamf.js → wt-context-menu-CfvdB5Xl.js} +1 -1
  29. package/dist/{wt-copy-action-Dd0tVB7g.js → wt-copy-action-CIa3ImHz.js} +1 -1
  30. package/dist/{wt-datepicker-B7sKwJlh.js → wt-datepicker-CEoYduIo.js} +1 -1
  31. package/dist/{wt-display-chip-items-IGBh7VMV.js → wt-display-chip-items-CD6E8917.js} +1 -1
  32. package/dist/{wt-dual-panel-CqN6YB0F.js → wt-dual-panel-Cm2oe8sF.js} +1 -1
  33. package/dist/{wt-dummy-OrcannPM.js → wt-dummy-DHdJccrG.js} +1 -1
  34. package/dist/{wt-error-page-BMpoQdQl.js → wt-error-page-Rt-F9oVv.js} +1 -1
  35. package/dist/{wt-expansion-card-DEDM3Znr.js → wt-expansion-card-v7GFQBoJ.js} +1 -1
  36. package/dist/{wt-expansion-panel-YCSPf-eq.js → wt-expansion-panel-DSsY-KFR.js} +1 -1
  37. package/dist/{wt-filters-panel-wrapper-Ck2bF7qg.js → wt-filters-panel-wrapper-Cr9dYYnT.js} +1 -1
  38. package/dist/{wt-galleria-CNDkujRu.js → wt-galleria-C2aburQk.js} +1 -1
  39. package/dist/{wt-inline-add-panel-BSEdS7eW.js → wt-inline-add-panel-BaDP2TC1.js} +1 -1
  40. package/dist/{wt-navigation-menu-igJBYaxO.js → wt-navigation-menu-B_R8-_Bk.js} +1 -1
  41. package/dist/{wt-notifications-bar-C0M5LC4G.js → wt-notifications-bar-CfoCOojR.js} +2 -2
  42. package/dist/{wt-pagination-BXDqQ9YV.js → wt-pagination-DW7KL87c.js} +1 -1
  43. package/dist/{wt-player-A13mN2qk.js → wt-player-Be2YAJcQ.js} +2 -2
  44. package/dist/{wt-screen-recordings-action-BQPS--RV.js → wt-screen-recordings-action-BJBx9KXM.js} +1 -1
  45. package/dist/{wt-search-bar-Cvt_urUF.js → wt-search-bar-BT5d_LDB.js} +1 -1
  46. package/dist/{wt-selection-popup-CcAfc6T6.js → wt-selection-popup-DK6oLjfk.js} +1 -1
  47. package/dist/{wt-send-message-popup-pN9zzJpT.js → wt-send-message-popup-C8oG1Kxc.js} +3 -3
  48. package/dist/{wt-start-page-DaotE9Vi.js → wt-start-page-BcV-IdG_.js} +1 -1
  49. package/dist/{wt-status-select-Dhw-c6FB.js → wt-status-select-BcrdWJ9m.js} +1 -1
  50. package/dist/{wt-stepper-DyM6hf_l.js → wt-stepper-B_ny-IQN.js} +1 -1
  51. package/dist/{wt-table-Do6tizZl.js → wt-table-BX5kDXje.js} +1 -1
  52. package/dist/{wt-table-actions-Stm_KC06.js → wt-table-actions-Cvk2_NUG.js} +1 -1
  53. package/dist/{wt-table-column-select-DaGMSlL1.js → wt-table-column-select-CPacgsbN.js} +2 -2
  54. package/dist/{wt-tabs-CTv4GgX8.js → wt-tabs-wcnQfMfj.js} +1 -1
  55. package/dist/{wt-tags-input-DJhQrEdL.js → wt-tags-input-CPO80nnI.js} +2 -2
  56. package/dist/{wt-timepicker-98DhU-ME.js → wt-timepicker-DbdcOXYa.js} +1 -1
  57. package/dist/{wt-tree-CfkLw1SI.js → wt-tree-CLs3S4Av.js} +2 -2
  58. package/dist/{wt-tree-table-DDyxMFbz.js → wt-tree-table-DtNIE08B.js} +1 -1
  59. package/dist/{wt-type-extension-value-input-B2CwLd8p.js → wt-type-extension-value-input-CjJ8_xRU.js} +3 -3
  60. package/dist/{wt-vidstack-player-BduaN7w2.js → wt-vidstack-player-DmD7s58v.js} +900 -882
  61. package/package.json +10 -2
  62. package/src/components/wt-vidstack-player/wt-vidstack-player.vue +47 -3
  63. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/bridgeCustomElements.ts +32 -0
  64. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/copyStyles.ts +18 -0
  65. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/domTraversal.ts +16 -0
  66. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/index.ts +1 -0
  67. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/mediaCollection.ts +13 -0
  68. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/mediaPlayback.ts +22 -0
  69. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/mediaSnapshot.ts +43 -0
  70. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/playbackRetry.ts +81 -0
  71. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/useDocumentPiP.ts +146 -0
  72. package/src/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/usePiPResizeObserver.ts +30 -0
  73. package/src/modules/CallSession/modules/VideoCall/composables/useReceiverLiveStream.ts +64 -0
  74. package/src/modules/CallSession/modules/VideoCall/types/types.ts +17 -0
  75. package/src/modules/CallSession/modules/VideoCall/video-call.vue +170 -18
  76. package/types/components/wt-vidstack-player/wt-vidstack-player.vue.d.ts +3 -1
  77. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/bridgeCustomElements.d.ts +1 -0
  78. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/copyStyles.d.ts +1 -0
  79. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/domTraversal.d.ts +1 -0
  80. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/index.d.ts +1 -0
  81. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/mediaCollection.d.ts +2 -0
  82. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/mediaPlayback.d.ts +3 -0
  83. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/mediaSnapshot.d.ts +16 -0
  84. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/playbackRetry.d.ts +24 -0
  85. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/useDocumentPiP.d.ts +8 -0
  86. package/types/modules/CallSession/modules/VideoCall/composables/useDocumentPiP/usePiPResizeObserver.d.ts +6 -0
  87. package/types/modules/CallSession/modules/VideoCall/composables/useReceiverLiveStream.d.ts +49 -0
  88. package/types/modules/CallSession/modules/VideoCall/types/types.d.ts +14 -0
  89. package/types/modules/CallSession/modules/VideoCall/video-call.vue.d.ts +6 -4
@@ -1,10 +1,14 @@
1
1
  <template>
2
2
  <wt-vidstack-player
3
- :class="[!props.static && `video-call-position--${props.position}`]"
4
- :hide-video-display-panel="props.hideVideoDisplayPanel"
5
- :size="props.size"
3
+ ref="playerRef"
4
+ :class="[
5
+ !props.static && !isPiP && `video-call-position--${props.position}`,
6
+ isPiP && 'video-call--pip',
7
+ ]"
8
+ :hide-video-display-panel="isPiP || props.hideVideoDisplayPanel"
9
+ :size="isPiP ? ComponentSize.MD : props.size"
6
10
  :stream="mainStream"
7
- :static="props.static"
11
+ :static="isPiP || props.static"
8
12
  :username="props.username"
9
13
  :hide-controls-panel="props.hideControlsPanel"
10
14
  :mirror-video="!showSenderScreen"
@@ -26,6 +30,17 @@
26
30
  <template #content="{ size: innerSize }">
27
31
  <slot :size="innerSize" name="content" />
28
32
 
33
+ <div
34
+ v-if="isPiP && props['receiver:mic:enabled'] === false"
35
+ class="video-call--pip__mic-indicator"
36
+ >
37
+ <wt-icon
38
+ :size="ComponentSize.SM"
39
+ icon="mic-muted"
40
+ color="on-dark"
41
+ />
42
+ </div>
43
+
29
44
  <slot v-if="!mainStream" :size="innerSize" name="overlay">
30
45
  <div class="video-call-overlay">
31
46
  <div
@@ -72,6 +87,7 @@
72
87
  <screenshot-box
73
88
  :size="innerSize"
74
89
  :src="props['screenshot:src']"
90
+ :style="pipContentSizeStyle"
75
91
  @close="emit(`action:${VideoCallAction.CloseScreenshot}`)"
76
92
  @zoom="emit(`action:${VideoCallAction.ZoomScreenshot}`)"
77
93
  />
@@ -91,6 +107,7 @@
91
107
  <template v-else-if="showSenderScreen">
92
108
  <wt-vidstack-player
93
109
  :class="`video-call-sender--${innerSize}`"
110
+ :style="pipContentSizeStyle"
94
111
  :stream="props['sender:stream']"
95
112
  autoplay
96
113
  class="video-call-sender"
@@ -133,6 +150,7 @@
133
150
  @[VideoCallAction.Settings]="(payload, options) => emit(emitKeys[VideoCallAction.Settings], payload, options)"
134
151
  @[VideoCallAction.Chat]="(payload, options) => emit(emitKeys[VideoCallAction.Chat], payload, options)"
135
152
  @[VideoCallAction.Hangup]="(payload, options) => emit(emitKeys[VideoCallAction.Hangup], payload, options)"
153
+
136
154
  />
137
155
  </template>
138
156
  </wt-vidstack-player>
@@ -143,9 +161,8 @@
143
161
  lang="ts"
144
162
  >
145
163
  import { WtVidstackPlayer } from '@webitel/ui-sdk/components';
146
- import { computed, onBeforeUnmount, ref, watch } from 'vue';
164
+ import { computed, isRef, onBeforeUnmount, type Ref, ref, watch } from 'vue';
147
165
  import { useI18n } from 'vue-i18n';
148
-
149
166
  import { WtIcon } from '../../../../components';
150
167
  import {
151
168
  RecordingIndicator,
@@ -156,6 +173,8 @@ import { ComponentSize, WtApplication } from '../../../../enums';
156
173
  import { convertDuration } from '../../../../scripts';
157
174
  import type { ResultCallbacks } from '../../../../types';
158
175
  import type { ScreenshotStatus } from '../../types';
176
+ import { useDocumentPiP } from './composables/useDocumentPiP';
177
+ import { useReceiverLiveStream } from './composables/useReceiverLiveStream';
159
178
  import { VideoCallAction } from './enums/VideoCallAction.enum';
160
179
 
161
180
  const props = withDefaults(
@@ -187,6 +206,9 @@ const props = withDefaults(
187
206
  hideVideoDisplayPanel?: boolean;
188
207
  hideAvatar?: boolean;
189
208
  resizable?: boolean;
209
+ hideSenderOnHold?: boolean;
210
+
211
+ isPipMode?: boolean;
190
212
 
191
213
  actions: VideoCallAction[];
192
214
  username?: string;
@@ -256,6 +278,61 @@ const emitKeys = {
256
278
 
257
279
  const { t } = useI18n();
258
280
 
281
+ const playerRef = ref<InstanceType<typeof WtVidstackPlayer> | null>(null);
282
+
283
+ /** `defineExpose({ rootEl })` on `WtVidstackPlayer` passes a Ref — DOM is ready after stream + Vidstack upgrade. */
284
+ const getVideoCallPlayerHostElement = (): HTMLElement | null => {
285
+ const inst = playerRef.value as unknown as {
286
+ rootEl?: HTMLElement | Ref<HTMLElement | null> | null;
287
+ $el?: HTMLElement | null;
288
+ } | null;
289
+ if (!inst) return null;
290
+ const rootEl = inst.rootEl;
291
+ const exposedElement = isRef(rootEl) ? rootEl.value : (rootEl ?? null);
292
+ return exposedElement ?? inst.$el ?? null;
293
+ };
294
+
295
+ const { isPiP, enterPiP, onPiPResize } = useDocumentPiP(
296
+ getVideoCallPlayerHostElement,
297
+ );
298
+
299
+ /**
300
+ * @author @Oleksandr Palionnyi
301
+ *
302
+ * [WTEL-9414](https://webitel.atlassian.net/browse/WTEL-9414)
303
+ *
304
+ * Sender preview dimensions relative to the main player, taken from Figma design (256×171 / 1366×912).
305
+ * https://webitel.atlassian.net/browse/WTEL-9542?focusedCommentId=754891
306
+ */
307
+ const SENDER_WIDTH_RATIO = 256 / 1366;
308
+ const SENDER_ASPECT_RATIO = 171 / 256;
309
+
310
+ const pipContentSize = ref<{
311
+ width: number;
312
+ height: number;
313
+ } | null>(null);
314
+
315
+ onPiPResize((rect) => {
316
+ const width = rect.width * SENDER_WIDTH_RATIO;
317
+ pipContentSize.value = {
318
+ width,
319
+ height: width * SENDER_ASPECT_RATIO,
320
+ };
321
+ });
322
+
323
+ watch(isPiP, (active) => {
324
+ if (!active) pipContentSize.value = null;
325
+ });
326
+
327
+ const pipContentSizeStyle = computed(() => {
328
+ if (!pipContentSize.value) return '';
329
+
330
+ return {
331
+ width: `${pipContentSize.value.width}px`,
332
+ height: `${pipContentSize.value.height}px`,
333
+ };
334
+ });
335
+
259
336
  const receiverStream = computed(() => props['receiver:stream']);
260
337
  const senderStream = computed(() => props['sender:stream']);
261
338
 
@@ -290,6 +367,12 @@ const bothStreamsAvailable = computed(
290
367
  () => !!receiverStream.value && !!senderStream.value,
291
368
  );
292
369
 
370
+ const receiverStreamLiveForMain = useReceiverLiveStream(
371
+ receiverStream,
372
+ receiverVideoEnabled,
373
+ isOnHold,
374
+ );
375
+
293
376
  const showReceiverOverlay = computed(
294
377
  () =>
295
378
  (!receiverStream.value &&
@@ -320,13 +403,22 @@ const mainStream = computed(() => {
320
403
  return senderStream.value;
321
404
  }
322
405
 
323
- return receiverStream.value ?? senderStream.value;
406
+ return receiverStreamLiveForMain.value ?? senderStream.value;
324
407
  });
325
408
 
326
409
  const showSenderScreen = computed(() => {
327
- if (!isOnHold.value) return bothStreamsAvailable.value;
328
-
329
- return !props.hideSenderOnHold && senderStream.value && receiverStream.value;
410
+ if (isOnHold.value) {
411
+ return (
412
+ !props.hideSenderOnHold && !!senderStream.value && !!receiverStream.value
413
+ );
414
+ }
415
+ if (!bothStreamsAvailable.value) {
416
+ return false;
417
+ }
418
+ if (!receiverVideoEnabled.value) {
419
+ return true;
420
+ }
421
+ return receiverStreamLiveForMain.value != null;
330
422
  });
331
423
 
332
424
  const showSenderMutedScreen = computed(() => {
@@ -363,8 +455,36 @@ watch(
363
455
  },
364
456
  );
365
457
 
458
+ /**
459
+ * @author @Oleksandr Palionnyi
460
+ *
461
+ * [WTEL-9414](https://webitel.atlassian.net/browse/WTEL-9414)
462
+ *
463
+ * Document PiP: call `requestWindow()` only when `mainStream` and a usable player host exist.
464
+ * `flush: 'post'` runs after DOM updates so Vidstack / WC upgrade can finish before we read `rootEl`.
465
+ * Stop the watcher only once `enterPiP` succeeds (`isPiP`), so gesture/API failures can retry on later ticks.
466
+ */
467
+ const stopAutoDocumentPiP = watch(
468
+ [
469
+ mainStream,
470
+ playerRef,
471
+ ],
472
+ async () => {
473
+ if (!props.isPipMode) return;
474
+ if (!mainStream.value || !playerRef.value || isPiP.value) return;
475
+ if (!getVideoCallPlayerHostElement()) return;
476
+ await enterPiP();
477
+ if (isPiP.value) stopAutoDocumentPiP();
478
+ },
479
+ {
480
+ flush: 'post',
481
+ immediate: true,
482
+ },
483
+ );
484
+
366
485
  onBeforeUnmount(() => {
367
486
  stopHoldTimer();
487
+ stopAutoDocumentPiP();
368
488
  });
369
489
 
370
490
  const receiverVideoMutedIconSizes = {
@@ -385,6 +505,46 @@ const senderVideoMutedIconSizes = {
385
505
  flex: 0 0 auto;
386
506
  }
387
507
 
508
+ .video-call--pip.wt-vidstack-player {
509
+ position: fixed;
510
+ top: 0;
511
+ right: 0;
512
+ bottom: 0;
513
+ left: 0;
514
+ width: 100%;
515
+ height: 100%;
516
+ max-width: 100%;
517
+ max-height: 100%;
518
+ border-radius: 0;
519
+ }
520
+
521
+ .video-call--pip :deep(.wt-vidstack-player__player:not(.video-call-sender *)),
522
+ .video-call--pip :deep(.wt-vidstack-player__provider:not(.video-call-sender *)),
523
+ .video-call--pip :deep(.wt-vidstack-player:not(.video-call-sender)),
524
+ .video-call--pip :deep(video:not(.video-call-sender *)) {
525
+ border-radius: 0;
526
+ }
527
+
528
+ .video-call--pip__mic-indicator {
529
+ display: flex;
530
+ align-items: center;
531
+ justify-content: center;
532
+ position: absolute;
533
+ top: var(--spacing-sm);
534
+ left: var(--spacing-sm);
535
+ z-index: 1;
536
+ padding: var(--spacing-xs);
537
+ background: var(--p-player-head-line-hover-background);
538
+ border-radius: var(--p-player-wrapper-sm-border-radius);
539
+ }
540
+
541
+ /* Placeholder occupies original layout space while element lives in PiP window */
542
+ .video-call--pip-active {
543
+ background: var(--p-player-wrapper-background, #000);
544
+ border-radius: inherit;
545
+ }
546
+
547
+
388
548
  .video-call-position--left-bottom.wt-vidstack-player--sm {
389
549
  top: unset;
390
550
  bottom: var(--spacing-sm);
@@ -533,10 +693,6 @@ const senderVideoMutedIconSizes = {
533
693
  height: var(--p-player-cam-preview-sm-height);
534
694
  }
535
695
 
536
- .video-call-sender--md :deep(video) {
537
- border-radius: var(--p-player-cam-preview-md-border-radius);
538
- }
539
-
540
696
  .video-call-sender--md.video-call-sender--muted {
541
697
  border-radius: var(--p-player-cam-preview-md-border-radius);
542
698
  }
@@ -549,10 +705,6 @@ const senderVideoMutedIconSizes = {
549
705
  height: var(--p-player-cam-preview-md-height);
550
706
  }
551
707
 
552
- .video-call-sender--lg :deep(video) {
553
- border-radius: var(--p-player-cam-preview-lg-border-radius);
554
- }
555
-
556
708
  .video-call-sender--lg.video-call-sender--muted {
557
709
  border-radius: var(--p-player-cam-preview-lg-border-radius);
558
710
  }
@@ -34,7 +34,9 @@ type __VLS_Slots = {} & {
34
34
  } & {
35
35
  content?: (props: typeof __VLS_32) => any;
36
36
  };
37
- declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
37
+ declare const __VLS_base: import("vue").DefineComponent<Props, {
38
+ rootEl: Readonly<import("vue").ShallowRef<HTMLElement>>;
39
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
38
40
  close: () => any;
39
41
  "change-size": (args_0: ComponentSize) => any;
40
42
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
@@ -0,0 +1 @@
1
+ export declare const bridgeCustomElements: (root: Element, targetWindow: Window) => void;
@@ -0,0 +1 @@
1
+ export declare const copyStyles: (targetWindow: Window) => void;
@@ -0,0 +1 @@
1
+ export declare const domTraversal: (root: Element | ShadowRoot, visit: (el: Element) => void) => void;
@@ -0,0 +1 @@
1
+ export { useDocumentPiP } from './useDocumentPiP';
@@ -0,0 +1,2 @@
1
+ export declare const safePlay: (el: HTMLMediaElement) => void;
2
+ export declare const collectMedia: (root: Element) => HTMLMediaElement[];
@@ -0,0 +1,3 @@
1
+ import type { MediaSnapshot } from '../../types/types';
2
+ export declare const requestVidstackPlayback: (root: Element) => void;
3
+ export declare const resumePlayback: (root: Element, snapshot: MediaSnapshot[]) => void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @author @PalonnyiOleksandr
3
+ *
4
+ * [WTEL-9414](https://webitel.atlassian.net/browse/WTEL-9414)
5
+ *
6
+ * Snapshot utilities for media elements inside Document PiP window.
7
+ * `snapshotMedia` captures current muted state and srcObject of all media
8
+ * elements, then forces mute to prevent autoplay policy violations.
9
+ * `restoreMedia` reverts muted state and re-attaches lost streams.
10
+ * `restoreStreams` re-attaches srcObject without touching muted state,
11
+ * used during playback retry polling.
12
+ */
13
+ import type { MediaSnapshot } from '../../types/types';
14
+ export declare const snapshotMedia: (root: Element, snapshot: MediaSnapshot[]) => void;
15
+ export declare const restoreMedia: (snapshot: MediaSnapshot[]) => void;
16
+ export declare const restoreStreams: (snapshot: MediaSnapshot[]) => void;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @author @PalonnyiOleksandr
3
+ *
4
+ * [WTEL-9414](https://webitel.atlassian.net/browse/WTEL-9414)
5
+ *
6
+ * Polling retry mechanism for media playback inside Document PiP window.
7
+ * Restores streams from snapshot, mutes and plays all media elements until
8
+ * all are ready or the timeout expires. Triggers vidstack playback after an
9
+ * initial delay and re-kicks it periodically when any element stays stalled,
10
+ * throttled to once per 1500 ms to avoid redundant calls.
11
+ *
12
+ * Background: browsers block autoplay until the user interacts with the page,
13
+ * which caused the video to freeze after opening PiP. Since the video must
14
+ * play immediately without any extra clicks, this retry loop works around that
15
+ * by muting elements (which bypasses the autoplay restriction) and
16
+ * re-attempting playback until all media is running.
17
+ *
18
+ * link to explanation - https://webitel.atlassian.net/browse/WTEL-9414?focusedCommentId=754533
19
+ */
20
+ import type { MediaSnapshot } from '../../types/types';
21
+ export declare const createPlaybackRetry: (snapshot: MediaSnapshot[]) => {
22
+ retryPlayback: (root: Element, durationMs?: number) => void;
23
+ stopPlaybackRetry: () => void;
24
+ };
@@ -0,0 +1,8 @@
1
+ export declare function useDocumentPiP(getElement: () => HTMLElement | null | undefined): {
2
+ isPiP: import("vue").Ref<boolean, boolean>;
3
+ isSupported: import("vue").ComputedRef<boolean>;
4
+ enterPiP: (width?: number, height?: number) => Promise<void>;
5
+ exitPiP: () => void;
6
+ armFirstGestureResume: (w?: Window) => void;
7
+ onPiPResize: (callback: import("../../types/types").PiPResizeCallback) => () => boolean;
8
+ };
@@ -0,0 +1,6 @@
1
+ import type { PiPResizeCallback } from '../../types/types';
2
+ export declare function usePiPResizeObserver(): {
3
+ startPiPResizeObserver: (element: HTMLElement) => void;
4
+ stopPiPResizeObserver: () => void;
5
+ onPiPResize: (callback: PiPResizeCallback) => () => boolean;
6
+ };
@@ -0,0 +1,49 @@
1
+ import { type ComputedRef } from 'vue';
2
+ /**
3
+ * Tracks whether the receiver's stream has a live video track.
4
+ * Reacts to track additions, unmute, and ended events on the stream.
5
+ * Returns null when stream is absent, video is disabled, or call is on hold.
6
+ */
7
+ export declare function useReceiverLiveStream(receiverStream: ComputedRef<MediaStream | null | undefined>, videoEnabled: ComputedRef<boolean | undefined>, isOnHold: ComputedRef<boolean>): import("vue").Ref<{
8
+ readonly active: boolean;
9
+ readonly id: string;
10
+ onaddtrack: (this: MediaStream, ev: MediaStreamTrackEvent) => any;
11
+ onremovetrack: (this: MediaStream, ev: MediaStreamTrackEvent) => any;
12
+ addTrack: (track: MediaStreamTrack) => void;
13
+ clone: () => MediaStream;
14
+ getAudioTracks: () => MediaStreamTrack[];
15
+ getTrackById: (trackId: string) => MediaStreamTrack | null;
16
+ getTracks: () => MediaStreamTrack[];
17
+ getVideoTracks: () => MediaStreamTrack[];
18
+ removeTrack: (track: MediaStreamTrack) => void;
19
+ addEventListener: {
20
+ <K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
21
+ (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
22
+ };
23
+ removeEventListener: {
24
+ <K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
25
+ (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
26
+ };
27
+ dispatchEvent: (event: Event) => boolean;
28
+ }, MediaStream | {
29
+ readonly active: boolean;
30
+ readonly id: string;
31
+ onaddtrack: (this: MediaStream, ev: MediaStreamTrackEvent) => any;
32
+ onremovetrack: (this: MediaStream, ev: MediaStreamTrackEvent) => any;
33
+ addTrack: (track: MediaStreamTrack) => void;
34
+ clone: () => MediaStream;
35
+ getAudioTracks: () => MediaStreamTrack[];
36
+ getTrackById: (trackId: string) => MediaStreamTrack | null;
37
+ getTracks: () => MediaStreamTrack[];
38
+ getVideoTracks: () => MediaStreamTrack[];
39
+ removeTrack: (track: MediaStreamTrack) => void;
40
+ addEventListener: {
41
+ <K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
42
+ (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
43
+ };
44
+ removeEventListener: {
45
+ <K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
46
+ (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
47
+ };
48
+ dispatchEvent: (event: Event) => boolean;
49
+ }>;
@@ -0,0 +1,14 @@
1
+ export type DocumentPiPWindow = Window & typeof globalThis & {
2
+ documentPictureInPicture: {
3
+ requestWindow: (opts: {
4
+ width: number;
5
+ height: number;
6
+ }) => Promise<Window>;
7
+ };
8
+ };
9
+ export type MediaSnapshot = {
10
+ el: HTMLMediaElement;
11
+ muted: boolean;
12
+ srcObject: MediaStream | null;
13
+ };
14
+ export type PiPResizeCallback = (rect: DOMRectReadOnly) => void;
@@ -23,21 +23,23 @@ type __VLS_Props = {
23
23
  hideVideoDisplayPanel?: boolean;
24
24
  hideAvatar?: boolean;
25
25
  resizable?: boolean;
26
+ hideSenderOnHold?: boolean;
27
+ isPipMode?: boolean;
26
28
  actions: VideoCallAction[];
27
29
  username?: string;
28
30
  'actions:settings:pressed'?: boolean;
29
31
  'actions:settings:disabled'?: boolean;
30
32
  'actions:chat:pressed'?: boolean;
31
33
  };
32
- declare var __VLS_17: {
34
+ declare var __VLS_18: {
33
35
  size: ComponentSize;
34
- }, __VLS_19: {
36
+ }, __VLS_25: {
35
37
  size: ComponentSize;
36
38
  };
37
39
  type __VLS_Slots = {} & {
38
- content?: (props: typeof __VLS_17) => any;
40
+ content?: (props: typeof __VLS_18) => any;
39
41
  } & {
40
- overlay?: (props: typeof __VLS_19) => any;
42
+ overlay?: (props: typeof __VLS_25) => any;
41
43
  };
42
44
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
43
45
  "change-size": (size: ComponentSize) => any;