- keyboards.py: MAIN_MENU (✍️ Написать пост / 💡 Идея / 🎨 Мой стиль / 📖 Помощь / 💳 Подписка / 👤 Баланс) и LOCKED_MENU — при блокировке первой кнопкой идёт «💳 Оплатить подписку» - кнопки не обходят роутинг: resolve_button_text превращает их в slash-команду (/help, /balance, /subscribe, /style) или готовый запрос («Напиши пост», «предложи идею…») - новая команда /style показывает сохранённый Tone of Voice и подсказывает, как его настроить - set_my_commands публикует slash-команды при старте, ошибка не роняет бот - fix: _send_idea вызывалась на bot.py, но была потеряна в коммите про подписку — /idea падал с NameError; функция восстановлена - 17 новых тестов клавиатуры; 92 теста OK; VERSION 0.1.0+26
71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
"""Reply-клавиатура бота: быстрый доступ к главным действиям.
|
|
|
|
Кнопки отправляют те же тексты, что и slash-команды, поэтому роутинг в
|
|
`handle_command_text` обрабатывает их без изменений.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from aiogram.types import (
|
|
KeyboardButton,
|
|
ReplyKeyboardMarkup,
|
|
ReplyKeyboardRemove,
|
|
)
|
|
|
|
from user_store import SUBSCRIPTION_PRICE_STARS
|
|
|
|
# Основное меню. Текст кнопки = текст команды, который обрабатывает handle_command_text.
|
|
MAIN_MENU = ReplyKeyboardMarkup(
|
|
keyboard=[
|
|
[
|
|
KeyboardButton(text="✍️ Написать пост"),
|
|
KeyboardButton(text="💡 Идея"),
|
|
],
|
|
[
|
|
KeyboardButton(text="🎨 Мой стиль"),
|
|
KeyboardButton(text="📖 Помощь"),
|
|
],
|
|
[
|
|
KeyboardButton(text="💳 Подписка"),
|
|
KeyboardButton(text="👤 Баланс"),
|
|
],
|
|
],
|
|
resize_keyboard=True,
|
|
input_field_placeholder="Напиши тему поста или нажми кнопку",
|
|
)
|
|
|
|
# Меню без подписки: главное — оплатить, а не генерация.
|
|
LOCKED_MENU = ReplyKeyboardMarkup(
|
|
keyboard=[
|
|
[
|
|
KeyboardButton(text="💳 Оплатить подписку"),
|
|
KeyboardButton(text="👤 Баланс"),
|
|
],
|
|
[KeyboardButton(text="📖 Помощь")],
|
|
],
|
|
resize_keyboard=True,
|
|
input_field_placeholder="Нужна подписка для генерации",
|
|
)
|
|
|
|
# Соответствие подписей кнопок текстам, которые понимает бот.
|
|
BUTTON_TEXT_MAP: dict[str, str] = {
|
|
"✍️ Написать пост": "Напиши пост",
|
|
"💡 Идея": "предложи идею для нового поста",
|
|
"🎨 Мой стиль": "/style",
|
|
"📖 Помощь": "/help",
|
|
"💳 Подписка": "/subscribe",
|
|
"👤 Баланс": "/balance",
|
|
"💳 Оплатить подписку": "/subscribe",
|
|
"🗑 Сбросить всё": "/clear",
|
|
}
|
|
|
|
|
|
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_PRICE_STARS} звёзд — кнопка «{LOCKED_MENU.keyboard[0][0].text}»."
|