TheMathemagicians/sevenkeys/tui/home.go

189 lines
3.8 KiB
Go
Raw Permalink Normal View History

2024-06-10 12:32:45 +00:00
package tui
import (
"sevenkeys/constants"
"sevenkeys/figlet"
"sevenkeys/tui/searchui"
"sevenkeys/tui/updateui"
"strings"
"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
)
type sessionState int
const (
homeView sessionState = iota
updateView
searchView
)
type homeKeyMappings struct {
Update key.Binding
SearchCriteria key.Binding
Search key.Binding
StorageOptions key.Binding
Find key.Binding
Quit key.Binding
}
func (k homeKeyMappings) ShortHelp() []key.Binding {
return []key.Binding{k.Update, k.SearchCriteria, k.Search, k.StorageOptions, k.Find, k.Quit}
}
func (k homeKeyMappings) FullHelp() [][]key.Binding {
return [][]key.Binding{
{k.Update, k.SearchCriteria, k.Search},
{k.StorageOptions, k.Find, k.Quit},
}
}
type MainModel struct {
state sessionState
updateModel tea.Model
searchModel tea.Model
help help.Model
keyMappings homeKeyMappings
}
func NewMainModel() MainModel {
help := help.New()
help.ShortSeparator = help.FullSeparator
updateModel := updateui.NewUpdateModel()
searchModel := searchui.NewSearchModel()
keyMappings := homeKeyMappings{
Update: key.NewBinding(
key.WithKeys("u"),
key.WithHelp("u", "update database"),
),
SearchCriteria: key.NewBinding(
key.WithKeys("c"),
key.WithHelp("c", "card printing search criteria"),
),
Search: key.NewBinding(
key.WithKeys("s"),
key.WithHelp("s", "card printing search"),
),
StorageOptions: key.NewBinding(
key.WithKeys("o"),
key.WithHelp("o", "card storage options"),
),
Find: key.NewBinding(
key.WithKeys("f"),
key.WithHelp("f", "find in storage"),
),
Quit: key.NewBinding(
key.WithKeys("ctrl+c", "q"),
key.WithHelp("q", "quit program"),
),
}
return MainModel{
state: homeView,
updateModel: updateModel,
searchModel: searchModel,
help: help,
keyMappings: keyMappings,
}
}
func (m MainModel) Init() tea.Cmd {
return nil
}
func renderHomeScreen(m MainModel) string {
var ui string
// Display splash screen
ui += figlet.SprintMsgSlant("SEVENKEYS", "center")
ui += figlet.SprintMsgTerm("the ultimate Magic: the Gathering trading card storage system", "center")
// Display help
ui += strings.Repeat("\n", constants.WindowHeight-8) // TODO: Avoid hardcoding height somehow
ui += m.help.View(m.keyMappings)
return ui
}
func (m MainModel) View() string {
var ui string
if constants.WindowWidth <= 0 {
return ui
}
switch m.state {
case homeView:
ui += renderHomeScreen(m)
break
case updateView:
ui += m.updateModel.View()
break
case searchView:
ui += m.searchModel.View()
break
}
return ui
}
func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
2024-06-10 13:15:10 +00:00
var cmds []tea.Cmd
2024-06-10 12:32:45 +00:00
switch msg := msg.(type) {
case tea.WindowSizeMsg:
constants.WindowHeight = msg.Height
constants.WindowWidth = msg.Width
m.help.Width = msg.Width
2024-06-10 12:35:58 +00:00
case tea.KeyMsg:
switch {
case key.Matches(msg, m.keyMappings.Quit):
return m, tea.Quit
}
2024-06-10 12:32:45 +00:00
case updateui.BackMsg:
m.state = homeView
}
switch m.state {
case homeView:
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, m.keyMappings.Update):
m.state = updateView
case key.Matches(msg, m.keyMappings.Search):
m.state = searchView
}
}
case updateView:
newUpdate, newCmd := m.updateModel.Update(msg)
newUpdateModel, ok := newUpdate.(updateui.Model)
if !ok {
panic("Could not perform assertion on updateui.Model")
}
m.updateModel = newUpdateModel
cmd = newCmd
case searchView:
newSearch, newCmd := m.searchModel.Update(msg)
newSearchModel, ok := newSearch.(searchui.Model)
if !ok {
panic("Could not perform assertion on searchui.Model")
}
m.searchModel = newSearchModel
cmd = newCmd
}
2024-06-10 13:15:10 +00:00
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
2024-06-10 12:32:45 +00:00
}