127 lines
5.0 KiB
Python
127 lines
5.0 KiB
Python
"""Клавиатуры главного меню и пользовательских режимов бота."""
|
||
from __future__ import annotations
|
||
|
||
from aiogram.types import (
|
||
InlineKeyboardButton,
|
||
InlineKeyboardMarkup,
|
||
KeyboardButton,
|
||
ReplyKeyboardMarkup,
|
||
)
|
||
|
||
from help_message import HELP_SECTIONS, HELP_SECTION_ORDER
|
||
from user_store import SUBSCRIPTION_PLANS
|
||
|
||
MODE_BUTTONS: dict[str, str] = {
|
||
"🎓 Обучение": "/training",
|
||
"✍️ Генерация": "/generate",
|
||
"💳 Подписка": "/subscription",
|
||
"📖 Помощь": "/help",
|
||
}
|
||
MAIN_MENU_BUTTON = "🏠 Главное меню"
|
||
MAIN_MENU_VALUE = "__main_menu__"
|
||
TRAINING_RESET_BUTTON = "🗑 Сбросить данные"
|
||
TRAINING_RESET_VALUE = "__training_reset__"
|
||
TRAINING_INFO_BUTTON = "ℹ️ Инфо"
|
||
TRAINING_INFO_VALUE = "__training_info__"
|
||
POST_GENERATE_BUTTON = "✍️ Придумать пост"
|
||
SUPPORT_BUTTON = "🆘 Поддержка"
|
||
SUPPORT_VALUE = "__support__"
|
||
SUBSCRIPTION_ACTION_VALUE = "__subscription_action__"
|
||
BUY_SUBSCRIPTION_BUTTON = "🛒 Купить подписку"
|
||
RENEW_SUBSCRIPTION_BUTTON = "🔄 Продлить подписку"
|
||
|
||
BUTTON_TEXT_MAP: dict[str, str] = {
|
||
**MODE_BUTTONS,
|
||
MAIN_MENU_BUTTON: MAIN_MENU_VALUE,
|
||
"Главное меню": MAIN_MENU_VALUE,
|
||
TRAINING_RESET_BUTTON: TRAINING_RESET_VALUE,
|
||
TRAINING_INFO_BUTTON: TRAINING_INFO_VALUE,
|
||
POST_GENERATE_BUTTON: "/post",
|
||
SUPPORT_BUTTON: SUPPORT_VALUE,
|
||
BUY_SUBSCRIPTION_BUTTON: SUBSCRIPTION_ACTION_VALUE,
|
||
RENEW_SUBSCRIPTION_BUTTON: SUBSCRIPTION_ACTION_VALUE,
|
||
}
|
||
|
||
|
||
def main_menu_keyboard() -> ReplyKeyboardMarkup:
|
||
"""Показывает только четыре доступных пользователю режима."""
|
||
return ReplyKeyboardMarkup(
|
||
keyboard=[
|
||
[KeyboardButton(text="🎓 Обучение"), KeyboardButton(text="✍️ Генерация")],
|
||
[KeyboardButton(text="💳 Подписка"), KeyboardButton(text="📖 Помощь")],
|
||
],
|
||
resize_keyboard=True,
|
||
input_field_placeholder="Выбери действие",
|
||
)
|
||
|
||
|
||
def mode_keyboard(
|
||
mode: str,
|
||
support: bool = False,
|
||
subscription_purchased: bool = False,
|
||
) -> ReplyKeyboardMarkup:
|
||
"""Внутри режима показывает релевантные действия и возврат в меню.
|
||
|
||
В активном обращении поддержки остаётся только кнопка «Главное меню».
|
||
"""
|
||
rows = [[KeyboardButton(text=MAIN_MENU_BUTTON)]]
|
||
if support:
|
||
return ReplyKeyboardMarkup(
|
||
keyboard=rows,
|
||
resize_keyboard=True,
|
||
input_field_placeholder="Опиши проблему или вернись в главное меню",
|
||
)
|
||
if mode == "training":
|
||
rows.insert(0, [KeyboardButton(text=TRAINING_INFO_BUTTON)])
|
||
rows.append([KeyboardButton(text=TRAINING_RESET_BUTTON)])
|
||
elif mode == "generation":
|
||
rows.insert(0, [KeyboardButton(text=POST_GENERATE_BUTTON)])
|
||
elif mode == "help":
|
||
rows.insert(0, [KeyboardButton(text=SUPPORT_BUTTON)])
|
||
elif mode == "subscription":
|
||
action = RENEW_SUBSCRIPTION_BUTTON if subscription_purchased else BUY_SUBSCRIPTION_BUTTON
|
||
rows.insert(0, [KeyboardButton(text=action)])
|
||
return ReplyKeyboardMarkup(
|
||
keyboard=rows,
|
||
resize_keyboard=True,
|
||
input_field_placeholder=(
|
||
"Управляй обучением или вернись в меню"
|
||
if mode == "training"
|
||
else "Напиши сообщение или вернись в главное меню"
|
||
),
|
||
)
|
||
|
||
|
||
def subscription_plans_keyboard() -> InlineKeyboardMarkup:
|
||
return InlineKeyboardMarkup(inline_keyboard=[
|
||
[InlineKeyboardButton(text="0 дней — 1 ⭐", callback_data="subscription:plan:0")],
|
||
[InlineKeyboardButton(text="1 день — 15 ⭐", callback_data="subscription:plan:1")],
|
||
[InlineKeyboardButton(text="10 дней — 150 ⭐", callback_data="subscription:plan:10")],
|
||
[InlineKeyboardButton(text="30 дней — 450 ⭐", callback_data="subscription:plan:30")],
|
||
])
|
||
|
||
|
||
def help_inline_keyboard() -> InlineKeyboardMarkup:
|
||
"""Стандартная inline-клавиатура для навигации по разделам справки."""
|
||
return InlineKeyboardMarkup(
|
||
inline_keyboard=[
|
||
[InlineKeyboardButton(text=HELP_SECTIONS[section][0], callback_data=f"help:{section}")]
|
||
for section in HELP_SECTION_ORDER
|
||
],
|
||
)
|
||
|
||
|
||
MAIN_MENU = main_menu_keyboard()
|
||
LOCKED_MENU = mode_keyboard("subscription")
|
||
|
||
|
||
def resolve_button_text(text: str | None) -> str | None:
|
||
"""Возвращает команду или текст запроса для нажатой кнопки, иначе None."""
|
||
if not text:
|
||
return None
|
||
return BUTTON_TEXT_MAP.get(text.strip())
|
||
|
||
|
||
def price_hint() -> str:
|
||
return f"Продление подписки — {SUBSCRIPTION_PLANS[30]} ⭐ за 30 дней."
|