| 1 | {{/* present-controls — the command buttons, shared by the presenter |
| 2 | view, the phone remote and the presenter's own fullscreen surface. |
| 3 | |
| 4 | Every button is its own <form method="post">, and that is the |
| 5 | whole point: with scripts off the remote still drives the talk |
| 6 | (spec §8), because a form and a redirect need nothing but a |
| 7 | browser. static/present.js posts the same fields with fetch when |
| 8 | it is there, so the two paths send identical requests and there is |
| 9 | no second protocol to keep in step. |
| 10 | |
| 11 | The capability rides as a hidden field rather than living in the |
| 12 | form's action: an action carrying a token would put it in the |
| 13 | address bar of every page the redirect lands on. |
| 14 | |
| 15 | Keys (the whole `controls` struct, presentation.go): |
| 16 | Action string — /p/{session}/command |
| 17 | Token string — the remote capability |
| 18 | Buttons []{Op, Label, Slide} — one form each; Slide only for a |
| 19 | goto, which nothing renders yet and which the handler |
| 20 | accepts so a native remote has it. */}} |
| 21 | {{/* data-busy="false": the busy rule is for buttons that save something. |
| 22 | Next, Previous and Blackout save nothing — they are presenting |
| 23 | controls, and they stay instant (Paul, 2026-09-29). */}} |
| 24 | {{define "present-controls"}} |
| 25 | {{- range .Buttons}} |
| 26 | <form method="post" action="{{$.Action}}" data-busy="false"> |
| 27 | <input type="hidden" name="op" value="{{.Op}}"> |
| 28 | {{- if .Slide}} |
| 29 | <input type="hidden" name="slide" value="{{.Slide}}"> |
| 30 | {{- end}} |
| 31 | <input type="hidden" name="t" value="{{$.Token}}"> |
| 32 | <button rst-btn type="submit" slides-op="{{.Op}}">{{.Label}}</button> |
| 33 | </form> |
| 34 | {{- end}} |
| 35 | {{end}} |
| 36 | |