From 1b4e10c620cda27cffbec321e6555df79b4702d5 Mon Sep 17 00:00:00 2001 From: somnek Date: Fri, 19 Jan 2024 07:06:23 +0800 Subject: [PATCH] =?UTF-8?q?container=20paddings=20=F0=9F=92=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helper.go | 4 +-- keys.go | 16 +++++------- model.go | 2 +- style.go | 21 ++++++++++----- view.go | 76 +++++++++++++++++++++++++++++++++++-------------------- 5 files changed, 72 insertions(+), 47 deletions(-) diff --git a/helper.go b/helper.go index de00b9b..f997d9f 100644 --- a/helper.go +++ b/helper.go @@ -233,7 +233,7 @@ func startAndWriteLog(m model) (tea.Model, tea.Cmd) { if successCount > 0 { logs += fmt.Sprintf( - "🚀 Starting %v container(s)\n", + "🚀 Start %v container(s)\n", itemCountStyle.Render(fmt.Sprintf("%d", successCount))) } @@ -276,7 +276,7 @@ func removeAndWriteLog(m model) (tea.Model, tea.Cmd) { if successCount > 0 { logs += fmt.Sprintf( - "🗑️ Removed %v container(s)\n", + "🔫 Removed %v container(s)\n", itemCountStyle.Render(fmt.Sprintf("%d", successCount))) } diff --git a/keys.go b/keys.go index 874a5f0..de4c01e 100644 --- a/keys.go +++ b/keys.go @@ -38,8 +38,6 @@ func (k keyMap) FullHelp() [][]key.Binding { k.Quit, k.Tab, k.Help, - }, - { k.Up, k.Down, k.Toggle, @@ -94,30 +92,30 @@ var keys = keyMap{ ), Remove: key.NewBinding( key.WithKeys("X"), - key.WithHelp("shift+x", "remove container"), + key.WithHelp("shift+x", "remove"), ), Restart: key.NewBinding( key.WithKeys("r"), - key.WithHelp("r", "restart container"), + key.WithHelp("r", "restart"), ), Kill: key.NewBinding( key.WithKeys("K"), - key.WithHelp("shift+k", "kill container"), + key.WithHelp("shift+k", "kill"), ), Stop: key.NewBinding( key.WithKeys("s"), - key.WithHelp("s", "stop container"), + key.WithHelp("s", "stop"), ), Start: key.NewBinding( key.WithKeys("u"), - key.WithHelp("u", "start container"), + key.WithHelp("u", "start"), ), Pause: key.NewBinding( key.WithKeys("p"), - key.WithHelp("p", "pause container"), + key.WithHelp("p", "pause"), ), Unpause: key.NewBinding( key.WithKeys("P"), - key.WithHelp("shift+p", "unpause container"), + key.WithHelp("shift+p", "unpause"), ), } diff --git a/model.go b/model.go index 929740a..b189918 100644 --- a/model.go +++ b/model.go @@ -82,7 +82,7 @@ func initialModel() model { // help h := help.New() - h.Width = fixedWidth + h.Width = fullWidth // processes processes := make(map[string]string) diff --git a/style.go b/style.go index 5b8175f..e4ac279 100644 --- a/style.go +++ b/style.go @@ -37,13 +37,20 @@ const ( ) const ( - lastPage = 4 - minHeightPerView = 8 // 6 item - maxHeightPerView = 12 // 10 item - fixedWidth = 88 // 92 - fixedBodyLWidth = 36 // exclude padding - fixedBodyRWidth = 44 // exclude padding - maxItemNameWidth = 21 + lastPage = 4 + minHeightPerView = 8 // 6 item + maxHeightPerView = 12 // 10 item + fullWidth = 90 + fixedPadL = 4 + fixedPadR = 4 + fixedPadM = 4 + fixedPadLR = fixedPadL + fixedPadR // 8 + fixedContentWidth = fullWidth - fixedPadLR // 86 + maxContainerNameWidth = 22 + maxImageNameWidth = 24 + prefixWidth = 6 + fixedBodyLWidth = prefixWidth + maxContainerNameWidth // 28 exclude padding + fixedBodyRWidth = 46 // exclude padding ) var ( diff --git a/view.go b/view.go index 2f4ff07..175f1d0 100644 --- a/view.go +++ b/view.go @@ -15,13 +15,20 @@ import ( // ----------------------------- render utils ----------------------------- +func buildEmptyBody(text, title string, width int) string { + emptyBody := text + padOuterComponent(&emptyBody, width) + emptyBody = strings.TrimSuffix(emptyBody, "\n") + return fmt.Sprintf("%s\n%s\n", title, emptyBody) +} + func padBodyHeight(s *string, itemCount int) { if itemCount < minHeightPerView { *s += strings.Repeat("\n", minHeightPerView-itemCount) } } -func padHelpWidth(s *string, windowWidth, maxAppWidth int) { +func padOuterComponent(s *string, windowWidth int) { var outerPad, innerPad, longest int // get width of longer help string (fullHelp) @@ -33,9 +40,9 @@ func padHelpWidth(s *string, windowWidth, maxAppWidth int) { } sWidth := longest - if windowWidth > 0 && longest < maxAppWidth-4 { - outerPad = (windowWidth - maxAppWidth) / 2 - innerPad = ((maxAppWidth - 4) - sWidth) / 2 + if windowWidth > 0 { + outerPad = (windowWidth - fullWidth) / 2 + innerPad = (fullWidth - sWidth) / 2 } var newS string @@ -45,12 +52,13 @@ func padHelpWidth(s *string, windowWidth, maxAppWidth int) { *s = newS } -func padItemWidth(s *string, maxWidth int) { - sWidth := lipgloss.Width(*s) - if sWidth < maxWidth-10 { - *s = *s + strings.Repeat(" ", maxWidth-sWidth) +func padItemName(name string) string { + nameWidth := lipgloss.Width(name) + if nameWidth < maxContainerNameWidth { + name = name + strings.Repeat(" ", maxContainerNameWidth-nameWidth) } - *s += "\n" + name += "\n" + return name } func formatCmd(cmd []string) string { @@ -123,19 +131,30 @@ func formatPortsMapping(portsMap map[docker.Port][]docker.PortBinding) string { // add column (container | hostmachine) if len(sortedPorts) > 0 { - s = fmt.Sprintf("%s -> %s", PortMapColStyle.Render("container"), PortMapColStyle.Render("host machine")) + s + s = fmt.Sprintf( + "%s -> %s", + PortMapColStyle.Render("container"), + PortMapColStyle.Render("host machine"), + ) + s } s = strings.TrimSuffix(s, "\n") return s } +func buildTitleView(m model) string { + s := "🐳 Killer Whale" + " " + padOuterComponent(&s, m.width) + s = strings.TrimSuffix(s, "\n") + return s +} + // ----------------------------- log view ----------------------------- func buildLogView(m model) string { var s string s += m.logs - logStyle.MarginLeft(((fixedWidth - 4) - lipgloss.Width(s)) / 2) + logStyle.MarginLeft((fullWidth - lipgloss.Width(s)) / 2) logStyle.AlignHorizontal(lipgloss.Center) return logStyle.Render(s) } @@ -172,8 +191,8 @@ func buildImageView(m model) (string, string) { if _, ok := m.selected[i]; ok { check = checkStyle.Render("✔") } + name = padItemName(name) row := fmt.Sprintf("%s %s %s", cursor, check, name) - padItemWidth(&row, fixedBodyLWidth-8) bodyL += row } padBodyHeight(&bodyL, len(m.images)+2) @@ -193,12 +212,15 @@ func buildContainerDescShort(id string) string { if err != nil { log.Fatal(err) } - desc := fmt.Sprintf("ID : %v\n", runewidth.Truncate(container.ID, fixedBodyRWidth-8, "...")) - desc += fmt.Sprintf("Image : %s\n", container.Config.Image) - desc += fmt.Sprintf("Cmd : %s\n", strings.Join(container.Config.Cmd, " ")) - desc += fmt.Sprintf("State : %s\n", container.State.String()) - desc += fmt.Sprintf("IP : %s\n", container.NetworkSettings.IPAddress) - desc += fmt.Sprintf("Ports : %v\n", formatPortsMapping(container.NetworkSettings.Ports)) + desc := fmt.Sprintf( + "ID : %v\n", + runewidth.Truncate(container.ID, fixedBodyRWidth-8, "..."), + ) + desc += fmt.Sprintf("Image : %s\n", container.Config.Image) + desc += fmt.Sprintf("Cmd : %s\n", strings.Join(container.Config.Cmd, " ")) + desc += fmt.Sprintf("State : %s\n", container.State.String()) + desc += fmt.Sprintf("IP : %s\n", container.NetworkSettings.IPAddress) + desc += fmt.Sprintf("Ports : %v\n", formatPortsMapping(container.NetworkSettings.Ports)) return desc } @@ -219,12 +241,13 @@ func buildContainerView(m model) (string, string) { } state := stateStyle.Render("●") name := choice.name - name = runewidth.Truncate(name, maxItemNameWidth, "...") + name = runewidth.Truncate(name, maxContainerNameWidth, "...") if _, ok := m.selected[i]; ok { check = checkStyle.Render("✔") } + // pad item name, not width + name = padItemName(name) row := fmt.Sprintf("%s %s %s %s", cursor, check, state, name) - padItemWidth(&row, fixedBodyLWidth-10) bodyL += row } @@ -249,8 +272,7 @@ func (m model) View() string { } // title - title := "🐳 Killer Whale" + " " - titleStyle.MarginLeft((m.width / 2) - (lipgloss.Width(title) / 2)) + title := buildTitleView(m) title = titleStyle.Render(title) // join left + right component @@ -262,19 +284,17 @@ func (m model) View() string { // help help := m.help.View(m.keys) - padHelpWidth(&help, m.width, fixedWidth) + padOuterComponent(&help, m.width) // join title + body + log + help final += lipgloss.JoinVertical(lipgloss.Top, body, bottom) - appStyle.MarginLeft((m.width - fixedWidth) / 2) + appStyle.MarginLeft((m.width - fullWidth) / 2) // 0 containers/ image if len(m.containers) == 0 && m.page == pageContainer { - body = bodyStyle.Render("No containers found") - return title + "\n" + titleStyle.Render(body) + "\n" + return buildEmptyBody("\nNo containers found.", title, m.width) } else if len(m.images) == 0 && m.page == pageImage { - body = bodyStyle.Render("No images found") - return title + "\n" + titleStyle.Render(body) + "\n" + return buildEmptyBody("\nNo images found.", title, m.width) } return title + "\n" + appStyle.Render(final) + "\n" + help