Skip to content

Instantly share code, notes, and snippets.

@Bhupesh-V
Created January 31, 2024 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bhupesh-V/82a85917ec486b259a1795f8d976f3d7 to your computer and use it in GitHub Desktop.
Save Bhupesh-V/82a85917ec486b259a1795f8d976f3d7 to your computer and use it in GitHub Desktop.
bubble tea with work
package main
import (
"fmt"
"net/http"
"os"
"time"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
const url = "https://charm.sh/"
var (
// Available spinners
spinners = []spinner.Spinner{
// spinner.Line,
// spinner.Dot,
// spinner.MiniDot,
// spinner.Jump,
spinner.Pulse,
}
textStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("252")).Render
spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("430"))
// helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render
)
type model struct {
status int
err error
index int
spinner spinner.Model
}
func checkServer() tea.Msg {
// Create an HTTP client and make a GET request.
c := &http.Client{Timeout: 10 * time.Second}
res, err := c.Get(url)
if err != nil {
// There was an error making our request. Wrap the error we received
// in a message and return it.
return errMsg{err}
}
// We received a response from the server. Return the HTTP status code
// as a message.
return statusMsg(res.StatusCode)
}
type statusMsg int
type errMsg struct{ err error }
// For messages that contain errors it's often handy to also implement the
// error interface on the message.
func (e errMsg) Error() string { return e.err.Error() }
func (m model) Init() tea.Cmd {
// return m.spinner.Tick
return tea.Batch(m.spinner.Tick, checkServer)
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case statusMsg:
// The server returned a status message. Save it to our model. Also
// tell the Bubble Tea runtime we want to exit because we have nothing
// else to do. We'll still be able to render a final view with our
// status message.
m.status = int(msg)
time.Sleep(2 * time.Second)
return m, tea.Quit
case errMsg:
// There was an error. Note it in the model. And tell the runtime
// we're done and want to quit.
m.err = msg
return m, tea.Quit
case tea.KeyMsg:
// Ctrl+c exits. Even with short running programs it's good to have
// a quit key, just in case your logic is off. Users will be very
// annoyed if they can't exit.
if msg.Type == tea.KeyCtrlC {
return m, tea.Quit
}
case spinner.TickMsg:
// var cmd tea.Cmd
// m.spinner, cmd = m.spinner.Update(msg)
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
default:
return m, nil
}
// If we happen to get any other messages, don't do anything.
return m, nil
}
func (m *model) initSpinner() {
m.spinner = spinner.New()
m.spinner.Style = spinnerStyle
m.spinner.Spinner = spinners[m.index]
}
func (m model) View() (s string) {
// If there's an error, print it out and don't do anything else.
if m.err != nil {
return fmt.Sprintf("\nWe had some trouble: %v\n\n", m.err)
}
var gap string
switch m.index {
case 1:
gap = ""
default:
gap = " "
}
s = fmt.Sprintf("\n %s%s%s %s", m.spinner.View(), gap, textStyle("Checking..."), textStyle(url))
// Tell the user we're doing something.
// s := fmt.Sprintf("Checking %s ... ", url)
// When the server responds with a status, add it to the current line.
if m.status > 0 {
s += fmt.Sprintf(" %d ✅!", m.status)
}
// Send off whatever we came up with above for rendering.
return "\n" + s + "\n\n"
}
func main() {
m := model{}
m.initSpinner()
if _, err := tea.NewProgram(m).Run(); err != nil {
fmt.Println("could not run program:", err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment