feat: switch to toml for config (#67)

* feat: switch to toml for config

* resolve indirect dep
This commit is contained in:
ayntgl 2021-10-02 18:52:23 +04:00 • committed by GitHub
parent b0ca25677f
commit 7c140afb03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 127 deletions

View file

@ -39,51 +39,11 @@ sudo mv ./discordo /usr/local/bin
1. Run the `discordo` executable with no arguments in a new Terminal window.
2. Log in using the account email and password (first-time login) and click on the "Login" button to continue.
> By default, Discordo utilizes OS-specific keyring to store credentials such as client authentication token. However, if you prefer not to use a keyring, you may set the `token` field in the configuration file (`~/.config/discordo/config.json`) and Discordo will prioritize the usage of `Token` field to login instead of keyring.
> By default, Discordo utilizes OS-specific keyring to store credentials such as client authentication token. However, if you prefer not to use a keyring (not recommended), you may set the `token` field in the configuration file (`~/.config/discordo/config.toml`) and Discordo will prioritize the usage of the provided token to login instead of keyring.
### Configuration
Discordo aims to be highly configurable, it may be easily customized via a configuration file. It creates a default configuration file on the first start-up. The default and newly created configuration file is located at `$HOME/.config/discordo/config.json`. Here is a sample (not default) configuration file:
```jsonc
{
// The client authentication token (optional)
"Token": "",
// Enables mouse support.
"Mouse": true,
// Enables OS-specific desktop notifications when the client user is mentioned in non-selected channels.
"Notifications": true,
// Set a custom user agent for all of the HTTP requests.
"UserAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
// Set the number of messages to retrieve when a text-based channel is selected.
"GetMessagesLimit": 30,
// The Theme field values can be hex color codes (#f44f36) or W3C color names.
"Theme": {
"PrimitiveBackgroundColor": "black",
"ContrastBackgroundColor": "blue",
"MoreContrastBackgroundColor": "green",
"BorderColor": "white",
"TitleColor": "white",
"GraphicsColor": "white",
"PrimaryTextColor": "white",
"SecondaryTextColor": "yellow",
"TertiaryTextColor": "green",
"InverseTextColor": "blue",
"ContrastSecondaryTextColor": "darkcyan"
},
"Keybindings": {
"GuildsTreeViewFocus": "Alt+Rune[1]",
"MessagesTextViewFocus": "Alt+Rune[2]",
"MessagesTextViewSelectPrevious": "Up",
"MessagesTextViewSelectNext": "Down",
"MessagesTextViewSelectFirst": "Home",
"MessagesTextViewSelectLast": "End",
"MessagesTextViewReplySelected": "Rune[r]",
"MessagesTextViewMentionReplySelected": "Rune[R]",
"MessageInputFieldFocus": "Alt+Rune[3]"
}
}
```
Discordo aims to be highly configurable, it may be easily customized via a configuration file. It creates a default configuration file on the first start-up. The default and newly created configuration file is located at `$HOME/.config/discordo/config.toml`.
### Clipboard support

159
config.go
View file

@ -1,48 +1,79 @@
package main
import (
"encoding/json"
"os"
"github.com/BurntSushi/toml"
)
var conf *config
type keybindingsChannelsTree struct {
Focus string `toml:"focus"`
}
type keybindingsMessagesTextView struct {
Focus string `toml:"focus"`
SelectPrevious string `toml:"select_previous"`
SelectNext string `toml:"select_next"`
SelectFirst string `toml:"select_first"`
SelectLast string `toml:"select_last"`
Reply string `toml:"reply"`
ReplyMention string `toml:"reply_mention"`
}
type keybindingsMessageInputField struct {
Focus string `toml:"focus"`
}
type keybindings struct {
GuildsTreeViewFocus string
ChannelsTree keybindingsChannelsTree `toml:"channels_tree"`
MessagesTextView keybindingsMessagesTextView `toml:"messages_textview"`
MessageInputField keybindingsMessageInputField `toml:"message_inputfield"`
}
MessagesTextViewFocus string
MessagesTextViewSelectPrevious string
MessagesTextViewSelectNext string
MessagesTextViewSelectFirst string
MessagesTextViewSelectLast string
MessagesTextViewReplySelected string
MessagesTextViewMentionReplySelected string
type themeBackground struct {
// Main background color for primitives.
Primitive string `toml:"primitive"`
// Background color for contrasting elements.
Contrast string `toml:"contrast"`
// Background color for even more contrasting elements.
MoreContrast string `toml:"more_contrast"`
}
MessageInputFieldFocus string
type themeText struct {
// Primary text.
Primary string `toml:"primary"`
// Secondary text (e.g. labels).
Secondary string `toml:"secondary"`
// Tertiary text (e.g. subtitles, notes).
Tertiary string `toml:"tertiary"`
// Text on primary-colored backgrounds.
Inverse string `toml:"inverse"`
// Secondary text on ContrastBackgroundColor-colored backgrounds.
ContrastSecondary string `toml:"contrast_secondary"`
}
type theme struct {
PrimitiveBackgroundColor string // Main background color for primitives.
ContrastBackgroundColor string // Background color for contrasting elements.
MoreContrastBackgroundColor string // Background color for even more contrasting elements.
BorderColor string // Box borders.
TitleColor string // Box titles.
GraphicsColor string // Graphics.
PrimaryTextColor string // Primary text.
SecondaryTextColor string // Secondary text (e.g. labels).
TertiaryTextColor string // Tertiary text (e.g. subtitles, notes).
InverseTextColor string // Text on primary-colored backgrounds.
ContrastSecondaryTextColor string // Secondary text on ContrastBackgroundColor-colored backgrounds.
// Box borders.
Border string `toml:"border"`
// Box titles.
Title string `toml:"title"`
// Graphics.
Graphics string `toml:"graphics"`
Background themeBackground `toml:"background"`
Text themeText `toml:"text"`
}
type config struct {
Token string
Mouse bool
Notifications bool
UserAgent string
GetMessagesLimit int
Theme theme
Keybindings keybindings
Token string `toml:"token"`
Mouse bool `toml:"mouse"`
Notifications bool `toml:"notifications"`
UserAgent string `toml:"user_agent"`
GetMessagesLimit int `toml:"get_messages_limit"`
Theme theme `toml:"theme"`
Keybindings keybindings `toml:"keybindings"`
}
func loadConfig() *config {
@ -51,7 +82,7 @@ func loadConfig() *config {
panic(err)
}
configPath := u + "/.config/discordo/config.json"
configPath := u + "/.config/discordo/config.toml"
if _, err = os.Stat(configPath); os.IsNotExist(err) {
err = os.MkdirAll(u+"/.config/discordo", 0700)
if err != nil {
@ -73,54 +104,52 @@ func loadConfig() *config {
"Chrome/92.0.4515.131 Safari/537.36",
GetMessagesLimit: 50,
Theme: theme{
PrimitiveBackgroundColor: "black",
ContrastBackgroundColor: "blue",
MoreContrastBackgroundColor: "green",
BorderColor: "white",
TitleColor: "white",
GraphicsColor: "white",
PrimaryTextColor: "white",
SecondaryTextColor: "yellow",
TertiaryTextColor: "green",
InverseTextColor: "blue",
ContrastSecondaryTextColor: "darkcyan",
Border: "white",
Title: "white",
Graphics: "white",
Background: themeBackground{
Primitive: "black",
Contrast: "blue",
MoreContrast: "green",
},
Text: themeText{
Primary: "white",
Secondary: "yellow",
Tertiary: "green",
Inverse: "blue",
ContrastSecondary: "darkcyan",
},
},
Keybindings: keybindings{
GuildsTreeViewFocus: "Alt+Rune[1]",
MessagesTextViewFocus: "Alt+Rune[2]",
MessagesTextViewSelectPrevious: "Up",
MessagesTextViewSelectNext: "Down",
MessagesTextViewSelectFirst: "Home",
MessagesTextViewSelectLast: "End",
MessagesTextViewReplySelected: "Rune[r]",
MessagesTextViewMentionReplySelected: "Rune[R]",
MessageInputFieldFocus: "Alt+Rune[3]",
ChannelsTree: keybindingsChannelsTree{
Focus: "Alt+Rune[1]",
},
MessagesTextView: keybindingsMessagesTextView{
Focus: "Alt+Rune[2]",
SelectPrevious: "Up",
SelectNext: "Down",
SelectFirst: "Home",
SelectLast: "End",
Reply: "Rune[r]",
ReplyMention: "Rune[R]",
},
MessageInputField: keybindingsMessageInputField{
Focus: "Alt+Rune[3]",
},
},
}
d, err := json.MarshalIndent(c, "", "\t")
err = toml.NewEncoder(f).Encode(c)
if err != nil {
panic(err)
}
_, err = f.Write(d)
if err != nil {
panic(err)
}
f.Sync()
return &c
}
d, err := os.ReadFile(configPath)
if err != nil {
panic(err)
}
var c config
if err = json.Unmarshal(d, &c); err != nil {
_, err = toml.DecodeFile(configPath, &c)
if err != nil {
panic(err)
}

1
go.mod
View file

@ -3,6 +3,7 @@ module github.com/ayntgl/discordo
go 1.16
require (
github.com/BurntSushi/toml v0.4.1
github.com/atotto/clipboard v0.1.4
github.com/ayntgl/discordgo v0.23.3-0.20210920064905-b79d709bbafb
github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1

2
go.sum
View file

@ -1,3 +1,5 @@
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/ayntgl/discordgo v0.23.3-0.20210920064905-b79d709bbafb h1:4WL/2+MpUEvYl5shkF4YpNJAT7MG/JXR1p/6DnJ3GPY=

22
main.go
View file

@ -11,17 +11,17 @@ const service = "discordo"
func main() {
conf = loadConfig()
tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(conf.Theme.PrimitiveBackgroundColor)
tview.Styles.ContrastBackgroundColor = tcell.GetColor(conf.Theme.ContrastBackgroundColor)
tview.Styles.MoreContrastBackgroundColor = tcell.GetColor(conf.Theme.MoreContrastBackgroundColor)
tview.Styles.BorderColor = tcell.GetColor(conf.Theme.BorderColor)
tview.Styles.TitleColor = tcell.GetColor(conf.Theme.TitleColor)
tview.Styles.GraphicsColor = tcell.GetColor(conf.Theme.GraphicsColor)
tview.Styles.PrimaryTextColor = tcell.GetColor(conf.Theme.PrimaryTextColor)
tview.Styles.SecondaryTextColor = tcell.GetColor(conf.Theme.SecondaryTextColor)
tview.Styles.TertiaryTextColor = tcell.GetColor(conf.Theme.TertiaryTextColor)
tview.Styles.InverseTextColor = tcell.GetColor(conf.Theme.InverseTextColor)
tview.Styles.ContrastSecondaryTextColor = tcell.GetColor(conf.Theme.ContrastSecondaryTextColor)
tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(conf.Theme.Background.Primitive)
tview.Styles.ContrastBackgroundColor = tcell.GetColor(conf.Theme.Background.Contrast)
tview.Styles.MoreContrastBackgroundColor = tcell.GetColor(conf.Theme.Background.MoreContrast)
tview.Styles.BorderColor = tcell.GetColor(conf.Theme.Border)
tview.Styles.TitleColor = tcell.GetColor(conf.Theme.Title)
tview.Styles.GraphicsColor = tcell.GetColor(conf.Theme.Graphics)
tview.Styles.PrimaryTextColor = tcell.GetColor(conf.Theme.Text.Primary)
tview.Styles.SecondaryTextColor = tcell.GetColor(conf.Theme.Text.Secondary)
tview.Styles.TertiaryTextColor = tcell.GetColor(conf.Theme.Text.Tertiary)
tview.Styles.InverseTextColor = tcell.GetColor(conf.Theme.Text.Inverse)
tview.Styles.ContrastSecondaryTextColor = tcell.GetColor(conf.Theme.Text.ContrastSecondary)
app = newApplication()
channelsTree = newChannelsTree()

18
ui.go
View file

@ -29,11 +29,11 @@ func newApplication() *tview.Application {
func onAppInputCapture(e *tcell.EventKey) *tcell.EventKey {
switch e.Name() {
case conf.Keybindings.GuildsTreeViewFocus:
case conf.Keybindings.ChannelsTree.Focus:
app.SetFocus(channelsTree)
case conf.Keybindings.MessagesTextViewFocus:
case conf.Keybindings.MessagesTextView.Focus:
app.SetFocus(messagesTextView)
case conf.Keybindings.MessageInputFieldFocus:
case conf.Keybindings.MessageInputField.Focus:
app.SetFocus(messageInputField)
}
@ -226,7 +226,7 @@ func onMessagesTextViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
}
switch e.Name() {
case conf.Keybindings.MessagesTextViewSelectPrevious:
case conf.Keybindings.MessagesTextView.SelectPrevious:
ms := selectedChannel.Messages
if len(ms) == 0 {
return nil
@ -249,7 +249,7 @@ func onMessagesTextViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
}
return nil
case conf.Keybindings.MessagesTextViewSelectNext:
case conf.Keybindings.MessagesTextView.SelectNext:
ms := selectedChannel.Messages
if len(ms) == 0 {
return nil
@ -272,7 +272,7 @@ func onMessagesTextViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
}
return nil
case conf.Keybindings.MessagesTextViewSelectFirst:
case conf.Keybindings.MessagesTextView.SelectFirst:
ms := selectedChannel.Messages
if len(ms) == 0 {
return nil
@ -281,7 +281,7 @@ func onMessagesTextViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
messagesTextView.
Highlight(ms[0].ID).
ScrollToHighlight()
case conf.Keybindings.MessagesTextViewSelectLast:
case conf.Keybindings.MessagesTextView.SelectLast:
ms := selectedChannel.Messages
if len(ms) == 0 {
return nil
@ -290,7 +290,7 @@ func onMessagesTextViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
messagesTextView.
Highlight(ms[len(ms)-1].ID).
ScrollToHighlight()
case conf.Keybindings.MessagesTextViewReplySelected:
case conf.Keybindings.MessagesTextView.Reply:
ms := selectedChannel.Messages
if len(ms) == 0 {
return nil
@ -306,7 +306,7 @@ func onMessagesTextViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
"Replying to " + selectedMessage.Author.Username,
)
app.SetFocus(messageInputField)
case conf.Keybindings.MessagesTextViewMentionReplySelected:
case conf.Keybindings.MessagesTextView.ReplyMention:
ms := selectedChannel.Messages
if len(ms) == 0 {
return nil