ui.go

  1package ui
  2
  3import (
  4	"github.com/charmbracelet/bubbles/key"
  5	tea "github.com/charmbracelet/bubbletea"
  6	"github.com/charmbracelet/soft-serve/ui/common"
  7	"github.com/charmbracelet/soft-serve/ui/pages/selection"
  8	"github.com/charmbracelet/soft-serve/ui/session"
  9)
 10
 11type sessionState int
 12
 13const (
 14	startState sessionState = iota
 15	errorState
 16	loadedState
 17)
 18
 19type UI struct {
 20	s          session.Session
 21	common     *common.Common
 22	pages      []tea.Model
 23	activePage int
 24	state      sessionState
 25}
 26
 27func New(s session.Session, common *common.Common, initialRepo string) *UI {
 28	ui := &UI{
 29		s:          s,
 30		common:     common,
 31		pages:      make([]tea.Model, 2), // selection & repo
 32		activePage: 0,
 33		state:      startState,
 34	}
 35	return ui
 36}
 37
 38func (ui *UI) Init() tea.Cmd {
 39	items := make([]string, 0)
 40	cfg := ui.s.Config()
 41	for _, r := range cfg.Repos {
 42		items = append(items, r.Name)
 43	}
 44	for _, r := range cfg.Source.AllRepos() {
 45		exists := false
 46		for _, i := range items {
 47			if i == r.Name() {
 48				exists = true
 49				break
 50			}
 51		}
 52		if !exists {
 53			items = append(items, r.Name())
 54		}
 55	}
 56	ui.pages[0] = selection.New(ui.s, ui.common)
 57	ui.pages[1] = selection.New(ui.s, ui.common)
 58	ui.state = loadedState
 59	return ui.pages[ui.activePage].Init()
 60}
 61
 62func (ui *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 63	cmds := make([]tea.Cmd, 0)
 64	switch msg := msg.(type) {
 65	case tea.WindowSizeMsg:
 66		for i, p := range ui.pages {
 67			m, cmd := p.Update(msg)
 68			ui.pages[i] = m
 69			if cmd != nil {
 70				cmds = append(cmds, cmd)
 71			}
 72		}
 73	case tea.KeyMsg:
 74		switch {
 75		case key.Matches(msg, ui.common.Keymap.Quit):
 76			return ui, tea.Quit
 77		default:
 78			m, cmd := ui.pages[ui.activePage].Update(msg)
 79			ui.pages[ui.activePage] = m
 80			if cmd != nil {
 81				cmds = append(cmds, cmd)
 82			}
 83		}
 84	default:
 85		m, cmd := ui.pages[ui.activePage].Update(msg)
 86		ui.pages[ui.activePage] = m
 87		if cmd != nil {
 88			cmds = append(cmds, cmd)
 89		}
 90	}
 91	return ui, tea.Batch(cmds...)
 92}
 93
 94func (ui *UI) View() string {
 95	switch ui.state {
 96	case startState:
 97		return "Loading..."
 98	case errorState:
 99		return "Error"
100	case loadedState:
101		return ui.common.Styles.App.Render(ui.pages[ui.activePage].View())
102	default:
103		return "Unknown state :/ this is a bug!"
104	}
105}