bubbletea/examples/send-msg/main.go

132 lines
2.7 KiB
Go
Raw Permalink Normal View History

package main
// A simple example that shows how to send messages to a Bubble Tea program
// from outside the program using Program.Send(Msg).
import (
"fmt"
"math/rand"
"os"
"strings"
"time"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var (
spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("63"))
helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Margin(1, 0)
dotStyle = helpStyle.Copy().UnsetMargins()
durationStyle = dotStyle.Copy()
appStyle = lipgloss.NewStyle().Margin(1, 2, 0, 2)
)
type resultMsg struct {
duration time.Duration
food string
}
func (r resultMsg) String() string {
if r.duration == 0 {
return dotStyle.Render(strings.Repeat(".", 30))
}
return fmt.Sprintf("🍔 Ate %s %s", r.food,
durationStyle.Render(r.duration.String()))
}
type model struct {
spinner spinner.Model
results []resultMsg
quitting bool
}
func newModel() model {
const numLastResults = 5
s := spinner.New()
s.Style = spinnerStyle
return model{
spinner: s,
results: make([]resultMsg, numLastResults),
}
}
func (m model) Init() tea.Cmd {
return m.spinner.Tick
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
m.quitting = true
return m, tea.Quit
case resultMsg:
m.results = append(m.results[1:], msg)
return m, nil
case spinner.TickMsg:
var cmd tea.Cmd
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
default:
return m, nil
}
}
func (m model) View() string {
var s string
if m.quitting {
s += "Thats all for today!"
} else {
s += m.spinner.View() + " Eating food..."
}
s += "\n\n"
for _, res := range m.results {
s += res.String() + "\n"
}
if !m.quitting {
s += helpStyle.Render("Press any key to exit")
}
if m.quitting {
s += "\n"
}
return appStyle.Render(s)
}
func main() {
p := tea.NewProgram(newModel())
// Simulate activity
go func() {
for {
pause := time.Duration(rand.Int63n(899)+100) * time.Millisecond // nolint:gosec
time.Sleep(pause)
2022-02-08 11:36:13 -05:00
// Send the Bubble Tea program a message from outside the
// tea.Program. This will block until it is ready to receive
// messages.
p.Send(resultMsg{food: randomFood(), duration: pause})
}
}()
if _, err := p.Run(); err != nil {
2022-02-08 11:36:13 -05:00
fmt.Println("Error running program:", err)
os.Exit(1)
}
}
func randomFood() string {
food := []string{
"an apple", "a pear", "a gherkin", "a party gherkin",
"a kohlrabi", "some spaghetti", "tacos", "a currywurst", "some curry",
"a sandwich", "some peanut butter", "some cashews", "some ramen",
}
return food[rand.Intn(len(food))] // nolint:gosec
}