message_input.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package main
  2. import (
  3. "log"
  4. "os"
  5. "os/exec"
  6. "strings"
  7. "github.com/atotto/clipboard"
  8. "github.com/diamondburned/arikawa/v3/api"
  9. "github.com/diamondburned/arikawa/v3/discord"
  10. "github.com/diamondburned/arikawa/v3/utils/json/option"
  11. "github.com/gdamore/tcell/v2"
  12. "github.com/rivo/tview"
  13. )
  14. type MessageInput struct {
  15. *tview.InputField
  16. }
  17. func newMessageInput() *MessageInput {
  18. mi := &MessageInput{
  19. InputField: tview.NewInputField(),
  20. }
  21. mi.SetInputCapture(mi.onInputCapture)
  22. mi.SetBackgroundColor(tcell.GetColor(config.Theme.BackgroundColor))
  23. mi.SetFieldBackgroundColor(tcell.GetColor(config.Theme.BackgroundColor))
  24. mi.SetTitleColor(tcell.GetColor(config.Theme.TitleColor))
  25. mi.SetTitleAlign(tview.AlignLeft)
  26. p := config.Theme.BorderPadding
  27. mi.SetBorder(config.Theme.Border)
  28. mi.SetBorderColor(tcell.GetColor(config.Theme.BorderColor))
  29. mi.SetBorderPadding(p[0], p[1], p[2], p[3])
  30. return mi
  31. }
  32. func (mi *MessageInput) reset() {
  33. mi.SetTitle("")
  34. mi.SetText("")
  35. }
  36. func (mi *MessageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
  37. switch event.Name() {
  38. case config.Keys.MessageInput.Send:
  39. mi.sendAction()
  40. return nil
  41. case config.Keys.MessageInput.Paste:
  42. mi.pasteAction()
  43. return nil
  44. case config.Keys.MessageInput.LaunchEditor:
  45. messageInput.launchEditorAction()
  46. return nil
  47. case config.Keys.Cancel:
  48. mi.reset()
  49. return nil
  50. }
  51. return event
  52. }
  53. func (mi *MessageInput) sendAction() {
  54. if guildsTree.selectedChannel == nil {
  55. return
  56. }
  57. text := strings.TrimSpace(mi.GetText())
  58. if text == "" {
  59. return
  60. }
  61. var err error
  62. if messagesText.selectedMessage != -1 {
  63. ms, err := discordState.Cabinet.Messages(guildsTree.selectedChannel.ID)
  64. if err != nil {
  65. log.Println(err)
  66. return
  67. }
  68. data := api.SendMessageData{
  69. Content: text,
  70. Reference: &discord.MessageReference{MessageID: ms[messagesText.selectedMessage].ID},
  71. AllowedMentions: &api.AllowedMentions{RepliedUser: option.False},
  72. }
  73. if strings.HasPrefix(mi.GetTitle(), "[@]") {
  74. data.AllowedMentions.RepliedUser = option.True
  75. }
  76. go discordState.SendMessageComplex(guildsTree.selectedChannel.ID, data)
  77. } else {
  78. go discordState.SendMessage(guildsTree.selectedChannel.ID, text)
  79. }
  80. if err != nil {
  81. log.Println(err)
  82. return
  83. }
  84. messagesText.selectedMessage = -1
  85. messagesText.Highlight()
  86. mi.reset()
  87. }
  88. func (mi *MessageInput) pasteAction() {
  89. text, err := clipboard.ReadAll()
  90. if err != nil {
  91. log.Fatal(err)
  92. }
  93. // Append the text to the message input.
  94. mi.SetText(mi.GetText() + text)
  95. }
  96. func (mi *MessageInput) launchEditorAction() {
  97. e := config.Editor
  98. if e == "default" {
  99. e = os.Getenv("EDITOR")
  100. }
  101. cmd := exec.Command(e)
  102. var b strings.Builder
  103. cmd.Stdout = &b
  104. app.Suspend(func() {
  105. err := cmd.Run()
  106. if err != nil {
  107. log.Println(err)
  108. return
  109. }
  110. })
  111. mi.SetText(b.String())
  112. }