110 lines
3.6 KiB
Python
110 lines
3.6 KiB
Python
"""
|
||
Утилиты навигационных переходов.
|
||
|
||
Логика:
|
||
- Если кнопка нажата на последнем навигационном сообщении (nav_mid в контексте),
|
||
редактируем его на месте (edit-in-place).
|
||
- Иначе удаляем триггерное сообщение и отправляем новое в конец чата.
|
||
|
||
nav_mid сохраняется в контексте и обновляется при каждом nav_finish.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from maxapi.context import BaseContext
|
||
from maxapi.types.updates.message_callback import MessageCallback
|
||
|
||
from bot.send_helper import bot_send
|
||
|
||
|
||
async def nav_prepare(
|
||
event: MessageCallback,
|
||
context: BaseContext,
|
||
loading_text: str,
|
||
chat_id: int | None,
|
||
user_id: int,
|
||
) -> str | None:
|
||
"""
|
||
Начать навигационный переход: показать индикатор загрузки.
|
||
|
||
Возвращает mid, который нужно передать в nav_finish.
|
||
"""
|
||
trigger_mid = event.message.body.mid if (event.message and event.message.body) else None
|
||
data = await context.get_data()
|
||
nav_mid = data.get("nav_mid")
|
||
|
||
if trigger_mid and trigger_mid == nav_mid:
|
||
# Это последнее навигационное сообщение — редактируем на месте
|
||
try:
|
||
await event.bot.edit_message(
|
||
message_id=trigger_mid,
|
||
text=loading_text,
|
||
attachments=[],
|
||
)
|
||
return trigger_mid
|
||
except Exception:
|
||
pass # fallthrough: отправим новое
|
||
|
||
# Старое сообщение (или nav_mid не совпадает) → удаляем и отправляем новое
|
||
if trigger_mid:
|
||
try:
|
||
await event.bot.delete_message(message_id=trigger_mid)
|
||
except Exception:
|
||
pass
|
||
|
||
return await bot_send(
|
||
event.bot,
|
||
chat_id=chat_id,
|
||
user_id=user_id,
|
||
text=loading_text,
|
||
attachments=[],
|
||
)
|
||
|
||
|
||
async def nav_finish(
|
||
bot,
|
||
context: BaseContext,
|
||
mid: str | None,
|
||
chat_id: int | None,
|
||
user_id: int,
|
||
text: str,
|
||
attachments: list,
|
||
) -> str | None:
|
||
"""
|
||
Завершить навигационный переход: вставить финальный контент в mid.
|
||
При неудаче редактирования — отправляет новое сообщение.
|
||
Всегда обновляет nav_mid в контексте.
|
||
"""
|
||
result_mid: str | None = None
|
||
|
||
if mid:
|
||
try:
|
||
await bot.edit_message(
|
||
message_id=mid,
|
||
text=text,
|
||
attachments=attachments or [],
|
||
)
|
||
result_mid = mid
|
||
except Exception:
|
||
pass
|
||
|
||
if not result_mid:
|
||
result_mid = await bot_send(
|
||
bot,
|
||
chat_id=chat_id,
|
||
user_id=user_id,
|
||
text=text,
|
||
attachments=attachments,
|
||
)
|
||
|
||
# Обновляем nav_mid, сохраняя остальные данные контекста
|
||
data = await context.get_data()
|
||
data["nav_mid"] = result_mid
|
||
await context.set_data(data)
|
||
return result_mid
|
||
|
||
|
||
async def nav_set(context: BaseContext, mid: str | None) -> None:
|
||
"""Сохранить nav_mid после ручной отправки навигационного сообщения."""
|
||
data = await context.get_data()
|
||
data["nav_mid"] = mid
|
||
await context.set_data(data)
|