From 1359fa14c1decd565d4f352721bb92d038cbe06d Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 20 Sep 2023 08:43:42 +0200 Subject: [PATCH] When pausing a task during a waiting status, hide the status while paused We do this for two reasons: - when popping up a credentials prompt, it looks distracting if the waiting status keeps spinning while the user is typing the password - the task that updates the waiting status periodically would keep the program busy, so integration tests would wait forever for the program to become idle again --- .../controllers/helpers/app_status_helper.go | 25 +++++++++++++++++-- pkg/gui/status/status_manager.go | 4 +-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/pkg/gui/controllers/helpers/app_status_helper.go b/pkg/gui/controllers/helpers/app_status_helper.go index bdab8f1b1..0ce30b460 100644 --- a/pkg/gui/controllers/helpers/app_status_helper.go +++ b/pkg/gui/controllers/helpers/app_status_helper.go @@ -33,11 +33,32 @@ func (self *AppStatusHelper) Toast(message string) { self.renderAppStatus() } +// A custom task for WithWaitingStatus calls; it wraps the original one and +// hides the status whenever the task is paused, and shows it again when +// continued. +type appStatusHelperTask struct { + gocui.Task + waitingStatusHandle *status.WaitingStatusHandle +} + +// poor man's version of explicitly saying that struct X implements interface Y +var _ gocui.Task = appStatusHelperTask{} + +func (self appStatusHelperTask) Pause() { + self.waitingStatusHandle.Hide() + self.Task.Pause() +} + +func (self appStatusHelperTask) Continue() { + self.Task.Continue() + self.waitingStatusHandle.Show() +} + // withWaitingStatus wraps a function and shows a waiting status while the function is still executing func (self *AppStatusHelper) WithWaitingStatus(message string, f func(gocui.Task) error) { self.c.OnWorker(func(task gocui.Task) { - self.statusMgr().WithWaitingStatus(message, self.renderAppStatus, func() { - if err := f(task); err != nil { + self.statusMgr().WithWaitingStatus(message, self.renderAppStatus, func(waitingStatusHandle *status.WaitingStatusHandle) { + if err := f(appStatusHelperTask{task, waitingStatusHandle}); err != nil { self.c.OnUIThread(func() error { return self.c.Error(err) }) diff --git a/pkg/gui/status/status_manager.go b/pkg/gui/status/status_manager.go index 1e2aa9cf1..1f4aaa569 100644 --- a/pkg/gui/status/status_manager.go +++ b/pkg/gui/status/status_manager.go @@ -44,11 +44,11 @@ func NewStatusManager() *StatusManager { return &StatusManager{} } -func (self *StatusManager) WithWaitingStatus(message string, renderFunc func(), f func()) { +func (self *StatusManager) WithWaitingStatus(message string, renderFunc func(), f func(*WaitingStatusHandle)) { handle := &WaitingStatusHandle{statusManager: self, message: message, renderFunc: renderFunc, id: -1} handle.Show() - f() + f(handle) handle.Hide() }