presently 0.26.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +25 -5
- data/lib/presently/clock.rb +15 -10
- data/lib/presently/presentation_controller.rb +7 -4
- data/lib/presently/presenter_view.rb +91 -22
- data/lib/presently/state.rb +3 -1
- data/lib/presently/version.rb +1 -1
- data/public/_static/index.css +2 -1
- data/public/_static/presenter.css +29 -0
- data/readme.md +10 -6
- data/release.cert +24 -0
- data/releases.md +6 -0
- data.tar.gz.sig +0 -0
- metadata +25 -28
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19e0176d3b7e17bd06f07d79e3ae4379d1992f3b75beb87b7725e47a713961be
|
|
4
|
+
data.tar.gz: 1b3bbd3f6a2c170f833a913cf1a0de5afb8030f3330773e62f1eba72153612c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e9e35182f5d1fcd2a4e0a625ebfe3d0f8d743ece09335a1a399c82b5f720138ef62044e070ca54c01995b685dd970956fe15600f3b2176aee318226c569030c
|
|
7
|
+
data.tar.gz: d53ee079a8042e0abbcde56bb92d262084c2a8ea695dd4c41dec203bcd5d2a4050ba69557d2456cfcf5f85ddb48b8989bfe186938d8cda9ce6669e21d43cff99
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/context/getting-started.md
CHANGED
|
@@ -231,11 +231,31 @@ The presenter view at `/presenter` provides:
|
|
|
231
231
|
|
|
232
232
|
- **Current and next slide previews** — see what's coming without switching windows.
|
|
233
233
|
- **Presenter notes** — notes from the slide's `---` separator section.
|
|
234
|
-
- **Timer controls** — Start, Pause
|
|
234
|
+
- **Timer controls** — Start when ready, Pause while running, and Resume or Reset while paused.
|
|
235
235
|
- **Pacing indicator** — shows whether you're on time, ahead, or behind based on per-slide `duration` metadata.
|
|
236
236
|
- **Progress bar** — visual indicator of time consumed for the current slide.
|
|
237
237
|
- **Reload button** — reload slides from disk without restarting the server.
|
|
238
238
|
|
|
239
|
+
### Timer Controls
|
|
240
|
+
|
|
241
|
+
Pause the timer before changing its elapsed time, whether you are rehearsing a section or preparing for another presentation.
|
|
242
|
+
|
|
243
|
+
A **ready** timer is waiting to start from its current timestamp. It can be ready at `0:00` or at a later position after Reset.
|
|
244
|
+
|
|
245
|
+
| Timer state | Available controls |
|
|
246
|
+
|---|---|
|
|
247
|
+
| Ready | **Start** begins timing, or **Auto-start** indicates that advancing will begin timing. |
|
|
248
|
+
| Running | **Pause** freezes elapsed time. |
|
|
249
|
+
| Paused | **Resume** continues timing, and **Reset** prepares the current slide to begin again. |
|
|
250
|
+
|
|
251
|
+
**Reset** always sets elapsed time to the sum of durations before the current slide. It normally leaves the timer paused; press **Resume** when ready to continue. On a slide with `timer: start`, Reset returns the timer to the ready state at that same timestamp, so advancing starts from the slide's expected time. Reset leaves the current slide unchanged and is only available while paused.
|
|
252
|
+
|
|
253
|
+
After a rehearsal, return to your waiting slide, pause, and press **Reset**. Advancing from that `timer: start` slide starts timing from its expected timestamp, regardless of its position in the deck. For example, a waiting slide after five minutes of allocated content resets to `5:00`, waits, and starts from `5:00` when you advance. The timestamp and ready state are also preserved when saving and restoring the presentation.
|
|
254
|
+
|
|
255
|
+
For slides with recognized timer metadata and a following slide, the **Next** tooltip describes what advancing will actually do. For example, a manually paused `timer: start` slide shows “Timer is paused. Advancing will leave it paused.” After Reset, the tooltip changes to “Advancing will start the timer.” The tooltip also reflects pause and resume actions, including when they would leave the clock unchanged.
|
|
256
|
+
|
|
257
|
+
While the timer is ready, an **Auto-start** indicator replaces **Start** on a `timer: start` slide with a following slide. Its play icon gently pulses, and its tooltip says “Advancing will start the timer.” Advance to begin timing; **Pause** and **Resume** are available while running and paused respectively. The animation respects reduced-motion preferences.
|
|
258
|
+
|
|
239
259
|
### Starting the Timer from a Title Slide
|
|
240
260
|
|
|
241
261
|
A title slide can stay on screen while the audience settles. Add `timer: start` to its frontmatter to start the presentation timer when you advance to the next slide:
|
|
@@ -252,7 +272,7 @@ timer: start
|
|
|
252
272
|
We'll begin shortly.
|
|
253
273
|
```
|
|
254
274
|
|
|
255
|
-
The timer stays
|
|
275
|
+
The timer stays ready while the title is displayed. Advancing from it in `/presenter` or `/display` starts the timer before showing the next slide. Setting `duration: 0` excludes the waiting slide from the expected presentation duration and pacing calculations. The `title` template itself does not control the timer.
|
|
256
276
|
|
|
257
277
|
Durations are read as floating-point seconds, including numeric strings. Negative, invalid, or non-finite values are treated as `0.0`. An unspecified or null duration defaults to `0.0` seconds, meaning no time has been allocated to that slide. Set explicit durations, or apply recorded narration durations, to establish a pacing schedule. When the total allocated duration is zero, the presenter shows elapsed time without pacing indicators, a progress bar, or a remaining-time estimate.
|
|
258
278
|
|
|
@@ -260,9 +280,9 @@ The `timer` field supports these actions:
|
|
|
260
280
|
|
|
261
281
|
| Value | Effect when advancing from this slide |
|
|
262
282
|
|---|---|
|
|
263
|
-
| `start` | Starts
|
|
264
|
-
| `pause` | Pauses the timer, preserving elapsed time. Has no effect
|
|
265
|
-
| `resume` | Resumes a
|
|
283
|
+
| `start` | Starts a ready timer from its current timestamp. Revisiting the slide does not reset elapsed time or resume a manually paused timer. |
|
|
284
|
+
| `pause` | Pauses the timer, preserving elapsed time. Has no effect while ready. |
|
|
285
|
+
| `resume` | Resumes a paused timer, preserving elapsed time. Has no effect while ready or already running. |
|
|
266
286
|
|
|
267
287
|
For a break, put `timer: pause` on the slide immediately before the break slide, and `timer: resume` on the break slide itself. Give the break slide `duration: 0` to exclude the break from pacing calculations. Advancing into the break pauses timing; advancing out resumes it.
|
|
268
288
|
|
data/lib/presently/clock.rb
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
module Presently
|
|
7
7
|
# A simple clock that tracks elapsed time with start, pause, resume, and reset.
|
|
8
8
|
#
|
|
9
|
-
#
|
|
9
|
+
# A ready clock waits to start at its current elapsed time. It accumulates time
|
|
10
|
+
# while running and freezes it when paused.
|
|
10
11
|
class Clock
|
|
11
|
-
# Initialize a new clock in the
|
|
12
|
+
# Initialize a new clock in the ready state at zero.
|
|
12
13
|
def initialize
|
|
13
14
|
@elapsed = 0
|
|
14
15
|
@started = false
|
|
@@ -16,7 +17,7 @@ module Presently
|
|
|
16
17
|
@last_tick = nil
|
|
17
18
|
end
|
|
18
19
|
|
|
19
|
-
# Whether the clock
|
|
20
|
+
# Whether the clock is running or paused; false when ready.
|
|
20
21
|
# @returns [Boolean]
|
|
21
22
|
def started?
|
|
22
23
|
@started
|
|
@@ -35,7 +36,7 @@ module Presently
|
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
# The total elapsed time in seconds.
|
|
38
|
-
# Includes time accumulated up to now if running, or frozen time if paused.
|
|
39
|
+
# Includes time accumulated up to now if running, or frozen time if paused or ready.
|
|
39
40
|
# @returns [Numeric] The elapsed time in seconds.
|
|
40
41
|
def elapsed
|
|
41
42
|
if @running
|
|
@@ -78,12 +79,16 @@ module Presently
|
|
|
78
79
|
@last_tick = Time.now
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
# Reset the
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
# Reset the clock to its initial, ready state, or set its elapsed time.
|
|
83
|
+
# A numeric value preserves whether the clock is running; a ready clock becomes paused.
|
|
84
|
+
# Pass `started: false` to make the clock ready at the given elapsed time.
|
|
85
|
+
# @parameter elapsed [Numeric | Nil] The elapsed time in seconds, or `nil` to clear the clock.
|
|
86
|
+
# @parameter started [Boolean] Whether the clock is running or paused at the reset position; false makes it ready.
|
|
87
|
+
def reset!(elapsed = nil, started: !elapsed.nil?)
|
|
88
|
+
@elapsed = elapsed || 0
|
|
89
|
+
@started = started
|
|
90
|
+
@running = @started && @running
|
|
91
|
+
@last_tick = @running ? Time.now : nil
|
|
87
92
|
end
|
|
88
93
|
end
|
|
89
94
|
end
|
|
@@ -105,9 +105,14 @@ module Presently
|
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
# Reset
|
|
108
|
+
# Reset a paused timer to begin the current slide again.
|
|
109
|
+
# All slides reset to their expected start time. A `timer: start` slide becomes
|
|
110
|
+
# ready to start when advancing; other slides remain paused.
|
|
109
111
|
def reset_timer!
|
|
110
|
-
@clock.
|
|
112
|
+
return unless @clock.paused? && current_slide
|
|
113
|
+
|
|
114
|
+
@clock.reset!(@presentation.expected_time_at(@current_index), started: current_slide.timer != "start")
|
|
115
|
+
|
|
111
116
|
notify_listeners!
|
|
112
117
|
end
|
|
113
118
|
|
|
@@ -133,8 +138,6 @@ module Presently
|
|
|
133
138
|
# The estimated time remaining in the presentation.
|
|
134
139
|
# @returns [Numeric] The remaining time in seconds.
|
|
135
140
|
def time_remaining
|
|
136
|
-
return total_duration unless @clock.started?
|
|
137
|
-
|
|
138
141
|
expected_remaining = @presentation.expected_time_at(slide_count) - @clock.elapsed
|
|
139
142
|
|
|
140
143
|
[expected_remaining, 0].max
|
|
@@ -21,6 +21,7 @@ module Presently
|
|
|
21
21
|
super(id, data)
|
|
22
22
|
@controller = controller
|
|
23
23
|
@clock_task = nil
|
|
24
|
+
@timing_state = nil
|
|
24
25
|
@preview_renderer = SlideRenderer.new(css_class: "slide preview-slide", templates: controller.templates)
|
|
25
26
|
end
|
|
26
27
|
|
|
@@ -51,11 +52,22 @@ module Presently
|
|
|
51
52
|
self.render_slide!
|
|
52
53
|
end
|
|
53
54
|
|
|
54
|
-
#
|
|
55
|
+
# Update the timing section and the Next tooltip when the clock state changes.
|
|
56
|
+
# Leave unchanged, paused controls in place to preserve keyboard focus.
|
|
55
57
|
def update_timing!
|
|
58
|
+
clock = @controller.clock
|
|
59
|
+
state_changed = @timing_state != [clock.started?, clock.running?]
|
|
60
|
+
return unless clock.running? || state_changed
|
|
61
|
+
|
|
56
62
|
replace(".timing") do |builder|
|
|
57
63
|
render_timing(builder, @controller.current_slide)
|
|
58
64
|
end
|
|
65
|
+
|
|
66
|
+
if state_changed
|
|
67
|
+
replace(".next-button") do |builder|
|
|
68
|
+
render_next_button(builder)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
59
71
|
end
|
|
60
72
|
|
|
61
73
|
# Handle an event from the client.
|
|
@@ -77,6 +89,7 @@ module Presently
|
|
|
77
89
|
@controller.clock.pause!
|
|
78
90
|
end
|
|
79
91
|
@controller.save_state!
|
|
92
|
+
update_timing! if @page
|
|
80
93
|
when "reset"
|
|
81
94
|
@controller.reset_timer!
|
|
82
95
|
when "reload"
|
|
@@ -96,13 +109,53 @@ module Presently
|
|
|
96
109
|
Editor.url_for(path, line)
|
|
97
110
|
end
|
|
98
111
|
|
|
112
|
+
# Describe the actual effect of the outgoing slide's timer metadata.
|
|
113
|
+
# @returns [String | Nil] The hint, or `nil` when there is no timer action or next slide.
|
|
114
|
+
def timer_action_hint
|
|
115
|
+
return unless @controller.next_slide
|
|
116
|
+
|
|
117
|
+
clock = @controller.clock
|
|
118
|
+
case @controller.current_slide.timer
|
|
119
|
+
when "start"
|
|
120
|
+
return "Advancing will start the timer." unless clock.started?
|
|
121
|
+
when "pause"
|
|
122
|
+
return "Advancing will pause the timer." if clock.running?
|
|
123
|
+
when "resume"
|
|
124
|
+
return "Advancing will resume the timer." if clock.paused?
|
|
125
|
+
else
|
|
126
|
+
return
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
if clock.running?
|
|
130
|
+
"Advancing will leave the timer running."
|
|
131
|
+
elsif clock.paused?
|
|
132
|
+
"Timer is paused. Advancing will leave it paused."
|
|
133
|
+
else
|
|
134
|
+
"Advancing will leave the timer stopped."
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Render the Next button with a tooltip describing its timer action.
|
|
139
|
+
# @parameter builder [XRB::Builder] The HTML builder.
|
|
140
|
+
def render_next_button(builder)
|
|
141
|
+
builder.tag(:button,
|
|
142
|
+
class: "next-button",
|
|
143
|
+
title: timer_action_hint,
|
|
144
|
+
onClick: forward_event(action: "next")
|
|
145
|
+
) do
|
|
146
|
+
builder.text("Next →")
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
99
150
|
# Render the timing bar with controls, elapsed/remaining time, and pacing.
|
|
100
151
|
# @parameter builder [XRB::Builder] The HTML builder.
|
|
101
152
|
# @parameter slide [Slide | Nil] The current slide.
|
|
102
153
|
def render_timing(builder, slide)
|
|
154
|
+
@timing_state = [@controller.clock.started?, @controller.clock.running?]
|
|
103
155
|
pacing = @controller.pacing
|
|
104
156
|
progress = pacing ? (@controller.slide_progress * 100).round(1) : 0.0
|
|
105
157
|
next_slide = @controller.next_slide
|
|
158
|
+
wait_for_advance = !@controller.clock.started? && slide&.timer == "start" && !!next_slide
|
|
106
159
|
builder.tag(:div, class: "timing", style: "--slide-progress: #{progress}%") do
|
|
107
160
|
pacing_class = case pacing
|
|
108
161
|
when :behind then "behind"
|
|
@@ -111,25 +164,45 @@ module Presently
|
|
|
111
164
|
end
|
|
112
165
|
|
|
113
166
|
builder.tag(:div, class: "toolbar timing-info #{pacing_class}") do
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
|
|
167
|
+
if wait_for_advance
|
|
168
|
+
builder.tag(:span,
|
|
169
|
+
class: "auto-start",
|
|
170
|
+
role: "status",
|
|
171
|
+
title: "Advancing will start the timer."
|
|
172
|
+
) do
|
|
173
|
+
builder.tag(:span, class: "auto-start-icon", "aria-hidden": "true"){builder.text("▶")}
|
|
174
|
+
builder.text("Auto-start")
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
builder.tag(:button,
|
|
178
|
+
class: "pause-button",
|
|
179
|
+
onClick: forward_event(action: "pause")
|
|
180
|
+
) do
|
|
181
|
+
label = if !@controller.clock.started?
|
|
182
|
+
"▶ Start"
|
|
183
|
+
elsif @controller.clock.paused?
|
|
184
|
+
"▶ Resume"
|
|
185
|
+
else
|
|
186
|
+
"⏸ Pause"
|
|
187
|
+
end
|
|
188
|
+
builder.text(label)
|
|
124
189
|
end
|
|
125
|
-
builder.text(label)
|
|
126
190
|
end
|
|
127
191
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
192
|
+
if @controller.clock.paused? && slide
|
|
193
|
+
title = if slide.timer == "start"
|
|
194
|
+
"Reset to this slide's timestamp and wait to start"
|
|
195
|
+
else
|
|
196
|
+
"Reset to this slide's timestamp and stay paused"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
builder.tag(:button,
|
|
200
|
+
class: "pause-button",
|
|
201
|
+
title: title,
|
|
202
|
+
onClick: forward_event(action: "reset")
|
|
203
|
+
) do
|
|
204
|
+
builder.text("↺ Reset")
|
|
205
|
+
end
|
|
133
206
|
end
|
|
134
207
|
|
|
135
208
|
builder.tag(:span, class: "elapsed") do
|
|
@@ -200,11 +273,7 @@ module Presently
|
|
|
200
273
|
builder.text("← Previous")
|
|
201
274
|
end
|
|
202
275
|
|
|
203
|
-
builder
|
|
204
|
-
onClick: forward_event(action: "next")
|
|
205
|
-
) do
|
|
206
|
-
builder.text("Next →")
|
|
207
|
-
end
|
|
276
|
+
render_next_button(builder)
|
|
208
277
|
|
|
209
278
|
builder.tag(:span, class: "slide-info") do
|
|
210
279
|
builder.tag(:span, class: "slide-position") do
|
data/lib/presently/state.rb
CHANGED
|
@@ -9,7 +9,7 @@ require "json"
|
|
|
9
9
|
module Presently
|
|
10
10
|
# Persists and restores presentation controller state to/from a JSON file.
|
|
11
11
|
#
|
|
12
|
-
# Tracks the current slide index, clock elapsed time, and
|
|
12
|
+
# Tracks the current slide index, clock elapsed time, and whether it is ready, running, or paused.
|
|
13
13
|
# This allows the presentation to survive server restarts without losing position.
|
|
14
14
|
class State
|
|
15
15
|
# The default state file path.
|
|
@@ -54,6 +54,8 @@ module Presently
|
|
|
54
54
|
# Restore clock state:
|
|
55
55
|
if data[:started]
|
|
56
56
|
controller.clock.restore!(data[:elapsed].to_f, running: data[:running])
|
|
57
|
+
else
|
|
58
|
+
controller.clock.reset!(data[:elapsed].to_f, started: false)
|
|
57
59
|
end
|
|
58
60
|
rescue => error
|
|
59
61
|
Console.warn(self, "Failed to restore state", exception: error)
|
data/lib/presently/version.rb
CHANGED
data/public/_static/index.css
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
--slide-text: #eee;
|
|
9
9
|
--accent: #e94560;
|
|
10
10
|
--accent-light: #ff6b81;
|
|
11
|
+
--text-emphasis: #6bb8ff;
|
|
11
12
|
--surface: #16213e;
|
|
12
13
|
--surface-light: #0f3460;
|
|
13
14
|
--font-sans: "Inter", "Helvetica Neue", Arial, sans-serif;
|
|
@@ -189,7 +190,7 @@ a {
|
|
|
189
190
|
======================== */
|
|
190
191
|
|
|
191
192
|
strong, b {
|
|
192
|
-
color: var(--
|
|
193
|
+
color: var(--text-emphasis);
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
code {
|
|
@@ -106,6 +106,35 @@
|
|
|
106
106
|
background: var(--accent);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
.timing-info .auto-start {
|
|
110
|
+
display: inline-flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
gap: 0.5rem;
|
|
113
|
+
height: 2.25rem;
|
|
114
|
+
padding: 0.3rem 0.75rem;
|
|
115
|
+
border: 1px solid rgba(233, 69, 96, 0.35);
|
|
116
|
+
border-radius: 6px;
|
|
117
|
+
background: rgba(233, 69, 96, 0.08);
|
|
118
|
+
color: var(--accent-light);
|
|
119
|
+
font-size: 0.9rem;
|
|
120
|
+
white-space: nowrap;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.auto-start-icon {
|
|
124
|
+
animation: auto-start-pulse 2.4s ease-in-out infinite;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@keyframes auto-start-pulse {
|
|
128
|
+
0%, 100% { opacity: 0.5; transform: scale(0.9); }
|
|
129
|
+
50% { opacity: 1; transform: scale(1.1); }
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@media (prefers-reduced-motion: reduce) {
|
|
133
|
+
.auto-start-icon {
|
|
134
|
+
animation: none;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
109
138
|
.timing-info .elapsed {
|
|
110
139
|
font-variant-numeric: tabular-nums;
|
|
111
140
|
}
|
data/readme.md
CHANGED
|
@@ -69,6 +69,12 @@ The task records the presentation at 1920×1080 and 30 frames per second by defa
|
|
|
69
69
|
|
|
70
70
|
Please see the [project releases](https://socketry.github.io/presently/releases/index) for all releases.
|
|
71
71
|
|
|
72
|
+
### v0.27.0
|
|
73
|
+
|
|
74
|
+
- Show **Reset** only while paused. Reset always sets elapsed time to the current slide's expected start. It stays paused on ordinary slides, or becomes ready at that timestamp on a `timer: start` slide. Advancing starts from the preserved timestamp, which also survives saving and restoring the presentation.
|
|
75
|
+
- Describe the effect of slide timer metadata in the **Next** tooltip. Show an animated **Auto-start** indicator when advancing from the current slide will start the timer, with a tooltip explaining how to begin.
|
|
76
|
+
- Make `Clock#reset!` (or `reset!(nil)`) clear the clock to its initial, ready state. Passing a numeric elapsed time preserves whether it is running, or puts a ready clock into the paused state. Pass `started: false` to make the clock ready at a nonzero elapsed time.
|
|
77
|
+
|
|
72
78
|
### v0.26.0
|
|
73
79
|
|
|
74
80
|
- Add `timer: start`, `timer: pause`, and `timer: resume` slide metadata, applied when advancing away from a slide in the presenter or display.
|
|
@@ -122,10 +128,6 @@ Please see the [project releases](https://socketry.github.io/presently/releases/
|
|
|
122
128
|
- Truncate long slide paths responsively while preserving their filenames in presenter controls.
|
|
123
129
|
- Preserve the complete saved presentation state when restoring the controller.
|
|
124
130
|
|
|
125
|
-
### v0.17.2
|
|
126
|
-
|
|
127
|
-
- Fix slide rendering events for generated view identifiers that begin with a digit.
|
|
128
|
-
|
|
129
131
|
## See Also
|
|
130
132
|
|
|
131
133
|
- [lively](https://github.com/socketry/lively) — The real-time application framework that powers Presently.
|
|
@@ -153,12 +155,14 @@ bundle exec sus
|
|
|
153
155
|
|
|
154
156
|
### Making Releases
|
|
155
157
|
|
|
156
|
-
To
|
|
158
|
+
To prepare a release branch and open a pull request from an up-to-date `main`:
|
|
157
159
|
|
|
158
160
|
``` shell
|
|
159
|
-
bundle exec bake gem:release:patch # or minor or major
|
|
161
|
+
bundle exec bake gem:github:release:patch # or minor or major
|
|
160
162
|
```
|
|
161
163
|
|
|
164
|
+
See [bake-gem-github](https://github.com/socketry/bake-gem-github) for setup, remote releases, and recovery.
|
|
165
|
+
|
|
162
166
|
### Developer Certificate of Origin
|
|
163
167
|
|
|
164
168
|
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
data/release.cert
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIEFDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADAwMREwDwYDVQQKDAhTb2Nr
|
|
3
|
+
ZXRyeTEbMBkGA1UEAwwSU29ja2V0cnkgUnVieSBHZW1zMB4XDTI2MDkyMTA3NTgx
|
|
4
|
+
NFoXDTI3MDkyMTA3NTgxNFowMDERMA8GA1UECgwIU29ja2V0cnkxGzAZBgNVBAMM
|
|
5
|
+
ElNvY2tldHJ5IFJ1YnkgR2VtczCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
|
|
6
|
+
ggGBAM/QgjVgDzDo/xJEQoFvAzcVFP7msnswkhPJB2UDsbxXCZmers5jV512TM5s
|
|
7
|
+
NwLHfzJiC4DcI5ax9ZYKM9Q+dS21YYagNqjtg3YPyDqR6phoibEA0VoMuInUQW68
|
|
8
|
+
i5OkCJzYKGD2pYYVZnuFNqyM2ECUvXh/fBmvPoHbncAHhWPaCBH8mQJ8sRNc6+RV
|
|
9
|
+
SoZZu1Yo/aW1zQ+SpZwad7s1ZmigfDNHKhJ22KwZHk+/5Zw1QXVfcajjswV0Mm2P
|
|
10
|
+
irgjKN3fyNVkwlly63EBlR4VydT+g9QtJtqh7ee0ThhI+v4wYovf4dbLNcEBTHu1
|
|
11
|
+
x1pGbXGx/2fBAST5eVwaXIx1V8VU22AJcBk1H2o5/1F0HfbD2HQjmFOA112KUwBW
|
|
12
|
+
9TtspZD3g6rCQFX53XvL9h6j2y1ukl7s5AdEzOe/x6r1MO8tSDtgcYoF89wgF/88
|
|
13
|
+
Q/Eski0FckQ+znfESZcFcpzs2sPDoYW6SNVX4tZcNty85Y6WBHfHKio14x63PeyC
|
|
14
|
+
CG1gMwIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
|
|
15
|
+
SuMc0x24Xshtaa8SQVkBr2Z5WzIwDQYJKoZIhvcNAQELBQADggGBABI62ey5lDWm
|
|
16
|
+
j8jsTQaNBMBb7LbKS3XkBwyL1UNGEwlicp399rJDeuNgVSHqBCZ/nE4yleNjgW9Y
|
|
17
|
+
N6DKdxXCvXmFUoHvUINeAvThHxmlEGhSfXl1x55xHEig0rEP4jgdjnYdQI4fqeOM
|
|
18
|
+
zIDN0F3ruArke4Y62SQgWVN7vspdAA41hBIRl1vsvs0KWG8DIVQ8cmR+TG6zjOmK
|
|
19
|
+
iUiUZGNPnStV1O1xW83c+Ba4Am0krP6/forxDPhRvTehqkVYvMdPfYcICNb5IM58
|
|
20
|
+
5vaYvuj5AtfZuZWN0F/0KtSphhNC17rh6h8QmuYdMJ1clvlrkiEaO1UjPVwjgtxC
|
|
21
|
+
x/ARh5X6q0/YTXl4r7EfSJEeqW7qhgu9EUj3mGIPHYdX0Dqih/NgK20F3GvQtTfB
|
|
22
|
+
7sse0duKBHXONYVwKAsceUVvqtCfyF608bCilCkbhw3QaInRj+BkRQKJ5Tuj2PZR
|
|
23
|
+
76a/hwaV2wWn5RtAFBaUQzQdo/xTqJ7IkwaFjOZe/QyvyoRjCK9Rdg==
|
|
24
|
+
-----END CERTIFICATE-----
|
data/releases.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.27.0
|
|
4
|
+
|
|
5
|
+
- Show **Reset** only while paused. Reset always sets elapsed time to the current slide's expected start. It stays paused on ordinary slides, or becomes ready at that timestamp on a `timer: start` slide. Advancing starts from the preserved timestamp, which also survives saving and restoring the presentation.
|
|
6
|
+
- Describe the effect of slide timer metadata in the **Next** tooltip. Show an animated **Auto-start** indicator when advancing from the current slide will start the timer, with a tooltip explaining how to begin.
|
|
7
|
+
- Make `Clock#reset!` (or `reset!(nil)`) clear the clock to its initial, ready state. Passing a numeric elapsed time preserves whether it is running, or puts a ready clock into the paused state. Pass `started: false` to make the clock ready at a nonzero elapsed time.
|
|
8
|
+
|
|
3
9
|
## v0.26.0
|
|
4
10
|
|
|
5
11
|
- Add `timer: start`, `timer: pause`, and `timer: resume` slide metadata, applied when advancing away from a slide in the presenter or display.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: presently
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.28.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -9,32 +9,28 @@ bindir: bin
|
|
|
9
9
|
cert_chain:
|
|
10
10
|
- |
|
|
11
11
|
-----BEGIN CERTIFICATE-----
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
|
|
35
|
-
eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
|
|
36
|
-
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
|
37
|
-
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
|
12
|
+
MIIEFDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADAwMREwDwYDVQQKDAhTb2Nr
|
|
13
|
+
ZXRyeTEbMBkGA1UEAwwSU29ja2V0cnkgUnVieSBHZW1zMB4XDTI2MDkyMTA3NTgx
|
|
14
|
+
NFoXDTI3MDkyMTA3NTgxNFowMDERMA8GA1UECgwIU29ja2V0cnkxGzAZBgNVBAMM
|
|
15
|
+
ElNvY2tldHJ5IFJ1YnkgR2VtczCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
|
|
16
|
+
ggGBAM/QgjVgDzDo/xJEQoFvAzcVFP7msnswkhPJB2UDsbxXCZmers5jV512TM5s
|
|
17
|
+
NwLHfzJiC4DcI5ax9ZYKM9Q+dS21YYagNqjtg3YPyDqR6phoibEA0VoMuInUQW68
|
|
18
|
+
i5OkCJzYKGD2pYYVZnuFNqyM2ECUvXh/fBmvPoHbncAHhWPaCBH8mQJ8sRNc6+RV
|
|
19
|
+
SoZZu1Yo/aW1zQ+SpZwad7s1ZmigfDNHKhJ22KwZHk+/5Zw1QXVfcajjswV0Mm2P
|
|
20
|
+
irgjKN3fyNVkwlly63EBlR4VydT+g9QtJtqh7ee0ThhI+v4wYovf4dbLNcEBTHu1
|
|
21
|
+
x1pGbXGx/2fBAST5eVwaXIx1V8VU22AJcBk1H2o5/1F0HfbD2HQjmFOA112KUwBW
|
|
22
|
+
9TtspZD3g6rCQFX53XvL9h6j2y1ukl7s5AdEzOe/x6r1MO8tSDtgcYoF89wgF/88
|
|
23
|
+
Q/Eski0FckQ+znfESZcFcpzs2sPDoYW6SNVX4tZcNty85Y6WBHfHKio14x63PeyC
|
|
24
|
+
CG1gMwIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
|
|
25
|
+
SuMc0x24Xshtaa8SQVkBr2Z5WzIwDQYJKoZIhvcNAQELBQADggGBABI62ey5lDWm
|
|
26
|
+
j8jsTQaNBMBb7LbKS3XkBwyL1UNGEwlicp399rJDeuNgVSHqBCZ/nE4yleNjgW9Y
|
|
27
|
+
N6DKdxXCvXmFUoHvUINeAvThHxmlEGhSfXl1x55xHEig0rEP4jgdjnYdQI4fqeOM
|
|
28
|
+
zIDN0F3ruArke4Y62SQgWVN7vspdAA41hBIRl1vsvs0KWG8DIVQ8cmR+TG6zjOmK
|
|
29
|
+
iUiUZGNPnStV1O1xW83c+Ba4Am0krP6/forxDPhRvTehqkVYvMdPfYcICNb5IM58
|
|
30
|
+
5vaYvuj5AtfZuZWN0F/0KtSphhNC17rh6h8QmuYdMJ1clvlrkiEaO1UjPVwjgtxC
|
|
31
|
+
x/ARh5X6q0/YTXl4r7EfSJEeqW7qhgu9EUj3mGIPHYdX0Dqih/NgK20F3GvQtTfB
|
|
32
|
+
7sse0duKBHXONYVwKAsceUVvqtCfyF608bCilCkbhw3QaInRj+BkRQKJ5Tuj2PZR
|
|
33
|
+
76a/hwaV2wWn5RtAFBaUQzQdo/xTqJ7IkwaFjOZe/QyvyoRjCK9Rdg==
|
|
38
34
|
-----END CERTIFICATE-----
|
|
39
35
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
40
36
|
dependencies:
|
|
@@ -265,6 +261,7 @@ files:
|
|
|
265
261
|
- public/playback.js
|
|
266
262
|
- public/recording_controls.js
|
|
267
263
|
- readme.md
|
|
264
|
+
- release.cert
|
|
268
265
|
- releases.md
|
|
269
266
|
- templates/code.xrb
|
|
270
267
|
- templates/default.xrb
|
|
@@ -295,7 +292,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
295
292
|
- !ruby/object:Gem::Version
|
|
296
293
|
version: '0'
|
|
297
294
|
requirements: []
|
|
298
|
-
rubygems_version: 4.0.
|
|
295
|
+
rubygems_version: 4.0.21
|
|
299
296
|
specification_version: 4
|
|
300
297
|
summary: A web-based presentation tool built with Lively.
|
|
301
298
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|