diff --git a/telegram_bot_project/bot/buttons.py b/telegram_bot_project/bot/buttons.py index 969fc86..c1cb1b1 100644 --- a/telegram_bot_project/bot/buttons.py +++ b/telegram_bot_project/bot/buttons.py @@ -27,4 +27,13 @@ def menu_reply_keyboard() -> ReplyKeyboardMarkup: reply_keyboard.keyboard.append([button_settings, button_idea]) reply_keyboard.keyboard.append([button_day, button_task]) - return reply_keyboard \ No newline at end of file + return reply_keyboard + +def get_idea_conf_keyboard() -> InlineKeyboardMarkup: + inline_markup = InlineKeyboardMarkup(inline_keyboard=[], row_width=2) + + delete_button: InlineKeyboardButton = InlineKeyboardButton(text=DEL_BUTTON, callback_data="delete_idea") + save_button: InlineKeyboardButton = InlineKeyboardButton(text=SAVE_BUTTON, callback_data="save_idea") + + inline_markup.inline_keyboard.append([delete_button, save_button]) + return inline_markup \ No newline at end of file diff --git a/telegram_bot_project/bot/callbacks.py b/telegram_bot_project/bot/callbacks.py index 9a016d6..9de9246 100644 --- a/telegram_bot_project/bot/callbacks.py +++ b/telegram_bot_project/bot/callbacks.py @@ -1,8 +1,10 @@ -from typing import Optional +from typing import Optional, Any from aiogram import types +from aiogram.fsm.context import FSMContext from bot.buttons import menu_reply_keyboard from messages import MESSAGES +from service.idea import IdeaService from service.user import UserService async def start_callback_language(callback_query: types.CallbackQuery) -> None: @@ -31,4 +33,45 @@ async def start_callback_language(callback_query: types.CallbackQuery) -> None: case _: print(f"--[INFO] - User {user_id} ({user_name}) sent invalid callback: {callback_query.data}") - await callback_query.message.answer(MESSAGES[language]["LANGUAGE_INVALID"]) \ No newline at end of file + await callback_query.message.answer(MESSAGES[language]["LANGUAGE_INVALID"]) + + +async def callback_idea_process(callback_query: types.CallbackQuery, state: FSMContext) -> None: + await callback_query.answer() + + user_id: int = callback_query.from_user.id + user_name: str = callback_query.from_user.username or "unknown" + user_find: Optional[dict] = await UserService.get_user_by_id(user_id) + language: str = await UserService.get_user_language(user_id) + if not language: + language = 'ENGLISH' + + if not user_find: + await callback_query.message.answer(MESSAGES['ENGLISH']["AUTHORIZATION_PROBLEM"]) + return + + match callback_query.data: + case "delete_idea": + print(f"--[INFO] - User {user_id} ({user_name}) deleted idea.") + await callback_query.message.answer(MESSAGES[language]["IDEA_DELETE"], reply_markup=menu_reply_keyboard()) + await state.clear() + case "save_idea": + try: + data: Any = await state.get_data() + idea: str = data.get("idea") + + if not idea: + print(f"--[INFO] - User {user_id} ({user_name}) sent empty idea.") + await callback_query.message.answer(MESSAGES[language]["IDEA_PROBLEM"], reply_markup=menu_reply_keyboard()) + return + else: + await IdeaService.create_user_idea(user_id, idea) + + print(f"--[INFO] - User {user_id} ({user_name}) saved idea: {idea}") + await callback_query.message.answer(MESSAGES[language]["IDEA_SAVED"], reply_markup=menu_reply_keyboard()) + await state.clear() + except Exception as e: + await callback_query.message.answer(MESSAGES[language]["IDEA_PROBLEM"]) + case _: + print(f"--[INFO] - User {user_id} ({user_name}) sent invalid callback: {callback_query.data}") + await callback_query.message.answer(MESSAGES[language]["IDEA_PROBLEM"], reply_markup=menu_reply_keyboard()) diff --git a/telegram_bot_project/bot/handlers.py b/telegram_bot_project/bot/handlers.py index 6e62b4c..111bd45 100644 --- a/telegram_bot_project/bot/handlers.py +++ b/telegram_bot_project/bot/handlers.py @@ -1,15 +1,12 @@ from aiogram.fsm.context import FSMContext -from aiogram.types import Message +from aiogram.types import Message, InlineKeyboardMarkup -from bot.buttons import menu_reply_keyboard +from bot.buttons import get_idea_conf_keyboard from messages import MESSAGES -from service.idea import IdeaService from service.user import UserService async def process_idea_save(message: Message, state: FSMContext) -> None: user_id = message.from_user.id - user_name = message.from_user.username or "unknown" - user_find = await UserService.get_user_by_id(user_id) if not user_find or not user_find.get("id"): await message.answer(MESSAGES["ENGLISH"]['AUTHORIZATION_PROBLEM']) @@ -20,10 +17,11 @@ async def process_idea_save(message: Message, state: FSMContext) -> None: print(f"--[INFO] User with id: {user_id} - provide idea.") try: - await IdeaService.create_user_idea(user_id, idea) - print(f"--[INFO] - User {user_id} ({user_name}) saved idea: {idea}") - await message.answer(MESSAGES[language]['IDEA_SAVED'], reply_markup=menu_reply_keyboard()) - await state.clear() + await state.update_data(idea=idea) + + dividers: str = "\n" + ("-" * int(len(MESSAGES[language]['IDEA_ACTION']) * 1.65)) + keyboard: InlineKeyboardMarkup = get_idea_conf_keyboard() + await message.answer(MESSAGES[language]['IDEA_ACTION'] + dividers + f"\nIDEA: {idea}", reply_markup=keyboard) except Exception as e: print(f"[ERROR] Saving idea failed: {e}") await message.answer(MESSAGES[language].get('ERROR_SAVING_IDEA', 'Ошибка при сохранении идеи. Попробуйте позже.')) diff --git a/telegram_bot_project/main.py b/telegram_bot_project/main.py index 9d106bb..6ca8f5c 100644 --- a/telegram_bot_project/main.py +++ b/telegram_bot_project/main.py @@ -7,7 +7,7 @@ from config import TOKEN from bot.commands import start_command, help_command, menu_command, language_command, idea_command from bot.handlers import process_idea_save -from bot.callbacks import start_callback_language +from bot.callbacks import start_callback_language, callback_idea_process from states import DialogStates storage: MemoryStorage = MemoryStorage() @@ -38,6 +38,10 @@ async def idea(message: Message, state: FSMContext): async def callback_language(callback_query: CallbackQuery): await start_callback_language(callback_query) +@dp.callback_query(F.data.in_({"delete_idea", "save_idea"})) +async def callback_idea(callback_query: CallbackQuery, state: FSMContext): + await callback_idea_process(callback_query, state) + @dp.message() async def process_idea_fallback(message: Message, state: FSMContext): current_state = await state.get_state() diff --git a/telegram_bot_project/messages.py b/telegram_bot_project/messages.py index e189490..dd068d6 100644 --- a/telegram_bot_project/messages.py +++ b/telegram_bot_project/messages.py @@ -2,51 +2,57 @@ MESSAGES: Any = { "UKRANIAN": { - "START_MSG": "🎉 Ласкаво просимо до бота!\nГотові почати новий продуктивний день?", - "START_MSG_AGAIN": "👋 З поверненням, чемпіоне!\nРадий вас бачити знову 😊", - "HELP_MSG": "ℹ️ Потрібна допомога?\nВикористовуйте /start, /language або /menu, щоб знайти потрібне 📋", - "MENU_MSG": "📋 **Ваше меню:**\nОбирайте дію нижче 👇", - "AUTHORIZATION_PROBLEM": "🚫 Упс, ви не авторизовані.\nБудь ласка, спробуйте /start, щоб почати.", - "TEXT_RESPONSE": "✉️ Ви написали: \"{response}\".\nДякую за повідомлення! 🙌", - "CONTINUE_MSG": "✨ Чим ще можу допомогти?\nСміливо користуйтесь /menu для всіх можливостей 🌟", - "SETTINGS_RESPONSE": "🔧 Відкриваю налаштування...", + "START_MSG": "🎉 Ласкаво просимо до бота!\nГотові розпочати свій продуктивний день разом зі мною?", + "START_MSG_AGAIN": "👋 Вітаю з поверненням, чемпіоне!\nРадий знову бачити вас 😊", + "HELP_MSG": "ℹ️ Потрібна допомога?\nСпробуйте /start, /language або /menu — я завжди поруч, щоб допомогти 📋", + "MENU_MSG": "📋 **Ось ваше меню:**\nОберіть потрібну дію 👇", + "AUTHORIZATION_PROBLEM": "🚫 Упс, здається, ви не авторизовані.\nБудь ласка, введіть /start, щоб почати.", + "TEXT_RESPONSE": "✉️ Ви написали: \"{response}\".\nДякую, що поділилися! 🙌", + "CONTINUE_MSG": "✨ Чим ще можу допомогти?\nСміливо відкривайте /menu для всіх можливостей 🌟", + "SETTINGS_RESPONSE": "🔧 Відкриваю налаштування для вас...", "MYDAY_RESPONSE": "📅 Ось ваш план на сьогодні...", - "IDEA_RESPONSE": "💡 Поділіться своєю ідеєю, я все запишу!", - "IDEA_SAVED": "💡 Ідея успішно збережена.", - "ADD_TASK_RESPONSE": "📝 Створюємо нову задачу...", + "IDEA_RESPONSE": "💡 Розкажіть свою ідею — я обов’язково її зафіксую!", + "IDEA_SAVED": "💡 Ідея успішно збережена. Молодець!", + "ADD_TASK_RESPONSE": "📝 Створюємо нове завдання...", + "IDEA_ACTION": "Що бажаєте зробити з цією ідеєю?", + "IDEA_DELETE": "🗑️ Ідею було видалено.", + "IDEA_PROBLEM": "⚠️ Виникла проблема із збереженням ідеї. Спробуйте ще раз.", "LANGUAGE_ASK": ( "🌐 **Оберіть мову інтерфейсу:**\n" "Натисніть кнопку нижче, щоб продовжити:" ), "LANGUAGE_OK": ( - "✅ **Мову оновлено!**\n" + "✅ **Мову успішно оновлено!**\n" "Продовжуємо працювати разом." ), "LANGUAGE_INVALID": ( - "⚠️ Упс! Це недійсний варіант.\n" + "⚠️ Упс! Цей варіант недійсний.\n" "Будь ласка, оберіть мову зі списку." ) }, "ENGLISH": { - "START_MSG": "🎉 Welcome to the bot!\nReady to kick off a productive day?", - "START_MSG_AGAIN": "👋 Welcome back, legend!\nHappy to see you again 😊", - "HELP_MSG": "ℹ️ Need some help?\nUse /start, /language, or /menu to get around 📋", - "MENU_MSG": "📋 **Your menu:**\nPick what you’d like to do 👇", - "AUTHORIZATION_PROBLEM": "🚫 Oops! You’re not authorized.\nPlease use /start to begin.", + "START_MSG": "🎉 Welcome to the bot!\nReady to start a productive day together?", + "START_MSG_AGAIN": "👋 Welcome back, legend!\nGlad to see you again 😊", + "HELP_MSG": "ℹ️ Need help?\nTry /start, /language, or /menu — I’m here for you 📋", + "MENU_MSG": "📋 **Here’s your menu:**\nChoose what you'd like to do 👇", + "AUTHORIZATION_PROBLEM": "🚫 Oops! You’re not authorized yet.\nPlease type /start to begin.", "TEXT_RESPONSE": "✉️ You wrote: \"{response}\".\nThanks for sharing! 🙌", - "CONTINUE_MSG": "✨ What else can I help you with?\nUse /menu to explore all options 🌟", - "SETTINGS_RESPONSE": "🔧 Opening your settings...", + "CONTINUE_MSG": "✨ What else can I do for you?\nFeel free to use /menu for all options 🌟", + "SETTINGS_RESPONSE": "🔧 Opening your settings now...", "MYDAY_RESPONSE": "📅 Here’s your plan for today...", - "IDEA_RESPONSE": "💡 Tell me your idea, I’ll save it for you!", - "IDEA_SAVED": "💡 Idea saved successfully.", + "IDEA_RESPONSE": "💡 Share your idea with me — I’ll save it safely!", + "IDEA_SAVED": "💡 Idea saved successfully. Well done!", "ADD_TASK_RESPONSE": "📝 Creating a new task...", + "IDEA_ACTION": "What would you like to do with your idea?", + "IDEA_DELETE": "🗑️ Idea has been deleted.", + "IDEA_PROBLEM": "⚠️ There was an issue saving your idea. Please try again.", "LANGUAGE_ASK": ( - "🌐 **Choose your language:**\n" + "🌐 **Please choose your interface language:**\n" "Tap a button below to continue:" ), "LANGUAGE_OK": ( - "✅ **Language updated!**\n" - "Let’s keep moving forward." + "✅ **Language updated successfully!**\n" + "Let’s keep moving forward together." ), "LANGUAGE_INVALID": ( "⚠️ Oops! That’s not a valid option.\n" @@ -61,4 +67,6 @@ BUTTON_SETTINGS: str = "⚙️ Settings" BUTTON_HELP: str = "❓ Help" BUTTON_UA_LANG: str = "🇺🇦 Ukrainian" -BUTTON_EN_LANG: str = "🇬🇧 English" \ No newline at end of file +BUTTON_EN_LANG: str = "🇬🇧 English" +DEL_BUTTON: str = "🗑️ Delete" +SAVE_BUTTON: str = "💾 Save" diff --git a/telegram_bot_project/states.py b/telegram_bot_project/states.py index ec2dfea..d2ec95b 100644 --- a/telegram_bot_project/states.py +++ b/telegram_bot_project/states.py @@ -2,3 +2,4 @@ class DialogStates(StatesGroup): waiting_for_idea = State() + confirm_idea = State() \ No newline at end of file