-
Notifications
You must be signed in to change notification settings - Fork 746
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example illustrating how to send messages via channels in realtime
- Loading branch information
1 parent
dd6a0a0
commit 1a9571e
Showing
1 changed file
with
92 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package main | ||
|
||
// A simple example that shows how to send activity to Bubble Tea in real-time | ||
// through a channel. | ||
|
||
import ( | ||
"fmt" | ||
"math/rand" | ||
"os" | ||
"time" | ||
|
||
"github.com/charmbracelet/bubbles/spinner" | ||
tea "github.com/charmbracelet/bubbletea" | ||
) | ||
|
||
// A message used to indicate that activity has occured. In the real world (for | ||
// example, chat) this would contain actual data. | ||
type responseMsg struct{} | ||
|
||
// Simulate a process that sends events at an irregular interval in real time. | ||
// In this case, we'll send events on the channel at a random interval between | ||
// 100 to 1000 milliseconds. As a command, Bubble Tea will run this | ||
// asyncronously. | ||
func listenForActivity(sub chan struct{}) tea.Cmd { | ||
return func() tea.Msg { | ||
for { | ||
time.Sleep(time.Millisecond * time.Duration(rand.Int63n(900)+100)) | ||
sub <- struct{}{} | ||
} | ||
} | ||
} | ||
|
||
// A command that waits for the activity on a channel. | ||
func waitForActivity(sub chan struct{}) tea.Cmd { | ||
return func() tea.Msg { | ||
return responseMsg(<-sub) | ||
} | ||
} | ||
|
||
type model struct { | ||
sub chan struct{} // where we'll receive activity notifications | ||
responses int // how many responses we've received | ||
spinner spinner.Model | ||
quitting bool | ||
} | ||
|
||
func (m model) Init() tea.Cmd { | ||
return tea.Batch( | ||
spinner.Tick, | ||
listenForActivity(m.sub), // generate activity | ||
waitForActivity(m.sub), // wait for activity | ||
) | ||
} | ||
|
||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | ||
switch msg.(type) { | ||
case tea.KeyMsg: | ||
m.quitting = true | ||
return m, tea.Quit | ||
case responseMsg: | ||
m.responses++ // record external activity | ||
return m, waitForActivity(m.sub) // wait for next event | ||
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 { | ||
s := fmt.Sprintf("\n %s Events received: %d\n\n Press any key to exit\n", m.spinner.View(), m.responses) | ||
if m.quitting { | ||
s += "\n" | ||
} | ||
return s | ||
} | ||
|
||
func main() { | ||
rand.Seed(time.Now().UTC().UnixNano()) | ||
|
||
p := tea.NewProgram(model{ | ||
sub: make(chan struct{}), | ||
spinner: spinner.NewModel(), | ||
}) | ||
|
||
if p.Start() != nil { | ||
fmt.Println("could not start program") | ||
os.Exit(1) | ||
} | ||
} |