Files
tgex-backend/tg_bot/screens/creative_view.go
Artem Tsyrulnikov ffd7a7c10f фиксы
2026-02-28 13:37:58 +03:00

242 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package screens
import (
"context"
"strings"
"github.com/NicoNex/echotron/v3"
"github.com/TelegramExchange/tgex-backend/tg_bot/backend"
"github.com/TelegramExchange/tgex-backend/tg_bot/bot"
"github.com/rs/zerolog/log"
)
// CreativeView - экран просмотра креатива (read-only mode)
// Показывает превью креатива и кнопки действий: Редактировать, Тег, Закупить
type CreativeView struct {
CreativeEditorFields // Встраивание общих полей для отображения превью
CreativeID string
ProjectID string
// Данные проекта для передачи в AddPurchase
ProjectTitle string
ProjectTelegramID int64
ProjectUsername string
ProjectStatus string
BackState bot.State
renaming bool // режим ввода нового названия
}
const msgCreativeView = `
<b>📋 Просмотр креатива</b>
Выберите действие:
`
func (s *CreativeView) Enter(b *bot.Bot, mode bot.RenderMode) {
// Сбрасываем старые ID — при re-enter всегда создаём свежие сообщения
s.CreativeMessageID = nil
s.ControlPanelMessageID = nil
// Загружаем креатив
creative, err := b.Backend.GetCreative(context.Background(), b.Session.JWT, b.Session.WorkspaceID, s.CreativeID)
if err != nil {
log.Error().Err(err).Str("creative_id", s.CreativeID).Msg("Failed to get creative")
b.SendNew("<b>❌ Не удалось загрузить креатив</b>", Keyboard(
Row(Button("← Назад", "back")),
))
return
}
// Загружаем проект для получения данных
project, err := b.Backend.GetProject(context.Background(), b.Session.JWT, b.Session.WorkspaceID, s.ProjectID)
if err != nil {
log.Error().Err(err).Str("project_id", s.ProjectID).Msg("Failed to get project")
} else {
s.ProjectTitle = project.Title
s.ProjectTelegramID = project.TelegramID
s.ProjectStatus = project.Status
if project.Username != nil {
s.ProjectUsername = *project.Username
}
}
// Заполняем поля креатива для отображения превью
s.Name = &creative.Name
if creative.Text != "" {
s.Text = &creative.Text
}
s.MediaItems = nil
if len(creative.MediaItems) > 0 {
for _, item := range creative.MediaItems {
s.MediaItems = append(s.MediaItems, MediaItem{
MediaType: item.MediaType,
MediaFileID: item.MediaFileID,
})
}
}
s.Buttons = nil
for _, btn := range creative.Buttons {
s.Buttons = append(s.Buttons, InlineButton{Text: btn.Text, URL: btn.URL})
}
if creative.Tag != "" {
s.Tag = &creative.Tag
}
// Отправляем превью креатива
s.SendCreativePreview(b)
// Отправляем панель управления с кнопками действий
s.showActionPanel(b)
}
func (s *CreativeView) HandleCallback(b *bot.Bot, u *echotron.Update) {
if u.CallbackQuery == nil || u.CallbackQuery.Data == "" {
return
}
data := u.CallbackQuery.Data
switch {
case data == "back":
s.CleanupMessages(b)
if s.BackState != nil {
b.SetState(s.BackState, bot.NewMessage)
}
case data == "rename":
s.renaming = true
s.ShowControlPanel(b, "<b>✏️ Введите новое название креатива:</b>", [][]echotron.InlineKeyboardButton{
Row(Button("← Отмена", "cancel_rename")),
})
case data == "cancel_rename":
s.renaming = false
s.showActionPanel(b)
case data == "edit":
s.CleanupMessages(b)
b.SetState(&CreativeDetails{
CreativeID: s.CreativeID,
ProjectID: s.ProjectID,
ViewMode: true,
ViewBackTo: s,
ProjectTitle: s.ProjectTitle,
BackState: s.BackState,
}, bot.NewMessage)
case data == "toggle_tag":
// Переключение тега (testing <-> production)
s.toggleTag(b)
case data == "purchase_creative":
s.CleanupMessages(b)
creativeTitle := ""
if s.Name != nil {
creativeTitle = *s.Name
}
b.SetState(&AddPurchase{
ProjectID: s.ProjectID,
ProjectTitle: s.ProjectTitle,
ProjectTelegramID: s.ProjectTelegramID,
ProjectUsername: s.ProjectUsername,
ProjectStatus: s.ProjectStatus,
CreativeID: s.CreativeID,
CreativeTitle: creativeTitle,
BackState: s,
}, bot.NewMessage)
default:
log.Warn().Str("callback", data).Msg("Unknown callback in CreativeView")
}
}
func (s *CreativeView) HandleMessage(b *bot.Bot, u *echotron.Update) {
if !s.renaming || u.Message == nil || u.Message.Text == "" {
return
}
newName := strings.TrimSpace(u.Message.Text)
s.DeleteUserMessage(b, u.Message.ID)
input := backend.UpdateCreativeInput{
Name: &newName,
}
_, err := b.Backend.UpdateCreative(
context.Background(), b.Session.JWT, b.Session.WorkspaceID, s.CreativeID, input,
)
if err != nil {
log.Error().Err(err).Str("creative_id", s.CreativeID).Msg("Failed to rename creative")
s.ShowControlPanel(b, "<b>❌ Не удалось переименовать</b>", [][]echotron.InlineKeyboardButton{
Row(Button("← Назад", "cancel_rename")),
})
return
}
s.Name = &newName
s.renaming = false
s.showActionPanel(b)
}
func (s *CreativeView) Handle(_ *bot.Bot, _ *echotron.Update) { return }
func (s *CreativeView) Exit() {}
// showActionPanel показывает панель действий с кнопками
func (s *CreativeView) showActionPanel(b *bot.Bot) {
tagLabel := s.GetTagLabel()
buttons := [][]echotron.InlineKeyboardButton{
Row(
Button("✎ Переименовать", "rename"),
Button("✎ Редактировать", "edit"),
),
Row(Button(" Закупить", "purchase_creative")),
Row(
Button("← Назад", "back"),
Button(tagLabel, "toggle_tag"),
),
}
s.ShowControlPanel(b, msgCreativeView, buttons)
}
// toggleTag переключает тег креатива (testing <-> production)
func (s *CreativeView) toggleTag(b *bot.Bot) {
newTag := "testing"
if s.Tag != nil && *s.Tag == "testing" {
newTag = "production"
}
// Обновляем тег через backend
input := backend.UpdateCreativeInput{
Tag: &newTag,
}
_, err := b.Backend.UpdateCreative(
context.Background(),
b.Session.JWT,
b.Session.WorkspaceID,
s.CreativeID,
input,
)
if err != nil {
log.Error().Err(err).Str("creative_id", s.CreativeID).Msg("Failed to update creative tag")
s.ShowControlPanel(b, "<b>❌ Не удалось изменить тег</b>\n\nПопробуйте еще раз.", [][]echotron.InlineKeyboardButton{
Row(Button("← Назад", "back")),
Row(Button("↻ Попробовать снова", "toggle_tag")),
})
return
}
// Обновляем локальное значение
s.Tag = &newTag
// Обновляем панель (показывает новый тег)
s.showActionPanel(b)
}