forked from Mirrors/bubbletea
137 lines
2.8 KiB
Go
137 lines
2.8 KiB
Go
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()
|
||
foodStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("36"))
|
||
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.NewModel()
|
||
s.Style = spinnerStyle
|
||
return model{
|
||
spinner: s,
|
||
results: make([]resultMsg, numLastResults),
|
||
}
|
||
}
|
||
|
||
func (m model) Init() tea.Cmd {
|
||
return 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 += "That’s 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() {
|
||
rand.Seed(time.Now().UTC().UnixNano())
|
||
|
||
done := make(chan struct{})
|
||
|
||
p := tea.NewProgram(newModel())
|
||
go func() {
|
||
if err := p.Start(); err != nil {
|
||
fmt.Println("Error running program:", err)
|
||
os.Exit(1)
|
||
}
|
||
close(done)
|
||
}()
|
||
|
||
// Simulate activity
|
||
go func() {
|
||
for {
|
||
pause := time.Duration(rand.Int63n(899)+100) * time.Millisecond
|
||
time.Sleep(pause)
|
||
|
||
// Send the Bubble Tea program a message from outside the program.
|
||
p.Send(resultMsg{food: randomFood(), duration: pause})
|
||
}
|
||
}()
|
||
|
||
<-done
|
||
}
|
||
|
||
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 string(food[rand.Intn(len(food))])
|
||
}
|