5b0e6fe51b
Autostart entries pass --start-in-tray only when the tray is enabled; Settings warns that the notification icon needs a restart (Fyne limitation). Co-authored-by: Cursor <cursoragent@cursor.com>
141 lines
5.9 KiB
Go
141 lines
5.9 KiB
Go
package domain
|
|
|
|
// StartInTrayArgument is written to the Windows Startup shortcut so autostart
|
|
// can keep the scheduler running without flashing the main window. Manual
|
|
// launches omit this flag and open the normal window.
|
|
const StartInTrayArgument = "--start-in-tray"
|
|
|
|
// AutostartArguments returns the command-line suffix written to a platform
|
|
// autostart entry when KeepRunningInTray is enabled. An empty string means the
|
|
// app should open its window normally after sign-in.
|
|
func AutostartArguments(keepInTray bool) string {
|
|
if keepInTray {
|
|
return StartInTrayArgument
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// ResolveStartHidden reports whether an autostart launch should skip showing
|
|
// the main window. The CLI flag is ignored when KeepRunningInTray is off so a
|
|
// stale shortcut cannot hide the app with no tray icon to restore it.
|
|
func ResolveStartHidden(cliStartInTray, keepInTray bool) bool {
|
|
return cliStartInTray && keepInTray
|
|
}
|
|
|
|
// ExecutionMode controls whether due jobs run concurrently or one at a time.
|
|
type ExecutionMode string
|
|
|
|
const (
|
|
// ExecutionModeParallel allows all due jobs to start simultaneously.
|
|
ExecutionModeParallel ExecutionMode = "parallel"
|
|
// ExecutionModeSequential runs due jobs one after another, in order.
|
|
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 (
|
|
// ThemeSystem keeps Fyne's built-in theme, following the platform look.
|
|
ThemeSystem Theme = "system"
|
|
// ThemeGoSentry applies the branded teal/amber theme derived from the logo
|
|
// and app icon.
|
|
ThemeGoSentry Theme = "gosentry"
|
|
)
|
|
|
|
// JobListView selects how densely the Jobs tab renders its sidebar list. Like
|
|
// Theme it is a UI-only choice with no effect on scheduling; it lives in Config
|
|
// so the user's preference survives a restart.
|
|
type JobListView string
|
|
|
|
const (
|
|
// JobListViewDetailed is the three-line row: name, metadata, status.
|
|
JobListViewDetailed JobListView = "detailed"
|
|
// JobListViewCompact is the one-line row: name on the left, status on the
|
|
// right, so many more jobs fit without scrolling.
|
|
JobListViewCompact JobListView = "compact"
|
|
)
|
|
|
|
// IsCompact reports whether the compact rendering is selected. Only the exact
|
|
// "compact" value counts, so empty, legacy, and unrecognised values all read as
|
|
// detailed — every consumer normalizes them the same way.
|
|
func (v JobListView) IsCompact() bool {
|
|
return v == JobListViewCompact
|
|
}
|
|
|
|
// OverlapPolicy decides what happens when a job's next run fires while the
|
|
// previous run is still active.
|
|
type OverlapPolicy string
|
|
|
|
const (
|
|
// OverlapPolicySkip discards the new run when the job is already running.
|
|
OverlapPolicySkip OverlapPolicy = "skip"
|
|
// OverlapPolicyQueue holds the new run and starts it as soon as the current
|
|
// run finishes.
|
|
OverlapPolicyQueue OverlapPolicy = "queue"
|
|
)
|
|
|
|
// Config is stored in gosentry.json next to the program. It contains only
|
|
// application-level choices: where to read jobs from, where to write logs, and
|
|
// how the desktop shell should behave.
|
|
type Config struct {
|
|
// JobsFile is the full path of the JSON file holding the job definitions,
|
|
// file name included, so the user can keep jobs under any name they like. A
|
|
// relative path is resolved against the program folder.
|
|
JobsFile string `json:"jobs_file"`
|
|
// JobsDir is the pre-0.15 setting that named only the directory, with the
|
|
// file name fixed to jobs.json. It is still read so an older gosentry.json
|
|
// keeps working: storage.loadOrCreateConfig turns it into JobsFile and
|
|
// clears it, so the field disappears from the file on the next save.
|
|
JobsDir string `json:"jobs_dir,omitempty"`
|
|
LogsDir string `json:"logs_dir"`
|
|
MaxLogFiles int `json:"max_log_files"`
|
|
MaxLogAgeDays int `json:"max_log_age_days"`
|
|
StartOnLogin bool `json:"start_on_login,omitempty"`
|
|
KeepRunningInTray bool `json:"keep_running_in_tray,omitempty"`
|
|
NotifyOnFailure bool `json:"notify_on_failure,omitempty"`
|
|
ExecutionMode ExecutionMode `json:"execution_mode,omitempty"`
|
|
OverlapPolicy OverlapPolicy `json:"overlap_policy,omitempty"`
|
|
// DefaultTimeoutSeconds is the run timeout applied to jobs that leave their
|
|
// own Job.TimeoutSeconds unset. 0 (the default) means no timeout: such jobs
|
|
// run to completion however long that takes. It is written even when 0 —
|
|
// omitempty would hide a deliberate choice from the hand-editable config.
|
|
DefaultTimeoutSeconds int `json:"default_timeout_seconds"`
|
|
Paused bool `json:"paused,omitempty"`
|
|
// Theme selects the visual appearance. Empty is treated as ThemeGoSentry so
|
|
// configs written before this field existed pick up the branded look.
|
|
Theme Theme `json:"theme,omitempty"`
|
|
// JobListView selects the Jobs list density. Empty is treated as
|
|
// JobListViewDetailed so configs written before this field existed keep the
|
|
// current three-line rows.
|
|
JobListView JobListView `json:"job_list_view,omitempty"`
|
|
}
|
|
|
|
// DefaultConfig returns the built-in default settings. It is the config used
|
|
// when gosentry.json does not yet exist, and is also what the Settings UI
|
|
// offers to restore via its "Defaults" button.
|
|
func DefaultConfig() Config {
|
|
return Config{
|
|
JobsFile: "jobs.json",
|
|
LogsDir: "logs",
|
|
MaxLogFiles: 100,
|
|
MaxLogAgeDays: 30,
|
|
StartOnLogin: false,
|
|
KeepRunningInTray: true,
|
|
NotifyOnFailure: true,
|
|
ExecutionMode: ExecutionModeParallel,
|
|
OverlapPolicy: OverlapPolicySkip,
|
|
Theme: ThemeGoSentry,
|
|
JobListView: JobListViewDetailed,
|
|
DefaultTimeoutSeconds: 0,
|
|
}
|
|
}
|
|
|
|
// JobsFile is the on-disk shape of jobs.json. Wrapping the slice in a top-level
|
|
// object leaves room for future metadata without breaking the basic file format.
|
|
type JobsFile struct {
|
|
Jobs []Job `json:"jobs"`
|
|
}
|