mirror of
https://github.com/openmax-server/server.git
synced 2026-05-23 20:11:41 +03:00
MAX: bootstrap-история в LOGIN — клиент перестал думать что всё уже синканулось
В ответе LOGIN сервер слал messages: {} и chatMarker: 0. Десктопный
клиент в этом случае считает, что локальная история уже синхронизирована
со старого запуска, и НЕ отправляет CHAT_HISTORY (49) при открытии чата.
В окне видно только lastMessage из chats[], а вся реальная переписка —
ничерта.
- src/common/tools.py: collect_bootstrap_history(chatIds, ...) —
собирает карту {chatId: [последние N сообщений]}, в т.ч. избранное
под клиентским id = senderId ^ senderId.
- src/oneme/processors/auth.py: подсовываем эту карту в
payload.messages, chatMarker = текущее время вместо 0.
This commit is contained in:
@@ -429,6 +429,44 @@ class Tools:
|
|||||||
# Возвращаем айдишки
|
# Возвращаем айдишки
|
||||||
return int(message_id), int(last_message_id), message_time
|
return int(message_id), int(last_message_id), message_time
|
||||||
|
|
||||||
|
async def collect_bootstrap_history(
|
||||||
|
self, chatIds, db_pool, senderId, protocol_type="mobile", limit=50, include_favourites=True
|
||||||
|
):
|
||||||
|
"""Собирает карту {chatId: [messages...]} для bootstrap-pre-fetch в LOGIN.
|
||||||
|
|
||||||
|
Десктопный MAX в ответе LOGIN ждёт поле `messages` как карту чат→история.
|
||||||
|
Если карта пустая — клиент полагает, что у него уже есть локальная
|
||||||
|
история и НЕ запрашивает CHAT_HISTORY (49). В итоге в окне чата
|
||||||
|
видно только lastMessage из chats[].
|
||||||
|
"""
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
async def _fetch(chat_db_id, key_for_client):
|
||||||
|
async with db_pool.acquire() as conn:
|
||||||
|
async with conn.cursor() as cursor:
|
||||||
|
await cursor.execute(
|
||||||
|
"SELECT * FROM `messages` WHERE chat_id = %s ORDER BY time DESC LIMIT %s",
|
||||||
|
(chat_db_id, limit),
|
||||||
|
)
|
||||||
|
rows = await cursor.fetchall()
|
||||||
|
|
||||||
|
if not rows:
|
||||||
|
return
|
||||||
|
|
||||||
|
messages = [self.build_message_dict(row, protocol_type) for row in rows]
|
||||||
|
messages.sort(key=lambda m: m["time"])
|
||||||
|
result[key_for_client] = messages
|
||||||
|
|
||||||
|
for chatId in chatIds:
|
||||||
|
await _fetch(chatId, chatId)
|
||||||
|
|
||||||
|
if include_favourites:
|
||||||
|
# Избранное: в БД хранится как chat_id = -senderId,
|
||||||
|
# но клиенту отдаётся под id = senderId ^ senderId (= 0)
|
||||||
|
await _fetch(-senderId, senderId ^ senderId)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
async def get_last_message(self, chatId, db_pool, protocol_type="mobile"):
|
async def get_last_message(self, chatId, db_pool, protocol_type="mobile"):
|
||||||
"""Получение последнего сообщения в чате"""
|
"""Получение последнего сообщения в чате"""
|
||||||
async with db_pool.acquire() as db_connection:
|
async with db_pool.acquire() as db_connection:
|
||||||
|
|||||||
@@ -603,11 +603,24 @@ class AuthProcessors(BaseProcessor):
|
|||||||
username=user.get("username"),
|
username=user.get("username"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Список ID чатов до того как generate_chats затрёт переменную
|
||||||
|
chat_ids_for_history = list(chats)
|
||||||
|
|
||||||
# Генерируем список чатов
|
# Генерируем список чатов
|
||||||
chats = await self.tools.generate_chats(
|
chats = await self.tools.generate_chats(
|
||||||
chats, self.db_pool, user.get("id"), protocol_type=self.type
|
chats, self.db_pool, user.get("id"), protocol_type=self.type
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Bootstrap-история: карта {chatId: [messages]}.
|
||||||
|
# Без неё десктопный MAX считает, что локальная история уже
|
||||||
|
# синхронизирована, и не запрашивает CHAT_HISTORY (49).
|
||||||
|
bootstrap_messages = await self.tools.collect_bootstrap_history(
|
||||||
|
chat_ids_for_history,
|
||||||
|
self.db_pool,
|
||||||
|
user.get("id"),
|
||||||
|
protocol_type=self.type,
|
||||||
|
)
|
||||||
|
|
||||||
# Генерируем список контактов
|
# Генерируем список контактов
|
||||||
contacts = await self.tools.collect_user_contacts(
|
contacts = await self.tools.collect_user_contacts(
|
||||||
user.get("id"), self.db_pool, self.config.avatar_base_url
|
user.get("id"), self.db_pool, self.config.avatar_base_url
|
||||||
@@ -621,8 +634,8 @@ class AuthProcessors(BaseProcessor):
|
|||||||
payload = {
|
payload = {
|
||||||
"profile": profile,
|
"profile": profile,
|
||||||
"chats": chats,
|
"chats": chats,
|
||||||
"chatMarker": 0,
|
"chatMarker": int(time.time() * 1000),
|
||||||
"messages": {},
|
"messages": bootstrap_messages,
|
||||||
"contacts": contacts,
|
"contacts": contacts,
|
||||||
"presence": presence,
|
"presence": presence,
|
||||||
"config": {
|
"config": {
|
||||||
|
|||||||
Reference in New Issue
Block a user