feat(config): add color_scheme setting to appearance config
- commit
- 98b0069696cbe5cabf561864d9958ef1f3af6ef9
- author
- bnema · · 2025-10-23 20:56 UTC
- parent
- 2d1ce89
- signature
- unsigned
2 files · +28 -0
M internal/config/config.go +27 -0
| @@ -124,6 +124,8 @@ type AppearanceConfig struct { | |||
| 124 | 124 | DefaultFontSize int `mapstructure:"default_font_size" yaml:"default_font_size"` | |
| 125 | 125 | LightPalette ColorPalette `mapstructure:"light_palette" yaml:"light_palette"` | |
| 126 | 126 | DarkPalette ColorPalette `mapstructure:"dark_palette" yaml:"dark_palette"` | |
| 127 | + | // ColorScheme controls the initial theme preference: "prefer-dark", "prefer-light", or "default" (follows system) | |
| 128 | + | ColorScheme string `mapstructure:"color_scheme" yaml:"color_scheme"` | |
| 127 | 129 | } | |
| 128 | 130 | ||
| 129 | 131 | // ColorPalette contains semantic color tokens for light/dark themes. | |
| @@ -545,6 +547,9 @@ func (m *Manager) Load() error { | |||
| 545 | 547 | // Validate and configure codec preferences | |
| 546 | 548 | config = m.validateAndConfigureCodecPreferences(config) | |
| 547 | 549 | ||
| 550 | + | // Validate ColorScheme setting | |
| 551 | + | m.validateColorScheme(config) | |
| 552 | + | ||
| 548 | 553 | m.config = config | |
| 549 | 554 | return nil | |
| 550 | 555 | } | |
| @@ -643,6 +648,9 @@ func (m *Manager) reload() error { | |||
| 643 | 648 | // Validate and configure codec preferences | |
| 644 | 649 | config = m.validateAndConfigureCodecPreferences(config) | |
| 645 | 650 | ||
| 651 | + | // Validate ColorScheme setting | |
| 652 | + | m.validateColorScheme(config) | |
| 653 | + | ||
| 646 | 654 | m.config = config | |
| 647 | 655 | return nil | |
| 648 | 656 | } | |
| @@ -713,6 +721,7 @@ func (m *Manager) setDefaults() { | |||
| 713 | 721 | m.viper.SetDefault("appearance.default_font_size", defaults.Appearance.DefaultFontSize) | |
| 714 | 722 | m.viper.SetDefault("appearance.light_palette", defaults.Appearance.LightPalette) | |
| 715 | 723 | m.viper.SetDefault("appearance.dark_palette", defaults.Appearance.DarkPalette) | |
| 724 | + | m.viper.SetDefault("appearance.color_scheme", defaults.Appearance.ColorScheme) | |
| 716 | 725 | ||
| 717 | 726 | // Video acceleration defaults | |
| 718 | 727 | m.viper.SetDefault("video_acceleration.enable_vaapi", defaults.VideoAcceleration.EnableVAAPI) | |
| @@ -894,3 +903,21 @@ func (m *Manager) validateAndConfigureCodecPreferences(config *Config) *Config { | |||
| 894 | 903 | ||
| 895 | 904 | return config | |
| 896 | 905 | } | |
| 906 | + | ||
| 907 | + | // validateColorScheme validates and normalizes the ColorScheme setting | |
| 908 | + | func (m *Manager) validateColorScheme(config *Config) { | |
| 909 | + | switch config.Appearance.ColorScheme { | |
| 910 | + | case "prefer-dark", "prefer-light", "default", "": | |
| 911 | + | // Valid values - no changes needed | |
| 912 | + | // Empty string is treated the same as "default" | |
| 913 | + | if config.Appearance.ColorScheme == "" { | |
| 914 | + | config.Appearance.ColorScheme = "default" | |
| 915 | + | logging.Info("Config: ColorScheme not set, defaulting to 'default' (follows system)") | |
| 916 | + | } | |
| 917 | + | default: | |
| 918 | + | // Invalid value - warn and reset to default | |
| 919 | + | logging.Info(fmt.Sprintf("Config: Invalid color_scheme value '%s', valid values are: 'prefer-dark', 'prefer-light', 'default'. Resetting to 'default'", | |
| 920 | + | config.Appearance.ColorScheme)) | |
| 921 | + | config.Appearance.ColorScheme = "default" | |
| 922 | + | } | |
| 923 | + | } | |
| @@ -124,6 +124,8 @@ type AppearanceConfig struct { | |||||
| 124 | DefaultFontSize int `mapstructure:"default_font_size" yaml:"default_font_size"` | 124 | DefaultFontSize int `mapstructure:"default_font_size" yaml:"default_font_size"` | ||
| 125 | LightPalette ColorPalette `mapstructure:"light_palette" yaml:"light_palette"` | 125 | LightPalette ColorPalette `mapstructure:"light_palette" yaml:"light_palette"` | ||
| 126 | DarkPalette ColorPalette `mapstructure:"dark_palette" yaml:"dark_palette"` | 126 | DarkPalette ColorPalette `mapstructure:"dark_palette" yaml:"dark_palette"` | ||
| 127 | + | // ColorScheme controls the initial theme preference: "prefer-dark", "prefer-light", or "default" (follows system) | |||
| 128 | + | ColorScheme string `mapstructure:"color_scheme" yaml:"color_scheme"` | |||
| 127 | } | 129 | } | ||
| 128 | 130 | ||||
| 129 | // ColorPalette contains semantic color tokens for light/dark themes. | 131 | // ColorPalette contains semantic color tokens for light/dark themes. | ||
| @@ -545,6 +547,9 @@ func (m *Manager) Load() error { | |||||
| 545 | // Validate and configure codec preferences | 547 | // Validate and configure codec preferences | ||
| 546 | config = m.validateAndConfigureCodecPreferences(config) | 548 | config = m.validateAndConfigureCodecPreferences(config) | ||
| 547 | 549 | ||||
| 550 | + | // Validate ColorScheme setting | |||
| 551 | + | m.validateColorScheme(config) | |||
| 552 | + | ||||
| 548 | m.config = config | 553 | m.config = config | ||
| 549 | return nil | 554 | return nil | ||
| 550 | } | 555 | } | ||
| @@ -643,6 +648,9 @@ func (m *Manager) reload() error { | |||||
| 643 | // Validate and configure codec preferences | 648 | // Validate and configure codec preferences | ||
| 644 | config = m.validateAndConfigureCodecPreferences(config) | 649 | config = m.validateAndConfigureCodecPreferences(config) | ||
| 645 | 650 | ||||
| 651 | + | // Validate ColorScheme setting | |||
| 652 | + | m.validateColorScheme(config) | |||
| 653 | + | ||||
| 646 | m.config = config | 654 | m.config = config | ||
| 647 | return nil | 655 | return nil | ||
| 648 | } | 656 | } | ||
| @@ -713,6 +721,7 @@ func (m *Manager) setDefaults() { | |||||
| 713 | m.viper.SetDefault("appearance.default_font_size", defaults.Appearance.DefaultFontSize) | 721 | m.viper.SetDefault("appearance.default_font_size", defaults.Appearance.DefaultFontSize) | ||
| 714 | m.viper.SetDefault("appearance.light_palette", defaults.Appearance.LightPalette) | 722 | m.viper.SetDefault("appearance.light_palette", defaults.Appearance.LightPalette) | ||
| 715 | m.viper.SetDefault("appearance.dark_palette", defaults.Appearance.DarkPalette) | 723 | m.viper.SetDefault("appearance.dark_palette", defaults.Appearance.DarkPalette) | ||
| 724 | + | m.viper.SetDefault("appearance.color_scheme", defaults.Appearance.ColorScheme) | |||
| 716 | 725 | ||||
| 717 | // Video acceleration defaults | 726 | // Video acceleration defaults | ||
| 718 | m.viper.SetDefault("video_acceleration.enable_vaapi", defaults.VideoAcceleration.EnableVAAPI) | 727 | m.viper.SetDefault("video_acceleration.enable_vaapi", defaults.VideoAcceleration.EnableVAAPI) | ||
| @@ -894,3 +903,21 @@ func (m *Manager) validateAndConfigureCodecPreferences(config *Config) *Config { | |||||
| 894 | 903 | ||||
| 895 | return config | 904 | return config | ||
| 896 | } | 905 | } | ||
| 906 | + | ||||
| 907 | + | // validateColorScheme validates and normalizes the ColorScheme setting | |||
| 908 | + | func (m *Manager) validateColorScheme(config *Config) { | |||
| 909 | + | switch config.Appearance.ColorScheme { | |||
| 910 | + | case "prefer-dark", "prefer-light", "default", "": | |||
| 911 | + | // Valid values - no changes needed | |||
| 912 | + | // Empty string is treated the same as "default" | |||
| 913 | + | if config.Appearance.ColorScheme == "" { | |||
| 914 | + | config.Appearance.ColorScheme = "default" | |||
| 915 | + | logging.Info("Config: ColorScheme not set, defaulting to 'default' (follows system)") | |||
| 916 | + | } | |||
| 917 | + | default: | |||
| 918 | + | // Invalid value - warn and reset to default | |||
| 919 | + | logging.Info(fmt.Sprintf("Config: Invalid color_scheme value '%s', valid values are: 'prefer-dark', 'prefer-light', 'default'. Resetting to 'default'", | |||
| 920 | + | config.Appearance.ColorScheme)) | |||
| 921 | + | config.Appearance.ColorScheme = "default" | |||
| 922 | + | } | |||
| 923 | + | } | |||
M internal/config/defaults.go +1 -0
| @@ -112,6 +112,7 @@ func DefaultConfig() *Config { | |||
| 112 | 112 | Accent: "#a8a8a8", | |
| 113 | 113 | Border: "#363636", | |
| 114 | 114 | }, | |
| 115 | + | ColorScheme: "default", // default follows system theme | |
| 115 | 116 | }, | |
| 116 | 117 | VideoAcceleration: VideoAccelerationConfig{ | |
| 117 | 118 | EnableVAAPI: true, | |
| @@ -112,6 +112,7 @@ func DefaultConfig() *Config { | |||||
| 112 | Accent: "#a8a8a8", | 112 | Accent: "#a8a8a8", | ||
| 113 | Border: "#363636", | 113 | Border: "#363636", | ||
| 114 | }, | 114 | }, | ||
| 115 | + | ColorScheme: "default", // default follows system theme | |||
| 115 | }, | 116 | }, | ||
| 116 | VideoAcceleration: VideoAccelerationConfig{ | 117 | VideoAcceleration: VideoAccelerationConfig{ | ||
| 117 | EnableVAAPI: true, | 118 | EnableVAAPI: true, | ||