Просмотр исходного кода

Merge branch 'main' into add-nix

Emanuel Johnson Godin 11 месяцев назад
Родитель
Сommit
0dd45a3fbc
7 измененных файлов с 176 добавлено и 179 удалено
  1. 1 41
      README.md
  2. 6 3
      cmd/root.go
  3. 13 0
      internal/config/border.go
  4. 28 41
      internal/config/config.go
  5. 128 0
      internal/config/config.toml
  6. 0 52
      internal/config/keys.go
  7. 0 42
      internal/config/theme.go

+ 1 - 41
README.md

@@ -55,46 +55,6 @@ go build .
 
 
 2. Enter your email and password and click on the "Login" button to continue.
 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
 ## Configuration
 
 
 The configuration file allows you to configure and customize the behavior, keybindings, and theme of the application.
 The configuration file allows you to configure and customize the behavior, keybindings, and theme of the application.
@@ -103,7 +63,7 @@ The configuration file allows you to configure and customize the behavior, keybi
 - Darwin: `$HOME/Library/Application Support/discordo/config.toml`
 - Darwin: `$HOME/Library/Application Support/discordo/config.toml`
 - Windows: `%AppData%/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
 ## FAQ
 
 

+ 6 - 3
cmd/root.go

@@ -20,6 +20,11 @@ var (
 
 
 func Run() error {
 func Run() error {
 	logLevel := flag.String("log-level", "info", "log level")
 	logLevel := flag.String("log-level", "info", "log level")
+	logFormat := flag.String("log-format", "text", "log format")
+	token := flag.String("token", "", "authentication token")
+	configPath := flag.String("config", config.DefaultPath(), "path to the configuration file")
+	flag.Parse()
+
 	var level slog.Level
 	var level slog.Level
 	switch *logLevel {
 	switch *logLevel {
 	case "debug":
 	case "debug":
@@ -33,7 +38,6 @@ func Run() error {
 		level = slog.LevelError
 		level = slog.LevelError
 	}
 	}
 
 
-	logFormat := flag.String("log-format", "text", "log format")
 	var format logger.Format
 	var format logger.Format
 	switch *logFormat {
 	switch *logFormat {
 	case "text":
 	case "text":
@@ -46,7 +50,6 @@ func Run() error {
 		return err
 		return err
 	}
 	}
 
 
-	token := flag.String("token", "", "authentication token")
 	tok := *token
 	tok := *token
 	if tok == "" {
 	if tok == "" {
 		var err error
 		var err error
@@ -56,7 +59,7 @@ func Run() error {
 		}
 		}
 	}
 	}
 
 
-	cfg, err := config.Load()
+	cfg, err := config.Load(*configPath)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 13 - 0
internal/config/border.go

@@ -19,6 +19,8 @@ func (p *BorderPreset) UnmarshalTOML(v any) error {
 		*p = borderPresetThick()
 		*p = borderPresetThick()
 	case "round":
 	case "round":
 		*p = borderPresetRound()
 		*p = borderPresetRound()
+	case "light":
+		*p = borderPresetLight()
 	case "hidden":
 	case "hidden":
 		*p = BorderPreset{
 		*p = BorderPreset{
 			Horizontal:  ' ',
 			Horizontal:  ' ',
@@ -65,3 +67,14 @@ func borderPresetRound() BorderPreset {
 		BottomRight: tview.BoxDrawingsLightArcUpAndLeft,
 		BottomRight: tview.BoxDrawingsLightArcUpAndLeft,
 	}
 	}
 }
 }
+
+func borderPresetLight() BorderPreset {
+	return BorderPreset{
+		Horizontal:  tview.BoxDrawingsLightHorizontal,
+		Vertical:    tview.BoxDrawingsLightVertical,
+		TopLeft:     tview.BoxDrawingsLightDownAndRight,
+		TopRight:    tview.BoxDrawingsLightDownAndLeft,
+		BottomLeft:  tview.BoxDrawingsLightUpAndRight,
+		BottomRight: tview.BoxDrawingsLightUpAndLeft,
+	}
+}

+ 28 - 41
internal/config/config.go

@@ -1,10 +1,10 @@
 package config
 package config
 
 
 import (
 import (
+	_ "embed"
 	"log/slog"
 	"log/slog"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
-	"time"
 
 
 	"github.com/BurntSushi/toml"
 	"github.com/BurntSushi/toml"
 	"github.com/ayn2op/discordo/internal/consts"
 	"github.com/ayn2op/discordo/internal/consts"
@@ -56,57 +56,31 @@ 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
 
 
-// Reads the configuration file and parses it.
-func Load() (*Config, error) {
+func DefaultPath() string {
 	path, err := os.UserConfigDir()
 	path, err := os.UserConfigDir()
 	if err != nil {
 	if err != nil {
 		slog.Info("user configuration directory path cannot be determined; falling back to the current directory path")
 		slog.Info("user configuration directory path cannot be determined; falling back to the current directory path")
 		path = "."
 		path = "."
 	}
 	}
 
 
-	path = filepath.Join(path, consts.Name, fileName)
+	return filepath.Join(path, consts.Name, fileName)
+}
+
+// Reads the configuration file and parses it.
+func Load(path string) (*Config, error) {
 	f, err := os.Open(path)
 	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) {
 	if os.IsNotExist(err) {
 		slog.Info("the configuration file does not exist, falling back to the default configuration", "path", path, "err", err)
 		slog.Info("the configuration file does not exist, falling back to the default configuration", "path", path, "err", err)
+		handleDefaults(cfg)
 		return cfg, nil
 		return cfg, nil
 	}
 	}
 
 
@@ -119,5 +93,18 @@ func Load() (*Config, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	handleDefaults(cfg)
 	return cfg, nil
 	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
+	}
+}

+ 128 - 0
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"

+ 0 - 52
internal/config/keys.go

@@ -52,55 +52,3 @@ type (
 		Cancel string `toml:"cancel"`
 		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",
-		},
-	}
-}

+ 0 - 42
internal/config/theme.go

@@ -68,45 +68,3 @@ type (
 		AttachmentColor string `toml:"attachment_color"`
 		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",
-		},
-	}
-}