diff --git a/README.md b/README.md index d4ddc46..d4a6fb2 100644 --- a/README.md +++ b/README.md @@ -53,46 +53,6 @@ go build . 2. Enter your email and password and click on the "Login" button to continue. -## Keymaps - -### Global - -- `Ctrl+G`: Focus Guilds Tree -- `Ctrl+T`: Focus Messages Text -- `Ctrl+P`: Focus Message Input -- `Ctrl+B`: Toggle Guilds Tree (sidebar) -- `Esc`: Reset message selection or close the channel selection popup. -- `Ctrl+C`: Quit the application. -- `Ctrl+D`: Log out and remove the authentication token from keyring (requires re-login upon restart). - -#### Navigation - -- `k`: Select Previous (any context except input) -- `j`: Select Next (any context except input) -- `g`: Select First (any context except input) -- `G`: Select Last (any context except input) - -### Guilds Tree - -- `Enter`: Select the currently highlighted text-based channel or expand a guild or channel. - -### Message Text - -- `s`: Select the message reference (reply) of the selected channel. -- `p`: Select the pinned message. -- `r`: Reply to the selected message. -- `R`: Reply (with mention) to the selected message. -- `d`: Delete the selected message. -- `y`: Yank (copy) the selected message's content. -- `o`: Open the selected message's attachments in the default browser application. - -### Message Input - -- `Alt+Enter`: Insert a new line to the current text. -- `Enter`: Send the message. -- `Ctrl+E`: Open message input in your default `$EDITOR`. -- `Esc`: Remove existing text or cancel reply. - ## Configuration The configuration file allows you to configure and customize the behavior, keybindings, and theme of the application. @@ -101,7 +61,7 @@ The configuration file allows you to configure and customize the behavior, keybi - Darwin: `$HOME/Library/Application Support/discordo/config.toml` - Windows: `%AppData%/discordo/config.toml` -[The default configuration can be found here](./internal/config/config.go). +[The default configuration can be found here](./internal/config/config.toml). ## FAQ diff --git a/internal/config/config.go b/internal/config/config.go index 2bc2165..b7936c0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -4,7 +4,6 @@ import ( "log/slog" "os" "path/filepath" - "time" "github.com/BurntSushi/toml" "github.com/ayn2op/discordo/internal/consts" @@ -56,42 +55,8 @@ type ( } ) -func defaultConfig() *Config { - return &Config{ - Mouse: true, - Editor: "default", - - HideBlockedUsers: true, - ShowAttachmentLinks: true, - MessagesLimit: 50, - - MarkdownEnabled: true, - - Timestamps: Timestamps{ - Enabled: true, - Format: time.Kitchen, - }, - - Identify: Identify{ - Status: discord.OnlineStatus, - Browser: consts.Browser, - BrowserVersion: consts.BrowserVersion, - UserAgent: consts.UserAgent, - }, - - Notifications: Notifications{ - Enabled: true, - Duration: 500, - Sound: Sound{ - Enabled: true, - OnlyOnPing: true, - }, - }, - - Keys: defaultKeys(), - Theme: defaultTheme(), - } -} +// go:embed config.toml +var defaultCfg []byte func DefaultPath() string { path, err := os.UserConfigDir() @@ -107,9 +72,14 @@ func DefaultPath() string { func Load(path string) (*Config, error) { f, err := os.Open(path) - cfg := defaultConfig() + var cfg *Config + if err := toml.Unmarshal(defaultCfg, &cfg); err != nil { + return nil, err + } + if os.IsNotExist(err) { slog.Info("the configuration file does not exist, falling back to the default configuration", "path", path, "err", err) + handleDefaults(cfg) return cfg, nil } @@ -122,5 +92,18 @@ func Load(path string) (*Config, error) { return nil, err } + handleDefaults(cfg) return cfg, nil } + +func handleDefaults(cfg *Config) { + if cfg.Identify.Browser == "default" { + cfg.Identify.Browser = consts.Browser + } + if cfg.Identify.BrowserVersion == "default" { + cfg.Identify.BrowserVersion = consts.BrowserVersion + } + if cfg.Identify.UserAgent == "default" { + cfg.Identify.UserAgent = consts.UserAgent + } +} diff --git a/internal/config/config.toml b/internal/config/config.toml new file mode 100644 index 0000000..75bcfd4 --- /dev/null +++ b/internal/config/config.toml @@ -0,0 +1,128 @@ +# Enable mouse controls +mouse = true + +# "default" means use $EDITOR. +editor = "default" + +hide_blocked_users = true +show_attachment_links = true +messages_limit = 50 +markdown_enabled = true + +# Timestamps uses Go timestamp format +# See: https://gosamples.dev/date-time-format-cheatsheet +[timestamps] +enabled = true +format = "3:04PM" + +[notifications] +enabled = true +duration = 500 +[notifications.sound] +enabled = true +only_on_ping = true + +# How Discord sees us. +# status: "online", "idle", "dnd" (Do Not Disturb), "" (invisible), +# note: does not seem to work +[identify] +status = "online" +browser = "default" +browser_version = "default" +user_agent = "default" + +# Global shortcuts +# Esc: Reset message selection or close the channel selection popup. +[keys] +focus_guilds_tree = "Ctrl+G" +focus_messages_text = "Ctrl+T" +focus_message_input = "Ctrl+P" +# Hide/show the guilds tree +toggle_guilds_tree = "Ctrl+B" +quit = "Ctrl+C" +# Log out and remove the authentication token from keyring. +# Requires re-login upon restart. +logout = "Ctrl+D" + +# Only while focusing on the guilds tree +[keys.guilds_tree] +select_previous = "Rune[k]" +select_next = "Rune[j]" +select_first = "Rune[g]" +select_last = "Rune[G]" +# Select the currently highlighted text-based channel or expand a guild or channel. +select_current = "Enter" +yank_id = "Rune[i]" +collapse_parent_node = "Rune[-]" +move_to_parent_node = "Rune[p]" + +# Only while focusing on sent messages +[keys.messages_text] +select_previous = "Rune[k]" +select_next = "Rune[j]" +select_first = "Rune[g]" +select_last = "Rune[G]" +# Select the message reference (reply) of the selected channel. +select_reply = "Rune[s]" +# Reply to the selected message. +reply = "Rune[r]" +# Reply (with mention) to the selected message. +reply_mention = "Rune[R]" +cancel = "Esc" +delete = "Rune[d]" +# Open the selected message's attachments or hyperlinks in the message +# using the default browser application. +open = "Rune[o]" +# Yank (copy) the selected message's content/url/id. +yank_content = "Rune[y]" +yank_url = "Rune[u]" +yank_id = "Rune[i]" + +# Only while typing a message +# Alt+Enter: Insert a new line to the current text. +[keys.message_input] +# Send the message. +send = "Enter" +# Open message input in your editor. +editor = "Ctrl+E" +# Remove existing text or cancel reply. +cancel = "Esc" + +# Applies to all +[theme] +background_color = "default" + +[theme.title] +# Title color of non-focused widgets +color = "default" +# Title color of the focused widget +active_color = "green" +align = "left" + +[theme.border] +enabled = true +# [top, bottom, left, right] +padding = [0, 0, 1, 1] +color = "default" +active_color = "green" +preset = "round" + +[theme.guilds_tree] +auto_expand_folders = true +# Give tree-like shape +graphics = true +private_channel_color = "white" +guild_color = "white" +channel_color = "white" + +[theme.messages_text] +# Set to false to show messages with usernames instead of nicknames +show_user_nicks = true +show_user_colors = true +reply_indicator = ">" +forwarded_indicator = "<" +author_color = "aqua" +content_color = "white" +emoji_color = "green" +link_color = "blue" +attachment_color = "yellow" diff --git a/internal/config/keys.go b/internal/config/keys.go index 313450a..1ffabcb 100644 --- a/internal/config/keys.go +++ b/internal/config/keys.go @@ -52,55 +52,3 @@ type ( Cancel string `toml:"cancel"` } ) - -func defaultKeys() Keys { - return Keys{ - FocusGuildsTree: "Ctrl+G", - FocusMessagesText: "Ctrl+T", - FocusMessageInput: "Ctrl+P", - ToggleGuildsTree: "Ctrl+B", - - Logout: "Ctrl+D", - Quit: "Ctrl+C", - - GuildsTree: GuildsTreeKeys{ - NavigationKeys: NavigationKeys{ - SelectPrevious: "Rune[k]", - SelectNext: "Rune[j]", - SelectFirst: "Rune[g]", - SelectLast: "Rune[G]", - }, - SelectCurrent: "Enter", - YankID: "Rune[i]", - CollapseParentNode: "Rune[-]", - MoveToParentNode: "Rune[p]", - }, - - MessagesText: MessagesTextKeys{ - NavigationKeys: NavigationKeys{ - SelectPrevious: "Rune[k]", - SelectNext: "Rune[j]", - SelectFirst: "Rune[g]", - SelectLast: "Rune[G]", - }, - SelectReply: "Rune[s]", - - Reply: "Rune[r]", - ReplyMention: "Rune[R]", - - Cancel: "Esc", - Delete: "Rune[d]", - Open: "Rune[o]", - - YankContent: "Rune[y]", - YankURL: "Rune[u]", - YankID: "Rune[i]", - }, - - MessageInput: MessageInputKeys{ - Send: "Enter", - Editor: "Ctrl+E", - Cancel: "Esc", - }, - } -} diff --git a/internal/config/theme.go b/internal/config/theme.go index 477b59a..0c6f073 100644 --- a/internal/config/theme.go +++ b/internal/config/theme.go @@ -68,45 +68,3 @@ type ( AttachmentColor string `toml:"attachment_color"` } ) - -func defaultTheme() Theme { - return Theme{ - BackgroundColor: "default", - - Border: BorderTheme{ - Enabled: true, - Padding: [...]int{0, 0, 1, 1}, - - Color: "default", - ActiveColor: "green", - Preset: borderPresetRound(), - }, - - Title: TitleTheme{ - Color: "default", - ActiveColor: "green", - Align: tview.AlignLeft, - }, - - GuildsTree: GuildsTreeTheme{ - AutoExpandFolders: true, - ChannelColor: tview.Styles.PrimaryTextColor.String(), - Graphics: true, - GuildColor: tview.Styles.PrimaryTextColor.String(), - PrivateChannelColor: tview.Styles.PrimaryTextColor.String(), - }, - MessagesText: MessagesTextTheme{ - ShowNicknames: true, - ShowUsernameColors: true, - - ReplyIndicator: ">", - ForwardedIndicator: "<", - - AuthorColor: "aqua", - ContentColor: tview.Styles.PrimaryTextColor.String(), - EmojiColor: "green", - LinkColor: "blue", - AttachmentColor: "yellow", - }, - } -}