diff --git a/client/discord/handler/handle_external_task.go b/client/discord/handler/handle_external_task.go index 61a1c99..6726d25 100644 --- a/client/discord/handler/handle_external_task.go +++ b/client/discord/handler/handle_external_task.go @@ -1,12 +1,15 @@ package handler import ( + "context" + "fmt" "log" + "ticket-pimp/internal/domain" "github.com/bwmarrin/discordgo" ) -func (h *router) setFlag(s *discordgo.Session, i *discordgo.InteractionCreate, tag *discordgo.ForumTag) error { +func (c *client) setFlag(s *discordgo.Session, i *discordgo.InteractionCreate, tag *discordgo.ForumTag) error { th, err := s.Channel(i.ChannelID) if err != nil { @@ -22,11 +25,12 @@ func (h *router) setFlag(s *discordgo.Session, i *discordgo.InteractionCreate, t if len(forum.AvailableTags) != 0 { for _, some := range forum.AvailableTags { if some.Name == tag.Name { - log.Print(tag.Name) - thE, err := s.ChannelEditComplex(i.ChannelID, &discordgo.ChannelEdit{ + _, err := s.ChannelEditComplex(i.ChannelID, &discordgo.ChannelEdit{ AppliedTags: &[]string{some.ID}, }) - _, _ = thE, err + if err != nil { + return err + } } } } @@ -34,105 +38,155 @@ func (h *router) setFlag(s *discordgo.Session, i *discordgo.InteractionCreate, t return nil } -func (h *router) CreateExternalTask() CommandRoute { - return CommandRoute{ +func (c *client) ListenPosts(s *discordgo.Session, th *discordgo.ThreadCreate) { - Command: discordgo.ApplicationCommand{ - Name: "test", - Description: "Buttons test", - }, - - Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) { - - // Моментальный ответ для избежания столкновения с протуханием токена - initialResponse := discordgo.InteractionResponse{ - Type: discordgo.InteractionResponseChannelMessageWithSource, - Data: &discordgo.InteractionResponseData{ - Flags: discordgo.MessageFlagsEphemeral, - Content: "👩‍🍳 Cooking your query..", - }, - } - - s.InteractionRespond(i.Interaction, &initialResponse) - - // go func() { - // h.controller.InitTask("something like a default description") - // }() - }, + // Check if thread starter is not a bot, and thread started at the tasks channel; + if th.ParentID != c.conf.IsTaskForum || th.OwnerID == s.State.User.ID { + return } -} -func (h *router) StartTask() ComponentRoute { - return ComponentRoute{ - Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) { + msgs, _ := s.ChannelMessages(th.ID, 1, "", "", "") - user := i.Member.User.Mention() + msg, _ := s.ChannelMessage(th.ID, msgs[0].ID) - convertable, err := h.controller.UpdateTask(i.Message.ID, 0, user) - if err != nil { + if msg.Author.ID == s.State.User.ID { + return + } - } + content := th.Name + content += "\n" + msg.Content - newContent := convertable.ExtractDomain().StartedMessage() - if err != nil { - newContent += "\n `In progress` action produced with error:" + err.Error() - } + user, _ := s.GuildMember(th.GuildID, msg.Author.ID) - newMsg := discordgo.MessageEdit{ - Content: &newContent, - Channel: i.ChannelID, - ID: i.Message.ID, + t, err := c.controller.WriteTaskToDB(&domain.Task{ + Description: content, + Creator: user.User.Mention(), + }) + if err != nil { + s.ChannelMessageSend(th.ID, fmt.Sprintf("unable to write task to db, %v", err)) + return + } + + // [x] -- Отредактировать Thread name как для задачи + _, err = s.ChannelEditComplex(th.ID, &discordgo.ChannelEdit{ + Name: fmt.Sprintf("Task ID: %d, by %s", t.ID, t.Creator), + }) + if err != nil { + log.Printf("th edition is not complete: %v", err) + } + + // Fix the original task message: + taskMessage, err := s.ChannelMessageSendComplex(th.ID, &discordgo.MessageSend{ + Content: content, + Components: []discordgo.MessageComponent{ + discordgo.ActionsRow{ Components: []discordgo.MessageComponent{ - discordgo.ActionsRow{ - Components: []discordgo.MessageComponent{ - discordgo.Button{ - Label: "Close", - Style: discordgo.DangerButton, - Disabled: false, - CustomID: "task_close", - }, - }, + discordgo.Button{ + Label: "Start", + Style: discordgo.SuccessButton, + Disabled: false, + CustomID: "task_start", + }, + discordgo.Button{ + Label: "Close", + Style: discordgo.DangerButton, + Disabled: true, + CustomID: "task_close", }, }, - } - - h.setFlag(s, i, &h.Tags[0]) - - _, err = s.ChannelMessageEditComplex(&newMsg) - if err != nil { - log.Println("edition NOT complete, ", err) - } + }, }, + }) + if err != nil { + log.Printf("th start message edition is not complete: %v", err) + } + + err = c.controller.UpdateTasksMessageID(context.TODO(), taskMessage.ID, t.ID) + if err != nil { + s.ChannelMessageSend(th.ID, fmt.Sprintf("unable to update task at the db, %v", err)) + return } } -func (h *router) CloseTask() ComponentRoute { - return ComponentRoute{ - Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) { - - user := i.Member.User.Mention() - convertable, err := h.controller.UpdateTask(i.Message.ID, 1, user) - - newContent := convertable.ExtractDomain().ClosedMessage() - if err != nil { - newContent += "\n `Close` action produced with error:" + err.Error() - } - - newMsg := discordgo.MessageEdit{ - Content: &newContent, - Channel: i.ChannelID, - ID: i.Message.ID, - Components: []discordgo.MessageComponent{}, - } - - msgE, err := s.ChannelMessageEditComplex(&newMsg) - if err != nil { - log.Println("edition NOT complete, ", err) - } - - _ = msgE - h.setFlag(s, i, &h.Tags[1]) - - }, +func (c *client) HandleTaskButtons() Component { + return Component{ + Handler: c.handleTaskButton, + } +} + +func (c *client) handleTaskButton(s *discordgo.Session, i *discordgo.InteractionCreate) { + + // Send an empty interaction response; ---------------------------------------------------------------- + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseUpdateMessage, + Data: &discordgo.InteractionResponseData{}, + }) + + // Get assignee value; --------------------------------------------------------------------------------- + user := i.Member.User.Mention() + + var ( + opt int = -1 + doneButtonIsDisabled bool = false + state domain.TaskState = domain.NewTaskState() + ) + + // Check what flow was touched: ------------------------------------------------------------------------- + switch i.Interaction.MessageComponentData().CustomID { + case "task_start": + opt = 0 + doneButtonIsDisabled = false + state = domain.InrpogressTaskState() + case "task_close": + opt = 1 + doneButtonIsDisabled = true + state = domain.DoneTaskState() + } + + // Send the task update to db -------------------------------------------------------------------------- + convertable, err := c.controller.UpdateTask(i.Message.ID, opt, user) + if err != nil { + s.ChannelMessageSend(i.ChannelID, fmt.Sprintf("Unable to update task at the db w/ error: %v", err)) + return + } + + // Map DB's response to domain.Task: ------------------------------------------------------------------- + newContent := convertable. + ExtractDomain(). + DiscordMessage(state) + + // Send a message to the thread about the task was started: --------------------------------------------- + _, err = s.ChannelMessageSendComplex(i.ChannelID, &discordgo.MessageSend{ + Content: newContent, + }) + if err != nil { + log.Printf("error while sending start task message: %v", err) + } + + // Fix the original task message: ---------------------------------------------------------------------- + _, err = s.ChannelMessageEditComplex(&discordgo.MessageEdit{ + Channel: i.ChannelID, + ID: i.Message.ID, + Components: []discordgo.MessageComponent{ + discordgo.ActionsRow{ + Components: []discordgo.MessageComponent{ + discordgo.Button{ + Label: "Close", + Style: discordgo.DangerButton, + Disabled: doneButtonIsDisabled, + CustomID: "task_close", + }, + }, + }, + }, + }) + if err != nil { + log.Printf("th start message edition is not complete: %v", err) + } + + // Устанавливаем тэги статуса на тред --------------------------------------------------------------------- + err = c.setFlag(s, i, &c.Tags[opt]) + if err != nil { + log.Printf("error while `start` tag setting: %v", err) } }