2020-05-25 19:26:40 -04:00
|
|
|
package tea
|
2020-05-14 10:49:08 -04:00
|
|
|
|
2020-10-12 10:57:06 -04:00
|
|
|
// Convenience commands. Not part of the Bubble Tea core, but potentially
|
2020-06-11 19:34:08 -04:00
|
|
|
// handy.
|
2020-05-17 19:28:12 -04:00
|
|
|
|
2020-05-14 10:49:08 -04:00
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Every is a command that ticks in sync with the system clock. So, if you
|
|
|
|
// wanted to tick with the system clock every second, minute or hour you
|
|
|
|
// could use this. It's also handy for having different things tick in sync.
|
|
|
|
//
|
2020-06-18 22:47:17 -04:00
|
|
|
// Because we're ticking with the system clock the tick will likely not run for
|
|
|
|
// the entire specified duration. For example, if we're ticking for one minute
|
|
|
|
// and the clock is at 12:34:20 then the next tick will happen at 12:35:00, 40
|
|
|
|
// seconds later.
|
2020-07-30 11:29:20 -04:00
|
|
|
//
|
2020-10-11 20:28:32 -04:00
|
|
|
// To produce the command, pass a duration and a function which returns
|
2020-07-30 11:29:20 -04:00
|
|
|
// a message containing the time at which the tick occurred.
|
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// type TickMsg time.Time
|
2020-07-30 11:29:20 -04:00
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// cmd := Every(time.Second, func(t time.Time) Msg {
|
|
|
|
// return TickMsg(t)
|
|
|
|
// })
|
2022-05-29 20:40:57 -04:00
|
|
|
//
|
|
|
|
// Beginners' note: Every sends a single message and won't automatically
|
|
|
|
// dispatch messages at an interval. To do that, you'll want to return another
|
|
|
|
// Every command after receiving your tick message. For example:
|
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// type TickMsg time.Time
|
|
|
|
//
|
|
|
|
// // Send a message every second.
|
|
|
|
// func tickEvery() Cmd {
|
|
|
|
// return Every(time.Second, func(t time.Time) Msg {
|
|
|
|
// return TickMsg(t)
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// func (m model) Init() Cmd {
|
|
|
|
// // Start ticking.
|
|
|
|
// return tickEvery()
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// func (m model) Update(msg Msg) (Model, Cmd) {
|
|
|
|
// switch msg.(type) {
|
|
|
|
// case TickMsg:
|
|
|
|
// // Return your Every command again to loop.
|
|
|
|
// return m, tickEvery()
|
|
|
|
// }
|
|
|
|
// return m, nil
|
|
|
|
// }
|
2022-05-29 20:40:57 -04:00
|
|
|
//
|
|
|
|
// Every is analogous to Tick in the Elm Architecture.
|
2020-05-14 10:49:08 -04:00
|
|
|
func Every(duration time.Duration, fn func(time.Time) Msg) Cmd {
|
|
|
|
return func() Msg {
|
|
|
|
n := time.Now()
|
|
|
|
d := n.Truncate(duration).Add(duration).Sub(n)
|
|
|
|
t := time.NewTimer(d)
|
2020-05-25 08:12:30 -04:00
|
|
|
return fn(<-t.C)
|
2020-05-14 10:49:08 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-12 10:59:36 -04:00
|
|
|
// Tick produces a command at an interval independent of the system clock at
|
2022-10-03 22:14:42 -04:00
|
|
|
// the given duration. That is, the timer begins precisely when invoked,
|
2020-10-12 10:59:36 -04:00
|
|
|
// and runs for its entire duration.
|
2020-07-30 11:29:20 -04:00
|
|
|
//
|
2020-10-11 20:28:32 -04:00
|
|
|
// To produce the command, pass a duration and a function which returns
|
2020-07-30 11:29:20 -04:00
|
|
|
// a message containing the time at which the tick occurred.
|
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// type TickMsg time.Time
|
2020-07-30 11:29:20 -04:00
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// cmd := Tick(time.Second, func(t time.Time) Msg {
|
|
|
|
// return TickMsg(t)
|
|
|
|
// })
|
2022-05-29 20:40:57 -04:00
|
|
|
//
|
|
|
|
// Beginners' note: Tick sends a single message and won't automatically
|
|
|
|
// dispatch messages at an interval. To do that, you'll want to return another
|
|
|
|
// Tick command after receiving your tick message. For example:
|
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// type TickMsg time.Time
|
|
|
|
//
|
|
|
|
// func doTick() Cmd {
|
|
|
|
// return Tick(time.Second, func(t time.Time) Msg {
|
|
|
|
// return TickMsg(t)
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// func (m model) Init() Cmd {
|
|
|
|
// // Start ticking.
|
|
|
|
// return doTick()
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// func (m model) Update(msg Msg) (Model, Cmd) {
|
|
|
|
// switch msg.(type) {
|
|
|
|
// case TickMsg:
|
|
|
|
// // Return your Tick command again to loop.
|
|
|
|
// return m, doTick()
|
|
|
|
// }
|
|
|
|
// return m, nil
|
|
|
|
// }
|
2020-05-14 10:49:08 -04:00
|
|
|
func Tick(d time.Duration, fn func(time.Time) Msg) Cmd {
|
|
|
|
return func() Msg {
|
|
|
|
t := time.NewTimer(d)
|
2020-05-25 08:12:30 -04:00
|
|
|
return fn(<-t.C)
|
2020-05-14 10:49:08 -04:00
|
|
|
}
|
|
|
|
}
|
2021-01-17 10:10:35 -05:00
|
|
|
|
|
|
|
// Sequentially produces a command that sequentially executes the given
|
|
|
|
// commands.
|
|
|
|
// The Msg returned is the first non-nil message returned by a Cmd.
|
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// func saveStateCmd() Msg {
|
|
|
|
// if err := save(); err != nil {
|
|
|
|
// return errMsg{err}
|
|
|
|
// }
|
|
|
|
// return nil
|
|
|
|
// }
|
2021-01-17 10:10:35 -05:00
|
|
|
//
|
2022-08-15 05:58:40 -04:00
|
|
|
// cmd := Sequentially(saveStateCmd, Quit)
|
2022-08-24 14:29:14 -04:00
|
|
|
//
|
|
|
|
// Deprecated: use Sequence instead.
|
2021-01-17 10:10:35 -05:00
|
|
|
func Sequentially(cmds ...Cmd) Cmd {
|
|
|
|
return func() Msg {
|
|
|
|
for _, cmd := range cmds {
|
2022-02-01 20:52:49 -05:00
|
|
|
if cmd == nil {
|
|
|
|
continue
|
|
|
|
}
|
2021-01-17 10:10:35 -05:00
|
|
|
if msg := cmd(); msg != nil {
|
|
|
|
return msg
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|