TheMathemagicians/sevenkeys/tui/updateui/updateui.go

136 lines
2.5 KiB
Go

package updateui
import (
"database/sql"
"log"
"sevenkeys/constants"
"sevenkeys/logic"
"sevenkeys/logic/scryfall"
"strings"
"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/lukesampson/figlet/figletlib"
)
type BackMsg int
type updateRequiredMsg bool
type errorMsg error
type updateKeyMappings struct {
back key.Binding
quit key.Binding
}
func (k updateKeyMappings) ShortHelp() []key.Binding {
return []key.Binding{k.back, k.quit}
}
func (k updateKeyMappings) FullHelp() [][]key.Binding {
return [][]key.Binding{{k.back, k.quit}}
}
type Model struct {
updateRequired bool
updateFinished bool
canLeave bool
help help.Model
keyMappings updateKeyMappings
}
func NewUpdateModel() Model {
help := help.New()
help.ShortSeparator = help.FullSeparator
keyMappings := updateKeyMappings{
back: key.NewBinding(
key.WithKeys("esc"),
key.WithHelp("esc", "back"),
),
quit: key.NewBinding(
key.WithKeys("q"),
key.WithHelp("q", "quit"),
),
}
return Model{
canLeave: true,
help: help,
keyMappings: keyMappings,
}
}
func (m Model) Init() tea.Cmd {
return nil
}
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
if m.canLeave {
switch {
case key.Matches(msg, m.keyMappings.back):
return m, backCmd()
}
}
break
case errorMsg:
log.Fatal(msg.Error())
break
case updateRequiredMsg:
m.updateRequired = bool(msg)
break
}
return m, cmd
}
func (m Model) View() string {
var ui string
ui += figletlib.SprintMsg("Update", constants.FigletFontSlant, constants.WindowWidth, constants.FigletFontSlant.Settings(), "left")
ui += strings.Repeat("-", constants.WindowWidth)
ui += "\n"
if m.updateRequired {
ui += "Database is out of date. Running update."
} else {
ui += "No update required."
}
if m.canLeave {
ui += strings.Repeat("\n", constants.WindowHeight-8) // TODO: Hardcoded height (again)
ui += m.help.View(m.keyMappings)
}
return ui
}
func checkUpdateRequiredCmd(db *sql.DB) tea.Cmd {
return func() tea.Msg {
bulkData, err := scryfall.GetBulkDataByType(scryfall.BulkDataTypeAllCards)
if err != nil {
return errorMsg(err)
}
needsUpdate, err := logic.CheckForUpdates(db, bulkData)
if err != nil {
return errorMsg(err)
}
return updateRequiredMsg(needsUpdate)
}
}
func backCmd() tea.Cmd {
return func() tea.Msg {
return BackMsg(1)
}
}