mirror of
https://github.com/taigrr/bubbletea.git
synced 2026-04-02 02:59:09 -07:00
Convert remaining examples to Model interface-based structure
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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..."
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
"What’s your favorite Pokémon?\n\n%s\n\n%s",
|
||||
input.View(m.textInput),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user