Skip to content

Commit

Permalink
Generally "smooth" out style and layout
Browse files Browse the repository at this point in the history
  • Loading branch information
meowgorithm committed Aug 19, 2021
1 parent 7456678 commit 6c1fa6c
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 98 deletions.
84 changes: 62 additions & 22 deletions tui/bubble.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package tui

import (
"fmt"
"io"
"smoothie/git"
"smoothie/tui/bubbles/commits"
"smoothie/tui/bubbles/repo"
Expand Down Expand Up @@ -91,7 +90,7 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.String() {
case "q", "ctrl+c":
return b, tea.Quit
case "tab":
case "tab", "shift+tab":
b.activeBox = (b.activeBox + 1) % 2
case "h", "left":
if b.activeBox > 0 {
Expand All @@ -118,6 +117,7 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, cmd)
}
}
// XXX: maybe propagate size changes to child bubbles (particularly height)
case selection.SelectedMsg:
b.activeBox = 1
rb := b.repoMenu[msg.Index].bubble
Expand All @@ -138,48 +138,88 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return b, tea.Batch(cmds...)
}

func (b *Bubble) viewForBox(i int, width int, height int) string {
var ls lipgloss.Style
if i == b.activeBox {
ls = activeBoxStyle.Copy()
} else {
ls = inactiveBoxStyle.Copy()
}
ls.Width(width)
if height > 0 {
ls.Height(height).MarginBottom(3)
func (b *Bubble) viewForBox(i int) string {
box := b.boxes[i]
isActive := i == b.activeBox
var s lipgloss.Style
var menuHeightFix int // TODO: figure out why we need this
switch box.(type) {
case *selection.Bubble:
menuHeightFix = 1
if isActive {
s = menuActiveStyle
break
}
s = menuStyle
case *repo.Bubble:
if isActive {
s = contentBoxActiveStyle
} else {
s = contentBoxStyle
}
const repoWidthFix = 1 // TODO: figure out why we need this
w := b.width -
lipgloss.Width(b.viewForBox(0)) -
appBoxStyle.GetHorizontalFrameSize() -
s.GetHorizontalFrameSize() + repoWidthFix
s = s.Copy().Width(w)
default:
panic(fmt.Sprintf("unknown box type %T", box))
}
return ls.Render(b.boxes[i].View())
h := b.height -
lipgloss.Height(b.headerView()) -
lipgloss.Height(b.footerView()) -
s.GetVerticalFrameSize() -
appBoxStyle.GetVerticalFrameSize() +
menuHeightFix
return s.Copy().Height(h).Render(box.View())
}

func (b Bubble) footerView(w io.Writer) {
func (b Bubble) headerView() string {
w := b.width - appBoxStyle.GetHorizontalFrameSize()
return headerStyle.Copy().Width(w).Render(b.config.Name)
}

func (b Bubble) footerView() string {
w := &strings.Builder{}
h := []helpEntry{
{"tab", "section"},
{"↑/↓", "navigate"},
{"q", "quit"},
}
if _, ok := b.boxes[b.activeBox].(*repo.Bubble); ok {
h = append(h[:2], helpEntry{"f/b", "pgup/pgdown"}, h[2])
}
for i, v := range h {
fmt.Fprint(w, v)
if i != len(h)-1 {
fmt.Fprint(w, helpDivider)
}
}
return footerStyle.Render(w.String())
}

func (b *Bubble) View() string {
func (b Bubble) View() string {
s := strings.Builder{}
w := b.width - 3
s.WriteString(headerStyle.Width(w - 2).Render(b.config.Name))
s.WriteString(b.headerView())
s.WriteRune('\n')
switch b.state {
case loadedState:
lb := b.viewForBox(0, boxLeftWidth, 0)
rb := b.viewForBox(1, b.width-boxLeftWidth-10, b.height-8)
lb := b.viewForBox(0)
rb := b.viewForBox(1)
s.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, lb, rb))
case errorState:
s.WriteString(errorStyle.Render(fmt.Sprintf("Bummer: %s", b.error)))
}
s.WriteRune('\n')
b.footerView(&s)
return appBoxStyle.Width(w).Height(b.height).Render(s.String())
s.WriteString(b.footerView())
return appBoxStyle.Render(s.String())
}

type helpEntry struct {
key string
val string
}

func (h helpEntry) String() string {
return fmt.Sprintf("%s %s", helpKeyStyle.Render(h.key), helpValueStyle.Render(h.val))
}
46 changes: 33 additions & 13 deletions tui/bubbles/repo/bubble.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import (
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/glamour"
"github.com/charmbracelet/lipgloss"
)

const glamourMaxWidth = 120

type ErrMsg struct {
Error error
}
Expand All @@ -28,21 +31,18 @@ type Bubble struct {
}

func NewBubble(rs *git.RepoSource, name string, width, wm, height, hm int, tmp interface{}) *Bubble {
return &Bubble{
b := &Bubble{
templateObject: tmp,
repoSource: rs,
name: name,
height: height,
width: width,
heightMargin: hm,
widthMargin: wm,
readmeViewport: &ViewportBubble{
Viewport: &viewport.Model{
Width: width - wm,
Height: height - hm,
},
Viewport: &viewport.Model{},
},
}
b.SetSize(width, height)
return b
}

func (b *Bubble) Init() tea.Cmd {
Expand All @@ -53,8 +53,10 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
b.readmeViewport.Viewport.Width = msg.Width - b.widthMargin
b.readmeViewport.Viewport.Height = msg.Height - b.heightMargin
b.SetSize(msg.Width, msg.Height)
// XXX: if we find that longer readmes take more than a few
// milliseconds to render we may need to move Glamour rendering into a
// command.
md, err := b.glamourize(b.readme)
if err != nil {
return b, nil
Expand All @@ -63,12 +65,17 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
rv, cmd := b.readmeViewport.Update(msg)
b.readmeViewport = rv.(*ViewportBubble)
if cmd != nil {
cmds = append(cmds, cmd)
}
cmds = append(cmds, cmd)
return b, tea.Batch(cmds...)
}

func (b *Bubble) SetSize(w, h int) {
b.width = w
b.height = h
b.readmeViewport.Viewport.Width = w - b.widthMargin
b.readmeViewport.Viewport.Height = h - b.heightMargin
}

func (b *Bubble) GotoTop() {
b.readmeViewport.Viewport.GotoTop()
}
Expand Down Expand Up @@ -116,9 +123,14 @@ func (b *Bubble) templatize(mdt string) (string, error) {
}

func (b *Bubble) glamourize(md string) (string, error) {
// TODO: read gaps in appropriate style to remove the magic number below.
w := b.width - b.widthMargin - 2
if w > glamourMaxWidth {
w = glamourMaxWidth
}
tr, err := glamour.NewTermRenderer(
glamour.WithStandardStyle("dark"),
glamour.WithWordWrap(b.width-b.widthMargin),
glamour.WithWordWrap(w),
)

if err != nil {
Expand All @@ -128,5 +140,13 @@ func (b *Bubble) glamourize(md string) (string, error) {
if err != nil {
return "", err
}
// Enforce a maximum width for cases when glamour lines run long.
//
// TODO: use Reflow's unconditional wrapping to force-wrap long lines. This
// should utlimately happen as a Glamour option.
//
// See:
// https://github.com/muesli/reflow#unconditional-wrapping
mdt = lipgloss.NewStyle().MaxWidth(w).Render(mdt)
return mdt, nil
}
14 changes: 10 additions & 4 deletions tui/bubbles/selection/bubble.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ type ActiveMsg struct {
type Bubble struct {
NormalStyle lipgloss.Style
SelectedStyle lipgloss.Style
Cursor string
Items []string
SelectedItem int
}

func NewBubble(items []string) *Bubble {
func NewBubble(items []string, normalStyle, selectedStyle lipgloss.Style, cursor string) *Bubble {
return &Bubble{
NormalStyle: normalStyle,
SelectedStyle: selectedStyle,
Cursor: cursor,
Items: items,
}
}
Expand All @@ -34,13 +36,17 @@ func (b *Bubble) Init() tea.Cmd {
return nil
}

func (b *Bubble) View() string {
func (b Bubble) View() string {
s := ""
for i, item := range b.Items {
if i == b.SelectedItem {
s += b.SelectedStyle.Render(item) + "\n"
s += b.Cursor
s += b.SelectedStyle.Render(item)
} else {
s += b.NormalStyle.Render(item) + "\n"
s += b.NormalStyle.Render(item)
}
if i < len(b.Items)-1 {
s += "\n"
}
}
return s
Expand Down
11 changes: 0 additions & 11 deletions tui/bubbles/selection/style.go

This file was deleted.

20 changes: 12 additions & 8 deletions tui/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package tui

import (
"fmt"
"smoothie/tui/bubbles/commits"
"smoothie/tui/bubbles/repo"
"smoothie/tui/bubbles/selection"

Expand Down Expand Up @@ -49,7 +48,10 @@ func (b *Bubble) setupCmd() tea.Msg {
if me.Repo == "config" {
tmplConfig = b.config
}
rb := repo.NewBubble(b.repoSource, me.Repo, b.width, boxLeftWidth+12, b.height, 12, tmplConfig)
width := b.width
boxLeftWidth := menuStyle.GetWidth() + menuStyle.GetHorizontalFrameSize()
const heightMargin = 12 // TODO: figure out why this needs to be 12
rb := repo.NewBubble(b.repoSource, me.Repo, width, boxLeftWidth, b.height, heightMargin, tmplConfig)
initCmd := rb.Init()
msg := initCmd()
switch msg := msg.(type) {
Expand All @@ -60,13 +62,15 @@ func (b *Bubble) setupCmd() tea.Msg {
b.repoMenu = append(b.repoMenu, me)
rs = append(rs, me.Name)
}
b.repoSelect = selection.NewBubble(rs)
b.repoSelect = selection.NewBubble(rs, menuItemStyle, selectedMenuItemStyle, menuCursor.String())
b.boxes[0] = b.repoSelect
b.commitsLog = commits.NewBubble(
b.height-verticalPadding-2,
boxRightWidth-horizontalPadding-2,
b.repoSource.GetCommits(200),
)
/*
b.commitsLog = commits.NewBubble(
b.height-verticalPadding-2,
boxRightWidth-horizontalPadding-2,
b.repoSource.GetCommits(200),
)
*/
ir := -1
if b.initialRepo != "" {
for i, me := range b.repoMenu {
Expand Down
12 changes: 0 additions & 12 deletions tui/help.go

This file was deleted.

Loading

0 comments on commit 6c1fa6c

Please sign in to comment.