Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: simple timer component #67

Merged
merged 6 commits into from Sep 9, 2021
Merged

feat: simple timer component #67

merged 6 commits into from Sep 9, 2021

Conversation

caarlos0
Copy link
Member

@caarlos0 caarlos0 commented Sep 4, 2021

closes #22

A simple timer component:

  • ticks every second
  • on timeout, executes the given tea.Cmd

Simplest possible usage example:

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/charmbracelet/bubbles/timer"
	tea "github.com/charmbracelet/bubbletea"
)

func main() {
	m := timer.Model{
		Timeout: 10 * time.Second,
		OnTimeout: func() tea.Cmd {
			return tea.Quit
		},
	}

	if err := tea.NewProgram(m).Start(); err != nil {
		fmt.Println("Oh no, it didn't work:", err)
		os.Exit(1)
	}
}

let me know what you think

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
@caarlos0
Copy link
Member Author

caarlos0 commented Sep 4, 2021

one thing that comes to mind now is: should we have an "increasing timer" as well? if so, maybe this component should be called timeout or something like that

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
@meowgorithm meowgorithm added the enhancement New feature or request label Sep 4, 2021
@meowgorithm
Copy link
Member

meowgorithm commented Sep 4, 2021

This is cool!

  • I'd expose tickMsg so users can respond to ticks if they want
  • It should probably also send a TimeoutMsg on timeout so that users have the option of listening for timeouts without running a command
  • It would be cool if View returned the time remaining (otherwise it won't ever change)

It would also be useful to allow for a custom decrement value, so you could do something like:

m := Timer{
	Timeout: time.Millisecond * 250,
	TickEvery: time.Millisecond, // or maybe it's called Decrement?
}

…and then maybe if the decrement value is 0 it defaults to time.Second?

Otherwise, Timer seems like a good name for this since it's similar to the functionality in time.Timer. I'd probably call an increasing one Stopwatch, which I think makes sense to include.

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
@caarlos0
Copy link
Member Author

caarlos0 commented Sep 4, 2021

agreed, made the changes...

view actually returns the time remaining because on update we do timeout =- interval

an example usage now looks like:

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/charmbracelet/bubbles/timer"
	tea "github.com/charmbracelet/bubbletea"
)

type model struct {
	timer timer.Model
}

func (m model) Init() tea.Cmd {
	return m.timer.Init()
}

func (m model) View() string {
	return "Will exit in " + m.timer.View()
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg.(type) {
	case timer.TimeoutMsg:
		return m, tea.Quit
	}
	var cmd tea.Cmd
	m.timer, cmd = m.timer.Update(msg)
	return m, cmd
}

func main() {
	m := model{
		timer: timer.New(3*time.Second),
	}

	if err := tea.NewProgram(m).Start(); err != nil {
		fmt.Println("Oh no, it didn't work:", err)
		os.Exit(1)
	}
}

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
@caarlos0 caarlos0 mentioned this pull request Sep 4, 2021
@meowgorithm
Copy link
Member

LGTM!

timer/timer.go Outdated Show resolved Hide resolved
Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
@meowgorithm meowgorithm merged commit 7941c49 into charmbracelet:master Sep 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timer component
2 participants