diff --git a/pkg/gui/containers_panel.go b/pkg/gui/containers_panel.go index 076dbb20..9e816f00 100644 --- a/pkg/gui/containers_panel.go +++ b/pkg/gui/containers_panel.go @@ -158,15 +158,6 @@ func (gui *Gui) renderLogsForRegularContainer(mainView *gocui.View, container *c return nil } -func (gui *Gui) obtainLock() { - gui.State.MainProcessChan <- struct{}{} - gui.State.MainProcessMutex.Lock() -} - -func (gui *Gui) releaseLock() { - gui.State.MainProcessMutex.Unlock() -} - func (gui *Gui) runProcessWithLock(cmd *exec.Cmd) { gui.T.NewTask(func(stop chan struct{}) { cmd.Start() diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index d30e2fa0..6e7c18b9 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -1,7 +1,6 @@ package gui import ( - "math" "sync" // "io" @@ -19,7 +18,6 @@ import ( "github.com/jesseduffield/lazydocker/pkg/config" "github.com/jesseduffield/lazydocker/pkg/i18n" "github.com/jesseduffield/lazydocker/pkg/tasks" - "github.com/jesseduffield/lazydocker/pkg/utils" "github.com/sirupsen/logrus" ) @@ -109,8 +107,6 @@ type guiState struct { Platform commands.Platform Panels *panelStates SubProcessOutput string - MainProcessMutex sync.Mutex - MainProcessChan chan struct{} Stats map[string]commands.ContainerStats } @@ -129,17 +125,8 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand ObjectKey: "", }, }, - MainProcessChan: make(chan struct{}), } - go func() { - // setting up a goroutine for listening to the first stop signal on this channel - // because whenever something wants to lock the mutex, it tells the existing process to stop - // but on startup we don't have a process so we just mock it - // this is because we're using an unbuffered channel - <-initialState.MainProcessChan - }() - gui := &Gui{ Log: log, DockerCommand: dockerCommand, @@ -158,32 +145,6 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand return gui, nil } -func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error { - mainView, _ := g.View("main") - mainView.Autoscroll = false - ox, oy := mainView.Origin() - newOy := int(math.Max(0, float64(oy-gui.Config.UserConfig.Gui.ScrollHeight))) - return mainView.SetOrigin(ox, newOy) -} - -func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error { - mainView, _ := g.View("main") - ox, oy := mainView.Origin() - y := oy - if !gui.Config.UserConfig.Gui.ScrollPastBottom { - _, sy := mainView.Size() - y += sy - } - // for some reason we can't work out whether we've hit the bottomq - // there is a large discrepancy in the origin's y value and the length of BufferLines - return mainView.SetOrigin(ox, oy+gui.Config.UserConfig.Gui.ScrollHeight) -} - -func (gui *Gui) autoScrollMain(g *gocui.Gui, v *gocui.View) error { - gui.getMainView().Autoscroll = true - return nil -} - func (gui *Gui) handleRefresh(g *gocui.Gui, v *gocui.View) error { return gui.refreshSidePanels(g) } @@ -195,260 +156,6 @@ func max(a, b int) int { return b } -// getFocusLayout returns a manager function for when view gain and lose focus -func (gui *Gui) getFocusLayout() func(g *gocui.Gui) error { - var previousView *gocui.View - return func(g *gocui.Gui) error { - newView := gui.g.CurrentView() - if err := gui.onFocusChange(); err != nil { - return err - } - // for now we don't consider losing focus to a popup panel as actually losing focus - if newView != previousView && !gui.isPopupPanel(newView.Name()) { - if err := gui.onFocusLost(previousView, newView); err != nil { - return err - } - if err := gui.onFocus(newView); err != nil { - return err - } - previousView = newView - } - return nil - } -} - -func (gui *Gui) onFocusChange() error { - currentView := gui.g.CurrentView() - for _, view := range gui.g.Views() { - view.Highlight = view == currentView - } - return nil -} - -func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error { - if v == nil { - return nil - } - gui.Log.Info(v.Name() + " focus lost") - return nil -} - -func (gui *Gui) onFocus(v *gocui.View) error { - if v == nil { - return nil - } - gui.Log.Info(v.Name() + " focus gained") - return nil -} - -// layout is called for every screen re-render e.g. when the screen is resized -func (gui *Gui) layout(g *gocui.Gui) error { - g.Highlight = true - width, height := g.Size() - - information := gui.Config.Version - - minimumHeight := 9 - minimumWidth := 10 - if height < minimumHeight || width < minimumWidth { - v, err := g.SetView("limit", 0, 0, width-1, height-1, 0) - if err != nil { - if err.Error() != "unknown view" { - return err - } - v.Title = gui.Tr.SLocalize("NotEnoughSpace") - v.Wrap = true - _, _ = g.SetViewOnTop("limit") - } - return nil - } - - currView := gui.g.CurrentView() - currentCyclebleView := gui.State.PreviousView - if currView != nil { - viewName := currView.Name() - usePreviouseView := true - for _, view := range cyclableViews { - if view == viewName { - currentCyclebleView = viewName - usePreviouseView = false - break - } - } - if usePreviouseView { - currentCyclebleView = gui.State.PreviousView - } - } - - usableSpace := height - 4 - - tallPanels := 3 - - vHeights := map[string]int{ - "status": tallPanels, - "services": usableSpace/tallPanels + usableSpace%tallPanels, - "containers": usableSpace / tallPanels, - "images": usableSpace / tallPanels, - "options": 1, - } - - if height < 28 { - defaultHeight := 3 - if height < 21 { - defaultHeight = 1 - } - vHeights = map[string]int{ - "status": defaultHeight, - "services": defaultHeight, - "containers": defaultHeight, - "images": defaultHeight, - "options": defaultHeight, - } - vHeights[currentCyclebleView] = height - defaultHeight*tallPanels - 1 - } - - optionsVersionBoundary := width - max(len(utils.Decolorise(information)), 1) - leftSideWidth := width / 3 - - appStatus := gui.statusManager.getStatusString() - appStatusOptionsBoundary := 0 - if appStatus != "" { - appStatusOptionsBoundary = len(appStatus) + 2 - } - - _, _ = g.SetViewOnBottom("limit") - g.DeleteView("limit") - - v, err := g.SetView("main", leftSideWidth+1, 0, width-1, height-2, gocui.LEFT) - if err != nil { - if err.Error() != "unknown view" { - return err - } - v.Wrap = true - v.FgColor = gocui.ColorWhite - } - - if v, err := g.SetView("status", 0, 0, leftSideWidth, vHeights["status"]-1, gocui.BOTTOM|gocui.RIGHT); err != nil { - if err.Error() != "unknown view" { - return err - } - v.Title = gui.Tr.SLocalize("StatusTitle") - v.FgColor = gocui.ColorWhite - } - - servicesView, err := g.SetViewBeneath("services", "status", vHeights["services"]) - if err != nil { - if err.Error() != "unknown view" { - return err - } - servicesView.Highlight = true - servicesView.Title = gui.Tr.SLocalize("ServicesTitle") - servicesView.FgColor = gocui.ColorWhite - - gui.focusPoint(0, gui.State.Panels.Services.SelectedLine, len(gui.DockerCommand.Services), servicesView) - } - - containersView, err := g.SetViewBeneath("containers", "services", vHeights["containers"]) - if err != nil { - if err.Error() != "unknown view" { - return err - } - containersView.Highlight = true - containersView.Title = gui.Tr.SLocalize("ContainersTitle") - containersView.FgColor = gocui.ColorWhite - - gui.focusPoint(0, gui.State.Panels.Containers.SelectedLine, len(gui.DockerCommand.Containers), containersView) - } - - imagesView, err := g.SetViewBeneath("images", "containers", vHeights["images"]) - if err != nil { - if err.Error() != "unknown view" { - return err - } - imagesView.Highlight = true - imagesView.Title = gui.Tr.SLocalize("ImagesTitle") - imagesView.FgColor = gocui.ColorWhite - - gui.focusPoint(0, gui.State.Panels.Images.SelectedLine, len(gui.DockerCommand.Images), imagesView) - } - - if v, err := g.SetView("options", appStatusOptionsBoundary-1, height-2, optionsVersionBoundary-1, height, 0); err != nil { - if err.Error() != "unknown view" { - return err - } - v.Frame = false - if v.FgColor, err = gui.GetOptionsPanelTextColor(); err != nil { - return err - } - } - - if appStatusView, err := g.SetView("appStatus", -1, height-2, width, height, 0); err != nil { - if err.Error() != "unknown view" { - return err - } - appStatusView.BgColor = gocui.ColorDefault - appStatusView.FgColor = gocui.ColorCyan - appStatusView.Frame = false - if _, err := g.SetViewOnBottom("appStatus"); err != nil { - return err - } - } - - if v, err := g.SetView("information", optionsVersionBoundary-1, height-2, width, height, 0); err != nil { - if err.Error() != "unknown view" { - return err - } - v.BgColor = gocui.ColorDefault - v.FgColor = gocui.ColorGreen - v.Frame = false - if err := gui.renderString(g, "information", information); err != nil { - return err - } - - // doing this here because it'll only happen once - if err := gui.loadNewDirectory(); err != nil { - return err - } - } - - if gui.g.CurrentView() == nil { - if _, err := gui.g.SetCurrentView(gui.getContainersView().Name()); err != nil { - return err - } - - if err := gui.switchFocus(gui.g, nil, gui.getServicesView()); err != nil { - return err - } - } - - type listViewState struct { - selectedLine int - lineCount int - } - - listViews := map[*gocui.View]listViewState{ - containersView: {selectedLine: gui.State.Panels.Containers.SelectedLine, lineCount: len(gui.DockerCommand.Containers)}, - imagesView: {selectedLine: gui.State.Panels.Images.SelectedLine, lineCount: len(gui.DockerCommand.Images)}, - } - - // menu view might not exist so we check to be safe - if menuView, err := gui.g.View("menu"); err == nil { - listViews[menuView] = listViewState{selectedLine: gui.State.Panels.Menu.SelectedLine, lineCount: gui.State.MenuItemCount} - } - for view, state := range listViews { - // check if the selected line is now out of view and if so refocus it - if err := gui.focusPoint(0, state.selectedLine, state.lineCount, view); err != nil { - return err - } - } - - // here is a good place log some stuff - // if you download humanlog and do tail -f development.log | humanlog - // this will let you see these branches as prettified json - // gui.Log.Info(utils.AsJson(gui.State.Branches[0:4])) - return gui.resizeCurrentPopupPanel(g) -} - func (gui *Gui) loadNewDirectory() error { gui.waitForIntro.Done() @@ -618,3 +325,11 @@ func (gui *Gui) runSyncOrAsyncCommand(sub *exec.Cmd, err error) (bool, error) { } return true, nil } + +func (gui *Gui) handleCustomCommand(g *gocui.Gui, v *gocui.View) error { + return gui.createPromptPanel(g, v, gui.Tr.SLocalize("CustomCommand"), func(g *gocui.Gui, v *gocui.View) error { + command := gui.trimmedContent(v) + gui.SubProcess = gui.OSCommand.RunCustomCommand(command) + return gui.Errors.ErrSubProcess + }) +} diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 354ecd89..843bd9d6 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -76,43 +76,57 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.quit, - }, { + }, + { ViewName: "", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpMain, - }, { + }, + { ViewName: "", Key: gocui.KeyPgdn, Modifier: gocui.ModNone, Handler: gui.scrollDownMain, - }, { + }, + { ViewName: "", Key: gocui.KeyCtrlU, Modifier: gocui.ModNone, Handler: gui.scrollUpMain, - }, { + }, + { ViewName: "", Key: gocui.KeyCtrlD, Modifier: gocui.ModNone, Handler: gui.scrollDownMain, - }, { + }, + { ViewName: "", Key: gocui.KeyEnd, Modifier: gocui.ModNone, Handler: gui.autoScrollMain, - }, { + }, + { ViewName: "", Key: 'x', Modifier: gocui.ModNone, Handler: gui.handleCreateOptionsMenu, - }, { + }, + { + ViewName: "", + Key: 'X', + Modifier: gocui.ModNone, + Handler: gui.handleCustomCommand, + }, + { ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, Description: gui.Tr.SLocalize("EditConfig"), - }, { + }, + { ViewName: "status", Key: 'o', Modifier: gocui.ModNone, @@ -124,23 +138,27 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleMenuClose, - }, { + }, + { ViewName: "menu", Key: 'q', Modifier: gocui.ModNone, Handler: gui.handleMenuClose, - }, { + }, + { ViewName: "information", Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleDonate, - }, { + }, + { ViewName: "containers", Key: '[', Modifier: gocui.ModNone, Handler: gui.handleContainersPrevContext, Description: gui.Tr.SLocalize("previousContext"), - }, { + }, + { ViewName: "containers", Key: ']', Modifier: gocui.ModNone, @@ -230,7 +248,8 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Modifier: gocui.ModNone, Handler: gui.handleImagesPrevContext, Description: gui.Tr.SLocalize("previousContext"), - }, { + }, + { ViewName: "images", Key: ']', Modifier: gocui.ModNone, diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go new file mode 100644 index 00000000..9b16a9d0 --- /dev/null +++ b/pkg/gui/layout.go @@ -0,0 +1,260 @@ +package gui + +import ( + "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazydocker/pkg/utils" +) + +// getFocusLayout returns a manager function for when view gain and lose focus +func (gui *Gui) getFocusLayout() func(g *gocui.Gui) error { + var previousView *gocui.View + return func(g *gocui.Gui) error { + newView := gui.g.CurrentView() + if err := gui.onFocusChange(); err != nil { + return err + } + // for now we don't consider losing focus to a popup panel as actually losing focus + if newView != previousView && !gui.isPopupPanel(newView.Name()) { + if err := gui.onFocusLost(previousView, newView); err != nil { + return err + } + if err := gui.onFocus(newView); err != nil { + return err + } + previousView = newView + } + return nil + } +} + +func (gui *Gui) onFocusChange() error { + currentView := gui.g.CurrentView() + for _, view := range gui.g.Views() { + view.Highlight = view == currentView + } + return nil +} + +func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error { + if v == nil { + return nil + } + gui.Log.Info(v.Name() + " focus lost") + return nil +} + +func (gui *Gui) onFocus(v *gocui.View) error { + if v == nil { + return nil + } + gui.Log.Info(v.Name() + " focus gained") + return nil +} + +// layout is called for every screen re-render e.g. when the screen is resized +func (gui *Gui) layout(g *gocui.Gui) error { + g.Highlight = true + width, height := g.Size() + + information := gui.Config.Version + + minimumHeight := 9 + minimumWidth := 10 + if height < minimumHeight || width < minimumWidth { + v, err := g.SetView("limit", 0, 0, width-1, height-1, 0) + if err != nil { + if err.Error() != "unknown view" { + return err + } + v.Title = gui.Tr.SLocalize("NotEnoughSpace") + v.Wrap = true + _, _ = g.SetViewOnTop("limit") + } + return nil + } + + currView := gui.g.CurrentView() + currentCyclebleView := gui.State.PreviousView + if currView != nil { + viewName := currView.Name() + usePreviouseView := true + for _, view := range cyclableViews { + if view == viewName { + currentCyclebleView = viewName + usePreviouseView = false + break + } + } + if usePreviouseView { + currentCyclebleView = gui.State.PreviousView + } + } + + usableSpace := height - 4 + + tallPanels := 3 + + vHeights := map[string]int{ + "status": tallPanels, + "services": usableSpace/tallPanels + usableSpace%tallPanels, + "containers": usableSpace / tallPanels, + "images": usableSpace / tallPanels, + "options": 1, + } + + if height < 28 { + defaultHeight := 3 + if height < 21 { + defaultHeight = 1 + } + vHeights = map[string]int{ + "status": defaultHeight, + "services": defaultHeight, + "containers": defaultHeight, + "images": defaultHeight, + "options": defaultHeight, + } + vHeights[currentCyclebleView] = height - defaultHeight*tallPanels - 1 + } + + optionsVersionBoundary := width - max(len(utils.Decolorise(information)), 1) + leftSideWidth := width / 3 + + appStatus := gui.statusManager.getStatusString() + appStatusOptionsBoundary := 0 + if appStatus != "" { + appStatusOptionsBoundary = len(appStatus) + 2 + } + + _, _ = g.SetViewOnBottom("limit") + g.DeleteView("limit") + + v, err := g.SetView("main", leftSideWidth+1, 0, width-1, height-2, gocui.LEFT) + if err != nil { + if err.Error() != "unknown view" { + return err + } + v.Wrap = true + v.FgColor = gocui.ColorWhite + } + + if v, err := g.SetView("status", 0, 0, leftSideWidth, vHeights["status"]-1, gocui.BOTTOM|gocui.RIGHT); err != nil { + if err.Error() != "unknown view" { + return err + } + v.Title = gui.Tr.SLocalize("StatusTitle") + v.FgColor = gocui.ColorWhite + } + + servicesView, err := g.SetViewBeneath("services", "status", vHeights["services"]) + if err != nil { + if err.Error() != "unknown view" { + return err + } + servicesView.Highlight = true + servicesView.Title = gui.Tr.SLocalize("ServicesTitle") + servicesView.FgColor = gocui.ColorWhite + + gui.focusPoint(0, gui.State.Panels.Services.SelectedLine, len(gui.DockerCommand.Services), servicesView) + } + + containersView, err := g.SetViewBeneath("containers", "services", vHeights["containers"]) + if err != nil { + if err.Error() != "unknown view" { + return err + } + containersView.Highlight = true + containersView.Title = gui.Tr.SLocalize("ContainersTitle") + containersView.FgColor = gocui.ColorWhite + + gui.focusPoint(0, gui.State.Panels.Containers.SelectedLine, len(gui.DockerCommand.Containers), containersView) + } + + imagesView, err := g.SetViewBeneath("images", "containers", vHeights["images"]) + if err != nil { + if err.Error() != "unknown view" { + return err + } + imagesView.Highlight = true + imagesView.Title = gui.Tr.SLocalize("ImagesTitle") + imagesView.FgColor = gocui.ColorWhite + + gui.focusPoint(0, gui.State.Panels.Images.SelectedLine, len(gui.DockerCommand.Images), imagesView) + } + + if v, err := g.SetView("options", appStatusOptionsBoundary-1, height-2, optionsVersionBoundary-1, height, 0); err != nil { + if err.Error() != "unknown view" { + return err + } + v.Frame = false + if v.FgColor, err = gui.GetOptionsPanelTextColor(); err != nil { + return err + } + } + + if appStatusView, err := g.SetView("appStatus", -1, height-2, width, height, 0); err != nil { + if err.Error() != "unknown view" { + return err + } + appStatusView.BgColor = gocui.ColorDefault + appStatusView.FgColor = gocui.ColorCyan + appStatusView.Frame = false + if _, err := g.SetViewOnBottom("appStatus"); err != nil { + return err + } + } + + if v, err := g.SetView("information", optionsVersionBoundary-1, height-2, width, height, 0); err != nil { + if err.Error() != "unknown view" { + return err + } + v.BgColor = gocui.ColorDefault + v.FgColor = gocui.ColorGreen + v.Frame = false + if err := gui.renderString(g, "information", information); err != nil { + return err + } + + // doing this here because it'll only happen once + if err := gui.loadNewDirectory(); err != nil { + return err + } + } + + if gui.g.CurrentView() == nil { + if _, err := gui.g.SetCurrentView(gui.getContainersView().Name()); err != nil { + return err + } + + if err := gui.switchFocus(gui.g, nil, gui.getServicesView()); err != nil { + return err + } + } + + type listViewState struct { + selectedLine int + lineCount int + } + + listViews := map[*gocui.View]listViewState{ + containersView: {selectedLine: gui.State.Panels.Containers.SelectedLine, lineCount: len(gui.DockerCommand.Containers)}, + imagesView: {selectedLine: gui.State.Panels.Images.SelectedLine, lineCount: len(gui.DockerCommand.Images)}, + } + + // menu view might not exist so we check to be safe + if menuView, err := gui.g.View("menu"); err == nil { + listViews[menuView] = listViewState{selectedLine: gui.State.Panels.Menu.SelectedLine, lineCount: gui.State.MenuItemCount} + } + for view, state := range listViews { + // check if the selected line is now out of view and if so refocus it + if err := gui.focusPoint(0, state.selectedLine, state.lineCount, view); err != nil { + return err + } + } + + // here is a good place log some stuff + // if you download humanlog and do tail -f development.log | humanlog + // this will let you see these branches as prettified json + // gui.Log.Info(utils.AsJson(gui.State.Branches[0:4])) + return gui.resizeCurrentPopupPanel(g) +} diff --git a/pkg/gui/main_panel.go b/pkg/gui/main_panel.go new file mode 100644 index 00000000..9ada6b2a --- /dev/null +++ b/pkg/gui/main_panel.go @@ -0,0 +1,33 @@ +package gui + +import ( + "math" + + "github.com/jesseduffield/gocui" +) + +func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error { + mainView, _ := g.View("main") + mainView.Autoscroll = false + ox, oy := mainView.Origin() + newOy := int(math.Max(0, float64(oy-gui.Config.UserConfig.Gui.ScrollHeight))) + return mainView.SetOrigin(ox, newOy) +} + +func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error { + mainView, _ := g.View("main") + ox, oy := mainView.Origin() + y := oy + if !gui.Config.UserConfig.Gui.ScrollPastBottom { + _, sy := mainView.Size() + y += sy + } + // for some reason we can't work out whether we've hit the bottomq + // there is a large discrepancy in the origin's y value and the length of BufferLines + return mainView.SetOrigin(ox, oy+gui.Config.UserConfig.Gui.ScrollHeight) +} + +func (gui *Gui) autoScrollMain(g *gocui.Gui, v *gocui.View) error { + gui.getMainView().Autoscroll = true + return nil +} diff --git a/pkg/gui/subprocess.go b/pkg/gui/subprocess.go index 78729329..909a0aac 100644 --- a/pkg/gui/subprocess.go +++ b/pkg/gui/subprocess.go @@ -62,9 +62,9 @@ func (gui *Gui) runCommand() error { gui.SubProcess.Stdin = nil gui.SubProcess = nil - // fmt.Fprintf(os.Stdout, "\n%s", utils.ColoredString(gui.Tr.SLocalize("pressEnterToReturn"), color.FgGreen)) + fmt.Fprintf(os.Stdout, "\n%s", utils.ColoredString(gui.Tr.SLocalize("pressEnterToReturn"), color.FgGreen)) - // fmt.Scanln() // wait for enter press + fmt.Scanln() // wait for enter press return nil } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 0c595bbe..6e8cb1d2 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -868,5 +868,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { ID: "StopService", Other: "Are you sure you want to stop this service's containers? (enter/esc)", }, + &i18n.Message{ + ID: "pressEnterToReturn", + Other: "Press enter to return to lazydocker", + }, ) } diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go index 951b189c..35203966 100644 --- a/pkg/tasks/tasks.go +++ b/pkg/tasks/tasks.go @@ -58,7 +58,7 @@ func (t *Task) Stop() { // NewTickerTask is a convenience function for making a new task that repeats some action once per e.g. second func (t *TaskManager) NewTickerTask(duration time.Duration, f func()) error { return t.NewTask(func(stop chan struct{}) { - tickChan := time.NewTicker(time.Second) + tickChan := time.NewTicker(duration) f() // calling f first so that we're not waiting for the first tick for { select {