💄 style(ui): Extract styling/views to seperate file

This commit is contained in:
punkfairie 2024-09-08 11:29:39 -07:00
parent 7212aa31f4
commit 6dd925467a
4 changed files with 90 additions and 77 deletions

View file

@ -2,8 +2,10 @@ package main
import ( import (
"bufio" "bufio"
"fmt"
"io" "io"
"os/exec" "os/exec"
"time"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
) )
@ -12,8 +14,12 @@ type cmdMsg string
type cmdDoneMsg struct{} type cmdDoneMsg struct{}
func installPackage(sub chan string) tea.Cmd { func (m menu) installPackage() tea.Cmd {
return func() tea.Msg { return func() tea.Msg {
pkg := m.order[m.current]
m.appendOutput(fmt.Sprintf("Installing %s", pkg))
cmd := exec.Command("./test.sh") cmd := exec.Command("./test.sh")
out, err := cmd.StdoutPipe() out, err := cmd.StdoutPipe()
if err != nil { if err != nil {
@ -29,6 +35,8 @@ func installPackage(sub chan string) tea.Cmd {
line, _, err := buf.ReadLine() line, _, err := buf.ReadLine()
if err == io.EOF { if err == io.EOF {
m.appendOutput(fmt.Sprintf("Finished installing %s!", pkg))
time.Sleep(3 * time.Second)
return cmdDoneMsg{} return cmdDoneMsg{}
} }
@ -36,7 +44,7 @@ func installPackage(sub chan string) tea.Cmd {
return errMsg{err} return errMsg{err}
} }
sub <- string(line) m.sub <- string(line)
} }
} }
} }

85
main.go
View file

@ -11,8 +11,7 @@ import (
"github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/spinner"
"github.com/charmbracelet/bubbles/viewport" "github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
gloss "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/list"
"golang.org/x/term" "golang.org/x/term"
) )
@ -38,7 +37,7 @@ const (
func initialModel() menu { func initialModel() menu {
s := spinner.New() s := spinner.New()
s.Spinner = spinner.MiniDot s.Spinner = spinner.MiniDot
s.Style = gloss.NewStyle().Foreground(gloss.Color("3")) s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("3"))
width, height, _ := term.GetSize(int(os.Stdout.Fd())) width, height, _ := term.GetSize(int(os.Stdout.Fd()))
m := menu{ m := menu{
@ -54,8 +53,6 @@ func initialModel() menu {
viewport: viewport.New(0, 30), viewport: viewport.New(0, 30),
} }
m.appendOutput("Running...")
return m return m
} }
@ -110,14 +107,16 @@ func (m menu) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case softwareListMsg: case softwareListMsg:
m.order = msg m.order = msg
cmds = append(cmds, installPackage(m.sub), waitForCmdResponses(m.sub)) cmds = append(cmds, m.installPackage(), waitForCmdResponses(m.sub))
case cmdMsg: case cmdMsg:
m.appendOutput(string(msg)) m.appendOutput(string(msg))
cmds = append(cmds, waitForCmdResponses(m.sub)) cmds = append(cmds, waitForCmdResponses(m.sub))
case cmdDoneMsg: case cmdDoneMsg:
m.appendOutput("Done!!") m.current++
m.output = new(string)
cmds = append(cmds, m.installPackage(), waitForCmdResponses(m.sub))
case tea.KeyMsg: case tea.KeyMsg:
switch { switch {
@ -132,8 +131,8 @@ func (m menu) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tea.WindowSizeMsg: case tea.WindowSizeMsg:
m.setDimensions() m.setDimensions()
m.viewport.Width = gloss.Width(m.mainView()) m.viewport.Width = lipgloss.Width(m.mainView())
m.viewport.Height = gloss.Height(m.mainView()) m.viewport.Height = lipgloss.Height(m.mainView())
case errMsg: case errMsg:
m.appendOutput("Error: " + msg.Error()) m.appendOutput("Error: " + msg.Error())
@ -145,70 +144,8 @@ func (m menu) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Batch(cmds...) return m, tea.Batch(cmds...)
} }
var borderStyle = gloss.NewStyle().
BorderStyle(gloss.RoundedBorder()).
BorderForeground(gloss.Color("5")).
Padding(0, 1)
var topPadding = 1
func (m menu) mainView() string {
mainWidth := int(float64(m.width) * 0.65)
mainStyle := borderStyle.
Width(mainWidth).
Height(m.calcInnerSidebarHeight() - 2)
mainContent := m.viewport.View()
return mainStyle.Render(mainContent)
}
func (m menu) calcInnerSidebarHeight() int {
return m.height - 3 - gloss.Height(m.helpView()) - topPadding
}
func (m menu) sidebarView() string {
sidebarStyle := borderStyle.
Width(int(float64(m.width) * 0.3))
softwareListEnumerator := func(l list.Items, i int) string {
if m.current == i {
return m.spinner.View()
} else if m.current > i {
return ""
}
return ""
}
software := list.New().Enumerator(softwareListEnumerator)
sidebarHeight := m.calcInnerSidebarHeight()
if len(m.order) > 0 {
start := max(m.current-10, 0)
end := min(start+sidebarHeight, len(m.order))
if (end - start) < sidebarHeight {
start = (len(m.order) - sidebarHeight)
}
for _, item := range m.order[start:end] {
software.Item(item)
}
}
sidebarContent := software.String()
return sidebarStyle.Render(sidebarContent)
}
func (m menu) helpView() string {
return m.help.View(m.keys)
}
func (m menu) View() string { func (m menu) View() string {
content := gloss.JoinHorizontal(gloss.Top, m.mainView(), m.sidebarView()) content := lipgloss.JoinHorizontal(lipgloss.Top, m.mainView(), m.sidebarView())
top := strings.Repeat("\n", topPadding) top := strings.Repeat("\n", topPadding)
last := "" last := ""
@ -216,9 +153,9 @@ func (m menu) View() string {
last = "\n" last = "\n"
} }
page := gloss.JoinVertical(gloss.Left, top, content, m.helpView(), last) page := lipgloss.JoinVertical(lipgloss.Left, top, content, m.helpView(), last)
return gloss.PlaceHorizontal(m.width, gloss.Center, page) return lipgloss.PlaceHorizontal(m.width, lipgloss.Center, page)
} }
func main() { func main() {

68
styles.go Normal file
View file

@ -0,0 +1,68 @@
package main
import (
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/list"
)
var borderStyle = lipgloss.NewStyle().
BorderStyle(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("5")).
Padding(0, 1)
var topPadding = 1
func (m menu) mainView() string {
mainWidth := int(float64(m.width) * 0.65)
mainStyle := borderStyle.
Width(mainWidth).
Height(m.calcInnerSidebarHeight() - 2)
mainContent := m.viewport.View()
return mainStyle.Render(mainContent)
}
func (m menu) calcInnerSidebarHeight() int {
return m.height - 3 - lipgloss.Height(m.helpView()) - topPadding
}
func (m menu) sidebarView() string {
sidebarStyle := borderStyle.
Width(int(float64(m.width) * 0.3))
softwareListEnumerator := func(l list.Items, i int) string {
if m.current == i {
return m.spinner.View()
} else if m.current > i {
return ""
}
return ""
}
software := list.New().Enumerator(softwareListEnumerator)
sidebarHeight := m.calcInnerSidebarHeight()
if len(m.order) > 0 {
start := max(m.current-10, 0)
end := min(start+sidebarHeight, len(m.order))
if (end - start) < sidebarHeight {
start = (len(m.order) - sidebarHeight)
}
for _, item := range m.order[start:end] {
software.Item(item)
}
}
sidebarContent := software.String()
return sidebarStyle.Render(sidebarContent)
}
func (m menu) helpView() string {
return m.help.View(m.keys)
}

View file

@ -2,7 +2,7 @@
i=0 i=0
while [ $i -le 200 ]; do while [ $i -le 30 ]; do
printf '%s line\n' "$i" printf '%s line\n' "$i"
i=$((i + 1)) i=$((i + 1))
sleep .1 sleep .1