Skip to content

UI Animation Service

Сервис UIAnimationService предназначен для создания визуального отклика («ожидания») в интерфейсе Telegram. Он позволяет показывать пользователю прогресс-бары или бесконечные индикаторы загрузки, пока бот выполняет длительную фоновую задачу.


🛠 Зачем это нужно?

В Telegram взаимодействие с ботом должно быть мгновенным. Если операция (например, поиск противника или запрос к тяжелому API) занимает более 1-2 секунд, пользователь может подумать, что бот завис.

UIAnimationService решает эту проблему, превращая статичное сообщение в динамический интерфейс с анимацией.


🚀 Основные сценарии

Сервис поддерживает три модели поведения:

1. Задержка перед запросом (run_delayed_fetch)

Сначала показывается анимация фиксированное время, и только в конце выполняется запрос за данными. - Применение: Симуляция поиска, «сканирование» данных, когда нужно создать эффект работы системы. - Тип анимации: Обычно PROGRESS_BAR.

2. Цикл опроса (run_polling_loop)

Бот делает запросы к бэкенду/базе каждые N секунд. Пока статус is_waiting=True, в сообщении крутится индикатор. - Применение: Ожидание подтверждения транзакции, поиск игрока на арену, ожидание ответа от LLM. - Тип анимации: Обычно INFINITE (бегущий индикатор).

3. Опрос по времени (run_timed_polling)

Комбинированный режим. Показывается прогресс-бар на основе ожидаемого времени (например, 10 секунд на перемещение), но при этом бот продолжает проверять реальный статус. - Применение: Таймеры перемещения в RPG, длительные расчеты с известным временем завершения.


✍️ Как использовать

Сервис обычно инициализируется в контейнере и доступен через container.animation_service.

Пример в оркестраторе:

async def handle_action(self, payload, director: Director):
    animation = director.container.animation_service

    async def check_status():
        # Логика проверки реального состояния
        res = await api.get_job_status(payload.job_id)
        return build_view(res), res.is_pending

    # Запускаем цикл ожидания
    await animation.run_polling_loop(
        check_func=check_status,
        loading_text="⏳ <b>Обработка данных...</b>",
        animation_type=AnimationType.INFINITE
    )

Управление местом анимации

Вы можете указать в тексте оркестратора плейсхолдер {ANIMATION}. Сервис вставит индикатор именно туда. Если плейсхолдера нет, анимация добавится в конец сообщения.

# В ViewResultDTO
text = "Статус задачи: {ANIMATION}\nПожалуйста, не закрывайте меню."

📊 Типы анимации (AnimationType)

  1. PROGRESS_BAR: Заполняющаяся полоса [■■■□□□□□□□] 30%.
  2. INFINITE: Бегущий квадратик [□□■□□□□□□□].
  3. NONE: Просто текст без графического индикатора.

🧭 Связанные компоненты

  • ViewSender — используется для пересылки кадров анимации пользователю.
  • Director — предоставляет доступ к сервису через контейнер.