feat: add translation language setting & onboarding flow
- Add separate translation_language setting (independent from interface language) - Implement 3-step onboarding for new users: 1. Choose interface language 2. Choose learning language 3. Choose translation language - Fix localization issues when using callback.message (user_id from state) - Add UserService.get_user_by_id() method - Add get_user_translation_lang() helper in i18n - Update all handlers to use correct translation language - Add localization keys for onboarding (ru/en/ja) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -24,11 +24,14 @@ async def cmd_level_test(message: Message, state: FSMContext):
|
||||
await start_level_test(message, state)
|
||||
|
||||
|
||||
async def start_level_test(message: Message, state: FSMContext):
|
||||
async def start_level_test(message: Message, state: FSMContext, telegram_id: int = None):
|
||||
"""Начать тест определения уровня"""
|
||||
# Определяем ID пользователя (telegram_id передаётся при вызове из callback)
|
||||
user_telegram_id = telegram_id or message.from_user.id
|
||||
|
||||
# Показываем описание теста
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
|
||||
user = await UserService.get_user_by_telegram_id(session, user_telegram_id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
await message.answer(t(lang, 'level_test.intro'))
|
||||
|
||||
@@ -83,7 +86,8 @@ async def begin_test(callback: CallbackQuery, state: FSMContext):
|
||||
current_question=0,
|
||||
correct_answers=0,
|
||||
answers=[], # Для отслеживания ответов по уровням
|
||||
learning_language=learning_lang
|
||||
learning_language=learning_lang,
|
||||
user_id=user.id
|
||||
)
|
||||
await state.set_state(LevelTestStates.taking_test)
|
||||
|
||||
@@ -96,6 +100,7 @@ async def show_question(message: Message, state: FSMContext):
|
||||
data = await state.get_data()
|
||||
questions = data.get('questions', [])
|
||||
current_idx = data.get('current_question', 0)
|
||||
user_id = data.get('user_id')
|
||||
|
||||
if current_idx >= len(questions):
|
||||
# Тест завершён
|
||||
@@ -105,9 +110,9 @@ async def show_question(message: Message, state: FSMContext):
|
||||
question = questions[current_idx]
|
||||
|
||||
# Формируем текст вопроса
|
||||
# Язык интерфейса
|
||||
# Язык интерфейса (берём user_id из state, т.к. message может быть от бота)
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
|
||||
user = await UserService.get_user_by_id(session, user_id)
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
|
||||
text = (
|
||||
@@ -127,10 +132,6 @@ async def show_question(message: Message, state: FSMContext):
|
||||
])
|
||||
|
||||
# Кнопка для показа перевода вопроса (локализованная)
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, message.chat.id)
|
||||
from utils.i18n import t
|
||||
lang = (user.language_interface if user else 'ru') or 'ru'
|
||||
keyboard.append([
|
||||
InlineKeyboardButton(text=t(lang, 'level_test.show_translation_btn'), callback_data=f"show_qtr_{current_idx}")
|
||||
])
|
||||
@@ -237,6 +238,7 @@ async def finish_test(message: Message, state: FSMContext):
|
||||
correct_answers = data.get('correct_answers', 0)
|
||||
answers = data.get('answers', [])
|
||||
learning_lang = data.get('learning_language', 'en')
|
||||
user_id = data.get('user_id')
|
||||
|
||||
total = len(questions)
|
||||
accuracy = int((correct_answers / total) * 100) if total > 0 else 0
|
||||
@@ -244,9 +246,9 @@ async def finish_test(message: Message, state: FSMContext):
|
||||
# Определяем уровень на основе правильных ответов по уровням
|
||||
level = determine_level(answers, learning_lang)
|
||||
|
||||
# Сохраняем уровень в базе данных
|
||||
# Сохраняем уровень в базе данных (берём user_id из state, т.к. message может быть от бота)
|
||||
async with async_session_maker() as session:
|
||||
user = await UserService.get_user_by_telegram_id(session, message.chat.id)
|
||||
user = await UserService.get_user_by_id(session, user_id)
|
||||
if user:
|
||||
await UserService.update_user_level(session, user.id, level, learning_lang)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user