more idiomatic setup of tui

This commit is contained in:
Erik Winter 2023-12-24 10:16:11 +01:00
parent 2adf65d5bf
commit a506bdcd10
5 changed files with 78 additions and 58 deletions

View File

@ -11,13 +11,12 @@ import (
) )
type baseModel struct { type baseModel struct {
config Config
emdb *client.EMDB emdb *client.EMDB
tmdb *client.TMDB tmdb *client.TMDB
Tabs []string Tabs []string
TabContent tea.Model TabContent tea.Model
activeTab int activeTab int
ready bool initialized bool
logger *Logger logger *Logger
logViewport viewport.Model logViewport viewport.Model
windowSize tea.WindowSizeMsg windowSize tea.WindowSizeMsg
@ -25,6 +24,22 @@ type baseModel struct {
tabSize tea.WindowSizeMsg tabSize tea.WindowSizeMsg
} }
func NewBaseModel(emdb *client.EMDB, tmdb *client.TMDB, logger *Logger) (tea.Model, tea.Cmd) {
logViewport := viewport.New(0, 0)
logViewport.KeyMap = viewport.KeyMap{}
m := baseModel{
emdb: emdb,
tmdb: tmdb,
Tabs: []string{"Erik's movie database", "The movie database"},
logViewport: logViewport,
logger: logger,
}
m.setSize()
return m, nil
}
func (m baseModel) Init() tea.Cmd { func (m baseModel) Init() tea.Cmd {
return nil return nil
} }
@ -47,8 +62,10 @@ func (m baseModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
case tea.WindowSizeMsg: case tea.WindowSizeMsg:
m.windowSize = msg m.windowSize = msg
if !m.ready { if !m.initialized {
m.initialModel() m.TabContent, cmd = NewEMDBTab(m.emdb, m.logger)
cmds = append(cmds, cmd)
m.initialized = true
} }
m.Log(fmt.Sprintf("new window size: %dx%d", msg.Width, msg.Height)) m.Log(fmt.Sprintf("new window size: %dx%d", msg.Width, msg.Height))
m.setSize() m.setSize()
@ -76,7 +93,7 @@ func (m *baseModel) Log(msg string) {
} }
func (m baseModel) View() string { func (m baseModel) View() string {
if !m.ready { if !m.initialized {
return "\n Initializing..." return "\n Initializing..."
} }
@ -116,14 +133,6 @@ func (m *baseModel) renderLog() string {
return windowStyle.Width(m.contentSize.Width).Height(logLineCount).Render(m.logViewport.View()) return windowStyle.Width(m.contentSize.Width).Height(logLineCount).Render(m.logViewport.View())
} }
func (m *baseModel) initialModel() {
m.logViewport = viewport.New(0, 0)
m.logViewport.KeyMap = viewport.KeyMap{}
m.setSize()
m.ready = true
}
func (m *baseModel) setSize() { func (m *baseModel) setSize() {
logHeight := logLineCount + docStyle.GetVerticalFrameSize() logHeight := logLineCount + docStyle.GetVerticalFrameSize()
menuHeight := 1 menuHeight := 1

View File

@ -1 +1,23 @@
package tui package tui
import (
"fmt"
"ewintr.nl/emdb/client"
tea "github.com/charmbracelet/bubbletea"
)
func FetchMovieList(emdb *client.EMDB, logger *Logger) tea.Cmd {
return func() tea.Msg {
logger.Log("fetching emdb movies...")
ems, err := emdb.GetMovies()
if err != nil {
logger.Log(err.Error())
}
//m.list.SetItems(items)
logger.Log(fmt.Sprintf("found %d movies in in emdb", len(ems)))
return Movies(ems)
}
}

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"ewintr.nl/emdb/model" "ewintr.nl/emdb/model"
"github.com/charmbracelet/bubbles/list"
) )
type Movie struct { type Movie struct {
@ -21,3 +22,13 @@ func (m Movie) Title() string {
func (m Movie) Description() string { func (m Movie) Description() string {
return fmt.Sprintf("%s", m.m.Summary) return fmt.Sprintf("%s", m.m.Summary)
} }
type Movies []model.Movie
func (ms Movies) listItems() []list.Item {
items := []list.Item{}
for _, m := range ms {
items = append(items, Movie{m: m})
}
return items
}

View File

@ -1,25 +1,30 @@
package tui package tui
import ( import (
"fmt" "ewintr.nl/emdb/client"
"github.com/charmbracelet/bubbles/list" "github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
) )
type emdbTab struct { type emdbTab struct {
ready bool initialized bool
list list.Model list list.Model
parent *baseModel emdb *client.EMDB
logger *Logger logger *Logger
} }
func NewEMDBTab(parent *baseModel, logger *Logger) tea.Model { func NewEMDBTab(emdb *client.EMDB, logger *Logger) (tea.Model, tea.Cmd) {
m := emdbTab{} list := list.New([]list.Item{}, list.NewDefaultDelegate(), 0, 0)
m.parent = parent list.Title = "Movies"
m.logger = logger list.SetShowHelp(false)
return m m := emdbTab{
emdb: emdb,
logger: logger,
list: list,
}
return m, FetchMovieList(emdb, logger)
} }
func (m emdbTab) Init() tea.Cmd { func (m emdbTab) Init() tea.Cmd {
@ -32,10 +37,13 @@ func (m emdbTab) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case TabSizeMsgType: case TabSizeMsgType:
if !m.ready { if !m.initialized {
m.initialModel() //cmds = append(cmds, FetchMovieList(m.emdb, m.logger))
m.initialized = true
} }
m.list.SetSize(msg.Width, msg.Height) m.list.SetSize(msg.Width, msg.Height)
case Movies:
m.list.SetItems(msg.listItems())
} }
m.list, cmd = m.list.Update(msg) m.list, cmd = m.list.Update(msg)
@ -48,29 +56,6 @@ func (m emdbTab) View() string {
return m.list.View() return m.list.View()
} }
func (m *emdbTab) initialModel() {
m.list = list.New([]list.Item{}, list.NewDefaultDelegate(), 0, 0)
m.list.Title = "Movies"
m.list.SetShowHelp(false)
m.refreshMovieList()
m.ready = true
}
func (m *emdbTab) Log(s string) { func (m *emdbTab) Log(s string) {
m.logger.Log(s) m.logger.Log(s)
} }
func (m *emdbTab) refreshMovieList() {
m.Log("fetch emdb movies...")
ems, err := m.parent.emdb.GetMovies()
if err != nil {
m.Log(err.Error())
}
items := make([]list.Item, len(ems))
for i, em := range ems {
items[i] = list.Item(Movie{m: em})
}
m.list.SetItems(items)
m.Log(fmt.Sprintf("found %d movies in in emdb", len(items)))
}

View File

@ -43,19 +43,12 @@ func (l *Logger) Log(s string) {
type TabSizeMsgType tea.WindowSizeMsg type TabSizeMsgType tea.WindowSizeMsg
func New(conf Config, logger *Logger) (*tea.Program, error) { func New(conf Config, logger *Logger) (*tea.Program, error) {
tabs := []string{"Erik's movie database", "The movie database"}
tmdb, err := client.NewTMDB(conf.TMDBAPIKey) tmdb, err := client.NewTMDB(conf.TMDBAPIKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
m := baseModel{ emdb := client.NewEMDB(conf.EMDBBaseURL, conf.EMDBAPIKey)
config: conf, m, _ := NewBaseModel(emdb, tmdb, logger)
emdb: client.NewEMDB(conf.EMDBBaseURL, conf.EMDBAPIKey),
tmdb: tmdb,
Tabs: tabs,
logger: logger,
}
m.TabContent = NewEMDBTab(&m, m.logger)
p := tea.NewProgram(m, tea.WithAltScreen()) p := tea.NewProgram(m, tea.WithAltScreen())