Detailed changes
@@ -3,10 +3,10 @@ package tui
import (
"fmt"
"smoothie/git"
- "smoothie/tui/bubbles/commits"
"time"
tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
"github.com/gliderlabs/ssh"
)
@@ -21,14 +21,16 @@ const (
)
type Model struct {
- state sessionState
- error string
- info string
- width int
- height int
- windowChanges <-chan ssh.Window
- repoSource *git.RepoSource
- commitTimeline *commits.Bubble
+ state sessionState
+ error string
+ info string
+ width int
+ height int
+ windowChanges <-chan ssh.Window
+ repoSource *git.RepoSource
+ repos []*git.Repo
+ activeBubble int
+ bubbles []tea.Model
}
func NewModel(width int, height int, windowChanges <-chan ssh.Window, repoSource *git.RepoSource) *Model {
@@ -37,6 +39,7 @@ func NewModel(width int, height int, windowChanges <-chan ssh.Window, repoSource
height: height,
windowChanges: windowChanges,
repoSource: repoSource,
+ bubbles: make([]tea.Model, 2),
}
m.state = startState
return m
@@ -56,9 +59,8 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.String() {
case "q", "ctrl+c":
return m, tea.Quit
- case "j", "k", "up", "down":
- _, cmd := m.commitTimeline.Update(msg)
- cmds = append(cmds, cmd)
+ case "tab":
+ m.activeBubble = (m.activeBubble + 1) % 2
}
case errMsg:
m.error = msg.Error()
@@ -71,11 +73,27 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
- m.commitTimeline.Height = msg.Height
+ }
+ if m.state == loadedState {
+ b, cmd := m.bubbles[m.activeBubble].Update(msg)
+ m.bubbles[m.activeBubble] = b
+ if cmd != nil {
+ cmds = append(cmds, cmd)
+ }
}
return m, tea.Batch(cmds...)
}
+func (m *Model) viewForBubble(i int, width int) string {
+ var ls lipgloss.Style
+ if i == m.activeBubble {
+ ls = activeBoxStyle.Width(width)
+ } else {
+ ls = inactiveBoxStyle.Width(width)
+ }
+ return ls.Render(m.bubbles[i].View())
+}
+
func (m *Model) View() string {
pad := 6
h := headerStyle.Width(m.width - pad).Render("Charm Beta")
@@ -84,7 +102,9 @@ func (m *Model) View() string {
content := ""
switch m.state {
case loadedState:
- s += m.commitTimeline.View()
+ lb := m.viewForBubble(0, 25)
+ rb := m.viewForBubble(1, 84)
+ s += lipgloss.JoinHorizontal(lipgloss.Top, lb, rb)
case errorState:
s += errorStyle.Render(fmt.Sprintf("Bummer: %s", m.error))
default:
@@ -62,7 +62,7 @@ func (b *Bubble) renderCommit(rc git.RepoCommit) string {
s += " "
s += commitAuthorEmailStyle.Render(rc.Commit.Author.Email)
s += " "
- return commitBoxStyle.Width(b.viewport.Height).Render(s)
+ return commitBoxStyle.Width(b.viewport.Width).Render(s)
}
func (b *Bubble) View() string {
@@ -0,0 +1,70 @@
+package selection
+
+import (
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
+)
+
+type SelectedMsg struct {
+ Name string
+ Index int
+}
+
+type Bubble struct {
+ NormalStyle lipgloss.Style
+ SelectedStyle lipgloss.Style
+ Items []string
+ selectedItem int
+}
+
+func NewBubble(items []string) *Bubble {
+ return &Bubble{
+ NormalStyle: normalStyle,
+ SelectedStyle: selectedStyle,
+ Items: items,
+ selectedItem: -1,
+ }
+}
+
+func (b *Bubble) Init() tea.Cmd {
+ return nil
+}
+
+func (b *Bubble) View() string {
+ s := ""
+ for i, item := range b.Items {
+ if i == b.selectedItem {
+ s += b.SelectedStyle.Render(item) + "\n"
+ } else {
+ s += b.NormalStyle.Render(item) + "\n"
+ }
+ }
+ return s
+}
+
+func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ cmds := make([]tea.Cmd, 0)
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ switch msg.String() {
+ case "k", "up":
+ if b.selectedItem > 0 {
+ b.selectedItem--
+ }
+ case "j", "down":
+ if b.selectedItem < len(b.Items)-1 {
+ b.selectedItem++
+ }
+ case "enter":
+ cmds = append(cmds, b.sendMessage)
+ }
+ }
+ return b, tea.Batch(cmds...)
+}
+
+func (b *Bubble) sendMessage() tea.Msg {
+ return SelectedMsg{
+ Name: b.Items[b.selectedItem],
+ Index: b.selectedItem,
+ }
+}
@@ -0,0 +1,11 @@
+package selection
+
+import (
+ "github.com/charmbracelet/lipgloss"
+)
+
+var normalStyle = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#FFFFFF"))
+
+var selectedStyle = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#714C7B"))
@@ -2,6 +2,7 @@ package tui
import (
"smoothie/tui/bubbles/commits"
+ "smoothie/tui/bubbles/selection"
tea "github.com/charmbracelet/bubbletea"
)
@@ -23,7 +24,13 @@ func (m *Model) windowChangesCmd() tea.Msg {
}
func (m *Model) loadGitCmd() tea.Msg {
- m.commitTimeline = commits.NewBubble(m.height, 2, 80, m.repoSource.GetCommits(200))
+ rs := make([]string, 0)
+ for _, r := range m.repoSource.AllRepos() {
+ rs = append(rs, r.Name)
+ }
+ m.bubbles[0] = selection.NewBubble(rs)
+ m.bubbles[1] = commits.NewBubble(m.height, 7, 80, m.repoSource.GetCommits(200))
+ m.activeBubble = 0
m.state = loadedState
return nil
}
@@ -9,6 +9,18 @@ var appBoxStyle = lipgloss.NewStyle().
PaddingRight(2).
MarginBottom(1)
+var inactiveBoxStyle = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#606060")).
+ BorderStyle(lipgloss.RoundedBorder()).
+ BorderForeground(lipgloss.Color("#303030")).
+ Padding(1)
+
+var activeBoxStyle = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#FFFFFF")).
+ BorderStyle(lipgloss.RoundedBorder()).
+ BorderForeground(lipgloss.Color("#714C7B")).
+ Padding(1)
+
var headerStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#670083")).
Align(lipgloss.Right).