фикс 2

This commit is contained in:
lizerk 2026-04-03 22:30:21 +03:00
parent a94b56ecb7
commit 4c24b01f06
3 changed files with 85 additions and 4 deletions

View File

@ -815,7 +815,10 @@ class ChatViewSet(viewsets.ModelViewSet):
# Если все еще нет around_id - возвращаем последние сообщения
if not around_id:
fallback_limit = before_limit + after_limit
messages = list(queryset.order_by('-created_at')[:fallback_limit])
messages = list(queryset.order_by('-created_at', '-id')[:fallback_limit + 1])
has_more_before = len(messages) > fallback_limit
if has_more_before:
messages = messages[:fallback_limit]
messages.reverse()
# Автоотметка: последнее ЗАГРУЖЕННОЕ становится last_read
@ -827,7 +830,9 @@ class ChatViewSet(viewsets.ModelViewSet):
'messages': [serialize_message(m) for m in messages],
'messages_count': len(messages),
'anchor_id': None,
'anchor_index': 0
'anchor_index': 0,
'has_more_before': has_more_before,
'has_more_after': False,
})
# Определяем, это ID сообщения или timestamp
@ -872,7 +877,10 @@ class ChatViewSet(viewsets.ModelViewSet):
if not anchor_msg:
# Если не найдено - возвращаем последние сообщения
fallback_limit = before_limit + after_limit
messages = list(queryset.order_by('-created_at')[:fallback_limit])
messages = list(queryset.order_by('-created_at', '-id')[:fallback_limit + 1])
has_more_before = len(messages) > fallback_limit
if has_more_before:
messages = messages[:fallback_limit]
messages.reverse()
# Автоотметка: последнее ЗАГРУЖЕННОЕ становится last_read
@ -884,7 +892,9 @@ class ChatViewSet(viewsets.ModelViewSet):
'messages': [serialize_message(m) for m in messages],
'messages_count': len(messages),
'anchor_id': None,
'anchor_index': 0
'anchor_index': 0,
'has_more_before': has_more_before,
'has_more_after': False,
})
# Асимметричная загрузка: больше контекста, меньше новых

View File

@ -286,6 +286,36 @@ class TestChatViewSet:
assert "messages" in response.data
assert response.data["messages_count"] > 0
def test_messages_around_without_anchor_reports_more_older(
self, auth_client, private_chat, user1
):
"""Fallback messages-around без якоря должен сообщать, что вверх есть история."""
for i in range(40):
Message.objects.create(chat=private_chat, author=user1, content=f"Msg {i}")
url = f"/api/v1/communications/chats/{private_chat.pk}/messages-around/"
response = auth_client.get(url, {"limit": 30})
assert response.status_code == status.HTTP_200_OK
assert response.data["messages_count"] == 30
assert response.data["has_more_before"] is True
assert response.data["has_more_after"] is False
def test_messages_around_with_missing_anchor_reports_more_older(
self, auth_client, private_chat, user1
):
"""Fallback messages-around с отсутствующим around_id не должен скрывать старую историю."""
for i in range(40):
Message.objects.create(chat=private_chat, author=user1, content=f"Msg {i}")
url = f"/api/v1/communications/chats/{private_chat.pk}/messages-around/"
response = auth_client.get(url, {"around_id": 999999, "limit": 30})
assert response.status_code == status.HTTP_200_OK
assert response.data["messages_count"] == 30
assert response.data["has_more_before"] is True
assert response.data["has_more_after"] is False
def test_messages_pagination_before(self, auth_client, private_chat, user1):
"""Пагинация сообщений (before)"""
messages = [

View File

@ -441,6 +441,47 @@ function MessageDialogPageContent() {
return () => viewport.removeEventListener("scroll", onScroll);
}, [cm, markRead, scroll]);
useEffect(() => {
if (cm.messagesLoading || cm.loadingOlder || displayMessages.length === 0) {
return;
}
if (!cm.hasMoreOlder && !cm.allowOneOlderProbe) {
return;
}
const component = messagesViewportRef.current;
const viewport = component?.containerRef?.current;
if (!viewport) {
return;
}
let cancelled = false;
const frameId = window.requestAnimationFrame(() => {
if (cancelled) {
return;
}
const hasScrollableOverflow = viewport.scrollHeight > viewport.clientHeight + 8;
if (!hasScrollableOverflow) {
void cm.loadOlderMessages();
}
});
return () => {
cancelled = true;
window.cancelAnimationFrame(frameId);
};
}, [
cm.allowOneOlderProbe,
cm.hasMoreOlder,
cm.loadingOlder,
cm.loadOlderMessages,
cm.messagesLoading,
displayMessages.length,
]);
/* ── fallback sync ── */
useChatFallbackSync({
chatId: chatId || null,