diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-29 14:24:16 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-29 14:24:16 +0200 |
| commit | 855859bdaac101e7e87d5cb0237b7c30f4f4b371 (patch) | |
| tree | e0d4af3c9082c4b7ceba2d05471c6a162cfe2940 /internal/web/templates/index.html | |
| parent | 18578434f41d4fe34438c2f171388109a288c18c (diff) | |
| download | lectio-855859bdaac101e7e87d5cb0237b7c30f4f4b371.tar.gz lectio-855859bdaac101e7e87d5cb0237b7c30f4f4b371.zip | |
web: declutter the UI, fix date arrows, red * for bookmarked verses in reader
Daily page (index.html):
- Date arrows now step the date input client-side and dispatch its change, so
they move relative to the CURRENT day and update the shown date (they were
stuck one step from the initial date, computed server-side).
- Theme picker removed (theme lives only in /settings now); bookmarks link
removed (bookmarks belong to the reader, not the daily readings).
- reader/settings nav + the download links move to a right-aligned .controls-side
cluster; essential controls (date, lectionary, versions, parts, layout, mono)
stay on the left. mono stops its change bubbling so it no longer refetches.
Reader (reader.html + RenderPassage): a bookmarked verse now shows a red "*"
(end of line in columns, after the verse number interlinear). Threaded a
marked set (keyed "chap:verse") through the reader render path only; the daily
RenderReadings path is untouched.
Settings (settings.html): Save button moved to the top; removed offline (dead),
width and pager (CLI/TUI-only, no web effect) -- their config values are
preserved since the handler no longer reads/zeroes them.
Footer: source/licence centred.
Web tests + full suite green both build modes.
Diffstat (limited to 'internal/web/templates/index.html')
| -rw-r--r-- | internal/web/templates/index.html | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/internal/web/templates/index.html b/internal/web/templates/index.html index b99725d..c706323 100644 --- a/internal/web/templates/index.html +++ b/internal/web/templates/index.html @@ -1,15 +1,12 @@ -{{/* index.html renders the full lectio-web page: top-bar controls (date, - lectionary, version checkboxes, all/gospel toggle, display select, - theme select) and the pre-rendered reading pane (#pane). +{{/* index.html renders the full lectio-web page: essential controls on the left + (date, lectionary, version checkboxes, all/gospel, layout, mono) and, pushed + to the right, the nav + download links. Theme lives only in /settings now. - The controls form (#controls) carries hx-get="/readings" and fires on - any "change" bubbling up from its fields (htmx auto-includes an - hx-get element's enclosing form fields as the request's query - params -- no hx-include needed), so "display" needs no extra wiring - beyond living inside #controls. The date +/- buttons are separate - hx-get elements nested in the same form so their own field values are - included too; they override "date" via hx-vals. The theme <select> - has no server round trip: it swaps the #theme <link>'s href directly. */}} + The controls form (#controls) carries hx-get="/readings" and fires on any + bubbling "change", so the readings pane re-fetches when a field changes. + The date arrows step the date input by a day client-side and dispatch its + change (so navigation is relative to the CURRENT date and updates the shown + day). mono lives OUTSIDE the form so toggling it doesn't refetch readings. */}} <!doctype html> <html lang="{{.Lang}}"> <head> @@ -19,6 +16,16 @@ <link rel="stylesheet" href="/static/base.css"> <link id="theme" rel="stylesheet" href="/theme.css?name={{.Theme}}"> <script src="/static/htmx.min.js"></script> +<script> +function stepDate(n){ + var el=document.querySelector('#controls input[name=date]'); + if(!el||!el.value)return; + var d=new Date(el.value+'T00:00:00'); + d.setDate(d.getDate()+n); + el.value=d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0'); + el.dispatchEvent(new Event('change',{bubbles:true})); +} +</script> </head> <body{{if .Mono}} class="mono"{{end}}> <div class="page"> @@ -28,11 +35,9 @@ version unchecked (show nothing) from a fresh visit (config default). */}} <input type="hidden" name="vset" value="1"> <span class="date-nav"> - <button type="button" hx-get="/readings" hx-target="#pane" - hx-vals='{"date":"{{.PrevDate}}"}'>←</button> + <button type="button" onclick="stepDate(-1)">←</button> <input type="date" name="date" value="{{.Date}}"> - <button type="button" hx-get="/readings" hx-target="#pane" - hx-vals='{"date":"{{.NextDate}}"}'>→</button> + <button type="button" onclick="stepDate(1)">→</button> </span> <label>{{.L.Lectionary}} @@ -61,31 +66,24 @@ </select> </label> - <a class="nav-link" href="/reader">{{.L.NavReader}} →</a> - <a class="nav-link" href="/settings">{{.L.NavSettings}}</a> - <a class="nav-link" href="/bookmarks">{{.L.NavBookmarks}}</a> - </form> - - <label class="theme-picker">{{.L.Theme}} - <select id="theme-select" - onchange="var o=document.getElementById('theme'),n=o.cloneNode(false);n.setAttribute('href','/theme.css?name='+encodeURIComponent(this.value));o.replaceWith(n);"> - {{range .ThemeOpts}} - <option value="{{.Name}}" {{if .Selected}}selected{{end}}>{{.Name}}</option> - {{end}} - </select> - </label> - - <label class="mono-toggle"><input type="checkbox" {{if .Mono}}checked{{end}} - onchange="document.body.classList.toggle('mono', this.checked)"> {{.L.Mono}}</label> + {{/* mono lives in the form but stops its change from bubbling, so toggling + it flips the body class without refetching the readings. */}} + <label class="mono-toggle"><input type="checkbox" {{if .Mono}}checked{{end}} + onchange="event.stopPropagation();document.body.classList.toggle('mono', this.checked)"> {{.L.Mono}}</label> - {{/* Download the current readings; the URL is built from the live control - values at click time so it always matches what's on screen. */}} - <span class="export">{{.L.Export}}: - <a href="#" onclick="location='/export?fmt=txt&'+new URLSearchParams(new FormData(document.getElementById('controls'))).toString();return false;">txt</a> - <a href="#" onclick="location='/export?fmt=md&'+new URLSearchParams(new FormData(document.getElementById('controls'))).toString();return false;">md</a> - <a href="#" onclick="location='/export?fmt=pdf&'+new URLSearchParams(new FormData(document.getElementById('controls'))).toString();return false;">pdf</a> - · <a href="#" onclick="var d=(document.querySelector('#controls [name=date]').value||'').slice(0,7);location='/calendar?month='+d+'&lectionary='+document.querySelector('#controls [name=lectionary]').value;return false;">{{.L.Calendar}}</a> - </span> + {{/* Utility links, pushed to the right (see .controls-side). The export URLs + are built from the live control values at click time. */}} + <span class="controls-side"> + <a class="nav-link" href="/reader">{{.L.NavReader}} →</a> + <a class="nav-link" href="/settings">{{.L.NavSettings}}</a> + <span class="export">{{.L.Export}}: + <a href="#" onclick="location='/export?fmt=txt&'+new URLSearchParams(new FormData(document.getElementById('controls'))).toString();return false;">txt</a> + <a href="#" onclick="location='/export?fmt=md&'+new URLSearchParams(new FormData(document.getElementById('controls'))).toString();return false;">md</a> + <a href="#" onclick="location='/export?fmt=pdf&'+new URLSearchParams(new FormData(document.getElementById('controls'))).toString();return false;">pdf</a> + · <a href="#" onclick="var d=(document.querySelector('#controls [name=date]').value||'').slice(0,7);location='/calendar?month='+d+'&lectionary='+document.querySelector('#controls [name=lectionary]').value;return false;">{{.L.Calendar}}</a> + </span> + </span> + </form> <div id="pane">{{.Reading}}</div> |
