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) } }