diff options
author | Botond Hende <nettingman@gmail.com> | 2024-06-19 22:47:12 +0200 |
---|---|---|
committer | Botond Hende <nettingman@gmail.com> | 2024-06-19 22:47:12 +0200 |
commit | b53ca78ad2591076e2bc1f353bdc22bac6ccebce (patch) | |
tree | 53bbac5f100711e759e985cbacb4758c7640454c /animatedtext.go |
Diffstat (limited to 'animatedtext.go')
-rw-r--r-- | animatedtext.go | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/animatedtext.go b/animatedtext.go new file mode 100644 index 0000000..155e371 --- /dev/null +++ b/animatedtext.go @@ -0,0 +1,94 @@ +package animatedtext + +import ( + "sync" + "time" + + tea "github.com/charmbracelet/bubbletea" +) + +var ( + lastID int + mutex sync.Mutex +) + +func nextID() int { + mutex.Lock() + defer mutex.Unlock() + lastID++ + return lastID +} + +type AnimatedText struct { + FullText string + PrintPauseTime time.Duration +} + +type Model struct { + AnimatedText AnimatedText + + id int + currentCharIdx int + finished bool +} + +func New(text string, pauseTime time.Duration) Model { + m := Model{ + AnimatedText: AnimatedText{FullText: text, PrintPauseTime: pauseTime}, + id: nextID(), + currentCharIdx: 0, + } + + return m +} + +type TickMsg struct { + Time time.Time + ID int +} + +func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { + if m.finished { + return m, nil + } + + switch msg := msg.(type) { + case TickMsg: + if msg.ID > 0 && msg.ID != m.id { + return m, nil + } + + if m.currentCharIdx + 1 >= len(m.AnimatedText.FullText) { + m.finished = true + return m, nil + } + + m.currentCharIdx++ + + return m, m.tick(m.id) + + default: + return m, nil + } +} + +func (m Model) View() string { + if (m.finished) { + return m.AnimatedText.FullText + } + + return m.AnimatedText.FullText[0:m.currentCharIdx] +} + +func (m Model) tick(id int) tea.Cmd { + return tea.Tick(m.AnimatedText.PrintPauseTime, func(t time.Time) tea.Msg { + return TickMsg{ + Time: t, + ID: id, + } + }) +} + +func Tick() tea.Msg { + return TickMsg{Time: time.Now()} +}
\ No newline at end of file |