Convert remaining examples to Model interface-based structure

This commit is contained in:
Christian Rocha
2020-10-15 19:48:42 -04:00
parent 7530fb0112
commit 847787e46d
8 changed files with 78 additions and 138 deletions

View File

@@ -16,7 +16,7 @@ type model int
type tickMsg time.Time
func main() {
p := tea.NewProgram(initialize, update, view)
p := tea.NewProgram(model(5))
p.EnterAltScreen()
err := p.Start()
@@ -27,13 +27,11 @@ func main() {
}
}
func initialize() (tea.Model, tea.Cmd) {
return model(5), tick()
func (m model) Init() tea.Cmd {
return tick()
}
func update(message tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
m, _ := mdl.(model)
func (m model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
switch msg := message.(type) {
case tea.KeyMsg:
@@ -58,8 +56,7 @@ func update(message tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
return m, nil
}
func view(mdl tea.Model) string {
m, _ := mdl.(model)
func (m model) View() string {
return fmt.Sprintf("\n\n Hi. This program will exit in %d seconds...", m)
}

View File

@@ -3,7 +3,6 @@ package main
// A simple program that makes a GET request and prints the response status.
import (
"errors"
"fmt"
"log"
"net/http"
@@ -14,31 +13,29 @@ import (
const url = "https://charm.sh/"
type Model struct {
type model struct {
status int
err error
}
type statusMsg int
type errMsg error
type errMsg struct{ error }
func (e errMsg) Error() string { return e.Error() }
func main() {
p := tea.NewProgram(initialize, update, view)
p := tea.NewProgram(model{})
if err := p.Start(); err != nil {
log.Fatal(err)
}
}
func initialize() (tea.Model, tea.Cmd) {
return Model{0, nil}, checkServer
func (m model) Init() tea.Cmd {
return checkServer
}
func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) {
m, ok := model.(Model)
if !ok {
return Model{err: errors.New("could not perform assertion on model during update")}, nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
@@ -66,8 +63,7 @@ func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) {
}
}
func view(model tea.Model) string {
m, _ := model.(Model)
func (m model) View() string {
s := fmt.Sprintf("Checking %s...", url)
if m.err != nil {
s += fmt.Sprintf("something went wrong: %s", m.err)
@@ -83,7 +79,7 @@ func checkServer() tea.Msg {
}
res, err := c.Get(url)
if err != nil {
return errMsg(err)
return errMsg{err}
}
return statusMsg(res.StatusCode)
}

View File

@@ -53,7 +53,7 @@ func main() {
defer f.Close()
}
p := tea.NewProgram(initialize(string(content)), update, view)
p := tea.NewProgram(model{content: string(content)})
// Use the full size of the terminal in its "alternate screen buffer"
p.EnterAltScreen()
@@ -75,19 +75,11 @@ type model struct {
viewport viewport.Model
}
func initialize(content string) func() (tea.Model, tea.Cmd) {
return func() (tea.Model, tea.Cmd) {
return model{
// Store content in the model so we can hand it off to the viewport
// later.
content: content,
}, nil
}
func (m model) Init() tea.Cmd {
return nil
}
func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
m, _ := mdl.(model)
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var (
cmd tea.Cmd
cmds []tea.Cmd
@@ -142,9 +134,7 @@ func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
return m, tea.Batch(cmds...)
}
func view(mdl tea.Model) string {
m, _ := mdl.(model)
func (m model) View() string {
if !m.ready {
return "\n Initalizing..."
}

View File

@@ -29,7 +29,8 @@ func main() {
// Pass the channel to the initialize function so our Bubble Tea program
// can send the final choice along when the time comes.
if err := tea.NewProgram(initialize(result), update, view).Start(); err != nil {
p := tea.NewProgram(model{cursor: 0, choice: result})
if err := p.Start(); err != nil {
fmt.Println("Oh no:", err)
os.Exit(1)
}
@@ -43,15 +44,15 @@ func main() {
// Pass a channel to the model to listen to the result value. This is a
// function that returns the initialize function and is typically how you would
// pass arguments to a tea.Init function.
func initialize(choice chan string) func() (tea.Model, tea.Cmd) {
return func() (tea.Model, tea.Cmd) {
return model{cursor: 0, choice: choice}, nil
}
func initialModel(choice chan string) model {
return model{cursor: 0, choice: choice}
}
func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
m, _ := mdl.(model)
func (m model) Init() tea.Cmd {
return nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
@@ -83,9 +84,7 @@ func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
return m, nil
}
func view(mdl tea.Model) string {
m, _ := mdl.(model)
func (m model) View() string {
s := strings.Builder{}
s.WriteString("What kind of Bubble Tea would you like to order?\n\n")

View File

@@ -27,10 +27,6 @@ func main() {
}
}
// Messages are events that we respond to in our Update function. This
// particular one indicates that the timer has ticked.
type tickMsg time.Time
// A model can be more or less any type of data. It holds all the data for a
// program, so often it's a struct. For this simple example, however, all
// we'll need is a simple integer.
@@ -66,6 +62,10 @@ func (m model) View() string {
return fmt.Sprintf("Hi. This program will exit in %d seconds. To quit sooner press any key.\n", m)
}
// Messages are events that we respond to in our Update function. This
// particular one indicates that the timer has ticked.
type tickMsg time.Time
func tick() tea.Msg {
time.Sleep(time.Second)
return tickMsg{}

View File

@@ -12,41 +12,35 @@ import (
"github.com/muesli/termenv"
)
var (
color = termenv.ColorProfile()
)
var term = termenv.ColorProfile()
type Model struct {
type errMsg error
type model struct {
spinner spinner.Model
quitting bool
err error
}
type errMsg error
func main() {
p := tea.NewProgram(initialize, update, view)
p := tea.NewProgram(initialModel())
if err := p.Start(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func initialize() (tea.Model, tea.Cmd) {
func initialModel() model {
s := spinner.NewModel()
s.Frames = spinner.Dot
return Model{
spinner: s,
}, spinner.Tick(s)
return model{spinner: s}
}
func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) {
m, ok := model.(Model)
if !ok {
return model, nil
}
func (m model) Init() tea.Cmd {
return spinner.Tick(m.spinner)
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
@@ -74,17 +68,13 @@ func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) {
}
func view(model tea.Model) string {
m, ok := model.(Model)
if !ok {
return "could not perform assertion on model in view\n"
}
func (m model) View() string {
if m.err != nil {
return m.err.Error()
}
s := termenv.
String(spinner.View(m.spinner)).
Foreground(color.Color("205")).
Foreground(term.Color("205")).
String()
str := fmt.Sprintf("\n\n %s Loading forever...press q to quit\n\n", s)
if m.quitting {

View File

@@ -4,7 +4,6 @@ package main
// component library.
import (
"errors"
"fmt"
"log"
@@ -12,48 +11,39 @@ import (
tea "github.com/charmbracelet/bubbletea"
)
type Model struct {
textInput input.Model
err error
}
type tickMsg struct{}
type errMsg error
func main() {
p := tea.NewProgram(
initialize,
update,
view,
)
p := tea.NewProgram(initialModel())
if err := p.Start(); err != nil {
log.Fatal(err)
}
}
func initialize() (tea.Model, tea.Cmd) {
type tickMsg struct{}
type errMsg error
type model struct {
textInput input.Model
err error
}
func initialModel() model {
inputModel := input.NewModel()
inputModel.Placeholder = "Pikachu"
inputModel.Focus()
return Model{
return model{
textInput: inputModel,
err: nil,
}, input.Blink(inputModel)
}
}
func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) {
func (m model) Init() tea.Cmd {
return input.Blink(m.textInput)
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
m, ok := model.(Model)
if !ok {
// When we encounter errors in Update we simply add the error to the
// model so we can handle it in the view. We could also return a command
// that does something else with the error, like logs it via IO.
return Model{
err: errors.New("could not perform assertion on model in update"),
}, nil
}
switch msg := msg.(type) {
case tea.KeyMsg:
@@ -76,13 +66,7 @@ func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) {
return m, cmd
}
func view(model tea.Model) string {
m, ok := model.(Model)
if !ok {
return "Oh no: could not perform assertion on model."
} else if m.err != nil {
return fmt.Sprintf("Uh oh: %s", m.err)
}
func (m model) View() string {
return fmt.Sprintf(
"Whats your favorite Pokémon?\n\n%s\n\n%s",
input.View(m.textInput),

View File

@@ -12,9 +12,7 @@ import (
te "github.com/muesli/termenv"
)
const (
focusedTextColor = "205"
)
const focusedTextColor = "205"
var (
color = te.ColorProfile().Color
@@ -25,11 +23,7 @@ var (
)
func main() {
if err := tea.NewProgram(
initialize,
update,
view,
).Start(); err != nil {
if err := tea.NewProgram(initialModel()).Start(); err != nil {
fmt.Printf("could not start program: %s\n", err)
os.Exit(1)
}
@@ -43,7 +37,7 @@ type model struct {
submitButton string
}
func initialize() (tea.Model, tea.Cmd) {
func initialModel() model {
name := input.NewModel()
name.Placeholder = "Name"
name.Focus()
@@ -58,25 +52,21 @@ func initialize() (tea.Model, tea.Cmd) {
email.Placeholder = "Email"
email.Prompt = blurredPrompt
return model{0, name, nickName, email, blurredSubmitButton},
tea.Batch(
input.Blink(name),
input.Blink(nickName),
input.Blink(email),
)
return model{0, name, nickName, email, blurredSubmitButton}
}
func (m model) Init() tea.Cmd {
return tea.Batch(
input.Blink(m.nameInput),
input.Blink(m.nickNameInput),
input.Blink(m.emailInput),
)
}
func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
m, ok := mdl.(model)
if !ok {
panic("could not perform assertion on model")
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
@@ -167,12 +157,7 @@ func updateInputs(msg tea.Msg, m model) (model, tea.Cmd) {
return m, tea.Batch(cmds...)
}
func view(mdl tea.Model) string {
m, ok := mdl.(model)
if !ok {
return "could not perform assertion on model"
}
func (m model) View() string {
s := "\n"
inputs := []string{
@@ -189,6 +174,5 @@ func view(mdl tea.Model) string {
}
s += "\n\n" + m.submitButton + "\n"
return s
}