""" Утилиты навигационных переходов. Логика: - Если кнопка нажата на последнем навигационном сообщении (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)