config.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package config
  2. import (
  3. _ "embed"
  4. "os"
  5. "path/filepath"
  6. "time"
  7. "gopkg.in/yaml.v3"
  8. )
  9. const Name = "discordo"
  10. type MessagesPanelKeysConfig struct {
  11. OpenActionsList string `yaml:"open_actions_list"`
  12. SelectPreviousMessage string `yaml:"select_previous_message"`
  13. SelectNextMessage string `yaml:"select_next_message"`
  14. SelectFirstMessage string `yaml:"select_first_message"`
  15. SelectLastMessage string `yaml:"select_last_message"`
  16. }
  17. type MessageInputKeysConfig struct {
  18. OpenExternalEditor string `yaml:"open_external_editor"`
  19. PasteClipboard string `yaml:"paste_clipboard"`
  20. }
  21. type KeysConfig struct {
  22. MessagesPanel MessagesPanelKeysConfig `yaml:"messages_panel"`
  23. MessageInput MessageInputKeysConfig `yaml:"message_input"`
  24. }
  25. type ThemeConfig struct {
  26. Background string `yaml:"background"`
  27. Border string `yaml:"border"`
  28. Title string `yaml:"title"`
  29. }
  30. type Config struct {
  31. // Whether the mouse is usable or not.
  32. Mouse bool `yaml:"mouse"`
  33. // 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.
  34. MessagesLimit uint `yaml:"messages_limit"`
  35. // Whether to display the timestamps of the messages beside the displayed message or not.
  36. Timestamps bool `yaml:"timestamps"`
  37. // The timezone of the timestamps. Learn more: https://pkg.go.dev/time#LoadLocation
  38. Timezone string `yaml:"timezone"`
  39. // A textual representation of the time value formatted according to the layout defined by its value. Learn more: https://pkg.go.dev/time#Layout
  40. TimeFormat string `yaml:"time_format"`
  41. // Keybindings
  42. Keys KeysConfig `yaml:"keys"`
  43. // Theme
  44. Theme ThemeConfig `yaml:"theme"`
  45. }
  46. func New() *Config {
  47. return &Config{
  48. Mouse: true,
  49. MessagesLimit: 50,
  50. Timestamps: false,
  51. Timezone: "Local",
  52. TimeFormat: time.Kitchen,
  53. Keys: KeysConfig{
  54. MessagesPanel: MessagesPanelKeysConfig{
  55. OpenActionsList: "Rune[a]",
  56. SelectPreviousMessage: "Up",
  57. SelectNextMessage: "Down",
  58. SelectFirstMessage: "Home",
  59. SelectLastMessage: "End",
  60. },
  61. },
  62. Theme: ThemeConfig{
  63. Background: "default",
  64. Border: "white",
  65. Title: "white",
  66. },
  67. }
  68. }
  69. func (c *Config) Load() error {
  70. configPath, err := os.UserConfigDir()
  71. if err != nil {
  72. return err
  73. }
  74. configPath = filepath.Join(configPath, Name)
  75. // Create directories that do not exist and are mentioned in the path recursively.
  76. err = os.MkdirAll(configPath, os.ModePerm)
  77. if err != nil {
  78. return err
  79. }
  80. configPath = filepath.Join(configPath, "config.yml")
  81. // Open the existing configuration file with read-only flag.
  82. f, err := os.OpenFile(configPath, os.O_CREATE|os.O_RDWR, os.ModePerm)
  83. if err != nil {
  84. return err
  85. }
  86. defer f.Close()
  87. fi, err := f.Stat()
  88. if err != nil {
  89. return err
  90. }
  91. // 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.
  92. if fi.Size() == 0 {
  93. return yaml.NewEncoder(f).Encode(c)
  94. }
  95. return yaml.NewDecoder(f).Decode(&c)
  96. }