feat: restructure menu and add file import
- Consolidate "Add word" menu with submenu (Manual, Thematic, Import) - Add file import support (.txt, .md) with AI batch translation - Add vocabulary pagination with navigation buttons - Add "Add word" button in tasks for new words mode - Fix undefined variables bug in vocabulary confirm handler - Add localization keys for add_menu in ru/en/ja 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -30,10 +30,6 @@ def main_menu_keyboard(lang: str = 'ru') -> ReplyKeyboardMarkup:
|
||||
KeyboardButton(text=t(lang, "menu.task")),
|
||||
KeyboardButton(text=t(lang, "menu.practice")),
|
||||
],
|
||||
[
|
||||
KeyboardButton(text=t(lang, "menu.words")),
|
||||
KeyboardButton(text=t(lang, "menu.import")),
|
||||
],
|
||||
[
|
||||
KeyboardButton(text=t(lang, "menu.stats")),
|
||||
KeyboardButton(text=t(lang, "menu.settings")),
|
||||
@@ -100,12 +96,109 @@ def _menu_match(key: str):
|
||||
|
||||
@router.message(_menu_match('menu.add'))
|
||||
async def btn_add_pressed(message: Message, state: FSMContext):
|
||||
from bot.handlers.vocabulary import AddWordStates
|
||||
"""Показать меню добавления слов"""
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
await message.answer(t(lang, 'add.prompt'))
|
||||
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text=t(lang, 'add_menu.manual'), callback_data="add_manual")],
|
||||
[InlineKeyboardButton(text=t(lang, 'add_menu.thematic'), callback_data="add_thematic")],
|
||||
[InlineKeyboardButton(text=t(lang, 'add_menu.import'), callback_data="add_import")]
|
||||
])
|
||||
|
||||
await message.answer(t(lang, 'add_menu.title'), reply_markup=keyboard)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "add_manual")
|
||||
async def add_manual_callback(callback: CallbackQuery, state: FSMContext):
|
||||
"""Добавить слово вручную"""
|
||||
await callback.answer()
|
||||
from bot.handlers.vocabulary import AddWordStates
|
||||
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
await state.set_state(AddWordStates.waiting_for_word)
|
||||
await callback.message.edit_text(t(lang, 'add.prompt'))
|
||||
|
||||
|
||||
@router.callback_query(F.data == "add_thematic")
|
||||
async def add_thematic_callback(callback: CallbackQuery):
|
||||
"""Тематические слова"""
|
||||
await callback.answer()
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
# Показываем подсказку по использованию /words
|
||||
text = (
|
||||
t(lang, 'words.help_title') + "\n\n" +
|
||||
t(lang, 'words.help_usage') + "\n\n" +
|
||||
t(lang, 'words.help_examples') + "\n\n" +
|
||||
t(lang, 'words.help_note')
|
||||
)
|
||||
|
||||
# Популярные темы как кнопки
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(text=t(lang, 'words.topic_travel'), callback_data="words_travel"),
|
||||
InlineKeyboardButton(text=t(lang, 'words.topic_food'), callback_data="words_food")
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(text=t(lang, 'words.topic_work'), callback_data="words_work"),
|
||||
InlineKeyboardButton(text=t(lang, 'words.topic_technology'), callback_data="words_technology")
|
||||
],
|
||||
[InlineKeyboardButton(text="⬅️ " + t(lang, 'settings.back'), callback_data="back_to_add_menu")]
|
||||
])
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=keyboard)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("words_"))
|
||||
async def words_topic_callback(callback: CallbackQuery, state: FSMContext):
|
||||
"""Генерация слов по теме"""
|
||||
topic = callback.data.replace("words_", "")
|
||||
await callback.answer()
|
||||
await callback.message.delete()
|
||||
|
||||
from bot.handlers.words import generate_words_for_theme
|
||||
await generate_words_for_theme(callback.message, state, topic, callback.from_user.id)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "add_import")
|
||||
async def add_import_callback(callback: CallbackQuery):
|
||||
"""Показать меню импорта"""
|
||||
await callback.answer()
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text=t(lang, 'import_menu.from_text'), callback_data="import_from_text")],
|
||||
[InlineKeyboardButton(text=t(lang, 'import_menu.from_file'), callback_data="import_from_file")],
|
||||
[InlineKeyboardButton(text="⬅️ " + t(lang, 'settings.back'), callback_data="back_to_add_menu")]
|
||||
])
|
||||
|
||||
await callback.message.edit_text(t(lang, 'import_menu.title'), reply_markup=keyboard)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "back_to_add_menu")
|
||||
async def back_to_add_menu_callback(callback: CallbackQuery):
|
||||
"""Вернуться в меню добавления"""
|
||||
await callback.answer()
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text=t(lang, 'add_menu.manual'), callback_data="add_manual")],
|
||||
[InlineKeyboardButton(text=t(lang, 'add_menu.thematic'), callback_data="add_thematic")],
|
||||
[InlineKeyboardButton(text=t(lang, 'add_menu.import'), callback_data="add_import")]
|
||||
])
|
||||
|
||||
await callback.message.edit_text(t(lang, 'add_menu.title'), reply_markup=keyboard)
|
||||
|
||||
|
||||
@router.message(_menu_match('menu.vocab'))
|
||||
@@ -128,8 +221,51 @@ async def btn_practice_pressed(message: Message, state: FSMContext):
|
||||
|
||||
@router.message(_menu_match('menu.import'))
|
||||
async def btn_import_pressed(message: Message, state: FSMContext):
|
||||
from bot.handlers.import_text import cmd_import
|
||||
await cmd_import(message, state)
|
||||
"""Показать меню импорта"""
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text=t(lang, 'import_menu.from_text'), callback_data="import_from_text")],
|
||||
[InlineKeyboardButton(text=t(lang, 'import_menu.from_file'), callback_data="import_from_file")]
|
||||
])
|
||||
|
||||
await message.answer(t(lang, 'import_menu.title'), reply_markup=keyboard)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "import_from_text")
|
||||
async def import_from_text_callback(callback: CallbackQuery, state: FSMContext):
|
||||
"""Импорт из текста"""
|
||||
await callback.answer()
|
||||
from bot.handlers.import_text import ImportStates
|
||||
|
||||
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.message.edit_text(t('ru', 'common.start_first'))
|
||||
return
|
||||
|
||||
lang = user.language_interface or 'ru'
|
||||
await state.set_state(ImportStates.waiting_for_text)
|
||||
await callback.message.edit_text(
|
||||
t(lang, 'import.title') + "\n\n" +
|
||||
t(lang, 'import.desc') + "\n\n" +
|
||||
t(lang, 'import.can_send') + "\n\n" +
|
||||
t(lang, 'import.cancel_hint')
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "import_from_file")
|
||||
async def import_from_file_callback(callback: CallbackQuery):
|
||||
"""Импорт из файла"""
|
||||
await callback.answer()
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
await callback.message.edit_text(t(lang, 'import_menu.file_hint'))
|
||||
|
||||
|
||||
@router.message(_menu_match('menu.stats'))
|
||||
|
||||
Reference in New Issue
Block a user