فهرست منبع

feat: implement image support (#274)

ayn2op 3 سال پیش
والد
کامیت
80f798056f
4فایلهای تغییر یافته به همراه99 افزوده شده و 13 حذف شده
  1. 56 0
      attachment_image.go
  2. 9 13
      config/config.go
  3. 2 0
      config/keys.go
  4. 32 0
      messages_text.go

+ 56 - 0
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
+}

+ 9 - 13
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) {

+ 2 - 0
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]",

+ 32 - 0
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)
+}