Fixed dark and light themes, ui.theme auto/dark/light
Colors no longer come from the terminal's palette, whose color 0 many color themes set to a grey that is not their background. A theme sets tview's default styles and the color names used in texts, all chosen from entries 16-255 of the 256-color table so terminals without 24-bit color show them exactly. "auto" picks light or dark from the background color the terminal reports. Settable in the Config view, applied at the next start (widgets copy their colors when created). Replaces using the terminal's own background and text colors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
This commit is contained in:
+33
-4
@@ -24,16 +24,23 @@ type settingsValues struct {
|
||||
covers bool
|
||||
coverStyle string
|
||||
notify, bell bool
|
||||
theme string
|
||||
}
|
||||
|
||||
var coverStyles = []string{"auto", "kitty", "sextant", "quadrant", "cells"}
|
||||
var (
|
||||
coverStyles = []string{"auto", "kitty", "sextant", "quadrant", "cells"}
|
||||
themes = []string{"auto", "dark", "light"}
|
||||
)
|
||||
|
||||
// settingsFrom reads the settings in use.
|
||||
func settingsFrom(c *config.Config) settingsValues {
|
||||
style := c.UI.CoverStyle
|
||||
style, th := c.UI.CoverStyle, c.UI.Theme
|
||||
if style == "" {
|
||||
style = "auto"
|
||||
}
|
||||
if th == "" {
|
||||
th = "auto"
|
||||
}
|
||||
return settingsValues{
|
||||
radarrURL: c.Radarr.URL, radarrKey: c.Radarr.APIKey,
|
||||
radarrProfile: c.Radarr.DefaultQualityProfile, radarrFolder: c.Radarr.DefaultRootFolder,
|
||||
@@ -43,6 +50,7 @@ func settingsFrom(c *config.Config) settingsValues {
|
||||
refresh: strconv.Itoa(c.UI.RefreshSeconds),
|
||||
covers: c.UI.ShowCovers(), coverStyle: style,
|
||||
notify: c.UI.ShouldNotifyDownloads(), bell: c.UI.Bell,
|
||||
theme: th,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +88,10 @@ func applySettings(raw config.Config, v settingsValues, overridden map[string]st
|
||||
if v.coverStyle == "auto" {
|
||||
raw.UI.CoverStyle = ""
|
||||
}
|
||||
raw.UI.Theme = v.theme
|
||||
if v.theme == "auto" {
|
||||
raw.UI.Theme = ""
|
||||
}
|
||||
|
||||
if _, err := raw.Effective(os.Getenv); err != nil {
|
||||
return raw, err
|
||||
@@ -97,7 +109,7 @@ func boolSetting(old *bool, value, def bool) *bool {
|
||||
}
|
||||
|
||||
// settingsView edits the configuration file's settings. Everything except
|
||||
// the cover style of already open panes applies right after saving.
|
||||
// the theme applies right after saving; the theme at the next start.
|
||||
type settingsView struct {
|
||||
app *App
|
||||
root *tview.Flex
|
||||
@@ -112,6 +124,7 @@ type settingsView struct {
|
||||
refresh *tview.InputField
|
||||
covers *tview.Checkbox
|
||||
style *tview.DropDown
|
||||
theme *tview.DropDown
|
||||
notify *tview.Checkbox
|
||||
bell *tview.Checkbox
|
||||
showKeys *tview.Checkbox
|
||||
@@ -171,6 +184,8 @@ func newSettingsView(app *App) *settingsView {
|
||||
f.AddFormItem(v.covers)
|
||||
v.style = tview.NewDropDown().SetLabel("Poster style").SetOptions(coverStyles, func(string, int) { v.edited() })
|
||||
f.AddFormItem(v.style)
|
||||
v.theme = tview.NewDropDown().SetLabel("Theme (at the next start)").SetOptions(themes, func(string, int) { v.edited() })
|
||||
f.AddFormItem(v.theme)
|
||||
v.notify = tview.NewCheckbox().SetLabel("Notify about finished downloads").SetChangedFunc(func(bool) { v.edited() })
|
||||
f.AddFormItem(v.notify)
|
||||
v.bell = tview.NewCheckbox().SetLabel("Ring the terminal bell too").SetChangedFunc(func(bool) { v.edited() })
|
||||
@@ -289,6 +304,11 @@ func (v *settingsView) fill(s settingsValues) {
|
||||
v.style.SetCurrentOption(i)
|
||||
}
|
||||
}
|
||||
for i, name := range themes {
|
||||
if name == s.theme {
|
||||
v.theme.SetCurrentOption(i)
|
||||
}
|
||||
}
|
||||
v.notify.SetChecked(s.notify)
|
||||
v.bell.SetChecked(s.bell)
|
||||
v.dirty = false
|
||||
@@ -302,6 +322,10 @@ func (v *settingsView) read() settingsValues {
|
||||
if i >= 0 && i < len(coverStyles) {
|
||||
style = coverStyles[i]
|
||||
}
|
||||
th := "auto"
|
||||
if i, _ := v.theme.GetCurrentOption(); i >= 0 && i < len(themes) {
|
||||
th = themes[i]
|
||||
}
|
||||
return settingsValues{
|
||||
radarrURL: text("radarr.url"), radarrKey: text("radarr.apikey"),
|
||||
radarrProfile: text("radarr.profile"), radarrFolder: text("radarr.folder"),
|
||||
@@ -311,6 +335,7 @@ func (v *settingsView) read() settingsValues {
|
||||
refresh: v.refresh.GetText(),
|
||||
covers: v.covers.IsChecked(), coverStyle: style,
|
||||
notify: v.notify.IsChecked(), bell: v.bell.IsChecked(),
|
||||
theme: th,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +347,7 @@ func (v *settingsView) describe() {
|
||||
} else {
|
||||
b.WriteString("Config file: " + tview.Escape(v.app.cfgPath) + "\n")
|
||||
}
|
||||
b.WriteString("Changes take effect when you save; nothing needs a restart.\n")
|
||||
b.WriteString("Changes take effect when you save; only the theme waits for the next start.\n")
|
||||
if len(v.overridden) > 0 {
|
||||
var names []string
|
||||
for _, env := range v.overridden {
|
||||
@@ -412,9 +437,13 @@ func (v *settingsView) save() {
|
||||
v.report("[red]Saved, but not applied: " + tview.Escape(err.Error()) + "[-]")
|
||||
return
|
||||
}
|
||||
themeChanged := effective.UI.Theme != v.app.cfg.UI.Theme
|
||||
v.app.cfgFile = &raw
|
||||
v.app.applyConfig(effective)
|
||||
v.dirty = false
|
||||
v.report("[green]Saved to " + tview.Escape(v.app.cfgPath) + " and applied.[-]")
|
||||
if themeChanged {
|
||||
v.report("The new theme is used from the next start.")
|
||||
}
|
||||
v.app.Notify(levelSuccess, "Settings saved")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user