@webitel/ui-chats 0.1.41 → 0.1.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-chats",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "description": "Reusable Webitel Frontend Code for Chats UI",
5
5
  "workspaces": [
6
6
  "../../",
@@ -9,7 +9,7 @@
9
9
  ],
10
10
  "scripts": {
11
11
  "dev": "vite",
12
- "build:types": "vue-tsc -p ./tsconfig.build.json",
12
+ "build:types": "vue-tsc -b tsconfig.build.json",
13
13
  "typecheck": "vue-tsc --noEmit -p ./tsconfig.typecheck.json",
14
14
  "lint:fix": "npx biome check --write ./src",
15
15
  "biome:ci:gh": "biome ci ./src --reporter=github",
@@ -23,6 +23,12 @@ export interface UseChatScrollOptions {
23
23
  onBeforeStart?: (options: {
24
24
  scrollToBottom: (behavior?: ScrollBehavior) => void;
25
25
  }) => void;
26
+ /**
27
+ * @author ye-pohranichna
28
+ * Fired when the viewer is at the bottom and has therefore seen the
29
+ * latest messages
30
+ */
31
+ onSeen?: () => void;
26
32
  }
27
33
 
28
34
  export const useChatScroll = ({
@@ -35,6 +41,7 @@ export const useChatScroll = ({
35
41
  onBeforeStart = (options) => {
36
42
  options.scrollToBottom();
37
43
  },
44
+ onSeen,
38
45
  }: UseChatScrollOptions) => {
39
46
  const { arrivedState } = useScroll(chatContainer);
40
47
 
@@ -50,6 +57,8 @@ export const useChatScroll = ({
50
57
  let lastVisibleMessageEl: HTMLElement | null = null;
51
58
  let prevScrollHeight = 0;
52
59
  let resizeObserver: ResizeObserver | null = null;
60
+ let isViewportTransition = false;
61
+ let viewportTransitionTimer: ReturnType<typeof setTimeout> | null = null;
53
62
  /**
54
63
  * @author PolinaSukhorukova-webitel
55
64
  *
@@ -80,6 +89,7 @@ export const useChatScroll = ({
80
89
  newUnseenMessagesCount.value = 0;
81
90
 
82
91
  resetScrollToBottomBtn();
92
+ onSeen?.();
83
93
  };
84
94
  const getTopMessageEl = () => {
85
95
  // help to fix chat viewing position when new messages was loaded
@@ -113,6 +123,12 @@ export const useChatScroll = ({
113
123
 
114
124
  const newScrollHeight = el.scrollHeight;
115
125
 
126
+ if (isViewportTransition) {
127
+ prevScrollHeight = newScrollHeight;
128
+ updateScrollToBottomBtnVisibility(el);
129
+ return;
130
+ }
131
+
116
132
  const wasNearBottom =
117
133
  el.scrollTop + el.clientHeight >= prevScrollHeight - bottomThreshold;
118
134
  const contentGrown = newScrollHeight > prevScrollHeight;
@@ -157,6 +173,26 @@ export const useChatScroll = ({
157
173
  resetScrollToBottomBtn();
158
174
  };
159
175
 
176
+ const onFullscreenChange = () => {
177
+ isViewportTransition = true;
178
+
179
+ if (viewportTransitionTimer) clearTimeout(viewportTransitionTimer);
180
+
181
+ viewportTransitionTimer = setTimeout(() => {
182
+ isViewportTransition = false;
183
+ viewportTransitionTimer = null;
184
+ }, 500);
185
+ };
186
+
187
+ /**
188
+ * @author PolinaSukhorukova-webitel
189
+ *
190
+ * WTEL-9968 (https://webitel.atlassian.net/browse/WTEL-9968)
191
+ * to avoid extra bottom scroll when chat is in fullscreen
192
+ */
193
+
194
+ document.addEventListener('fullscreenchange', onFullscreenChange);
195
+
160
196
  watch(
161
197
  () => messages.value?.length,
162
198
  (newValue, oldValue) => {
@@ -209,12 +245,17 @@ export const useChatScroll = ({
209
245
  watch(
210
246
  () => arrivedState.bottom,
211
247
  (bottom) => {
212
- if (bottom) newUnseenMessagesCount.value = 0;
248
+ if (bottom) {
249
+ newUnseenMessagesCount.value = 0;
250
+ onSeen?.();
251
+ }
213
252
  },
214
253
  );
215
254
 
216
255
  onUnmounted(() => {
217
256
  stopStickToBottomObserving();
257
+ document.removeEventListener('fullscreenchange', onFullscreenChange);
258
+ if (viewportTransitionTimer) clearTimeout(viewportTransitionTimer);
218
259
  });
219
260
 
220
261
  return {
@@ -12,6 +12,19 @@ export const useObserveHeightUntilStable = (
12
12
  callback: () => void,
13
13
  ) => {
14
14
  let observer: ResizeObserver | null = null;
15
+ let isViewportTransition = false;
16
+ let viewportTransitionTimer: ReturnType<typeof setTimeout> | null = null;
17
+
18
+ const onFullscreenChange = () => {
19
+ isViewportTransition = true;
20
+
21
+ if (viewportTransitionTimer) clearTimeout(viewportTransitionTimer);
22
+
23
+ viewportTransitionTimer = setTimeout(() => {
24
+ isViewportTransition = false;
25
+ viewportTransitionTimer = null;
26
+ }, 500);
27
+ };
15
28
 
16
29
  const stopObserve = () => {
17
30
  observer?.disconnect();
@@ -26,7 +39,8 @@ export const useObserveHeightUntilStable = (
26
39
 
27
40
  observer = new ResizeObserver(() => {
28
41
  const currentClientHeight = chatContainer.value?.clientHeight;
29
- callback();
42
+
43
+ if (!isViewportTransition) callback();
30
44
 
31
45
  if (currentClientHeight === lastClientHeight) {
32
46
  stableCount++;
@@ -40,7 +54,19 @@ export const useObserveHeightUntilStable = (
40
54
  observer.observe(chatContainer.value);
41
55
  };
42
56
 
43
- onUnmounted(stopObserve);
57
+ /**
58
+ * @author PolinaSukhorukova-webitel
59
+ *
60
+ * WTEL-9968 (https://webitel.atlassian.net/browse/WTEL-9968)
61
+ * to avoid extra bottom scroll when chat is in fullscreen
62
+ */
63
+ document.addEventListener('fullscreenchange', onFullscreenChange);
64
+
65
+ onUnmounted(() => {
66
+ stopObserve();
67
+ document.removeEventListener('fullscreenchange', onFullscreenChange);
68
+ if (viewportTransitionTimer) clearTimeout(viewportTransitionTimer);
69
+ });
44
70
 
45
71
  return {
46
72
  startObserve,
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />