feat(start): человекочитаемые кнопки главного меню и обработчики\n\n- Добавлена постоянная клавиатура с удобными подписями (эмодзи)\n- Добавлен /menu для показа клавиатуры в любой момент\n- Реализованы обработчики нажатий по тексту кнопок: /add, /vocabulary, /task, /practice, /import, /stats, /settings\n- Добавлены быстрые темы для тематических слов (inline) и обработчик их выбора

This commit is contained in:
2025-12-04 17:22:50 +03:00
parent c009b28843
commit fbdd339eb1

View File

@@ -15,6 +15,16 @@ from services.user_service import UserService
router = Router() router = Router()
# Тексты кнопок главного меню
BTN_ADD = " Добавить слово"
BTN_VOCAB = "📚 Словарь"
BTN_TASK = "🧠 Задание"
BTN_PRACTICE = "💬 Практика"
BTN_WORDS = "🎯 Тематические слова"
BTN_IMPORT = "📖 Импорт из текста"
BTN_STATS = "📊 Статистика"
BTN_SETTINGS = "⚙️ Настройки"
def main_menu_keyboard() -> ReplyKeyboardMarkup: def main_menu_keyboard() -> ReplyKeyboardMarkup:
"""Клавиатура с основными командами (кнопки отправляют команды).""" """Клавиатура с основными командами (кнопки отправляют команды)."""
@@ -22,20 +32,20 @@ def main_menu_keyboard() -> ReplyKeyboardMarkup:
resize_keyboard=True, resize_keyboard=True,
keyboard=[ keyboard=[
[ [
KeyboardButton(text="/add"), KeyboardButton(text=BTN_ADD),
KeyboardButton(text="/vocabulary"), KeyboardButton(text=BTN_VOCAB),
], ],
[ [
KeyboardButton(text="/task"), KeyboardButton(text=BTN_TASK),
KeyboardButton(text="/practice"), KeyboardButton(text=BTN_PRACTICE),
], ],
[ [
KeyboardButton(text="/words travel"), KeyboardButton(text=BTN_WORDS),
KeyboardButton(text="/import"), KeyboardButton(text=BTN_IMPORT),
], ],
[ [
KeyboardButton(text="/stats"), KeyboardButton(text=BTN_STATS),
KeyboardButton(text="/settings"), KeyboardButton(text=BTN_SETTINGS),
], ],
], ],
) )
@@ -114,6 +124,108 @@ async def cmd_menu(message: Message):
await message.answer("Главное меню доступно ниже ⤵️", reply_markup=main_menu_keyboard()) await message.answer("Главное меню доступно ниже ⤵️", reply_markup=main_menu_keyboard())
# Обработчики кнопок главного меню (по тексту)
@router.message(F.text == BTN_ADD)
async def btn_add_pressed(message: Message, state: FSMContext):
from bot.handlers.vocabulary import AddWordStates
await message.answer(
"Отправь слово, которое хочешь добавить:\n"
"Например: <code>/add elephant</code>\n\n"
"Или просто отправь слово без команды!"
)
await state.set_state(AddWordStates.waiting_for_word)
@router.message(F.text == BTN_VOCAB)
async def btn_vocab_pressed(message: Message):
from bot.handlers.vocabulary import cmd_vocabulary
await cmd_vocabulary(message)
@router.message(F.text == BTN_TASK)
async def btn_task_pressed(message: Message, state: FSMContext):
from bot.handlers.tasks import cmd_task
await cmd_task(message, state)
@router.message(F.text == BTN_PRACTICE)
async def btn_practice_pressed(message: Message, state: FSMContext):
from bot.handlers.practice import cmd_practice
await cmd_practice(message, state)
@router.message(F.text == BTN_IMPORT)
async def btn_import_pressed(message: Message, state: FSMContext):
from bot.handlers.import_text import cmd_import
await cmd_import(message, state)
@router.message(F.text == BTN_STATS)
async def btn_stats_pressed(message: Message):
from bot.handlers.tasks import cmd_stats
await cmd_stats(message)
@router.message(F.text == BTN_SETTINGS)
async def btn_settings_pressed(message: Message):
from bot.handlers.settings import cmd_settings
await cmd_settings(message)
@router.message(F.text == BTN_WORDS)
async def btn_words_pressed(message: Message, state: FSMContext):
"""Подсказать про тематические слова и показать быстрые темы."""
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
text = (
"📚 <b>Тематические подборки слов</b>\n\n"
"Используй: <code>/words [тема]</code>\n\n"
"Популярные темы:"
)
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="✈️ Путешествия", callback_data="menu_theme_travel")],
[InlineKeyboardButton(text="🍔 Еда", callback_data="menu_theme_food")],
[InlineKeyboardButton(text="💼 Работа", callback_data="menu_theme_work")],
[InlineKeyboardButton(text="🌿 Природа", callback_data="menu_theme_nature")],
[InlineKeyboardButton(text="💻 Технологии", callback_data="menu_theme_technology")],
])
await message.answer(text, reply_markup=keyboard)
@router.callback_query(F.data.startswith("menu_theme_"))
async def pick_theme_from_menu(callback: CallbackQuery, state: FSMContext):
"""Сгенерировать слова по выбранной теме из меню и показать список."""
from database.db import async_session_maker
from services.user_service import UserService
from services.ai_service import ai_service
from bot.handlers.words import show_words_list, WordsStates
theme = callback.data.split("menu_theme_")[-1]
async with async_session_maker() as session:
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
if not user:
await callback.answer("Сначала /start", show_alert=True)
return
generating = await callback.message.answer(f"🔄 Генерирую подборку слов по теме '{theme}'...")
words = await ai_service.generate_thematic_words(theme=theme, level=user.level.value, count=10)
await generating.delete()
if not words:
await callback.message.answer("Не удалось сгенерировать подборку. Попробуй позже.")
await callback.answer()
return
# Сохраняем в состояние как в /words
await state.update_data(theme=theme, words=words, user_id=user.id, level=user.level.name)
await state.set_state(WordsStates.viewing_words)
await show_words_list(callback.message, words, theme)
await callback.answer()
@router.message(Command("help")) @router.message(Command("help"))
async def cmd_help(message: Message): async def cmd_help(message: Message):
"""Обработчик команды /help""" """Обработчик команды /help"""