6
6
tea "github.com/charmbracelet/bubbletea"
7
7
"github.com/charmbracelet/lipgloss"
8
8
9
+ "time"
10
+
9
11
"github.com/museslabs/kyma/internal/config"
10
12
"github.com/museslabs/kyma/internal/tui/transitions"
11
13
)
@@ -19,6 +21,7 @@ type keyMap struct {
19
21
Command key.Binding
20
22
GoTo key.Binding
21
23
Jump key.Binding
24
+ Timer key.Binding
22
25
}
23
26
24
27
func (k keyMap ) ShortHelp () []key.Binding {
@@ -62,36 +65,66 @@ var keys = keyMap{
62
65
key .WithKeys ("1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" ),
63
66
key .WithHelp ("1-9" , "jump slides" ),
64
67
),
68
+ Timer : key .NewBinding (
69
+ key .WithKeys ("t" ),
70
+ key .WithHelp ("t" , "toggle timer" ),
71
+ ),
65
72
}
66
73
67
74
func style (width , height int , styleConfig config.StyleConfig ) config.SlideStyle {
68
75
return styleConfig .Apply (width , height )
69
76
}
70
77
78
+ // navigateToSlide handles the common pattern of pausing current timer, switching slides, and resuming
79
+ func (m * model ) navigateToSlide (newSlide * Slide ) {
80
+ if m .slide != nil {
81
+ m .slide .Timer = m .slide .Timer .Pause ()
82
+ }
83
+ m .slide = newSlide
84
+ EnsureTimerInitialized (m .slide )
85
+ if m .slide != nil {
86
+ m .slide .Timer = m .slide .Timer .Resume ()
87
+ }
88
+ }
89
+
71
90
type model struct {
72
91
width int
73
92
height int
74
93
75
- slide * Slide
76
- keys keyMap
77
- help help.Model
78
- command * Command
79
- goTo * GoTo
80
- jump * Jump
81
- rootSlide * Slide
94
+ slide * Slide
95
+ keys keyMap
96
+ help help.Model
97
+ command * Command
98
+ goTo * GoTo
99
+ jump * Jump
100
+ rootSlide * Slide
101
+ globalTimer Timer
102
+ timerDisplay TimerDisplay
82
103
}
83
104
84
105
func New (rootSlide * Slide ) model {
106
+ // Initialize timer only for the first slide
107
+ if rootSlide != nil {
108
+ rootSlide .Timer = NewTimer ().Start ()
109
+ }
110
+
85
111
return model {
86
- slide : rootSlide ,
87
- keys : keys ,
88
- help : help .New (),
89
- rootSlide : rootSlide ,
112
+ slide : rootSlide ,
113
+ keys : keys ,
114
+ help : help .New (),
115
+ rootSlide : rootSlide ,
116
+ globalTimer : NewTimer ().Start (),
117
+ timerDisplay : NewTimerDisplay (),
90
118
}
91
119
}
92
120
93
121
func (m model ) Init () tea.Cmd {
94
- return tea .ClearScreen
122
+ return tea .Batch (
123
+ tea .ClearScreen ,
124
+ tea .Tick (time .Second , func (time.Time ) tea.Msg {
125
+ return TimerTickMsg {}
126
+ }),
127
+ )
95
128
}
96
129
97
130
func (m model ) Update (msg tea.Msg ) (tea.Model , tea.Cmd ) {
@@ -101,7 +134,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
101
134
102
135
if command .quitting || command .Choice () != nil {
103
136
if command .Choice () != nil {
104
- m .slide = command .Choice ()
137
+ m .navigateToSlide ( command .Choice () )
105
138
}
106
139
m .command = nil
107
140
return m , nil
@@ -121,7 +154,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
121
154
slide = slide .Next
122
155
}
123
156
if slide != nil {
124
- m .slide = slide
157
+ m .navigateToSlide ( slide )
125
158
}
126
159
}
127
160
m .goTo = nil
@@ -136,17 +169,19 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
136
169
137
170
if jump .Quitting () {
138
171
if steps := jump .JumpSteps (); steps != 0 {
172
+ newSlide := m .slide
139
173
if steps > 0 {
140
174
// Jump forward
141
- for i := 0 ; i < steps && m . slide .Next != nil ; i ++ {
142
- m . slide = m . slide .Next
175
+ for i := 0 ; i < steps && newSlide .Next != nil ; i ++ {
176
+ newSlide = newSlide .Next
143
177
}
144
178
} else {
145
179
// Jump backward
146
- for i := 0 ; i < - steps && m . slide .Prev != nil ; i ++ {
147
- m . slide = m . slide .Prev
180
+ for i := 0 ; i < - steps && newSlide .Prev != nil ; i ++ {
181
+ newSlide = newSlide .Prev
148
182
}
149
183
}
184
+ m .navigateToSlide (newSlide )
150
185
}
151
186
m .jump = nil
152
187
return m , nil
@@ -208,18 +243,21 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
208
243
jump , cmd := jump .Update (msg )
209
244
m .jump = & jump
210
245
return m , cmd
246
+ } else if key .Matches (msg , m .keys .Timer ) {
247
+ m .timerDisplay = m .timerDisplay .ToggleVisible ()
248
+ return m , nil
211
249
} else if key .Matches (msg , m .keys .Next ) {
212
250
if m .slide .Next == nil || m .slide .ActiveTransition != nil && m .slide .ActiveTransition .Animating () {
213
251
return m , nil
214
252
}
215
- m .slide = m .slide .Next
253
+ m .navigateToSlide ( m .slide .Next )
216
254
m .slide .ActiveTransition = m .slide .Properties .Transition .Start (m .width , m .height , transitions .Forwards )
217
255
return m , transitions .Animate (transitions .Fps )
218
256
} else if key .Matches (msg , m .keys .Prev ) {
219
257
if m .slide .Prev == nil || m .slide .ActiveTransition != nil && m .slide .ActiveTransition .Animating () {
220
258
return m , nil
221
259
}
222
- m .slide = m .slide .Prev
260
+ m .navigateToSlide ( m .slide .Prev )
223
261
m .slide .ActiveTransition = m .slide .
224
262
Next .
225
263
Properties .
@@ -229,16 +267,20 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
229
267
230
268
return m , transitions .Animate (transitions .Fps )
231
269
} else if key .Matches (msg , m .keys .Top ) {
232
- m .slide = m .slide .First ()
270
+ m .navigateToSlide ( m .slide .First () )
233
271
return m , nil
234
272
} else if key .Matches (msg , m .keys .Bottom ) {
235
- m .slide = m .slide .Last ()
273
+ m .navigateToSlide ( m .slide .Last () )
236
274
return m , nil
237
275
}
238
276
case transitions.FrameMsg :
239
277
slide , cmd := m .slide .Update ()
240
278
m .slide = slide
241
279
return m , cmd
280
+ case TimerTickMsg :
281
+ var cmd tea.Cmd
282
+ m .globalTimer , cmd = m .globalTimer .Update (msg )
283
+ return m , cmd
242
284
}
243
285
244
286
return m , nil
@@ -267,5 +309,9 @@ func (m model) View() string {
267
309
return m .jump .Show (slideView , m .width , m .height )
268
310
}
269
311
312
+ if m .timerDisplay .IsVisible () {
313
+ return m .timerDisplay .Show (slideView , m .width , m .height , m .globalTimer , m .slide .Timer )
314
+ }
315
+
270
316
return slideView
271
317
}
0 commit comments