Преглед изворни кода

Squash merge edit into main

ayn2op пре 7 месеци
родитељ
комит
2210a6dab9

+ 27 - 5
cmd/message_input.go

@@ -22,6 +22,7 @@ import (
 	"github.com/diamondburned/arikawa/v3/api"
 	"github.com/diamondburned/arikawa/v3/discord"
 	"github.com/diamondburned/arikawa/v3/state"
+	"github.com/diamondburned/arikawa/v3/utils/json/option"
 	"github.com/diamondburned/arikawa/v3/utils/sendpart"
 	"github.com/diamondburned/ningen/v3/discordmd"
 	"github.com/gdamore/tcell/v2"
@@ -39,6 +40,7 @@ type messageInput struct {
 	*tview.TextArea
 	cfg *config.Config
 
+	edit            bool
 	sendMessageData *api.SendMessageData
 	cache           *cache.Cache
 	mentionsList    *tview.List
@@ -157,13 +159,33 @@ func (mi *messageInput) send() {
 		return
 	}
 
-	data := mi.sendMessageData
-	if text := strings.TrimSpace(mi.GetText()); text != "" {
-		data.Content = processText(app.guildsTree.selectedChannelID, []byte(text))
+	text := strings.TrimSpace(mi.GetText())
+	if text == "" {
+		return
+	}
+
+	text = processText(app.guildsTree.selectedChannelID, []byte(text))
+	if text == "" {
+		return
 	}
 
-	if _, err := discordState.SendMessageComplex(app.guildsTree.selectedChannelID, *data); err != nil {
-		slog.Error("failed to send message in channel", "channel_id", app.guildsTree.selectedChannelID, "err", err)
+	if mi.edit {
+		m, err := app.messagesList.selectedMessage()
+		if err != nil {
+			slog.Error("failed to get selected message", "err", err)
+			return
+		}
+
+		data := api.EditMessageData{Content: option.NewNullableString(text)}
+		if _, err := discordState.EditMessageComplex(m.ChannelID, m.ID, data); err != nil {
+			slog.Error("failed to edit message", "err", err)
+		}
+	} else {
+		data := mi.sendMessageData
+		data.Content = text
+		if _, err := discordState.SendMessageComplex(app.guildsTree.selectedChannelID, *data); err != nil {
+			slog.Error("failed to send message in channel", "channel_id", app.guildsTree.selectedChannelID, "err", err)
+		}
 	}
 
 	// Close the attached files after sending the message.

+ 41 - 25
cmd/messages_list.go

@@ -81,7 +81,7 @@ func (ml *messagesList) setTitle(channel discord.Channel) {
 		title += " - " + topic
 	}
 
-	app.messagesList.SetTitle(title)
+	ml.SetTitle(title)
 }
 
 func (ml *messagesList) drawMessages(messages []discord.Message) {
@@ -139,20 +139,20 @@ func (ml *messagesList) drawTimestamps(ts discord.Timestamp) {
 	fmt.Fprintf(ml, "[::d]%s[::D] ", ml.formatTimestamp(ts))
 }
 
-func (ml *messagesList) drawAuthor(msg discord.Message) {
-	name := msg.Author.DisplayOrUsername()
+func (ml *messagesList) drawAuthor(message discord.Message) {
+	name := message.Author.DisplayOrUsername()
 	foreground := tcell.ColorDefault
-	if msg.GuildID.IsValid() {
-		member, err := discordState.Cabinet.Member(msg.GuildID, msg.Author.ID)
+	if message.GuildID.IsValid() {
+		member, err := discordState.Cabinet.Member(message.GuildID, message.Author.ID)
 		if err != nil {
-			slog.Error("failed to get member from state", "guild_id", msg.GuildID, "member_id", msg.Author.ID, "err", err)
+			slog.Error("failed to get member from state", "guild_id", message.GuildID, "member_id", message.Author.ID, "err", err)
 		} else {
 			if member.Nick != "" {
 				name = member.Nick
 			}
 
 			color, ok := state.MemberColor(member, func(id discord.RoleID) *discord.Role {
-				r, _ := discordState.Cabinet.Role(msg.GuildID, id)
+				r, _ := discordState.Cabinet.Role(message.GuildID, id)
 				return r
 			})
 			if ok {
@@ -164,10 +164,10 @@ func (ml *messagesList) drawAuthor(msg discord.Message) {
 	fmt.Fprintf(ml, "[%s::b]%s[-::B] ", foreground, name)
 }
 
-func (ml *messagesList) drawContent(msg discord.Message) {
-	c := []byte(tview.Escape(msg.Content))
+func (ml *messagesList) drawContent(message discord.Message) {
+	c := []byte(tview.Escape(message.Content))
 	if app.cfg.Markdown {
-		ast := discordmd.ParseWithMessage(c, *discordState.Cabinet, &msg, false)
+		ast := discordmd.ParseWithMessage(c, *discordState.Cabinet, &message, false)
 		markdown.DefaultRenderer.Render(ml, c, ast)
 	} else {
 		ml.Write(c) // write the content as is
@@ -215,10 +215,10 @@ func (ml *messagesList) drawForwardedMessage(message discord.Message) {
 func (ml *messagesList) drawReplyMessage(message discord.Message) {
 	// reply
 	fmt.Fprintf(ml, "[::d]%s ", ml.cfg.Theme.MessagesList.ReplyIndicator)
-	if refMsg := message.ReferencedMessage; refMsg != nil {
-		refMsg.GuildID = message.GuildID
-		ml.drawAuthor(*refMsg)
-		ml.drawContent(*refMsg)
+	if m := message.ReferencedMessage; m != nil {
+		m.GuildID = message.GuildID
+		ml.drawAuthor(*m)
+		ml.drawContent(*m)
 	} else {
 		io.WriteString(ml, "Original message was deleted")
 	}
@@ -232,20 +232,20 @@ func (ml *messagesList) drawPinnedMessage(message discord.Message) {
 	fmt.Fprintf(ml, "%s pinned a message", message.Author.DisplayOrUsername())
 }
 
-func (ml *messagesList) selectedMsg() (*discord.Message, error) {
+func (ml *messagesList) selectedMessage() (*discord.Message, error) {
 	if !ml.selectedMessageID.IsValid() {
 		return nil, errors.New("no message is currently selected")
 	}
 
-	msg, err := discordState.Cabinet.Message(app.guildsTree.selectedChannelID, ml.selectedMessageID)
+	m, err := discordState.Cabinet.Message(app.guildsTree.selectedChannelID, ml.selectedMessageID)
 	if err != nil {
 		return nil, fmt.Errorf("could not retrieve selected message: %w", err)
 	}
 
-	return msg, nil
+	return m, nil
 }
 
-func (ml *messagesList) selectedMsgIndex() (int, error) {
+func (ml *messagesList) selectedMessageIndex() (int, error) {
 	ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID)
 	if err != nil {
 		return -1, err
@@ -280,11 +280,14 @@ func (ml *messagesList) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
 		ml.reply(false)
 	case ml.cfg.Keys.MessagesList.ReplyMention:
 		ml.reply(true)
+	case ml.cfg.Keys.MessagesList.Edit:
+		ml.edit()
 	case ml.cfg.Keys.MessagesList.Delete:
 		ml.delete()
 	case ml.cfg.Keys.MessagesList.DeleteConfirm:
 		ml.confirmDelete()
 	}
+
 	return nil
 }
 
@@ -295,7 +298,7 @@ func (ml *messagesList) _select(name string) {
 		return
 	}
 
-	msgIdx, err := ml.selectedMsgIndex()
+	msgIdx, err := ml.selectedMessageIndex()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return
@@ -355,7 +358,7 @@ func (ml *messagesList) onHighlighted(added, removed, remaining []string) {
 }
 
 func (ml *messagesList) yankID() {
-	msg, err := ml.selectedMsg()
+	msg, err := ml.selectedMessage()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return
@@ -365,7 +368,7 @@ func (ml *messagesList) yankID() {
 }
 
 func (ml *messagesList) yankContent() {
-	msg, err := ml.selectedMsg()
+	msg, err := ml.selectedMessage()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return
@@ -375,7 +378,7 @@ func (ml *messagesList) yankContent() {
 }
 
 func (ml *messagesList) yankURL() {
-	msg, err := ml.selectedMsg()
+	msg, err := ml.selectedMessage()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return
@@ -385,7 +388,7 @@ func (ml *messagesList) yankURL() {
 }
 
 func (ml *messagesList) open() {
-	msg, err := ml.selectedMsg()
+	msg, err := ml.selectedMessage()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return
@@ -525,7 +528,7 @@ func (ml *messagesList) openURL(url string) {
 }
 
 func (ml *messagesList) reply(mention bool) {
-	msg, err := ml.selectedMsg()
+	msg, err := ml.selectedMessage()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return
@@ -558,6 +561,19 @@ func (ml *messagesList) reply(mention bool) {
 	app.SetFocus(app.messageInput)
 }
 
+func (ml *messagesList) edit() {
+	message, err := ml.selectedMessage()
+	if err != nil {
+		slog.Error("failed to get selected message", "err", err)
+		return
+	}
+
+	app.messageInput.SetTitle("Editing")
+	app.messageInput.edit = true
+	app.messageInput.SetText(message.Content, true)
+	app.SetFocus(app.messageInput)
+}
+
 func (ml *messagesList) confirmDelete() {
 	onChoice := func(choice string) {
 		if choice == "Yes" {
@@ -573,7 +589,7 @@ func (ml *messagesList) confirmDelete() {
 }
 
 func (ml *messagesList) delete() {
-	msg, err := ml.selectedMsg()
+	msg, err := ml.selectedMessage()
 	if err != nil {
 		slog.Error("failed to get selected message", "err", err)
 		return

+ 1 - 0
internal/config/config.toml

@@ -69,6 +69,7 @@ reply = "Rune[r]"
 # Reply (with mention) to the selected message.
 reply_mention = "Rune[R]"
 cancel = "Esc"
+edit = "Rune[e]"
 delete = "Rune[D]"
 delete_confirm = "Rune[d]"
 # Open the selected message's attachments or hyperlinks in the message

+ 1 - 2
internal/config/keys.go

@@ -28,8 +28,6 @@ type (
 		SelectCurrent string `toml:"select_current"`
 		YankID        string `toml:"yank_id"`
 
-		CollapseAll        string `toml:"collapse_all"`
-		ExpandAll          string `toml:"expand_all"`
 		CollapseParentNode string `toml:"collapse_parent_node"`
 		MoveToParentNode   string `toml:"move_to_parent_node"`
 	}
@@ -41,6 +39,7 @@ type (
 		ReplyMention string `toml:"reply_mention"`
 
 		Cancel        string `toml:"cancel"`
+		Edit          string `toml:"edit"`
 		Delete        string `toml:"delete"`
 		DeleteConfirm string `toml:"delete_confirm"`
 		Open          string `toml:"open"`

+ 10 - 10
internal/notifications/notifications.go

@@ -15,29 +15,29 @@ import (
 	"github.com/diamondburned/ningen/v3"
 )
 
-func Notify(state *ningen.State, msg *gateway.MessageCreateEvent, cfg *config.Config) error {
+func Notify(state *ningen.State, message *gateway.MessageCreateEvent, cfg *config.Config) error {
 	if !cfg.Notifications.Enabled || cfg.Status == discord.DoNotDisturbStatus {
 		return nil
 	}
 
-	mentions := state.MessageMentions(&msg.Message)
+	mentions := state.MessageMentions(&message.Message)
 	if mentions == 0 {
 		return nil
 	}
 
 	// Handle sent files
-	content := msg.Content
-	if msg.Content == "" && len(msg.Attachments) > 0 {
-		content = "Uploaded " + msg.Attachments[0].Filename
+	content := message.Content
+	if message.Content == "" && len(message.Attachments) > 0 {
+		content = "Uploaded " + message.Attachments[0].Filename
 	}
 
 	if content == "" {
 		return nil
 	}
 
-	title := msg.Author.DisplayOrUsername()
+	title := message.Author.DisplayOrUsername()
 
-	channel, err := state.Cabinet.Channel(msg.ChannelID)
+	channel, err := state.Cabinet.Channel(message.ChannelID)
 	if err != nil {
 		return fmt.Errorf("failed to get channel from state: %w", err)
 	}
@@ -48,19 +48,19 @@ func Notify(state *ningen.State, msg *gateway.MessageCreateEvent, cfg *config.Co
 			return fmt.Errorf("failed to get guild from state: %w", err)
 		}
 
-		if member := msg.Member; member != nil && member.Nick != "" {
+		if member := message.Member; member != nil && member.Nick != "" {
 			title = member.Nick
 		}
 
 		title += " (#" + channel.Name + ", " + guild.Name + ")"
 	}
 
-	hash := msg.Author.Avatar
+	hash := message.Author.Avatar
 	if hash == "" {
 		hash = "default"
 	}
 
-	imagePath, err := getCachedProfileImage(hash, msg.Author.AvatarURLWithType(discord.PNGImage))
+	imagePath, err := getCachedProfileImage(hash, message.Author.AvatarURLWithType(discord.PNGImage))
 	if err != nil {
 		slog.Info("failed to get profile image from cache for notification", "err", err, "hash", hash)
 	}