Use yaml for configuration instead of Lua (#215)
This commit is contained in:
parent
cb1a830888
commit
40e2e7e6a5
12 changed files with 150 additions and 542 deletions
|
|
@ -73,7 +73,7 @@ sudo mv ./discordo /usr/local/bin
|
|||
|
||||
### Configuration
|
||||
|
||||
A default configuration file is created on first start-up at `$HOME/.config/discordo/config.lua` on Unix, `$HOME/Library/Application Support/discordo/config.lua` on Darwin, and `%AppData%/discordo/config.lua` on Windows. You can configure the default configuration directory path using the `config` command-line flag (eg: `discordo --config $HOME/my-custom-dir).
|
||||
A default configuration file is created on first start-up at `$HOME/.config/discordo/config.yml` on Unix, `$HOME/Library/Application Support/discordo/config.yml` on Darwin, and `%AppData%/discordo/config.yml` on Windows. You can configure the default configuration directory path using the `config` command-line flag (eg: `discordo --config $HOME/my-custom-dir).
|
||||
|
||||
## Disclaimer
|
||||
|
||||
|
|
|
|||
122
config/config.go
122
config/config.go
|
|
@ -2,78 +2,114 @@ package config
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const Name = "discordo"
|
||||
|
||||
//go:embed config.lua
|
||||
var LuaConfig []byte
|
||||
type MessagesPanelKeysConfig struct {
|
||||
OpenActionsList string `yaml:"open_actions_list"`
|
||||
|
||||
// Config initializes a new Lua state, loads a configuration file, and defines essential micellaneous fields.
|
||||
type Config struct {
|
||||
// Path is the path of the configuration file. Its value is the configuration directory until Load() is called.
|
||||
Path string
|
||||
State *lua.LState
|
||||
SelectPreviousMessage string `yaml:"select_previous_message"`
|
||||
SelectNextMessage string `yaml:"select_next_message"`
|
||||
SelectFirstMessage string `yaml:"select_first_message"`
|
||||
SelectLastMessage string `yaml:"select_last_message"`
|
||||
}
|
||||
|
||||
func New(path string) *Config {
|
||||
type MessageInputKeysConfig struct {
|
||||
OpenExternalEditor string `yaml:"open_external_editor"`
|
||||
PasteClipboard string `yaml:"paste_clipboard"`
|
||||
}
|
||||
|
||||
type KeysConfig struct {
|
||||
MessagesPanel MessagesPanelKeysConfig `yaml:"messages_panel"`
|
||||
MessageInput MessageInputKeysConfig `yaml:"message_input"`
|
||||
}
|
||||
|
||||
type ThemeConfig struct {
|
||||
Background string `yaml:"background"`
|
||||
Border string `yaml:"border"`
|
||||
Title string `yaml:"title"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
// Whether the mouse is usable or not.
|
||||
Mouse bool `yaml:"mouse"`
|
||||
// The maximum number of messages to fetch and display on the messages panel. Its value must not be lesser than 1 and greater than 100.
|
||||
MessagesLimit uint `yaml:"messages_limit"`
|
||||
// Whether to display the timestamps of the messages beside the displayed message or not.
|
||||
Timestamps bool `yaml:"timestamps"`
|
||||
// The timezone of the timestamps. Learn more: https://pkg.go.dev/time#LoadLocation
|
||||
Timezone string `yaml:"timezone"`
|
||||
// A textual representation of the time value formatted according to the layout defined by its value. Learn more: https://pkg.go.dev/time#Layout
|
||||
TimeFormat string `yaml:"time_format"`
|
||||
// Keybindings
|
||||
Keys KeysConfig `yaml:"keys"`
|
||||
// Theme
|
||||
Theme ThemeConfig `yaml:"theme"`
|
||||
}
|
||||
|
||||
func New() *Config {
|
||||
return &Config{
|
||||
Path: path,
|
||||
State: lua.NewState(),
|
||||
Mouse: true,
|
||||
MessagesLimit: 50,
|
||||
|
||||
Timestamps: false,
|
||||
Timezone: "Local",
|
||||
TimeFormat: time.Kitchen,
|
||||
|
||||
Keys: KeysConfig{
|
||||
MessagesPanel: MessagesPanelKeysConfig{
|
||||
OpenActionsList: "Rune[a]",
|
||||
|
||||
SelectPreviousMessage: "Up",
|
||||
SelectNextMessage: "Down",
|
||||
SelectFirstMessage: "Home",
|
||||
SelectLastMessage: "End",
|
||||
},
|
||||
},
|
||||
Theme: ThemeConfig{
|
||||
Background: "default",
|
||||
Border: "white",
|
||||
Title: "white",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) Load() error {
|
||||
// Create directories that do not exist and are mentioned in the path recursively.
|
||||
err := os.MkdirAll(c.Path, os.ModePerm)
|
||||
configPath, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Path = filepath.Join(c.Path, "config.lua")
|
||||
// Open the existing configuration file with read-only flag.
|
||||
f, err := os.Open(c.Path)
|
||||
// If the configuration file does not exist, create a new configuration file with the read-write flag.
|
||||
if os.IsNotExist(err) {
|
||||
f, err = os.Create(c.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Write(LuaConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return f.Sync()
|
||||
configPath = filepath.Join(configPath, Name)
|
||||
// Create directories that do not exist and are mentioned in the path recursively.
|
||||
err = os.MkdirAll(configPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configPath = filepath.Join(configPath, "config.yml")
|
||||
// Open the existing configuration file with read-only flag.
|
||||
f, err := os.OpenFile(configPath, os.O_CREATE|os.O_RDWR, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
LuaConfig = b
|
||||
return nil
|
||||
}
|
||||
// If the configuration file is empty (the size of the file is zero; a new configuration file was created), write the default configuration to the file.
|
||||
if fi.Size() == 0 {
|
||||
return yaml.NewEncoder(f).Encode(c)
|
||||
}
|
||||
|
||||
func (c *Config) KeyLua(s *lua.LState) int {
|
||||
keyTable := s.NewTable()
|
||||
keyTable.RawSetString("name", s.Get(1))
|
||||
keyTable.RawSetString("description", s.Get(2))
|
||||
keyTable.RawSetString("action", s.Get(3))
|
||||
|
||||
s.Push(keyTable) // Push the result
|
||||
return 1 // Number of results
|
||||
return yaml.NewDecoder(f).Decode(&c)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
local string = require "string"
|
||||
|
||||
-- Whether the mouse is usable or not.
|
||||
mouse = true
|
||||
|
||||
-- The maximum number of messages to fetch and display on the messages panel.
|
||||
-- Its value must not be lesser than 1 and greater than 100.
|
||||
messagesLimit = 50
|
||||
|
||||
-- Whether to display the timestamp of the message beside the displayed message or not.
|
||||
timestamps = false
|
||||
|
||||
-- The timezone of the timestamps.
|
||||
-- Learn more: https://pkg.go.dev/time#LoadLocation
|
||||
timezone = "Local"
|
||||
|
||||
-- A textual representation of the time value formatted according to the layout defined by its value.
|
||||
-- Learn more: https://pkg.go.dev/time#Layout
|
||||
timeFormat = "3:04PM"
|
||||
|
||||
browser = "Chrome"
|
||||
browserVersion = "104.0.5112.102"
|
||||
oss = "Linux"
|
||||
|
||||
-- Identify properties are connection properties that are dispatched in the IDENTIFY gateway event to trigger the initial handshake with the gateway.
|
||||
-- Learn more: https://discord.com/developers/docs/topics/gateway#identify
|
||||
identifyProperties = {
|
||||
userAgent = string.format(
|
||||
"Mozilla/5.0 (X11; %s x86_64) AppleWebKit/537.36 (KHTML, like Gecko) %s/%s Safari/537.36",
|
||||
oss,
|
||||
browser,
|
||||
browserVersion
|
||||
),
|
||||
browser = browser,
|
||||
browserVersion = browserVersion,
|
||||
os = oss
|
||||
}
|
||||
|
||||
-- Keybindings
|
||||
keys = {
|
||||
-- application = {
|
||||
-- key(
|
||||
-- "Ctrl+R",
|
||||
-- "Refresh the screen.",
|
||||
-- function(core, event)
|
||||
-- core.Application:Sync()
|
||||
-- return nil
|
||||
-- end
|
||||
-- )
|
||||
-- },
|
||||
messagesPanel = {
|
||||
key(
|
||||
"Rune[a]",
|
||||
"Open the message actions list widget.",
|
||||
function(core, event)
|
||||
return openMessageActionsList()
|
||||
end
|
||||
),
|
||||
key(
|
||||
"Up",
|
||||
"Select the previous message.",
|
||||
function(core, event)
|
||||
return selectPreviousMessage()
|
||||
end
|
||||
),
|
||||
key(
|
||||
"Down",
|
||||
"Select the next message.",
|
||||
function(core, event)
|
||||
return selectNextMessage()
|
||||
end
|
||||
),
|
||||
key(
|
||||
"Home",
|
||||
"Select the first message.",
|
||||
function(core, event)
|
||||
return selectFirstMessage()
|
||||
end
|
||||
),
|
||||
key(
|
||||
"End",
|
||||
"Select the last message.",
|
||||
function(core, event)
|
||||
return selectLastMessage()
|
||||
end
|
||||
)
|
||||
},
|
||||
messageInput = {
|
||||
key(
|
||||
"Ctrl+E",
|
||||
"Open the external editor.",
|
||||
function()
|
||||
return openExternalEditor()
|
||||
end
|
||||
),
|
||||
key(
|
||||
"Ctrl+V",
|
||||
"Paste the clipboard content.",
|
||||
function()
|
||||
return pasteClipboardContent()
|
||||
end
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-- Theme
|
||||
theme = {background = "default", border = "white", title = "white"}
|
||||
3
go.mod
3
go.mod
|
|
@ -8,9 +8,8 @@ require (
|
|||
github.com/gdamore/tcell/v2 v2.5.3
|
||||
github.com/rivo/tview v0.0.0-20220906194528-4664d8bf22d9
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64
|
||||
github.com/zalando/go-keyring v0.2.1
|
||||
layeh.com/gopher-luar v1.0.10
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
|
|||
10
go.sum
10
go.sum
|
|
@ -2,9 +2,6 @@ github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVK
|
|||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
|
||||
github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
|
||||
github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=
|
||||
|
|
@ -46,14 +43,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||
github.com/zalando/go-keyring v0.2.1 h1:MBRN/Z8H4U5wEKXiD67YbDAr5cj/DOStmSga70/2qKc=
|
||||
github.com/zalando/go-keyring v0.2.1/go.mod h1:g63M2PPn0w5vjmEbwAX3ib5I+41zdm4esSETOn9Y6Dw=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
@ -73,11 +66,10 @@ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
layeh.com/gopher-luar v1.0.10 h1:55b0mpBhN9XSshEd2Nz6WsbYXctyBT35azk4POQNSXo=
|
||||
layeh.com/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
|
||||
|
|
|
|||
26
main.go
26
main.go
|
|
@ -3,8 +3,6 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ayntgl/discordo/config"
|
||||
"github.com/ayntgl/discordo/ui"
|
||||
|
|
@ -12,38 +10,24 @@ import (
|
|||
"github.com/zalando/go-keyring"
|
||||
)
|
||||
|
||||
const (
|
||||
name = "discordo"
|
||||
)
|
||||
|
||||
var (
|
||||
token string
|
||||
configPath string
|
||||
)
|
||||
var token string
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&token, "token", "", "The client authentication token.")
|
||||
// If the token is provided via a command-line flag, store it in the default keyring.
|
||||
if token != "" {
|
||||
go keyring.Set(name, "token", token)
|
||||
go keyring.Set(config.Name, "token", token)
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
token, _ = keyring.Get(name, "token")
|
||||
token, _ = keyring.Get(config.Name, "token")
|
||||
}
|
||||
|
||||
configDirPath, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
flag.StringVar(&configPath, "config", filepath.Join(configDirPath, name), "The path to the configuration directory.")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
cfg := config.New(configPath)
|
||||
cfg := config.New()
|
||||
err := cfg.Load()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
@ -80,7 +64,7 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
go keyring.Set(name, "token", tkn)
|
||||
go keyring.Set(config.Name, "token", tkn)
|
||||
|
||||
c.DrawMainFlex()
|
||||
c.Application.SetRoot(c.MainFlex, true)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
func buildMessage(c *Core, m discord.Message) []byte {
|
||||
|
|
@ -23,19 +22,14 @@ func buildMessage(c *Core, m discord.Message) []byte {
|
|||
// Build the message associated with crosspost, channel follow add, pin, or a reply.
|
||||
buildReferencedMessage(&b, m.ReferencedMessage, c.State.Ready().User.ID)
|
||||
|
||||
timestamps := c.Config.State.GetGlobal("timestamps")
|
||||
|
||||
if lua.LVAsBool(timestamps) {
|
||||
timezone := c.Config.State.GetGlobal("timezone")
|
||||
loc, err := time.LoadLocation(lua.LVAsString(timezone))
|
||||
if c.Config.Timestamps {
|
||||
loc, err := time.LoadLocation(c.Config.Timezone)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
timeFormat := c.Config.State.GetGlobal("timeFormat")
|
||||
|
||||
b.WriteString("[::d]")
|
||||
b.WriteString(m.Timestamp.Time().In(loc).Format(lua.LVAsString(timeFormat)))
|
||||
b.WriteString(m.Timestamp.Time().In(loc).Format(c.Config.TimeFormat))
|
||||
b.WriteString("[::-]")
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
"github.com/rivo/tview"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
type ChannelsTree struct {
|
||||
|
|
@ -64,9 +63,8 @@ func (ct *ChannelsTree) onSelected(node *tview.TreeNode) {
|
|||
ct.core.MessagesPanel.SetTitle(title)
|
||||
|
||||
go func() {
|
||||
messagesLimit := ct.core.Config.State.GetGlobal("messagesLimit")
|
||||
// The returned slice will be sorted from latest to oldest.
|
||||
ms, err := ct.core.State.Messages(c.ID, uint(lua.LVAsNumber(messagesLimit)))
|
||||
ms, err := ct.core.State.Messages(c.ID, ct.core.Config.MessagesLimit)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
221
ui/core.go
221
ui/core.go
|
|
@ -1,15 +1,9 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/ayntgl/discordo/config"
|
||||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
"github.com/diamondburned/arikawa/v3/gateway"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
type focused int
|
||||
|
|
@ -47,7 +41,14 @@ func NewCore(cfg *config.Config) *Core {
|
|||
Config: cfg,
|
||||
}
|
||||
|
||||
tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(cfg.Theme.Background)
|
||||
tview.Styles.BorderColor = tcell.GetColor(cfg.Theme.Border)
|
||||
tview.Styles.TitleColor = tcell.GetColor(cfg.Theme.Title)
|
||||
|
||||
c.Application.EnableMouse(c.Config.Mouse)
|
||||
c.Application.SetInputCapture(c.onInputCapture)
|
||||
c.Application.SetBeforeDrawFunc(c.beforeDraw)
|
||||
|
||||
c.GuildsTree = NewGuildsTree(c)
|
||||
c.ChannelsTree = NewChannelsTree(c)
|
||||
c.MessagesPanel = NewMessagesPanel(c)
|
||||
|
|
@ -56,65 +57,10 @@ func NewCore(cfg *config.Config) *Core {
|
|||
}
|
||||
|
||||
func (c *Core) Run(token string) error {
|
||||
c.register()
|
||||
err := c.Config.State.DoString(string(config.LuaConfig))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
themeTable, ok := c.Config.State.GetGlobal("theme").(*lua.LTable)
|
||||
if !ok {
|
||||
themeTable = c.Config.State.NewTable()
|
||||
}
|
||||
|
||||
backgroundColor := tcell.GetColor(lua.LVAsString(themeTable.RawGetString("background")))
|
||||
borderColor := tcell.GetColor(lua.LVAsString(themeTable.RawGetString("border")))
|
||||
titleColor := tcell.GetColor(lua.LVAsString(themeTable.RawGetString("title")))
|
||||
|
||||
c.GuildsTree.SetBackgroundColor(backgroundColor)
|
||||
c.GuildsTree.SetBorderColor(borderColor)
|
||||
c.GuildsTree.SetTitleColor(titleColor)
|
||||
|
||||
c.ChannelsTree.SetBackgroundColor(backgroundColor)
|
||||
c.ChannelsTree.SetBorderColor(borderColor)
|
||||
c.ChannelsTree.SetTitleColor(titleColor)
|
||||
|
||||
c.MessagesPanel.SetBackgroundColor(backgroundColor)
|
||||
c.MessagesPanel.SetBorderColor(borderColor)
|
||||
c.MessagesPanel.SetTitleColor(titleColor)
|
||||
|
||||
c.MessageInput.SetBackgroundColor(backgroundColor)
|
||||
c.MessageInput.SetBorderColor(borderColor)
|
||||
c.MessageInput.SetTitleColor(titleColor)
|
||||
c.MessageInput.SetPlaceholderStyle(tcell.StyleDefault.Background(backgroundColor))
|
||||
|
||||
c.Application.SetBeforeDrawFunc(func(s tcell.Screen) bool {
|
||||
if backgroundColor == 0 {
|
||||
s.Clear()
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
c.Application.EnableMouse(lua.LVAsBool(c.Config.State.GetGlobal("mouse")))
|
||||
|
||||
c.State = NewState(token, c)
|
||||
return c.State.Run()
|
||||
}
|
||||
|
||||
func (c *Core) register() {
|
||||
c.Config.State.SetGlobal("key", c.Config.State.NewFunction(c.Config.KeyLua))
|
||||
// Messages panel
|
||||
c.Config.State.SetGlobal("openMessageActionsList", c.Config.State.NewFunction(c.MessagesPanel.openMessageActionsListLua))
|
||||
c.Config.State.SetGlobal("selectPreviousMessage", c.Config.State.NewFunction(c.MessagesPanel.selectPreviousMessageLua))
|
||||
c.Config.State.SetGlobal("selectNextMessage", c.Config.State.NewFunction(c.MessagesPanel.selectNextMessageLua))
|
||||
c.Config.State.SetGlobal("selectFirstMessage", c.Config.State.NewFunction(c.MessagesPanel.selectFirstMessageLua))
|
||||
c.Config.State.SetGlobal("selectLastMessage", c.Config.State.NewFunction(c.MessagesPanel.selectLastMessageLua))
|
||||
// Message input
|
||||
c.Config.State.SetGlobal("openExternalEditor", c.Config.State.NewFunction(c.MessageInput.openExternalEditorLua))
|
||||
c.Config.State.SetGlobal("pasteClipboardContent", c.Config.State.NewFunction(c.MessageInput.pasteClipboardContentLua))
|
||||
}
|
||||
|
||||
func (c *Core) DrawMainFlex() {
|
||||
leftFlex := tview.NewFlex().
|
||||
SetDirection(tview.FlexRow).
|
||||
|
|
@ -129,52 +75,21 @@ func (c *Core) DrawMainFlex() {
|
|||
AddItem(rightFlex, 0, 4, false)
|
||||
}
|
||||
|
||||
func (c *Core) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
||||
func (c *Core) beforeDraw(screen tcell.Screen) bool {
|
||||
if c.Config.Theme.Background == "default" {
|
||||
screen.Clear()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Core) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
// If the main flex is nil, that is, it is not initialized yet, then the login form is currently focused.
|
||||
if c.MainFlex == nil {
|
||||
return e
|
||||
return event
|
||||
}
|
||||
|
||||
keysTable, ok := c.Config.State.GetGlobal("keys").(*lua.LTable)
|
||||
if !ok {
|
||||
keysTable = c.Config.State.NewTable()
|
||||
}
|
||||
|
||||
applicationTable, ok := keysTable.RawGetString("application").(*lua.LTable)
|
||||
if !ok {
|
||||
applicationTable = c.Config.State.NewTable()
|
||||
}
|
||||
|
||||
var fn lua.LValue
|
||||
applicationTable.ForEach(func(k, v lua.LValue) {
|
||||
keyTable := v.(*lua.LTable)
|
||||
if e.Name() == lua.LVAsString(keyTable.RawGetString("name")) {
|
||||
fn = keyTable.RawGetString("action")
|
||||
}
|
||||
})
|
||||
|
||||
if fn != nil {
|
||||
c.Config.State.CallByParam(lua.P{
|
||||
Fn: fn,
|
||||
NRet: 1,
|
||||
Protect: true,
|
||||
}, luar.New(c.Config.State, c), luar.New(c.Config.State, e))
|
||||
// Returned value
|
||||
ret, ok := c.Config.State.Get(-1).(*lua.LUserData)
|
||||
if !ok {
|
||||
return e
|
||||
}
|
||||
|
||||
// Remove returned value
|
||||
c.Config.State.Pop(1)
|
||||
ev, ok := ret.Value.(*tcell.EventKey)
|
||||
if ok {
|
||||
return ev
|
||||
}
|
||||
}
|
||||
|
||||
// Default
|
||||
switch e.Key() {
|
||||
switch event.Key() {
|
||||
case tcell.KeyEsc:
|
||||
c.focused = 0
|
||||
case tcell.KeyBacktab:
|
||||
|
|
@ -197,7 +112,7 @@ func (c *Core) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|||
c.setFocus()
|
||||
}
|
||||
|
||||
return e
|
||||
return event
|
||||
}
|
||||
|
||||
func (c *Core) setFocus() {
|
||||
|
|
@ -215,101 +130,3 @@ func (c *Core) setFocus() {
|
|||
|
||||
c.Application.SetFocus(p)
|
||||
}
|
||||
|
||||
func (c *Core) onStateReady(r *gateway.ReadyEvent) {
|
||||
rootNode := c.GuildsTree.GetRoot()
|
||||
for _, gf := range r.UserSettings.GuildFolders {
|
||||
if gf.ID == 0 {
|
||||
for _, gID := range gf.GuildIDs {
|
||||
g, err := c.State.Cabinet.Guild(gID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
guildNode := tview.NewTreeNode(g.Name)
|
||||
guildNode.SetReference(g.ID)
|
||||
rootNode.AddChild(guildNode)
|
||||
}
|
||||
} else {
|
||||
var b strings.Builder
|
||||
|
||||
if gf.Color != discord.NullColor {
|
||||
b.WriteByte('[')
|
||||
b.WriteString(gf.Color.String())
|
||||
b.WriteByte(']')
|
||||
} else {
|
||||
b.WriteString("[#ED4245]")
|
||||
}
|
||||
|
||||
if gf.Name != "" {
|
||||
b.WriteString(gf.Name)
|
||||
} else {
|
||||
b.WriteString("Folder")
|
||||
}
|
||||
|
||||
b.WriteString("[-]")
|
||||
|
||||
folderNode := tview.NewTreeNode(b.String())
|
||||
rootNode.AddChild(folderNode)
|
||||
|
||||
for _, gID := range gf.GuildIDs {
|
||||
g, err := c.State.Cabinet.Guild(gID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
guildNode := tview.NewTreeNode(g.Name)
|
||||
guildNode.SetReference(g.ID)
|
||||
folderNode.AddChild(guildNode)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
c.GuildsTree.SetCurrentNode(rootNode)
|
||||
c.Application.SetFocus(c.GuildsTree)
|
||||
}
|
||||
|
||||
func (c *Core) onStateGuildCreate(g *gateway.GuildCreateEvent) {
|
||||
guildNode := tview.NewTreeNode(g.Name)
|
||||
guildNode.SetReference(g.ID)
|
||||
|
||||
rootNode := c.GuildsTree.GetRoot()
|
||||
rootNode.AddChild(guildNode)
|
||||
|
||||
c.GuildsTree.SetCurrentNode(rootNode)
|
||||
c.Application.SetFocus(c.GuildsTree)
|
||||
c.Application.Draw()
|
||||
}
|
||||
|
||||
func (c *Core) onStateGuildDelete(g *gateway.GuildDeleteEvent) {
|
||||
rootNode := c.GuildsTree.GetRoot()
|
||||
var parentNode *tview.TreeNode
|
||||
rootNode.Walk(func(node, _ *tview.TreeNode) bool {
|
||||
if node.GetReference() == g.ID {
|
||||
parentNode = node
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
if parentNode != nil {
|
||||
rootNode.RemoveChild(parentNode)
|
||||
}
|
||||
|
||||
c.Application.Draw()
|
||||
}
|
||||
|
||||
func (c *Core) onStateMessageCreate(m *gateway.MessageCreateEvent) {
|
||||
if c.ChannelsTree.SelectedChannel != nil && c.ChannelsTree.SelectedChannel.ID == m.ChannelID {
|
||||
_, err := c.MessagesPanel.Write(buildMessage(c, m.Message))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(c.MessagesPanel.GetHighlights()) == 0 {
|
||||
c.MessagesPanel.ScrollToEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ import (
|
|||
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
type MessageInput struct {
|
||||
|
|
@ -30,7 +28,7 @@ func NewMessageInput(c *Core) *MessageInput {
|
|||
mi.SetFieldBackgroundColor(tview.Styles.PrimitiveBackgroundColor)
|
||||
mi.SetPlaceholder("Message...")
|
||||
mi.SetPlaceholderStyle(tcell.StyleDefault.Background(tview.Styles.PrimitiveBackgroundColor))
|
||||
mi.SetInputCapture(mi.onInputCapture)
|
||||
mi.SetInputCapture(mi.inputCapture)
|
||||
|
||||
mi.SetTitleAlign(tview.AlignLeft)
|
||||
mi.SetBorder(true)
|
||||
|
|
@ -39,50 +37,14 @@ func NewMessageInput(c *Core) *MessageInput {
|
|||
return mi
|
||||
}
|
||||
|
||||
func (mi *MessageInput) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
||||
keysTable, ok := mi.core.Config.State.GetGlobal("keys").(*lua.LTable)
|
||||
if !ok {
|
||||
keysTable = mi.core.Config.State.NewTable()
|
||||
}
|
||||
|
||||
messageInputTable, ok := keysTable.RawGetString("messageInput").(*lua.LTable)
|
||||
if !ok {
|
||||
messageInputTable = mi.core.Config.State.NewTable()
|
||||
}
|
||||
|
||||
var fn lua.LValue
|
||||
messageInputTable.ForEach(func(k, v lua.LValue) {
|
||||
keyTable := v.(*lua.LTable)
|
||||
if e.Name() == lua.LVAsString(keyTable.RawGetString("name")) {
|
||||
fn = keyTable.RawGetString("action")
|
||||
}
|
||||
})
|
||||
|
||||
if fn != nil {
|
||||
mi.core.Config.State.CallByParam(lua.P{
|
||||
Fn: fn,
|
||||
NRet: 1,
|
||||
Protect: true,
|
||||
}, luar.New(mi.core.Config.State, mi.core), luar.New(mi.core.Config.State, e))
|
||||
// Returned value
|
||||
ret, ok := mi.core.Config.State.Get(-1).(*lua.LUserData)
|
||||
if !ok {
|
||||
return e
|
||||
}
|
||||
|
||||
// Remove returned value
|
||||
mi.core.Config.State.Pop(1)
|
||||
|
||||
ev, ok := ret.Value.(*tcell.EventKey)
|
||||
if ok {
|
||||
return ev
|
||||
}
|
||||
}
|
||||
|
||||
// Defaults
|
||||
switch e.Name() {
|
||||
func (mi *MessageInput) inputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
switch event.Name() {
|
||||
case "Enter":
|
||||
return mi.sendMessage()
|
||||
case mi.core.Config.Keys.MessageInput.OpenExternalEditor:
|
||||
return mi.openExternalEditor()
|
||||
case mi.core.Config.Keys.MessageInput.PasteClipboard:
|
||||
return mi.pasteClipboard()
|
||||
case "Esc":
|
||||
mi.
|
||||
SetText("").
|
||||
|
|
@ -92,7 +54,7 @@ func (mi *MessageInput) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
return e
|
||||
return event
|
||||
}
|
||||
|
||||
func (mi *MessageInput) sendMessage() *tcell.EventKey {
|
||||
|
|
@ -105,8 +67,7 @@ func (mi *MessageInput) sendMessage() *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
messagesLimit := mi.core.Config.State.GetGlobal("messagesLimit")
|
||||
ms, err := mi.core.State.Messages(mi.core.ChannelsTree.SelectedChannel.ID, uint(lua.LVAsNumber(messagesLimit)))
|
||||
ms, err := mi.core.State.Messages(mi.core.ChannelsTree.SelectedChannel.ID, mi.core.Config.MessagesLimit)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -143,22 +104,22 @@ func (mi *MessageInput) sendMessage() *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (mi *MessageInput) pasteClipboardContentLua(s *lua.LState) int {
|
||||
func (mi *MessageInput) pasteClipboard() *tcell.EventKey {
|
||||
text, _ := clipboard.ReadAll()
|
||||
text = mi.GetText() + text
|
||||
mi.SetText(text)
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mi *MessageInput) openExternalEditorLua(s *lua.LState) int {
|
||||
func (mi *MessageInput) openExternalEditor() *tcell.EventKey {
|
||||
e := os.Getenv("EDITOR")
|
||||
if e == "" {
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := os.CreateTemp(os.TempDir(), "discordo-*.md")
|
||||
if err != nil {
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
|
|
@ -175,9 +136,9 @@ func (mi *MessageInput) openExternalEditorLua(s *lua.LState) int {
|
|||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
mi.SetText(string(b))
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import (
|
|||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
type MessagesPanel struct {
|
||||
|
|
@ -51,47 +49,19 @@ func (mp *MessagesPanel) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
keysTable, ok := mp.core.Config.State.GetGlobal("keys").(*lua.LTable)
|
||||
if !ok {
|
||||
keysTable = mp.core.Config.State.NewTable()
|
||||
}
|
||||
|
||||
messagesPanel, ok := keysTable.RawGetString("messagesPanel").(*lua.LTable)
|
||||
if !ok {
|
||||
messagesPanel = mp.core.Config.State.NewTable()
|
||||
}
|
||||
|
||||
var fn lua.LValue
|
||||
messagesPanel.ForEach(func(k, v lua.LValue) {
|
||||
keyTable := v.(*lua.LTable)
|
||||
if e.Name() == lua.LVAsString(keyTable.RawGetString("name")) {
|
||||
fn = keyTable.RawGetString("action")
|
||||
}
|
||||
})
|
||||
|
||||
if fn != nil {
|
||||
mp.core.Config.State.CallByParam(lua.P{
|
||||
Fn: fn,
|
||||
NRet: 1,
|
||||
Protect: true,
|
||||
}, luar.New(mp.core.Config.State, mp.core), luar.New(mp.core.Config.State, e))
|
||||
// Returned value
|
||||
ret, ok := mp.core.Config.State.Get(-1).(*lua.LUserData)
|
||||
if !ok {
|
||||
return e
|
||||
}
|
||||
|
||||
// Remove returned value
|
||||
mp.core.Config.State.Pop(1)
|
||||
|
||||
ev, ok := ret.Value.(*tcell.EventKey)
|
||||
if ok {
|
||||
return ev
|
||||
}
|
||||
}
|
||||
|
||||
// Defaults
|
||||
switch e.Name() {
|
||||
case mp.core.Config.Keys.MessagesPanel.OpenActionsList:
|
||||
return mp.openMessageActionsList(ms)
|
||||
|
||||
case mp.core.Config.Keys.MessagesPanel.SelectPreviousMessage:
|
||||
return mp.selectPreviousMessage(ms)
|
||||
case mp.core.Config.Keys.MessagesPanel.SelectNextMessage:
|
||||
return mp.selectNextMessage(ms)
|
||||
case mp.core.Config.Keys.MessagesPanel.SelectFirstMessage:
|
||||
return mp.selectFirstMessage(ms)
|
||||
case mp.core.Config.Keys.MessagesPanel.SelectLastMessage:
|
||||
return mp.selectLastMessage(ms)
|
||||
case "Esc":
|
||||
mp.SelectedMessage = -1
|
||||
mp.core.Application.SetFocus(mp.core.MainFlex)
|
||||
|
|
@ -105,13 +75,7 @@ func (mp *MessagesPanel) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|||
return e
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectPreviousMessageLua(s *lua.LState) int {
|
||||
// Messages should return messages ordered from latest to earliest.
|
||||
ms, err := mp.core.State.Cabinet.Messages(mp.core.ChannelsTree.SelectedChannel.ID)
|
||||
if err != nil || len(ms) == 0 {
|
||||
return returnNilLua(s)
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectPreviousMessage(ms []discord.Message) *tcell.EventKey {
|
||||
// If there are no highlighted regions, select the latest (last) message in the messages panel.
|
||||
if len(mp.GetHighlights()) == 0 {
|
||||
mp.SelectedMessage = 0
|
||||
|
|
@ -126,16 +90,10 @@ func (mp *MessagesPanel) selectPreviousMessageLua(s *lua.LState) int {
|
|||
|
||||
mp.Highlight(ms[mp.SelectedMessage].ID.String())
|
||||
mp.ScrollToHighlight()
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectNextMessageLua(s *lua.LState) int {
|
||||
// Messages should return messages ordered from latest to earliest.
|
||||
ms, err := mp.core.State.Cabinet.Messages(mp.core.ChannelsTree.SelectedChannel.ID)
|
||||
if err != nil || len(ms) == 0 {
|
||||
return returnNilLua(s)
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectNextMessage(ms []discord.Message) *tcell.EventKey {
|
||||
// If there are no highlighted regions, select the latest (last) message in the messages panel.
|
||||
if len(mp.GetHighlights()) == 0 {
|
||||
mp.SelectedMessage = 0
|
||||
|
|
@ -151,60 +109,42 @@ func (mp *MessagesPanel) selectNextMessageLua(s *lua.LState) int {
|
|||
mp.
|
||||
Highlight(ms[mp.SelectedMessage].ID.String()).
|
||||
ScrollToHighlight()
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectFirstMessageLua(s *lua.LState) int {
|
||||
// Messages should return messages ordered from latest to earliest.
|
||||
ms, err := mp.core.State.Cabinet.Messages(mp.core.ChannelsTree.SelectedChannel.ID)
|
||||
if err != nil || len(ms) == 0 {
|
||||
return returnNilLua(s)
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectFirstMessage(ms []discord.Message) *tcell.EventKey {
|
||||
mp.SelectedMessage = len(ms) - 1
|
||||
mp.
|
||||
Highlight(ms[mp.SelectedMessage].ID.String()).
|
||||
ScrollToHighlight()
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectLastMessageLua(s *lua.LState) int {
|
||||
// Messages should return messages ordered from latest to earliest.
|
||||
ms, err := mp.core.State.Cabinet.Messages(mp.core.ChannelsTree.SelectedChannel.ID)
|
||||
if err != nil || len(ms) == 0 {
|
||||
return returnNilLua(s)
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) selectLastMessage(ms []discord.Message) *tcell.EventKey {
|
||||
mp.SelectedMessage = 0
|
||||
mp.
|
||||
Highlight(ms[mp.SelectedMessage].ID.String()).
|
||||
ScrollToHighlight()
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) openMessageActionsListLua(s *lua.LState) int {
|
||||
// Messages should return messages ordered from latest to earliest.
|
||||
ms, err := mp.core.State.Cabinet.Messages(mp.core.ChannelsTree.SelectedChannel.ID)
|
||||
if err != nil || len(ms) == 0 {
|
||||
return returnNilLua(s)
|
||||
}
|
||||
|
||||
func (mp *MessagesPanel) openMessageActionsList(ms []discord.Message) *tcell.EventKey {
|
||||
hs := mp.GetHighlights()
|
||||
if len(hs) == 0 {
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
mID, err := discord.ParseSnowflake(hs[0])
|
||||
if err != nil {
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
_, m := findMessageByID(ms, discord.MessageID(mID))
|
||||
if m == nil {
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
actionsList := NewMessageActionsList(mp.core, m)
|
||||
mp.core.Application.SetRoot(actionsList, true)
|
||||
return returnNilLua(s)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -66,8 +65,3 @@ func hasPermission(s *State, cID discord.ChannelID, p discord.Permissions) bool
|
|||
|
||||
return perm&p == p
|
||||
}
|
||||
|
||||
func returnNilLua(s *lua.LState) int {
|
||||
s.Push(lua.LNil) // Push the result
|
||||
return 1 // Number of results
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue