Files
social-post-writer-bot/keyboards.py
T
admin 971bf115da feat: reply-клавиатура + фикс пропавший _send_idea
- 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
2026-10-07 11:30:39 +02:00

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}»."