Stage 07.3.3: multi live screens and UI optimization
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user