This commit is contained in:
Eva Ho 2025-12-17 17:13:03 -05:00
parent 5a5d3260f4
commit dc573715c4
2 changed files with 42 additions and 44 deletions

View File

@ -120,6 +120,7 @@ type UpdaterInterface interface {
DownloadUpdate(ctx context.Context, updateVersion string) error
InstallAndRestart() error
CancelOngoingDownload()
TriggerImmediateCheck()
}
func (s *Server) log() *slog.Logger {
@ -1465,43 +1466,25 @@ func (s *Server) settings(w http.ResponseWriter, r *http.Request) error {
return fmt.Errorf("failed to save settings: %w", err)
}
// Update tray notification based on auto-update toggle
if old.AutoUpdateEnabled && !settings.AutoUpdateEnabled {
// Auto-update disabled: cancel any ongoing download and clear tray notification
if s.Updater != nil {
s.Updater.CancelOngoingDownload()
}
if s.ClearUpdateAvailableFunc != nil {
s.ClearUpdateAvailableFunc()
}
} else if !old.AutoUpdateEnabled && settings.AutoUpdateEnabled {
// Auto-update enabled: check for updates and download if available
go func() {
// First, show notification if update is already pending
// Handle auto-update toggle changes
if old.AutoUpdateEnabled != settings.AutoUpdateEnabled {
if !settings.AutoUpdateEnabled {
// Auto-update disabled: cancel any ongoing download and clear tray notification
if s.Updater != nil {
s.Updater.CancelOngoingDownload()
}
if s.ClearUpdateAvailableFunc != nil {
s.ClearUpdateAvailableFunc()
}
} else {
// Auto-update re-enabled: show notification if update is already staged, or trigger immediate check
if (updater.IsUpdatePending() || updater.UpdateDownloaded) && s.UpdateAvailableFunc != nil {
s.UpdateAvailableFunc()
} else if s.Updater != nil {
// Otherwise, immediately check for and download new updates
slog.Info("auto-update re-enabled, checking for updates")
available, updateVersion, err := s.Updater.CheckForUpdate(r.Context())
if err != nil {
slog.Error("failed to check for update after re-enabling auto-update", "error", err)
return
}
if available {
slog.Info("update available, starting download", "version", updateVersion)
err := s.Updater.DownloadUpdate(r.Context(), updateVersion)
if err != nil {
slog.Error("failed to download update", "error", err)
return
}
// Show tray notification after successful download
if s.UpdateAvailableFunc != nil {
s.UpdateAvailableFunc()
}
}
// Trigger the background checker to run immediately
s.Updater.TriggerImmediateCheck()
}
}()
}
}
if old.ContextLength != settings.ContextLength ||

View File

@ -264,6 +264,7 @@ type Updater struct {
Store *store.Store
cancelDownload context.CancelFunc
cancelDownloadLock sync.Mutex
checkNow chan struct{}
}
// CancelOngoingDownload cancels any currently running download
@ -277,24 +278,45 @@ func (u *Updater) CancelOngoingDownload() {
}
}
// TriggerImmediateCheck signals the background checker to check for updates immediately
func (u *Updater) TriggerImmediateCheck() {
if u.checkNow != nil {
u.checkNow <- struct{}{}
}
}
func (u *Updater) StartBackgroundUpdaterChecker(ctx context.Context, cb func(string) error) {
u.checkNow = make(chan struct{}, 1)
go func() {
// Don't blast an update message immediately after startup
time.Sleep(UpdateCheckInitialDelay)
slog.Info("beginning update checker", "interval", UpdateCheckInterval)
ticker := time.NewTicker(UpdateCheckInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
slog.Debug("stopping background update checker")
return
case <-u.checkNow:
// Immediate check triggered
case <-ticker.C:
// Regular interval check
}
// Check if auto-update is enabled
settings, err := u.Store.Settings()
if err != nil {
slog.Error("failed to load settings", "error", err)
time.Sleep(UpdateCheckInterval)
continue
}
if !settings.AutoUpdateEnabled {
// When auto-update is disabled, don't check or download anything
slog.Debug("auto-update disabled, skipping check")
time.Sleep(UpdateCheckInterval)
continue
}
@ -303,21 +325,14 @@ func (u *Updater) StartBackgroundUpdaterChecker(ctx context.Context, cb func(str
if available {
err := u.DownloadNewRelease(ctx, resp)
if err != nil {
slog.Error(fmt.Sprintf("failed to download new release: %s", err))
slog.Error("failed to download new release", "error", err)
} else {
err = cb(resp.UpdateVersion)
if err != nil {
slog.Warn(fmt.Sprintf("failed to register update available with tray: %s", err))
slog.Warn("failed to register update available with tray", "error", err)
}
}
}
select {
case <-ctx.Done():
slog.Debug("stopping background update checker")
return
default:
time.Sleep(UpdateCheckInterval)
}
}
}()
}