diff --git a/attachment_image.go b/attachment_image.go new file mode 100644 index 0000000..fcf46dc --- /dev/null +++ b/attachment_image.go @@ -0,0 +1,56 @@ +package main + +import ( + "image" + _ "image/jpeg" + _ "image/png" + "net/http" + + "github.com/diamondburned/arikawa/v3/discord" + "github.com/gdamore/tcell/v2" + "github.com/rivo/tview" +) + +type AttachmentImage struct { + *tview.Image +} + +func newAttachmentImage(a discord.Attachment) (*AttachmentImage, error) { + ai := &AttachmentImage{ + Image: tview.NewImage(), + } + + ai.SetInputCapture(ai.onInputCapture) + ai.SetBackgroundColor(tcell.GetColor(cfg.Theme.BackgroundColor)) + ai.SetTitleColor(tcell.GetColor(cfg.Theme.TitleColor)) + ai.SetTitleAlign(tview.AlignLeft) + + p := cfg.Theme.BorderPadding + ai.SetBorder(cfg.Theme.Border) + ai.SetBorderColor(tcell.GetColor(cfg.Theme.BorderColor)) + ai.SetBorderPadding(p[0], p[1], p[2], p[3]) + + resp, err := http.Get(a.URL) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + i, _, err := image.Decode(resp.Body) + if err != nil { + return nil, err + } + + ai.SetTitle(a.Filename) + ai.SetImage(i) + return ai, nil +} + +func (ai *AttachmentImage) onInputCapture(event *tcell.EventKey) *tcell.EventKey { + if event.Name() == cfg.Keys.Cancel { + app.SetRoot(mainFlex, true) + return nil + } + + return event +} diff --git a/config/config.go b/config/config.go index d239dbb..2a8f1fb 100644 --- a/config/config.go +++ b/config/config.go @@ -23,18 +23,6 @@ type Config struct { Theme Theme `yaml:"theme"` } -func new() Config { - return Config{ - Mouse: true, - Timestamps: false, - MessagesLimit: 50, - Editor: "default", - - Keys: newKeys(), - Theme: newTheme(), - } -} - // Load reads the configuration file and decodes the configuration file or creates a new one if it does not exist already and writes the default configuration to the newly-created configuration file. func Load() (*Config, error) { path, err := os.UserConfigDir() @@ -48,7 +36,15 @@ func Load() (*Config, error) { return nil, err } - c := new() + c := Config{ + Mouse: true, + Timestamps: false, + MessagesLimit: 50, + Editor: "default", + + Keys: newKeys(), + Theme: newTheme(), + } path = filepath.Join(path, "config.yml") _, err = os.Stat(path) if os.IsNotExist(err) { diff --git a/config/keys.go b/config/keys.go index 176711c..81b098b 100644 --- a/config/keys.go +++ b/config/keys.go @@ -8,6 +8,7 @@ type ( MessagesTextKeys struct { Focus string `yaml:"focus"` + ShowImage string `yaml:"show_image"` CopyContent string `yaml:"copy_content"` Reply string `yaml:"reply"` @@ -49,6 +50,7 @@ func newKeys() Keys { MessagesText: MessagesTextKeys{ Focus: "Alt+Rune[m]", + ShowImage: "Rune[i]", CopyContent: "Rune[c]", Reply: "Rune[r]", diff --git a/messages_text.go b/messages_text.go index 539d201..86267e2 100644 --- a/messages_text.go +++ b/messages_text.go @@ -130,6 +130,9 @@ func (mt *MessagesText) onInputCapture(event *tcell.EventKey) *tcell.EventKey { case cfg.Keys.MessagesText.SelectReply: mt.selectReplyAction() return nil + case cfg.Keys.MessagesText.ShowImage: + mt.showImageAction() + return nil case cfg.Keys.Cancel: guildsTree.selectedChannel = nil @@ -254,6 +257,10 @@ func (mt *MessagesText) selectReplyAction() { } func (mt *MessagesText) copyContentAction() { + if mt.selectedMessage == -1 { + return + } + ms, err := discordState.Cabinet.Messages(guildsTree.selectedChannel.ID) if err != nil { log.Println(err) @@ -266,3 +273,28 @@ func (mt *MessagesText) copyContentAction() { return } } + +func (mt *MessagesText) showImageAction() { + if mt.selectedMessage == -1 { + return + } + + ms, err := discordState.Cabinet.Messages(guildsTree.selectedChannel.ID) + if err != nil { + log.Println(err) + return + } + + as := ms[mt.selectedMessage].Attachments + if len(as) == 0 { + return + } + + ai, err := newAttachmentImage(as[0]) + if err != nil { + log.Println(err) + return + } + + app.SetRoot(ai, true) +}