oficina / slides Public

Clone
git clone https://amadan.net/oficina/slides

Plain git — no account needed to clone.

Download

Download this file

1{{/* present_notes — GET /p/{session}/notes, the presenter view.
2
3 The screen somebody actually presents from: what the room is
4 looking at, what is coming next, the notes for the slide that is
5 up, a clock, and the four controls. Meant for a second window on a
6 laptop or for the presenter's own phone.
7
8 The pairing block appears exactly once — on the one request that
9 carries the remote capability, and only for the person presenting
10 (presentation.go says why). Coming back to this URL later shows
11 the talk and no secret, because there is no secret left to show:
12 only the hash was stored. */}}
13{{define "page-head"}}<link rel="stylesheet" href="{{asset "static/slides.css"}}">
14<script defer src="{{asset "static/present.js"}}"></script>
15<style>
16 /* Two slides side by side above the notes, and one column the
17 moment there is not room for two — the notes are the part being
18 read, so they get the width. */
19 [slides-preview] {
20 display: grid;
21 gap: var(--rst-sp-4);
22 grid-template-columns: 2fr 1fr;
23 }
24 @media (max-width: 60rem) {
25 [slides-preview] {
26 grid-template-columns: 1fr;
27 }
28 }
29 /* The two slides are pictures of themselves (presentation.go's
30 slideThumbImg): one <img> each of the session's SVG thumbnail,
31 rather than a live copy of the slide. A border and a background
32 under it so a picture still loading is a slide-shaped space. */
33 [slides-thumb-img] {
34 aspect-ratio: 16 / 9;
35 background: var(--rst-surface-2);
36 block-size: auto;
37 border: 1px solid var(--rst-line);
38 border-radius: var(--rst-radius);
39 display: block;
40 inline-size: 100%;
41 }
42 [slides-clock] {
43 align-items: baseline;
44 display: flex;
45 flex-wrap: wrap;
46 gap: var(--rst-sp-3);
47 }
48 [slides-clock-now] {
49 font-size: var(--rst-fs-lg);
50 font-variant-numeric: tabular-nums;
51 margin: 0;
52 }
53 [slides-clock] p {
54 color: var(--rst-text-muted);
55 margin: 0;
56 }
57 [slides-commands] {
58 display: flex;
59 flex-wrap: wrap;
60 gap: var(--rst-sp-2);
61 }
62 [slides-commands] form {
63 margin: 0;
64 }
65 [slides-commands] button {
66 min-height: 44px;
67 }
68 [slides-tools] {
69 display: flex;
70 flex-wrap: wrap;
71 gap: var(--rst-sp-2);
72 }
73 [slides-code] {
74 font-size: var(--rst-fs-lg);
75 letter-spacing: 0.25em;
76 margin: 0;
77 }
78 [slides-pair] {
79 display: flex;
80 flex-wrap: wrap;
81 gap: var(--rst-sp-4);
82 }
83 [slides-pair-fields] {
84 flex: 1 1 18rem;
85 }
86</style>{{end}}
87{{define "content"}}
88{{template "page-header" dict "Title" .Title "Sub" .DeckTitle}}
89
90<div slides-clock>
91 <p slides-clock-now data-clock>{{.Clock}}</p>
92 <p>{{.Started}}</p>
93 <p data-elapsed-since="{{.StartedAt}}" data-elapsed-template="{{.ElapsedTemplate}}">{{.Elapsed}}</p>
94 <p slides-counter>{{.Counter}}</p>
95</div>
96
97{{if .Blackout}}
98{{/* State in words, never in colour alone: the presenter's own screen
99 is the one place that has to say the room is looking at nothing. */}}
100{{template "status-pill" dict "Tone" "neutral" "Label" .BlackoutLabel}}
101{{end}}
102
103{{if .Controls}}
104<div slides-commands>{{template "present-controls" .Controls}}</div>
105{{end}}
106
107{{/* The script's root: the session it is watching, and — only when
108 this request carried it — the capability its keyboard sends with.
109 A presenter view opened without the token watches and cannot
110 drive, which is exactly what the buttons above do too. */}}
111<div slides-preview data-session="{{.Session}}"
112 data-slide="{{.Now}}"
113 data-blackout="{{if .Blackout}}true{{else}}false{{end}}"
114 {{- if .Token}} data-remote-token="{{.Token}}"{{end}}>
115 <div>
116 <h2>{{.CurrentLabel}}</h2>
117 {{.Current}}
118 </div>
119 <div>
120 <h2>{{.NextLabel}}</h2>
121 {{if .HasNext}}{{.Next}}{{end}}
122 </div>
123</div>
124
125<div rst-box>
126 <h2>{{.NotesLabel}}</h2>
127 {{if .Notes}}{{.Notes}}{{else}}<p>{{.NoNotes}}</p>{{end}}
128</div>
129
130{{if .Pair}}
131<div rst-box>
132 {{template "callout" dict "Tone" "info" "Title" .PairTitle "Body" .PairBody}}
133 <div slides-pair>
134 {{.QR}}
135 <div slides-pair-fields>
136 <p slides-code>{{.Code}}</p>
137 {{/* Hand-written for one attribute, share.html's reason: readonly
138 is not in field-text's contract, and the field is here to be
139 selected and copied. */}}
140 <div rst-field>
141 <label rst-field-label for="remote-url">{{.URLLabel}}</label>
142 <input rst-input id="remote-url" name="remote-url" type="text"
143 value="{{.RemoteURL}}" readonly aria-describedby="remote-url-hint">
144 <small rst-field-hint id="remote-url-hint">{{.CodeLabel}} {{.Code}}</small>
145 </div>
146 </div>
147 </div>
148</div>
149{{end}}
150
151<nav slides-tools aria-label="{{.ToolsLabel}}">
152 {{if .StageHref}}<a rst-btn href="{{.StageHref}}">{{.StageLabel}}</a>{{end}}
153 <a rst-btn href="{{.DeckHref}}">{{.DeckLabel}}</a>
154</nav>
155{{end}}
156