245 lines
9.7 KiB
Python
245 lines
9.7 KiB
Python
from __future__ import annotations
|
||
from typing import Iterable, List, Optional, Any
|
||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||
|
||
from .messages import MessageType
|
||
|
||
def template_type_keyboard() -> InlineKeyboardMarkup:
|
||
"""Возвращает клавиатуру выбора типа шаблона."""
|
||
return KbBuilder.template_type_keyboard()
|
||
|
||
def get_templates_keyboard(templates: List[Any], page: int = 0) -> InlineKeyboardMarkup:
|
||
"""Возвращает клавиатуру со списком шаблонов."""
|
||
return KbBuilder.get_templates_keyboard(templates, page)
|
||
|
||
|
||
class KbBuilder:
|
||
"""Строитель клавиатур для различных состояний бота."""
|
||
|
||
PAGE_SIZE = 8
|
||
|
||
@staticmethod
|
||
def channels(channels: Iterable) -> InlineKeyboardMarkup:
|
||
"""Клавиатура выбора канала."""
|
||
rows = [
|
||
[InlineKeyboardButton(
|
||
ch.title or str(ch.chat_id),
|
||
callback_data=f"channel:{ch.id}"
|
||
)]
|
||
for ch in channels
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def post_types() -> InlineKeyboardMarkup:
|
||
"""Клавиатура выбора типа поста."""
|
||
rows = [
|
||
[
|
||
InlineKeyboardButton("📝 Текст", callback_data=f"type:{MessageType.TEXT.value}"),
|
||
InlineKeyboardButton("📷 Фото", callback_data=f"type:{MessageType.PHOTO.value}")
|
||
],
|
||
[
|
||
InlineKeyboardButton("🎥 Видео", callback_data=f"type:{MessageType.VIDEO.value}"),
|
||
InlineKeyboardButton("🎬 GIF", callback_data=f"type:{MessageType.ANIMATION.value}")
|
||
],
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def parse_modes() -> InlineKeyboardMarkup:
|
||
"""Клавиатура выбора формата текста."""
|
||
rows = [
|
||
[
|
||
InlineKeyboardButton("HTML", callback_data="fmt:HTML"),
|
||
InlineKeyboardButton("MarkdownV2", callback_data="fmt:MarkdownV2")
|
||
]
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def template_type_keyboard() -> InlineKeyboardMarkup:
|
||
"""Клавиатура выбора типа шаблона."""
|
||
rows = [
|
||
[
|
||
InlineKeyboardButton("📝 Текст", callback_data=f"tpl_type:{MessageType.TEXT.value}"),
|
||
InlineKeyboardButton("📷 Фото", callback_data=f"tpl_type:{MessageType.PHOTO.value}")
|
||
],
|
||
[
|
||
InlineKeyboardButton("🎥 Видео", callback_data=f"tpl_type:{MessageType.VIDEO.value}"),
|
||
InlineKeyboardButton("🎬 GIF", callback_data=f"tpl_type:{MessageType.ANIMATION.value}")
|
||
]
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def get_templates_keyboard(templates: List[Any], page: int = 0) -> InlineKeyboardMarkup:
|
||
"""Клавиатура списка шаблонов с пагинацией."""
|
||
start_idx = page * KbBuilder.PAGE_SIZE
|
||
end_idx = start_idx + KbBuilder.PAGE_SIZE
|
||
page_templates = templates[start_idx:end_idx]
|
||
|
||
rows = []
|
||
for template in page_templates:
|
||
rows.append([
|
||
InlineKeyboardButton(
|
||
f"{template.name} ({template.type})",
|
||
callback_data=f"template:{template.id}"
|
||
)
|
||
])
|
||
|
||
nav_row = []
|
||
if page > 0:
|
||
nav_row.append(InlineKeyboardButton("◀️ Назад", callback_data=f"page:{page-1}"))
|
||
if end_idx < len(templates):
|
||
nav_row.append(InlineKeyboardButton("Вперед ▶️", callback_data=f"page:{page+1}"))
|
||
|
||
if nav_row:
|
||
rows.append(nav_row)
|
||
|
||
return InlineKeyboardMarkup(rows)
|
||
@staticmethod
|
||
def go_back() -> InlineKeyboardMarkup:
|
||
"""Клавиатура с кнопкой назад."""
|
||
return InlineKeyboardMarkup([
|
||
[InlineKeyboardButton("« Назад", callback_data="back")]
|
||
])
|
||
|
||
@staticmethod
|
||
def text_input_options() -> InlineKeyboardMarkup:
|
||
"""Клавиатура при вводе текста."""
|
||
rows = [
|
||
[InlineKeyboardButton("📋 Использовать шаблон", callback_data="tpl:choose")],
|
||
[InlineKeyboardButton("⌨️ Добавить клавиатуру", callback_data="kb:add")],
|
||
[InlineKeyboardButton("❌ Отмена", callback_data="cancel")]
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def send_confirm() -> InlineKeyboardMarkup:
|
||
"""Клавиатура подтверждения отправки."""
|
||
rows = [
|
||
[InlineKeyboardButton("📤 Отправить сейчас", callback_data="send:now")],
|
||
[InlineKeyboardButton("⏰ Запланировать", callback_data="send:schedule")],
|
||
[InlineKeyboardButton("✏️ Редактировать", callback_data="send:edit")],
|
||
[InlineKeyboardButton("❌ Отмена", callback_data="send:cancel")]
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def preview_confirm() -> InlineKeyboardMarkup:
|
||
"""Клавиатура после предпросмотра."""
|
||
rows = [
|
||
[InlineKeyboardButton("✅ Использовать", callback_data="pv:use")],
|
||
[InlineKeyboardButton("✏️ Изменить переменные", callback_data="pv:edit")],
|
||
[InlineKeyboardButton("❌ Отмена", callback_data="tpl:cancel")]
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def templates_list(
|
||
items: List,
|
||
page: int,
|
||
total: int,
|
||
show_delete: bool = False
|
||
) -> InlineKeyboardMarkup:
|
||
"""
|
||
Клавиатура списка шаблонов с пагинацией.
|
||
|
||
Args:
|
||
items: Список шаблонов на текущей странице
|
||
page: Номер текущей страницы
|
||
total: Общее количество шаблонов
|
||
show_delete: Показывать ли кнопку удаления
|
||
"""
|
||
rows: List[List[InlineKeyboardButton]] = []
|
||
|
||
for t in items:
|
||
row = [
|
||
InlineKeyboardButton(
|
||
(t.title or t.name),
|
||
callback_data=f"tpluse:{t.name}"
|
||
),
|
||
InlineKeyboardButton(
|
||
"👁 Предпросмотр",
|
||
callback_data=f"tplprev:{t.name}"
|
||
)
|
||
]
|
||
if show_delete:
|
||
row.append(InlineKeyboardButton(
|
||
"🗑",
|
||
callback_data=f"tpldel:{t.name}"
|
||
))
|
||
rows.append(row)
|
||
|
||
# Навигация
|
||
nav: List[InlineKeyboardButton] = []
|
||
if page > 0:
|
||
nav.append(InlineKeyboardButton(
|
||
"◀️ Назад",
|
||
callback_data=f"tplpage:{page-1}"
|
||
))
|
||
if (page + 1) * KbBuilder.PAGE_SIZE < total:
|
||
nav.append(InlineKeyboardButton(
|
||
"Вперёд ▶️",
|
||
callback_data=f"tplpage:{page+1}"
|
||
))
|
||
|
||
if nav:
|
||
rows.append(nav)
|
||
|
||
# Кнопка отмены
|
||
rows.append([InlineKeyboardButton("❌ Отмена", callback_data="tpl:cancel")])
|
||
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def template_delete_confirm(name: str) -> InlineKeyboardMarkup:
|
||
"""Клавиатура подтверждения удаления шаблона."""
|
||
rows = [
|
||
[
|
||
InlineKeyboardButton("✅ Удалить", callback_data=f"tpldelok:{name}"),
|
||
InlineKeyboardButton("❌ Отмена", callback_data="tpl:cancel")
|
||
]
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
if nav:
|
||
rows.append(nav)
|
||
|
||
rows.append([InlineKeyboardButton("Отмена", callback_data="tpl:cancel")])
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def preview_actions() -> InlineKeyboardMarkup:
|
||
rows = [
|
||
[InlineKeyboardButton("✅ Использовать", callback_data="pv:use")],
|
||
[InlineKeyboardButton("✏️ Изменить переменные", callback_data="pv:edit")],
|
||
[InlineKeyboardButton("Отмена", callback_data="tpl:cancel")],
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def tpl_types() -> InlineKeyboardMarkup:
|
||
rows = [
|
||
[InlineKeyboardButton("Текст", callback_data="tpltype:text"),
|
||
InlineKeyboardButton("Фото", callback_data="tpltype:photo")],
|
||
[InlineKeyboardButton("Видео", callback_data="tpltype:video"),
|
||
InlineKeyboardButton("GIF", callback_data="tpltype:animation")],
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def tpl_formats() -> InlineKeyboardMarkup:
|
||
rows = [
|
||
[InlineKeyboardButton("HTML (по умолчанию)", callback_data="tplfmt:HTML")],
|
||
[InlineKeyboardButton("MarkdownV2", callback_data="tplfmt:MarkdownV2")],
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|
||
|
||
@staticmethod
|
||
def tpl_list_actions(tpl_id: int) -> InlineKeyboardMarkup:
|
||
rows = [
|
||
[InlineKeyboardButton("Удалить", callback_data=f"tpldelok:{tpl_id}")],
|
||
[InlineKeyboardButton("Назад", callback_data="tpl:cancel")],
|
||
]
|
||
return InlineKeyboardMarkup(rows)
|