Skip to content

Commit c636184

Browse files
authored
Merge pull request #656 from gibmat/improve-modal-display
Improve modal display
2 parents 53cdc65 + a68cb8f commit c636184

4 files changed

Lines changed: 51 additions & 24 deletions

File tree

incus-osd/cmd/incus-osd/main.go

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ var (
3939
runPath = "/run/incus-os/"
4040
)
4141

42-
var updateModal *tui.Modal
43-
4442
func main() {
4543
ctx := context.Background()
4644

@@ -131,7 +129,7 @@ func run(ctx context.Context, s *state.State, t *tui.TUI) error {
131129
// Verify that the system meets minimum requirements for running IncusOS.
132130
err := install.CheckSystemRequirements(ctx)
133131
if err != nil {
134-
modal := t.AddModal(s.OS.Name)
132+
modal := t.AddModal(s.OS.Name, "system-check")
135133
modal.Update("System check error: [red]" + err.Error() + "[white]\n" + s.OS.Name + " is unable to run until the problem is resolved.")
136134

137135
slog.ErrorContext(ctx, "System check error: "+err.Error())
@@ -225,7 +223,7 @@ func shutdown(ctx context.Context, s *state.State, t *tui.TUI) error {
225223
// Save state on exit.
226224
defer func() { _ = s.Save() }()
227225

228-
modal := t.AddModal("System shutdown")
226+
modal := t.AddModal("System Shutdown", "shutdown")
229227

230228
slog.InfoContext(ctx, "System is shutting down", "version", s.OS.RunningRelease)
231229
modal.Update("System is shutting down")
@@ -586,8 +584,10 @@ func updateChecker(ctx context.Context, s *state.State, t *tui.TUI, p providers.
586584
showModalError := func(msg string, err error) {
587585
slog.ErrorContext(ctx, msg, "err", err.Error(), "provider", p.Type())
588586

589-
if updateModal == nil {
590-
updateModal = t.AddModal(s.OS.Name + " Update")
587+
updateModal := t.GetModal("update")
588+
589+
if t.GetModal("update") == nil {
590+
updateModal = t.AddModal(s.OS.Name+" Update", "update")
591591
}
592592

593593
updateModal.Update("[red]Error[white] " + msg + ": " + err.Error() + " (provider: " + p.Type() + ")")
@@ -815,9 +815,11 @@ func updateChecker(ctx context.Context, s *state.State, t *tui.TUI, p providers.
815815
}
816816
}
817817

818+
updateModal := t.GetModal("update")
819+
818820
if newInstalledOSVersion != "" {
819821
if updateModal == nil {
820-
updateModal = t.AddModal(s.OS.Name + " Update")
822+
updateModal = t.AddModal(s.OS.Name+" Update", "update")
821823
}
822824

823825
s.System.Update.State.Status = s.OS.Name + " has been updated to version " + newInstalledOSVersion
@@ -826,6 +828,10 @@ func updateChecker(ctx context.Context, s *state.State, t *tui.TUI, p providers.
826828
s.System.Update.State.NeedsReboot = true
827829
} else {
828830
s.System.Update.State.Status = "Update check completed"
831+
832+
if updateModal != nil {
833+
updateModal.Done()
834+
}
829835
}
830836

831837
if isStartupCheck || isUserRequested {
@@ -922,17 +928,20 @@ func checkDownloadUpdate(ctx context.Context, s *state.State, t *tui.TUI, p prov
922928
}
923929

924930
func applyUpdate(ctx context.Context, s *state.State, t *tui.TUI, update providers.CommonUpdate, updateType string, appName string, isStartupCheck bool) (string, error) {
925-
// Download the update.
926-
modal := t.AddModal(s.OS.Name + " Update")
927-
defer modal.Done()
931+
updateModal := t.GetModal("update")
928932

933+
if t.GetModal("update") == nil {
934+
updateModal = t.AddModal(s.OS.Name+" Update", "update")
935+
}
936+
937+
// Download the update.
929938
_, isApplication := update.(providers.ApplicationUpdate)
930939
if isApplication {
931940
slog.InfoContext(ctx, "Downloading "+updateType+" update", "application", appName, "version", update.Version())
932-
modal.Update("Downloading " + updateType + " update " + appName + " update " + update.Version())
941+
updateModal.Update("Downloading " + updateType + " update " + appName + " update " + update.Version())
933942
} else {
934943
slog.InfoContext(ctx, "Downloading "+updateType+" update", "version", update.Version())
935-
modal.Update("Downloading " + updateType + " update " + update.Version())
944+
updateModal.Update("Downloading " + updateType + " update " + update.Version())
936945
}
937946

938947
targetPath := ""
@@ -946,18 +955,18 @@ func applyUpdate(ctx context.Context, s *state.State, t *tui.TUI, update provide
946955
targetPath = systemd.SystemExtensionsPath
947956
}
948957

949-
err := update.Download(ctx, targetPath, modal.UpdateProgress)
958+
err := update.Download(ctx, targetPath, updateModal.UpdateProgress)
950959
if err != nil {
951960
return "", err
952961
}
953962

954963
// Hide the progress bar.
955-
modal.UpdateProgress(0.0)
964+
updateModal.UpdateProgress(0.0)
956965

957966
switch u := update.(type) {
958967
case providers.SecureBootCertUpdate:
959968
slog.InfoContext(ctx, "Applying Secure Boot certificate update", "version", update.Version())
960-
modal.Update("Applying Secure Boot certificate update version " + update.Version())
969+
updateModal.Update("Applying Secure Boot certificate update version " + update.Version())
961970

962971
// Immediately set FullyApplied to false and save state to disk.
963972
s.SecureBoot.FullyApplied = false
@@ -971,13 +980,17 @@ func applyUpdate(ctx context.Context, s *state.State, t *tui.TUI, update provide
971980
// If an EFI variable was updated, we'll either be rebooting automatically or waiting
972981
// for the user to restart the system before going any further.
973982
if needsReboot {
983+
updateModal.Done()
984+
974985
s.System.Update.State.NeedsReboot = true
975986

976-
sbModal := t.AddModal(s.OS.Name + " SecureBoot Certificate Update")
987+
sbModal := t.GetModal("secureboot-update")
977988

978-
if isStartupCheck {
979-
modal.Done()
989+
if t.GetModal("secureboot-update") == nil {
990+
sbModal = t.AddModal(s.OS.Name+" SecureBoot Certificate Update", "secureboot-update")
991+
}
980992

993+
if isStartupCheck {
981994
slog.InfoContext(ctx, "Automatically rebooting system in five seconds")
982995
sbModal.Update("Automatically rebooting system in five seconds")
983996

@@ -1006,7 +1019,7 @@ func applyUpdate(ctx context.Context, s *state.State, t *tui.TUI, update provide
10061019

10071020
// Apply the update and reboot if first time through loop, otherwise wait for user to reboot system.
10081021
slog.InfoContext(ctx, "Applying OS update", "version", update.Version())
1009-
modal.Update("Applying " + s.OS.Name + " update version " + update.Version())
1022+
updateModal.Update("Applying " + s.OS.Name + " update version " + update.Version())
10101023

10111024
err = systemd.ApplySystemUpdate(ctx, s.System.Security.Config.EncryptionRecoveryKeys[0], update.Version(), s.System.Update.Config.AutoReboot || isStartupCheck)
10121025
if err != nil {

incus-osd/internal/install/install.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ func NewInstall(t *tui.TUI) (*Install, error) {
151151

152152
// DoInstall performs the necessary steps for installing incus-osd to a local disk.
153153
func (i *Install) DoInstall(ctx context.Context, osName string) error {
154-
modal := i.tui.AddModal(osName + " Install")
154+
modal := i.tui.AddModal(osName+" Install", "install")
155155
slog.InfoContext(ctx, "Starting install of "+osName+" to local disk")
156156
modal.Update("Starting install of " + osName + " to local disk.")
157157

incus-osd/internal/tui/modal.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tui
33
// Modal holds the information for a given modal dialog.
44
type Modal struct {
55
title string
6+
category string
67
message string
78
progress float64
89
isDone bool
@@ -27,6 +28,7 @@ func (m *Modal) UpdateProgress(progress float64) {
2728
// Done indicates that the modal is no longer needed and should be removed.
2829
func (m *Modal) Done() {
2930
m.isDone = true
31+
m.category = "__DONE__"
3032

3133
m.t.quickDraw()
3234
}

incus-osd/internal/tui/tui.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,12 @@ func (t *TUI) Run() error {
172172
}
173173

174174
// AddModal adds a new modal popup to display to the user.
175-
func (t *TUI) AddModal(title string) *Modal {
175+
func (t *TUI) AddModal(title string, category string) *Modal {
176176
ret := &Modal{
177-
title: title,
178-
isDone: false,
179-
t: t,
177+
title: title,
178+
category: category,
179+
isDone: false,
180+
t: t,
180181
}
181182

182183
t.modalMutex.Lock()
@@ -186,6 +187,17 @@ func (t *TUI) AddModal(title string) *Modal {
186187
return ret
187188
}
188189

190+
// GetModal returns an existing modal with the specified category, and nil if it doesn't exist.
191+
func (t *TUI) GetModal(category string) *Modal {
192+
for _, m := range t.modalMessages {
193+
if m.category == category {
194+
return m
195+
}
196+
}
197+
198+
return nil
199+
}
200+
189201
// quickDraw() will immediately render the modal update if there is only a single modal
190202
// in existence. Otherwise, do nothing and wait for the normal rotation of modal messages
191203
// to display the update.

0 commit comments

Comments
 (0)