💄 style(ui): Extract styling/views to seperate file
This commit is contained in:
parent
7212aa31f4
commit
6dd925467a
4 changed files with 90 additions and 77 deletions
12
install.go
12
install.go
|
@ -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
85
main.go
|
@ -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
68
styles.go
Normal 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)
|
||||||
|
}
|
2
test.sh
2
test.sh
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue