From 068e956f7cc55aaf02ae8986a84a54bc4b266878 Mon Sep 17 00:00:00 2001 From: lizerk Date: Fri, 3 Apr 2026 14:32:31 +0300 Subject: [PATCH] Fix chat floating date badge behavior --- frontend/src/app/messages/[chatId]/page.tsx | 91 +++++++++++++-------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/frontend/src/app/messages/[chatId]/page.tsx b/frontend/src/app/messages/[chatId]/page.tsx index ed1a0711..fb5739e6 100644 --- a/frontend/src/app/messages/[chatId]/page.tsx +++ b/frontend/src/app/messages/[chatId]/page.tsx @@ -18,7 +18,7 @@ import { useChatFallbackSync } from "@/hooks/useChatFallbackSync"; import { useSilentChatReloadGuard } from "@/hooks/useSilentChatReloadGuard"; import { useWebSocket } from "@/hooks/useWebSocket"; import { getMessageTimestamp, mergeDisplayMessages, uniqueMessagesById } from "@/lib/messages/chatUtils"; -import { formatDayDivider, getMessagePreviewText, getReplyToId } from "@/lib/messages/messageUtils"; +import { formatDayDivider, getMessageDate, getMessagePreviewText, getReplyToId } from "@/lib/messages/messageUtils"; import wsManager from "@/lib/websocketManager"; import ScrollableMessageList, { ScrollableMessageListInner } from "@/components/ScrollableMessageList"; @@ -57,6 +57,15 @@ function uniqueEmoji(items: string[]): string[] { return out; } +function getMessageDayKey(message: Message): string | null { + const date = getMessageDate(message); + if (!date) { + return null; + } + + return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`; +} + export default function MessageDialogPage() { const params = useParams<{ chatId: string }>(); const chatId = Number(params.chatId); @@ -1148,20 +1157,20 @@ export default function MessageDialogPage() { loadNewerMessages(); } - // Обновление плавающей даты const messageEls = viewport.querySelectorAll('[data-message-date]'); - let topDate: string | null = null; const viewportTop = viewport.getBoundingClientRect().top; + let topDate: string | null = null; - for (let i = 0; i < messageEls.length; i++) { + for (let i = 0; i < messageEls.length; i += 1) { const el = messageEls[i]; const rect = el.getBoundingClientRect(); - if (rect.bottom > viewportTop) { + + if (rect.bottom > viewportTop + 8) { const isoDate = el.getAttribute('data-message-date'); if (isoDate) { - const d = new Date(isoDate); - if (!Number.isNaN(d.getTime())) { - topDate = formatDayDivider(d); + const date = new Date(isoDate); + if (!Number.isNaN(date.getTime())) { + topDate = formatDayDivider(date); } } break; @@ -1172,10 +1181,13 @@ export default function MessageDialogPage() { setFloatingDate(topDate); setShowFloatingDate(true); - if (floatingDateTimeoutRef.current) clearTimeout(floatingDateTimeoutRef.current); + if (floatingDateTimeoutRef.current) { + clearTimeout(floatingDateTimeoutRef.current); + } + floatingDateTimeoutRef.current = setTimeout(() => { setShowFloatingDate(false); - }, 1500); + }, 1100); } // Показ кнопки scroll-to-bottom когда не внизу @@ -1538,16 +1550,13 @@ export default function MessageDialogPage() { />
- {/* Плавающая дата */} - {floatingDate && ( -
+ {floatingDate ? ( +
{floatingDate}
- )} + ) : null} Подгружаем старые сообщения...

) : null} - {displayMessages.map((message) => { + {displayMessages.map((message, index) => { const replyToId = getReplyToId(message); const repliedMessage = replyToId ? messagesById.get(replyToId) : null; + const currentDayKey = getMessageDayKey(message); + const previousDayKey = index > 0 ? getMessageDayKey(displayMessages[index - 1]) : null; + const currentMessageDate = getMessageDate(message); + const showDayDivider = Boolean(currentMessageDate && currentDayKey !== previousDayKey); return ( - + + {showDayDivider && currentMessageDate ? ( +
+ + {formatDayDivider(currentMessageDate)} + +
+ ) : null} + +
); })}