Stage 07.3.3: multi live screens and UI optimization

This commit is contained in:
2026-04-29 12:38:29 +03:00
parent 93cdd164ae
commit 861f98024c
3 changed files with 111 additions and 89 deletions

View File

@@ -34,21 +34,26 @@ class LiveScreen:
class LiveScreenRunner:
_screens: dict[str, LiveScreen] = {}
_screens: dict[str, list[LiveScreen]] = {}
_tasks: dict[str, asyncio.Task] = {}
_current_screen: str | None = None
# переключить активный экран
@classmethod
def set_current_screen(cls, screen: str) -> None:
cls._current_screen = screen
# зарегистрировать live-экран
@classmethod
def register_screen(cls, live_screen: LiveScreen) -> None:
cls._screens[live_screen.screen] = live_screen
screens = cls._screens.setdefault(live_screen.screen, [])
# удалить старый live-экран из Telegram
screens[:] = [
item
for item in screens
if not (
item.chat_id == live_screen.chat_id
and item.message_id == live_screen.message_id
)
]
screens.append(live_screen)
# удалить все live-экраны указанного типа из Telegram
@classmethod
async def delete_screen(
cls,
@@ -57,25 +62,29 @@ class LiveScreenRunner:
bot: Bot,
chat_id: int,
) -> None:
live_screen = cls._screens.get(screen)
screens = cls._screens.get(screen, [])
if live_screen is None:
return
remaining: list[LiveScreen] = []
if live_screen.chat_id != chat_id:
return
for live_screen in screens:
if live_screen.chat_id != chat_id:
remaining.append(live_screen)
continue
try:
await bot.delete_message(
chat_id=live_screen.chat_id,
message_id=live_screen.message_id,
)
except Exception:
pass
try:
await bot.delete_message(
chat_id=live_screen.chat_id,
message_id=live_screen.message_id,
)
except Exception:
pass
cls._screens.pop(screen, None)
if remaining:
cls._screens[screen] = remaining
else:
cls._screens.pop(screen, None)
# запустить автообновление экрана
# запустить автообновление группы экранов
@classmethod
def start(cls, screen: str) -> None:
task = cls._tasks.get(screen)
@@ -85,7 +94,7 @@ class LiveScreenRunner:
cls._tasks[screen] = asyncio.create_task(cls._worker(screen))
# остановить автообновление экрана
# остановить автообновление группы экранов
@classmethod
def stop(cls, screen: str) -> None:
task = cls._tasks.get(screen)
@@ -96,38 +105,44 @@ class LiveScreenRunner:
task.cancel()
cls._tasks.pop(screen, None)
# фоновый цикл обновления одного экрана
# фоновый цикл обновления группы экранов
@classmethod
async def _worker(cls, screen: str) -> None:
while True:
await cls._refresh_screen(screen)
await asyncio.sleep(cls._screen_interval(screen))
# получить интервал обновления экрана
# получить интервал обновления группы экранов
@classmethod
def _screen_interval(cls, screen: str) -> int:
live_screen = cls._screens.get(screen)
if live_screen is None:
screens = cls._screens.get(screen, [])
if not screens:
return 5
return live_screen.interval_seconds
return screens[0].interval_seconds
# обновить Telegram-сообщение live-экрана
# обновить все Telegram-сообщения live-экрана
@classmethod
async def _refresh_screen(cls, screen: str) -> None:
if cls._current_screen != screen:
screens = cls._screens.get(screen, [])
if not screens:
return
live_screen = cls._screens.get(screen)
if live_screen is None:
return
alive_screens: list[LiveScreen] = []
try:
await live_screen.bot.edit_message_text(
chat_id=live_screen.chat_id,
message_id=live_screen.message_id,
text=live_screen.render_text(),
reply_markup=live_screen.render_markup(),
)
except Exception:
pass
for live_screen in screens:
try:
await live_screen.bot.edit_message_text(
chat_id=live_screen.chat_id,
message_id=live_screen.message_id,
text=live_screen.render_text(),
reply_markup=live_screen.render_markup(),
)
alive_screens.append(live_screen)
except Exception:
pass
if alive_screens:
cls._screens[screen] = alive_screens
else:
cls._screens.pop(screen, None)