add images panel
parent
1488bfbcd4
commit
4fe26f4f88
@ -0,0 +1,24 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/fatih/color"
|
||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Image : A docker Image
|
||||
type Image struct {
|
||||
Name string
|
||||
ID string
|
||||
Image types.ImageSummary
|
||||
Client *client.Client
|
||||
OSCommand *OSCommand
|
||||
Log *logrus.Entry
|
||||
}
|
||||
|
||||
// GetDisplayStrings returns the display string of Image
|
||||
func (i *Image) GetDisplayStrings(isFocused bool) []string {
|
||||
return []string{utils.ColoredString(i.Name, color.FgWhite)}
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazydocker/pkg/commands"
|
||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getImageContexts() []string {
|
||||
return []string{"config"}
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedImage(g *gocui.Gui) (*commands.Image, error) {
|
||||
selectedLine := gui.State.Panels.Images.SelectedLine
|
||||
if selectedLine == -1 {
|
||||
return &commands.Image{}, gui.Errors.ErrNoImages
|
||||
}
|
||||
|
||||
return gui.State.Images[selectedLine], nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImagesFocus(g *gocui.Gui, v *gocui.View) error {
|
||||
if gui.popupPanelFocused() {
|
||||
return nil
|
||||
}
|
||||
|
||||
cx, cy := v.Cursor()
|
||||
_, oy := v.Origin()
|
||||
|
||||
prevSelectedLine := gui.State.Panels.Images.SelectedLine
|
||||
newSelectedLine := cy - oy
|
||||
|
||||
if newSelectedLine > len(gui.State.Images)-1 || len(utils.Decolorise(gui.State.Images[newSelectedLine].Name)) < cx {
|
||||
return gui.handleImageSelect(gui.g, v)
|
||||
}
|
||||
|
||||
gui.State.Panels.Images.SelectedLine = newSelectedLine
|
||||
|
||||
if prevSelectedLine == newSelectedLine && gui.currentViewName() == v.Name() {
|
||||
return gui.handleImagePress(gui.g, v)
|
||||
} else {
|
||||
return gui.handleImageSelect(gui.g, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImageSelect(g *gocui.Gui, v *gocui.View) error {
|
||||
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Image, err := gui.getSelectedImage(g)
|
||||
if err != nil {
|
||||
if err != gui.Errors.ErrNoImages {
|
||||
return err
|
||||
}
|
||||
return gui.renderString(g, "main", gui.Tr.SLocalize("NoImages"))
|
||||
}
|
||||
|
||||
key := Image.ID + "-" + gui.getImageContexts()[gui.State.Panels.Images.ContextIndex]
|
||||
if gui.State.Panels.Main.ObjectKey == key {
|
||||
return nil
|
||||
} else {
|
||||
gui.State.Panels.Main.ObjectKey = key
|
||||
}
|
||||
|
||||
if err := gui.focusPoint(0, gui.State.Panels.Images.SelectedLine, len(gui.State.Images), v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mainView := gui.getMainView()
|
||||
|
||||
gui.State.Panels.Main.WriterID++
|
||||
writerID := gui.State.Panels.Main.WriterID
|
||||
|
||||
mainView.Clear()
|
||||
mainView.SetOrigin(0, 0)
|
||||
mainView.SetCursor(0, 0)
|
||||
|
||||
switch gui.getImageContexts()[gui.State.Panels.Images.ContextIndex] {
|
||||
case "config":
|
||||
if err := gui.renderImageConfig(mainView, Image, writerID); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errors.New("Unknown context for Images panel")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) renderImageConfig(mainView *gocui.View, Image *commands.Image, writerID int) error {
|
||||
mainView.Autoscroll = false
|
||||
mainView.Title = "Config"
|
||||
|
||||
data, err := json.MarshalIndent(&Image.Image, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gui.renderString(gui.g, "main", string(data))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshImages() error {
|
||||
ImagesView := gui.getImagesView()
|
||||
if ImagesView == nil {
|
||||
// if the ImagesView hasn't been instantiated yet we just return
|
||||
return nil
|
||||
}
|
||||
if err := gui.refreshStateImages(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(gui.State.Images) > 0 && gui.State.Panels.Images.SelectedLine == -1 {
|
||||
gui.State.Panels.Images.SelectedLine = 0
|
||||
}
|
||||
if len(gui.State.Images)-1 < gui.State.Panels.Images.SelectedLine {
|
||||
gui.State.Panels.Images.SelectedLine = len(gui.State.Images) - 1
|
||||
}
|
||||
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
|
||||
ImagesView.Clear()
|
||||
isFocused := gui.g.CurrentView().Name() == "Images"
|
||||
list, err := utils.RenderList(gui.State.Images, isFocused)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprint(ImagesView, list)
|
||||
|
||||
if ImagesView == g.CurrentView() {
|
||||
return gui.handleImageSelect(g, ImagesView)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshStateImages() error {
|
||||
Images, err := gui.DockerCommand.GetImages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gui.State.Images = Images
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImagesNextLine(g *gocui.Gui, v *gocui.View) error {
|
||||
if gui.popupPanelFocused() {
|
||||
return nil
|
||||
}
|
||||
|
||||
panelState := gui.State.Panels.Images
|
||||
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Images), false)
|
||||
|
||||
return gui.handleImageSelect(gui.g, v)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImagesPrevLine(g *gocui.Gui, v *gocui.View) error {
|
||||
if gui.popupPanelFocused() {
|
||||
return nil
|
||||
}
|
||||
|
||||
panelState := gui.State.Panels.Images
|
||||
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Images), true)
|
||||
|
||||
return gui.handleImageSelect(gui.g, v)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImagePress(g *gocui.Gui, v *gocui.View) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImagesPrevContext(g *gocui.Gui, v *gocui.View) error {
|
||||
contexts := gui.getImageContexts()
|
||||
if gui.State.Panels.Images.ContextIndex >= len(contexts)-1 {
|
||||
gui.State.Panels.Images.ContextIndex = 0
|
||||
} else {
|
||||
gui.State.Panels.Images.ContextIndex++
|
||||
}
|
||||
|
||||
gui.handleImageSelect(gui.g, v)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleImagesNextContext(g *gocui.Gui, v *gocui.View) error {
|
||||
contexts := gui.getImageContexts()
|
||||
if gui.State.Panels.Images.ContextIndex <= 0 {
|
||||
gui.State.Panels.Images.ContextIndex = len(contexts) - 1
|
||||
} else {
|
||||
gui.State.Panels.Images.ContextIndex--
|
||||
}
|
||||
|
||||
gui.handleImageSelect(gui.g, v)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// type removeOption struct {
|
||||
// description string
|
||||
// command string
|
||||
// configOptions types.ImageRemoveOptions
|
||||
// runCommand bool
|
||||
// }
|
||||
|
||||
// // GetDisplayStrings is a function.
|
||||
// func (r *removeOption) GetDisplayStrings(isFocused bool) []string {
|
||||
// return []string{r.description, color.New(color.FgRed).Sprint(r.command)}
|
||||
// }
|
||||
|
||||
// func (gui *Gui) handleImagesRemoveMenu(g *gocui.Gui, v *gocui.View) error {
|
||||
// Image, err := gui.getSelectedImage(g)
|
||||
// if err != nil {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// options := []*removeOption{
|
||||
// {
|
||||
// description: gui.Tr.SLocalize("remove"),
|
||||
// command: "docker rm " + Image.ID[1:10],
|
||||
// configOptions: types.ImageRemoveOptions{},
|
||||
// runCommand: true,
|
||||
// },
|
||||
// {
|
||||
// description: gui.Tr.SLocalize("removeWithVolumes"),
|
||||
// command: "docker rm --volumes " + Image.ID[1:10],
|
||||
// configOptions: types.ImageRemoveOptions{RemoveVolumes: true},
|
||||
// runCommand: true,
|
||||
// },
|
||||
// {
|
||||
// description: gui.Tr.SLocalize("cancel"),
|
||||
// runCommand: false,
|
||||
// },
|
||||
// }
|
||||
|
||||
// handleMenuPress := func(index int) error {
|
||||
// if !options[index].runCommand {
|
||||
// return nil
|
||||
// }
|
||||
// configOptions := options[index].configOptions
|
||||
// if cerr := Image.Remove(configOptions); cerr != nil {
|
||||
// var originalErr commands.ComplexError
|
||||
// if xerrors.As(cerr, &originalErr) {
|
||||
// if originalErr.Code == commands.MustStopImage {
|
||||
// return gui.createConfirmationPanel(gui.g, v, gui.Tr.SLocalize("Confirm"), gui.Tr.SLocalize("mustForceToRemove"), func(g *gocui.Gui, v *gocui.View) error {
|
||||
// configOptions.Force = true
|
||||
// if err := Image.Remove(configOptions); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return gui.refreshImages()
|
||||
// }, nil)
|
||||
// }
|
||||
// } else {
|
||||
// return gui.createErrorPanel(gui.g, err.Error())
|
||||
// }
|
||||
// }
|
||||
|
||||
// return gui.refreshImages()
|
||||
// }
|
||||
|
||||
// return gui.createMenu("", options, len(options), handleMenuPress)
|
||||
// }
|
Loading…
Reference in New Issue