fix: используем asyncio.Event для неблокирующего ожидания кнопок
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
40ce40f218
commit
d0f91d7daa
|
|
@ -56,11 +56,15 @@ async def menu_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
state = state_manager.get(user_id)
|
state = state_manager.get(user_id)
|
||||||
state.waiting_for_output_control = False
|
state.waiting_for_output_control = False
|
||||||
state.continue_output = True
|
state.continue_output = True
|
||||||
# Сразу удаляем сообщение с кнопками
|
# Удаляем сообщение с кнопками
|
||||||
try:
|
try:
|
||||||
await query.delete_message()
|
await query.delete_message()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
# Устанавливаем event чтобы разблокировать send_long_message
|
||||||
|
if state.output_continue_event:
|
||||||
|
state.output_continue_event.set()
|
||||||
|
await query.answer()
|
||||||
return
|
return
|
||||||
|
|
||||||
elif callback == "cancel_output":
|
elif callback == "cancel_output":
|
||||||
|
|
@ -68,11 +72,15 @@ async def menu_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
state = state_manager.get(user_id)
|
state = state_manager.get(user_id)
|
||||||
state.waiting_for_output_control = False
|
state.waiting_for_output_control = False
|
||||||
state.continue_output = False
|
state.continue_output = False
|
||||||
# Сразу удаляем сообщение с кнопками
|
# Удаляем сообщение с кнопками
|
||||||
try:
|
try:
|
||||||
await query.delete_message()
|
await query.delete_message()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
# Устанавливаем event чтобы разблокировать send_long_message
|
||||||
|
if state.output_continue_event:
|
||||||
|
state.output_continue_event.set()
|
||||||
|
await query.answer()
|
||||||
return
|
return
|
||||||
|
|
||||||
elif callback == "preset_menu":
|
elif callback == "preset_menu":
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ class UserState:
|
||||||
waiting_for_output_control: bool = False # Ожидание решения пользователя
|
waiting_for_output_control: bool = False # Ожидание решения пользователя
|
||||||
output_remaining: int = 0 # Сколько сообщений осталось
|
output_remaining: int = 0 # Сколько сообщений осталось
|
||||||
output_wait_message = None # Сообщение с кнопками
|
output_wait_message = None # Сообщение с кнопками
|
||||||
|
output_continue_event = None # asyncio.Event для разблокировки
|
||||||
continue_output: bool = True # Решение пользователя
|
continue_output: bool = True # Решение пользователя
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -231,21 +231,22 @@ async def send_long_message(update: Update, text: str, parse_mode: str = None, p
|
||||||
reply_markup=keyboard
|
reply_markup=keyboard
|
||||||
)
|
)
|
||||||
|
|
||||||
# Ждём ответа пользователя БЕСКОНЕЧНО
|
# Ждём ответа пользователя через asyncio.Event (не блокируем event loop)
|
||||||
from bot.config import state_manager
|
from bot.config import state_manager
|
||||||
|
import asyncio
|
||||||
|
|
||||||
user_id = update.effective_user.id
|
user_id = update.effective_user.id
|
||||||
|
|
||||||
# Сохраняем состояние ожидания
|
# Создаём Event для этого пользователя
|
||||||
|
continue_event = asyncio.Event()
|
||||||
state = state_manager.get(user_id)
|
state = state_manager.get(user_id)
|
||||||
state.waiting_for_output_control = True
|
state.waiting_for_output_control = True
|
||||||
state.output_remaining = remaining
|
state.output_remaining = remaining
|
||||||
state.output_wait_message = wait_msg
|
state.output_wait_message = wait_msg
|
||||||
|
state.output_continue_event = continue_event
|
||||||
|
|
||||||
# Ждём пока пользователь не нажмёт кнопку
|
# Ждём пока callback handler не установит event
|
||||||
while state.waiting_for_output_control:
|
await continue_event.wait()
|
||||||
await asyncio.sleep(1)
|
|
||||||
state = state_manager.get(user_id)
|
|
||||||
|
|
||||||
# Пользователь ответил
|
# Пользователь ответил
|
||||||
if state.continue_output:
|
if state.continue_output:
|
||||||
|
|
@ -254,17 +255,20 @@ async def send_long_message(update: Update, text: str, parse_mode: str = None, p
|
||||||
await wait_msg.delete()
|
await wait_msg.delete()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
# Очищаем состояние
|
|
||||||
state.output_remaining = None
|
|
||||||
state.output_wait_message = None
|
|
||||||
else:
|
else:
|
||||||
# Отменил - редактируем сообщение и убираем кнопки
|
# Отменил - удаляем сообщение с кнопками
|
||||||
try:
|
try:
|
||||||
await wait_msg.edit_text("❌ **Вывод отменен пользователем**", parse_mode="Markdown")
|
await wait_msg.delete()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return # Прерываем вывод
|
return # Прерываем вывод
|
||||||
|
|
||||||
|
# Очищаем состояние
|
||||||
|
state.waiting_for_output_control = False
|
||||||
|
state.output_remaining = None
|
||||||
|
state.output_wait_message = None
|
||||||
|
state.output_continue_event = None
|
||||||
|
|
||||||
|
|
||||||
def format_long_output(text: str, max_lines: int = 100, head_lines: int = 50, tail_lines: int = 50) -> str:
|
def format_long_output(text: str, max_lines: int = 100, head_lines: int = 50, tail_lines: int = 50) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue