diff --git a/pkg/gui/arrangement.go b/pkg/gui/arrangement.go index 58b53706..b24c82af 100644 --- a/pkg/gui/arrangement.go +++ b/pkg/gui/arrangement.go @@ -222,10 +222,6 @@ func (gui *Gui) sidePanelChildren(width int, height int) []*boxlayout.Box { // return "files" // default // } -func (gui *Gui) currentNonPopupWindowName() string { - return gui.peekPreviousView() -} - // TODO: do this better. func (gui *Gui) currentSideWindowName() string { windowName := gui.currentWindow() diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index ccafc9ef..17710987 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -8,7 +8,6 @@ import ( "time" "github.com/docker/docker/api/types" - "github.com/golang-collections/collections/stack" // "io" // "io/ioutil" @@ -123,8 +122,9 @@ type panelStates struct { } type guiState struct { - MenuItemCount int // can't store the actual list because it's of interface{} type - PreviousViews *stack.Stack + MenuItemCount int // can't store the actual list because it's of interface{} type + // the names of views in the current focus stack (last item is the current view) + ViewStack []string Platform commands.Platform Panels *panelStates SubProcessOutput string @@ -165,8 +165,8 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand }, Project: &projectState{ContextIndex: 0}, }, - SessionIndex: 0, - PreviousViews: stack.New(), + SessionIndex: 0, + ViewStack: []string{}, } cyclableViews := []string{"project", "containers", "images", "volumes"} diff --git a/pkg/gui/subprocess.go b/pkg/gui/subprocess.go index df23afd6..059f05e1 100644 --- a/pkg/gui/subprocess.go +++ b/pkg/gui/subprocess.go @@ -22,7 +22,7 @@ func (gui *Gui) RunWithSubprocesses() error { break } else if err == gui.Errors.ErrSubProcess { // preparing the state for when we return - gui.pushPreviousView(gui.currentViewName()) + gui.pushView(gui.currentViewName()) // giving goEvery goroutines time to finish gui.State.SessionIndex++ @@ -31,7 +31,7 @@ func (gui *Gui) RunWithSubprocesses() error { } // pop here so we don't stack up view names - gui.popPreviousView() + gui.popView() // ensuring we render e.g. the logs of the currently selected item upon return gui.State.Panels.Main.ObjectKey = "" } else { diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index a594ccb5..a585d807 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -7,6 +7,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazydocker/pkg/utils" + "github.com/samber/lo" "github.com/spkg/bom" ) @@ -32,7 +33,7 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error { panic(err) } gui.resetMainView() - gui.popPreviousView() + gui.popView() return gui.switchFocus(g, v, focusedView, false) } @@ -58,7 +59,7 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error { panic(err) } gui.resetMainView() - gui.popPreviousView() + gui.popView() return gui.switchFocus(g, v, focusedView, false) } @@ -95,28 +96,42 @@ func (gui *Gui) newLineFocused(v *gocui.View) error { } } -func (gui *Gui) popPreviousView() string { - if gui.State.PreviousViews.Len() > 0 { - return gui.State.PreviousViews.Pop().(string) +func (gui *Gui) popView() string { + if len(gui.State.ViewStack) > 0 { + value := gui.State.ViewStack[len(gui.State.ViewStack)-1] + gui.State.ViewStack = gui.State.ViewStack[:len(gui.State.ViewStack)-1] + return value } return "" } func (gui *Gui) peekPreviousView() string { - if gui.State.PreviousViews.Len() > 0 { - return gui.State.PreviousViews.Peek().(string) + if len(gui.State.ViewStack) > 0 { + return gui.State.ViewStack[len(gui.State.ViewStack)-1] } return "" } -func (gui *Gui) pushPreviousView(name string) { - gui.State.PreviousViews.Push(name) +func (gui *Gui) pushView(name string) { + // No matter what view we're pushing, we first remove all popup panels from the stack + gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool { + return viewName != "confirmation" && viewName != "menu" + }) + + // If we're pushing a side panel, we remove all other panels + if lo.Contains(gui.sideViewNames(), name) { + gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool { + return viewName != "main" + }) + } + + gui.State.ViewStack = append(gui.State.ViewStack, name) } func (gui *Gui) returnFocus(g *gocui.Gui, v *gocui.View) error { - previousViewName := gui.popPreviousView() + previousViewName := gui.popView() previousView, err := g.View(previousViewName) if err != nil { // always fall back to services view if there's no 'previous' view stored @@ -134,7 +149,7 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View, returnin // we assume we'll never want to return focus to a popup panel i.e. // we should never stack popup panels if oldView != nil && !gui.isPopupPanel(oldView.Name()) && !returning { - gui.pushPreviousView(oldView.Name()) + gui.pushView(oldView.Name()) } gui.Log.Info("setting highlight to true for view " + newView.Name())