diff --git a/tui/bubble.go b/tui/bubble.go index a12a20925..cead1f5bd 100644 --- a/tui/bubble.go +++ b/tui/bubble.go @@ -1,13 +1,11 @@ package tui import ( - "encoding/json" "fmt" - "log" "smoothie/git" "smoothie/tui/bubbles/commits" + "smoothie/tui/bubbles/repo" "smoothie/tui/bubbles/selection" - "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -34,9 +32,10 @@ type Config struct { } type MenuEntry struct { - Name string `json:"name"` - Note string `json:"note"` - Repo string `json:"repo"` + Name string `json:"name"` + Note string `json:"note"` + Repo string `json:"repo"` + bubble *repo.Bubble } type SessionConfig struct { @@ -68,6 +67,7 @@ func NewBubble(cfg *Config, sCfg *SessionConfig) *Bubble { height: sCfg.Height, windowChanges: sCfg.WindowChanges, repoSource: cfg.RepoSource, + repoMenu: make([]MenuEntry, 0), boxes: make([]tea.Model, 2), } b.state = startState @@ -100,9 +100,13 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) { b.height = msg.Height case selection.SelectedMsg: b.activeBox = 1 - cmds = append(cmds, b.getRepoCmd(b.repoMenu[msg.Index].Repo)) + rb := b.repoMenu[msg.Index].bubble + rb.GotoTop() + b.boxes[1] = rb case selection.ActiveMsg: - cmds = append(cmds, b.getRepoCmd(b.repoMenu[msg.Index].Repo)) + rb := b.repoMenu[msg.Index].bubble + rb.GotoTop() + b.boxes[1] = b.repoMenu[msg.Index].bubble } if b.state == loadedState { ab, cmd := b.boxes[b.activeBox].Update(msg) @@ -136,77 +140,7 @@ func (b *Bubble) View() string { s += lipgloss.JoinHorizontal(lipgloss.Top, lb, rb) case errorState: s += errorStyle.Render(fmt.Sprintf("Bummer: %s", b.error)) - default: - s = normalStyle.Render(fmt.Sprintf("Doing something weird %d", b.state)) } content = h + "\n\n" + s + "\n" + f return appBoxStyle.Render(content) } - -func loadConfig(rs *git.RepoSource) (*Config, error) { - cfg := &Config{} - cfg.RepoSource = rs - cr, err := rs.GetRepo("config") - if err != nil { - return nil, fmt.Errorf("cannot load config repo: %s", err) - } - cs, err := cr.LatestFile("config.json") - if err != nil { - return nil, fmt.Errorf("cannot load config.json: %s", err) - } - err = json.Unmarshal([]byte(cs), cfg) - if err != nil { - return nil, fmt.Errorf("bad json in config.json: %s", err) - } - return cfg, nil -} - -func SessionHandler(reposPath string, repoPoll time.Duration) func(ssh.Session) (tea.Model, []tea.ProgramOption) { - rs := git.NewRepoSource(reposPath) - err := createDefaultConfigRepo(rs) - if err != nil { - if err != nil { - log.Fatalf("cannot create config repo: %s", err) - } - } - appCfg, err := loadConfig(rs) - if err != nil { - if err != nil { - log.Printf("cannot load config: %s", err) - } - } - go func() { - for { - time.Sleep(repoPoll) - err := rs.LoadRepos() - if err != nil { - log.Printf("cannot load repos: %s", err) - continue - } - cfg, err := loadConfig(rs) - if err != nil { - if err != nil { - log.Printf("cannot load config: %s", err) - continue - } - } - appCfg = cfg - } - }() - - return func(s ssh.Session) (tea.Model, []tea.ProgramOption) { - if len(s.Command()) == 0 { - pty, changes, active := s.Pty() - if !active { - return nil, nil - } - cfg := &SessionConfig{ - Width: pty.Window.Width, - Height: pty.Window.Height, - WindowChanges: changes, - } - return NewBubble(appCfg, cfg), []tea.ProgramOption{tea.WithAltScreen()} - } - return nil, nil - } -} diff --git a/tui/bubbles/repo/bubble.go b/tui/bubbles/repo/bubble.go index dbfd40e0b..be50cfeaf 100644 --- a/tui/bubbles/repo/bubble.go +++ b/tui/bubbles/repo/bubble.go @@ -50,12 +50,19 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return b, tea.Batch(cmds...) } +func (b *Bubble) GotoTop() { + b.readmeViewport.Viewport.GotoTop() +} + func (b *Bubble) View() string { return b.readmeViewport.View() } func (b *Bubble) setupCmd() tea.Msg { r, err := b.repoSource.GetRepo(b.name) + if err == git.ErrMissingRepo { + return nil + } if err != nil { return ErrMsg{err} } @@ -70,7 +77,7 @@ func (b *Bubble) setupCmd() tea.Msg { if err != nil { return ErrMsg{err} } - b.readmeViewport.Viewport.GotoTop() + b.GotoTop() b.readmeViewport.Viewport.SetContent(md) return nil } diff --git a/tui/commands.go b/tui/commands.go index 0cfaa03ef..a1ebe49c1 100644 --- a/tui/commands.go +++ b/tui/commands.go @@ -1,6 +1,7 @@ package tui import ( + "fmt" "smoothie/tui/bubbles/commits" "smoothie/tui/bubbles/repo" "smoothie/tui/bubbles/selection" @@ -43,8 +44,22 @@ func (b *Bubble) setupCmd() tea.Msg { mes = append(mes, MenuEntry{Name: r.Name, Repo: r.Name}) } } - b.repoMenu = mes + var tmplConfig *Config + h := b.height - verticalPadding - viewportHeightConstant + w := boxRightWidth - 2 for _, me := range mes { + if me.Repo == "config" { + tmplConfig = b.config + } + rb := repo.NewBubble(b.repoSource, me.Repo, w, h, tmplConfig) + initCmd := rb.Init() + msg := initCmd() + switch msg := msg.(type) { + case repo.ErrMsg: + return errMsg{fmt.Errorf("missing %s: %s", me.Repo, msg.Error)} + } + me.bubble = rb + b.repoMenu = append(b.repoMenu, me) rs = append(rs, me.Name) } b.repoSelect = selection.NewBubble(rs) @@ -54,20 +69,8 @@ func (b *Bubble) setupCmd() tea.Msg { boxRightWidth-horizontalPadding-2, b.repoSource.GetCommits(200), ) - msg := b.getRepoCmd("config")() + b.boxes[1] = b.repoMenu[0].bubble b.activeBox = 0 b.state = loadedState - return msg -} - -func (b *Bubble) getRepoCmd(name string) tea.Cmd { - var tmplConfig *Config - if name == "config" { - tmplConfig = b.config - } - h := b.height - verticalPadding - viewportHeightConstant - w := boxRightWidth - 2 - rb := repo.NewBubble(b.repoSource, name, w, h, tmplConfig) - b.boxes[1] = rb - return rb.Init() + return nil } diff --git a/tui/session.go b/tui/session.go new file mode 100644 index 000000000..c00f6674e --- /dev/null +++ b/tui/session.go @@ -0,0 +1,80 @@ +package tui + +import ( + "encoding/json" + "fmt" + "log" + "smoothie/git" + "time" + + tea "github.com/charmbracelet/bubbletea" + "github.com/gliderlabs/ssh" +) + +func SessionHandler(reposPath string, repoPoll time.Duration) func(ssh.Session) (tea.Model, []tea.ProgramOption) { + rs := git.NewRepoSource(reposPath) + err := createDefaultConfigRepo(rs) + if err != nil { + if err != nil { + log.Fatalf("cannot create config repo: %s", err) + } + } + appCfg, err := loadConfig(rs) + if err != nil { + if err != nil { + log.Printf("cannot load config: %s", err) + } + } + go func() { + for { + time.Sleep(repoPoll) + err := rs.LoadRepos() + if err != nil { + log.Printf("cannot load repos: %s", err) + continue + } + cfg, err := loadConfig(rs) + if err != nil { + if err != nil { + log.Printf("cannot load config: %s", err) + continue + } + } + appCfg = cfg + } + }() + + return func(s ssh.Session) (tea.Model, []tea.ProgramOption) { + if len(s.Command()) == 0 { + pty, changes, active := s.Pty() + if !active { + return nil, nil + } + cfg := &SessionConfig{ + Width: pty.Window.Width, + Height: pty.Window.Height, + WindowChanges: changes, + } + return NewBubble(appCfg, cfg), []tea.ProgramOption{tea.WithAltScreen()} + } + return nil, nil + } +} + +func loadConfig(rs *git.RepoSource) (*Config, error) { + cfg := &Config{} + cfg.RepoSource = rs + cr, err := rs.GetRepo("config") + if err != nil { + return nil, fmt.Errorf("cannot load config repo: %s", err) + } + cs, err := cr.LatestFile("config.json") + if err != nil { + return nil, fmt.Errorf("cannot load config.json: %s", err) + } + err = json.Unmarshal([]byte(cs), cfg) + if err != nil { + return nil, fmt.Errorf("bad json in config.json: %s", err) + } + return cfg, nil +}