feat: selectable branded GoSentry color theme

Add a custom Fyne theme derived from the logo and app icon (deep teal
primary, amber accent, branded job-status colors) with light and dark
variants, and let the user choose between it and Fyne's default theme
from Settings. The dark variant uses deep-teal surfaces to echo the app
icon.

The choice is persisted as a new Config.Theme field ("default" /
"gosentry"), applied at startup before the first frame and live-previewed
when picked in Settings. Empty/legacy configs normalize to the default
theme so existing installs keep the original look.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mixeme
2026-07-26 10:12:28 +03:00
parent eedae3b9f0
commit 84212764e4
8 changed files with 257 additions and 1 deletions
+16
View File
@@ -15,6 +15,19 @@ const (
ExecutionModeSequential ExecutionMode = "sequential"
)
// Theme selects the application's visual appearance. It is a UI-only choice with
// no effect on scheduling; it is stored in Config so it persists across launches
// alongside the other desktop-shell preferences.
type Theme string
const (
// ThemeDefault keeps Fyne's built-in theme — the original look.
ThemeDefault Theme = "default"
// ThemeGoSentry applies the branded teal/amber theme derived from the logo
// and app icon.
ThemeGoSentry Theme = "gosentry"
)
// OverlapPolicy decides what happens when a job's next run fires while the
// previous run is still active.
type OverlapPolicy string
@@ -44,6 +57,9 @@ type Config struct {
// their own Job.TimeoutSeconds. It carries the formerly hard-coded 30s guard.
DefaultTimeoutSeconds int `json:"default_timeout_seconds,omitempty"`
Paused bool `json:"paused,omitempty"`
// Theme selects the visual appearance. Empty is treated as ThemeDefault so
// configs written before this field existed keep the original look.
Theme Theme `json:"theme,omitempty"`
}
// JobsFile is the on-disk shape of jobs.json. Wrapping the slice in a top-level