@webitel/ui-chats 0.1.50 → 0.1.52

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.50",
3
+ "version": "0.1.52",
4
4
  "description": "Reusable Webitel Frontend Code for Chats UI",
5
5
  "workspaces": [
6
6
  "../../",
@@ -56,6 +56,7 @@ export const useChatScroll = ({
56
56
  let isLoadingNextMessages = false;
57
57
  let lastVisibleMessageEl: HTMLElement | null = null;
58
58
  let prevScrollHeight = 0;
59
+ let prevScrollTop = 0;
59
60
  let resizeObserver: ResizeObserver | null = null;
60
61
  let isViewportTransition = false;
61
62
  let viewportTransitionTimer: ReturnType<typeof setTimeout> | null = null;
@@ -72,6 +73,15 @@ export const useChatScroll = ({
72
73
  const lastMessage = computed(() => messages.value?.at(-1));
73
74
  const isLastMessageMy = computed(() => !!lastMessage.value?.member?.self);
74
75
 
76
+ const isViewingBottom = (el: HTMLElement) =>
77
+ el.clientHeight > 0 &&
78
+ el.scrollHeight - (el.scrollTop + el.clientHeight) <= bottomThreshold;
79
+
80
+ const markSeenIfAtBottom = () => {
81
+ const el = chatContainer.value;
82
+ if (el && isViewingBottom(el)) onSeen?.();
83
+ };
84
+
75
85
  const handleBtnAfterNewMessage = () => {
76
86
  if (isLastMessageMy.value) {
77
87
  scrollToBottom('instant');
@@ -89,8 +99,14 @@ export const useChatScroll = ({
89
99
  newUnseenMessagesCount.value = 0;
90
100
 
91
101
  resetScrollToBottomBtn();
92
- onSeen?.();
102
+ markSeenIfAtBottom();
103
+ };
104
+
105
+ const handleChatScrollWithSeen = () => {
106
+ handleChatScroll();
107
+ markSeenIfAtBottom();
93
108
  };
109
+
94
110
  const getTopMessageEl = () => {
95
111
  // help to fix chat viewing position when new messages was loaded
96
112
  if (!chatContainer.value?.children) return;
@@ -116,6 +132,7 @@ export const useChatScroll = ({
116
132
  if (!chatContent.value) return;
117
133
 
118
134
  prevScrollHeight = chatContainer.value?.scrollHeight ?? 0;
135
+ prevScrollTop = chatContainer.value?.scrollTop ?? 0;
119
136
 
120
137
  resizeObserver = new ResizeObserver(() => {
121
138
  const el = chatContainer.value;
@@ -125,11 +142,23 @@ export const useChatScroll = ({
125
142
 
126
143
  if (isViewportTransition) {
127
144
  prevScrollHeight = newScrollHeight;
145
+ prevScrollTop = el.scrollTop;
128
146
  updateScrollToBottomBtnVisibility(el);
129
147
  return;
130
148
  }
131
149
 
150
+ const heightDelta = newScrollHeight - prevScrollHeight;
151
+ const scrollTopDelta = el.scrollTop - prevScrollTop;
152
+ /**
153
+ * @author PolinaSukhorukova-webitel
154
+ *
155
+ * Prepend after pagination shifts scrollTop by the height it adds on top; bottom
156
+ * growth leaves scrollTop still. Matching deltas = prepend - skip scroll.
157
+ */
158
+ const isPrepend =
159
+ Math.abs(scrollTopDelta - heightDelta) <= bottomThreshold;
132
160
  const wasNearBottom =
161
+ !isPrepend &&
133
162
  el.scrollTop + el.clientHeight >= prevScrollHeight - bottomThreshold;
134
163
  const contentGrown = newScrollHeight > prevScrollHeight;
135
164
 
@@ -147,6 +176,7 @@ export const useChatScroll = ({
147
176
  }
148
177
 
149
178
  prevScrollHeight = newScrollHeight;
179
+ prevScrollTop = el.scrollTop;
150
180
  updateScrollToBottomBtnVisibility(el);
151
181
  });
152
182
 
@@ -247,7 +277,7 @@ export const useChatScroll = ({
247
277
  (bottom) => {
248
278
  if (bottom) {
249
279
  newUnseenMessagesCount.value = 0;
250
- onSeen?.();
280
+ markSeenIfAtBottom();
251
281
  }
252
282
  },
253
283
  );
@@ -262,7 +292,8 @@ export const useChatScroll = ({
262
292
  showScrollToBottomBtn,
263
293
  newUnseenMessagesCount,
264
294
  scrollToBottom,
295
+ markSeenIfAtBottom,
265
296
  loadNextMessages,
266
- handleChatScroll,
297
+ handleChatScroll: handleChatScrollWithSeen,
267
298
  };
268
299
  };