fix(ui): subtle ui changes

Ayman Bagabas created

* hide help from repo page
* file sizes now appear on the right side

Change summary

ui/components/statusbar/statusbar.go |  4 ++
ui/pages/repo/filesitem.go           | 31 ++++++++++++------------
ui/pages/repo/repo.go                |  6 ++++
ui/styles/styles.go                  | 18 ++++++++++----
ui/ui.go                             | 37 ++++++++++++++++++++++-------
5 files changed, 64 insertions(+), 32 deletions(-)

Detailed changes

ui/components/statusbar/statusbar.go 🔗

@@ -51,13 +51,14 @@ func (s *StatusBar) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 func (s *StatusBar) View() string {
 	st := s.common.Styles
 	w := lipgloss.Width
+	help := st.StatusBarHelp.Render("? Help")
 	key := st.StatusBarKey.Render(s.msg.Key)
 	info := ""
 	if s.msg.Info != "" {
 		info = st.StatusBarInfo.Render(s.msg.Info)
 	}
 	branch := st.StatusBarBranch.Render(s.msg.Branch)
-	maxWidth := s.common.Width - w(key) - w(info) - w(branch)
+	maxWidth := s.common.Width - w(key) - w(info) - w(branch) - w(help)
 	v := truncate.StringWithTail(s.msg.Value, uint(maxWidth-st.StatusBarValue.GetHorizontalFrameSize()), "…")
 	value := st.StatusBarValue.
 		Width(maxWidth).
@@ -68,5 +69,6 @@ func (s *StatusBar) View() string {
 		value,
 		info,
 		branch,
+		help,
 	)
 }

ui/pages/repo/filesitem.go 🔗

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"io"
 	"io/fs"
+	"strings"
 
 	"github.com/charmbracelet/bubbles/key"
 	"github.com/charmbracelet/bubbles/list"
@@ -103,8 +104,9 @@ func (d FileItemDelegate) Render(w io.Writer, m list.Model, index int, listItem
 
 	name := i.Title()
 	size := humanize.Bytes(uint64(i.entry.Size()))
+	sizeLen := lipgloss.Width(size)
 	if i.entry.IsTree() {
-		size = ""
+		size = strings.Repeat(" ", sizeLen)
 		name = s.TreeFileDir.Render(name)
 	}
 	var cs lipgloss.Style
@@ -116,23 +118,20 @@ func (d FileItemDelegate) Render(w io.Writer, m list.Model, index int, listItem
 		cs = s.TreeItemInactive
 		fmt.Fprint(w, s.TreeItemSelector.Render(" "))
 	}
+	sizeStyle := s.TreeFileSize.Copy().
+		Width(8).
+		Align(lipgloss.Right).
+		MarginLeft(1)
 	leftMargin := s.TreeItemSelector.GetMarginLeft() +
 		s.TreeItemSelector.GetWidth() +
 		s.TreeFileMode.GetMarginLeft() +
 		s.TreeFileMode.GetWidth() +
-		cs.GetMarginLeft()
-	rightMargin := s.TreeFileSize.GetMarginLeft() + lipgloss.Width(size)
-	name = common.TruncateString(name, m.Width()-leftMargin-rightMargin)
-	sizeStyle := s.TreeFileSize.Copy().
-		Width(m.Width() -
-			leftMargin -
-			s.TreeFileSize.GetMarginLeft() -
-			lipgloss.Width(name)).
-		Align(lipgloss.Right)
-	if index == m.Index() {
-		sizeStyle = sizeStyle.Bold(true)
-	}
-	fmt.Fprint(w, s.TreeFileMode.Render(mode.String())+
-		cs.Render(name)+
-		sizeStyle.Render(size))
+		cs.GetMarginLeft() +
+		sizeStyle.GetHorizontalFrameSize()
+	name = common.TruncateString(name, m.Width()-leftMargin)
+	fmt.Fprint(w,
+		s.TreeFileMode.Render(mode.String()),
+		sizeStyle.Render(size),
+		cs.Render(name),
+	)
 }

ui/pages/repo/repo.go 🔗

@@ -289,11 +289,15 @@ func (r *Repo) updateStatusBarCmd() tea.Msg {
 	}
 	value := r.boxes[r.activeTab].(statusbar.Model).StatusBarValue()
 	info := r.boxes[r.activeTab].(statusbar.Model).StatusBarInfo()
+	ref := ""
+	if r.ref != nil {
+		ref = r.ref.Name().Short()
+	}
 	return statusbar.StatusBarMsg{
 		Key:    r.selectedRepo.Repo(),
 		Value:  value,
 		Info:   info,
-		Branch: fmt.Sprintf(" %s", r.ref.Name().Short()),
+		Branch: fmt.Sprintf(" %s", ref),
 	}
 }
 

ui/styles/styles.go 🔗

@@ -91,6 +91,7 @@ type Styles struct {
 	StatusBarValue  lipgloss.Style
 	StatusBarInfo   lipgloss.Style
 	StatusBarBranch lipgloss.Style
+	StatusBarHelp   lipgloss.Style
 
 	Tabs         lipgloss.Style
 	TabInactive  lipgloss.Style
@@ -110,8 +111,9 @@ func DefaultStyles() *Styles {
 
 	s.Header = lipgloss.NewStyle().
 		Foreground(lipgloss.Color("15")).
-		Align(lipgloss.Right).
+		Align(lipgloss.Left).
 		Height(1).
+		MarginBottom(1).
 		Bold(true)
 
 	s.Menu = lipgloss.NewStyle().
@@ -199,7 +201,7 @@ func DefaultStyles() *Styles {
 	s.RepoHeader = lipgloss.NewStyle().
 		Height(2).
 		Border(lipgloss.NormalBorder(), false, false, true, false).
-		BorderForeground(lipgloss.Color("241"))
+		BorderForeground(lipgloss.Color("238"))
 
 	s.RepoHeaderName = lipgloss.NewStyle().
 		Foreground(lipgloss.Color("15")).
@@ -210,6 +212,7 @@ func DefaultStyles() *Styles {
 		Foreground(lipgloss.Color("15"))
 
 	s.Footer = lipgloss.NewStyle().
+		MarginTop(1).
 		Padding(0, 1).
 		Height(1)
 
@@ -356,8 +359,8 @@ func DefaultStyles() *Styles {
 
 	s.StatusBarValue = lipgloss.NewStyle().
 		Padding(0, 1).
-		Background(lipgloss.Color("#373737")).
-		Foreground(lipgloss.Color("#F1F1F1"))
+		Background(lipgloss.Color("235")).
+		Foreground(lipgloss.Color("243"))
 
 	s.StatusBarInfo = lipgloss.NewStyle().
 		Padding(0, 1).
@@ -369,6 +372,11 @@ func DefaultStyles() *Styles {
 		Background(lipgloss.Color("#6E6ED8")).
 		Foreground(lipgloss.Color("#F1F1F1"))
 
+	s.StatusBarHelp = lipgloss.NewStyle().
+		Padding(0, 1).
+		Background(lipgloss.Color("237")).
+		Foreground(lipgloss.Color("243"))
+
 	s.Tabs = lipgloss.NewStyle()
 
 	s.TabInactive = lipgloss.NewStyle().
@@ -381,7 +389,7 @@ func DefaultStyles() *Styles {
 	s.TabSeparator = lipgloss.NewStyle().
 		SetString("│").
 		Padding(0, 1).
-		Foreground(lipgloss.Color("241"))
+		Foreground(lipgloss.Color("238"))
 
 	return s
 }

ui/ui.go 🔗

@@ -45,6 +45,7 @@ type UI struct {
 	state       sessionState
 	header      *header.Header
 	footer      *footer.Footer
+	showFooter  bool
 	error       error
 }
 
@@ -62,22 +63,28 @@ func New(cfg *config.Config, s ssh.Session, c common.Common, initialRepo string)
 		state:       startState,
 		header:      h,
 		initialRepo: initialRepo,
+		showFooter:  true,
 	}
 	ui.footer = footer.New(c, ui)
 	return ui
 }
 
 func (ui *UI) getMargins() (wm, hm int) {
-	wm = ui.common.Styles.App.GetHorizontalFrameSize()
-	hm = ui.common.Styles.App.GetVerticalFrameSize() +
-		ui.common.Styles.Footer.GetVerticalFrameSize() +
-		ui.footer.Height()
+	style := ui.common.Styles.App.Copy()
 	switch ui.activePage {
 	case selectionPage:
 		hm += ui.common.Styles.Header.GetHeight() +
 			ui.common.Styles.Header.GetVerticalFrameSize()
 	case repoPage:
 	}
+	wm += style.GetHorizontalFrameSize()
+	hm += style.GetVerticalFrameSize()
+	if ui.showFooter {
+		// NOTE: we don't use the footer's style to determine the margins
+		// because footer.Height() is the height of the footer after applying
+		// the styles.
+		hm += ui.footer.Height()
+	}
 	return
 }
 
@@ -175,16 +182,26 @@ func (ui *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			case key.Matches(msg, ui.common.KeyMap.Back) && ui.error != nil:
 				ui.error = nil
 				ui.state = loadedState
+				// Always show the footer on error.
+				ui.showFooter = true
 			case key.Matches(msg, ui.common.KeyMap.Help):
 				ui.footer.SetShowAll(!ui.footer.ShowAll())
+				// Show the footer when on repo page and shot all help.
+				if ui.activePage == repoPage {
+					ui.showFooter = !ui.showFooter
+				}
 			case key.Matches(msg, ui.common.KeyMap.Quit):
 				return ui, tea.Quit
 			case ui.activePage == repoPage && key.Matches(msg, ui.common.KeyMap.Back):
 				ui.activePage = selectionPage
+				// Always show the footer on selection page.
+				ui.showFooter = true
 			}
 		}
 	case repo.RepoMsg:
 		ui.activePage = repoPage
+		// Show the footer on repo page if show all is set.
+		ui.showFooter = ui.footer.ShowAll()
 	case common.ErrorMsg:
 		ui.error = msg
 		ui.state = errorState
@@ -223,7 +240,6 @@ func (ui *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 func (ui *UI) View() string {
 	var view string
 	wm, hm := ui.getMargins()
-	footer := ui.footer.View()
 	style := ui.common.Styles.App.Copy()
 	switch ui.state {
 	case startState:
@@ -252,11 +268,14 @@ func (ui *UI) View() string {
 		)
 	case repoPage:
 	}
-	return style.Render(
-		lipgloss.JoinVertical(lipgloss.Bottom,
+	if ui.showFooter {
+		view = lipgloss.JoinVertical(lipgloss.Bottom,
 			view,
-			footer,
-		),
+			ui.footer.View(),
+		)
+	}
+	return style.Render(
+		view,
 	)
 }