Add notification settings
This commit is contained in:
@@ -3,7 +3,7 @@ from aiogram.filters import Command
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
|
||||
from keyboards.main_menu import get_main_menu
|
||||
from keyboards.inline import get_marathons_keyboard, get_marathon_details_keyboard
|
||||
from keyboards.inline import get_marathons_keyboard, get_marathon_details_keyboard, get_settings_keyboard
|
||||
from services.api_client import api_client
|
||||
|
||||
router = Router()
|
||||
@@ -197,15 +197,66 @@ async def cmd_settings(message: Message):
|
||||
)
|
||||
return
|
||||
|
||||
# Get current notification settings
|
||||
settings = await api_client.get_notification_settings(message.from_user.id)
|
||||
if not settings:
|
||||
settings = {"notify_events": True, "notify_disputes": True, "notify_moderation": True}
|
||||
|
||||
await message.answer(
|
||||
"<b>⚙️ Настройки</b>\n\n"
|
||||
"Управление уведомлениями будет доступно в следующем обновлении.\n\n"
|
||||
"Сейчас ты получаешь все уведомления:\n"
|
||||
"• 🌟 События (Golden Hour, Jackpot и др.)\n"
|
||||
"• 🚀 Старт/финиш марафонов\n"
|
||||
"• ⚠️ Споры по заданиям\n\n"
|
||||
"Команды:\n"
|
||||
"/unlink - Отвязать аккаунт\n"
|
||||
"/status - Проверить привязку",
|
||||
"<b>⚙️ Настройки уведомлений</b>\n\n"
|
||||
"Нажми на категорию, чтобы включить/выключить:\n\n"
|
||||
"✅ — уведомления включены\n"
|
||||
"❌ — уведомления выключены\n\n"
|
||||
"<i>Уведомления о старте/финише марафонов и коды безопасности нельзя отключить.</i>",
|
||||
reply_markup=get_settings_keyboard(settings)
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("toggle:"))
|
||||
async def toggle_notification(callback: CallbackQuery):
|
||||
"""Toggle notification setting."""
|
||||
setting_name = callback.data.split(":")[1]
|
||||
|
||||
# Get current settings
|
||||
current_settings = await api_client.get_notification_settings(callback.from_user.id)
|
||||
if not current_settings:
|
||||
await callback.answer("Не удалось загрузить настройки", show_alert=True)
|
||||
return
|
||||
|
||||
# Toggle the setting
|
||||
current_value = current_settings.get(setting_name, True)
|
||||
new_value = not current_value
|
||||
|
||||
# Update on backend
|
||||
result = await api_client.update_notification_settings(
|
||||
callback.from_user.id,
|
||||
{setting_name: new_value}
|
||||
)
|
||||
|
||||
if not result or result.get("error"):
|
||||
await callback.answer("Не удалось сохранить настройки", show_alert=True)
|
||||
return
|
||||
|
||||
# Update keyboard with new values
|
||||
await callback.message.edit_reply_markup(
|
||||
reply_markup=get_settings_keyboard(result)
|
||||
)
|
||||
|
||||
status = "включены" if new_value else "выключены"
|
||||
setting_names = {
|
||||
"notify_events": "События",
|
||||
"notify_disputes": "Споры",
|
||||
"notify_moderation": "Модерация"
|
||||
}
|
||||
await callback.answer(f"{setting_names.get(setting_name, setting_name)}: {status}")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "back_to_menu")
|
||||
async def back_to_menu(callback: CallbackQuery):
|
||||
"""Go back to main menu from settings."""
|
||||
await callback.message.delete()
|
||||
await callback.message.answer(
|
||||
"Главное меню",
|
||||
reply_markup=get_main_menu()
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@@ -40,3 +40,45 @@ def get_marathon_details_keyboard(marathon_id: int) -> InlineKeyboardMarkup:
|
||||
]
|
||||
|
||||
return InlineKeyboardMarkup(inline_keyboard=buttons)
|
||||
|
||||
|
||||
def get_settings_keyboard(settings: dict) -> InlineKeyboardMarkup:
|
||||
"""Create keyboard for notification settings."""
|
||||
# Get current values with defaults
|
||||
notify_events = settings.get("notify_events", True)
|
||||
notify_disputes = settings.get("notify_disputes", True)
|
||||
notify_moderation = settings.get("notify_moderation", True)
|
||||
|
||||
# Status indicators
|
||||
events_status = "✅" if notify_events else "❌"
|
||||
disputes_status = "✅" if notify_disputes else "❌"
|
||||
moderation_status = "✅" if notify_moderation else "❌"
|
||||
|
||||
buttons = [
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=f"{events_status} События (Golden Hour, Jackpot...)",
|
||||
callback_data="toggle:notify_events"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=f"{disputes_status} Споры",
|
||||
callback_data="toggle:notify_disputes"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=f"{moderation_status} Модерация (игры/челленджи)",
|
||||
callback_data="toggle:notify_moderation"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="◀️ Назад",
|
||||
callback_data="back_to_menu"
|
||||
)
|
||||
]
|
||||
]
|
||||
|
||||
return InlineKeyboardMarkup(inline_keyboard=buttons)
|
||||
|
||||
@@ -124,6 +124,22 @@ class APIClient:
|
||||
"""Get user's overall statistics."""
|
||||
return await self._request("GET", f"/telegram/stats/{telegram_id}")
|
||||
|
||||
async def get_notification_settings(self, telegram_id: int) -> dict[str, Any] | None:
|
||||
"""Get user's notification settings."""
|
||||
return await self._request("GET", f"/telegram/notifications/{telegram_id}")
|
||||
|
||||
async def update_notification_settings(
|
||||
self,
|
||||
telegram_id: int,
|
||||
settings: dict[str, bool]
|
||||
) -> dict[str, Any] | None:
|
||||
"""Update user's notification settings."""
|
||||
return await self._request(
|
||||
"PATCH",
|
||||
f"/telegram/notifications/{telegram_id}",
|
||||
json=settings
|
||||
)
|
||||
|
||||
async def close(self):
|
||||
"""Close the HTTP session."""
|
||||
if self._session and not self._session.closed:
|
||||
|
||||
Reference in New Issue
Block a user