diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/config/config.go | 2 | ||||
| -rw-r--r-- | internal/web/server.go | 29 | ||||
| -rw-r--r-- | internal/web/server_test.go | 30 | ||||
| -rw-r--r-- | internal/web/templates/index.html | 3 |
4 files changed, 56 insertions, 8 deletions
diff --git a/internal/config/config.go b/internal/config/config.go index 9a6df04..493b4f5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -24,7 +24,7 @@ var seedTOML []byte // Version is lectio's release version, shared by every binary's // -v/--version output (lectio, lectio-ui, lectio-web). -const Version = "0.12.0" +const Version = "0.13.0" // validVersions are the five scripture versions lectio understands. var validVersions = map[string]bool{ diff --git a/internal/web/server.go b/internal/web/server.go index 667e986..6393076 100644 --- a/internal/web/server.go +++ b/internal/web/server.go @@ -89,13 +89,18 @@ func shiftDate(date string, days int) string { } // requestVersions returns the versions requested via one or more repeated -// ?v= query params, falling back to a single cfg.DefaultVersion (not the -// full cfg.Versions set) when none were given, so a plain visit checks -// exactly one version box. +// ?v= query params. The controls form always submits a hidden "vset" marker, +// so a request that carries "vset" but no "v" means the user unchecked EVERY +// version -- return none (the pane then shows nothing). A request with neither +// (a fresh visit or a bare link) falls back to cfg.WebVersions, else a single +// cfg.DefaultVersion, so a plain visit checks exactly one box. func requestVersions(cfg config.Config, r *http.Request) []string { if vs, ok := r.URL.Query()["v"]; ok && len(vs) > 0 { return vs } + if r.URL.Query().Has("vset") { + return nil // form submitted with every box unchecked + } if len(cfg.WebVersions) > 0 { return append([]string(nil), cfg.WebVersions...) } @@ -214,8 +219,15 @@ func indexHandler(cfg config.Config) http.HandlerFunc { theme = cfg.WebTheme } - secs, dayInfo, loadVersions, err := loadSections(cfg, lectionary, date, all, versions) - reading := renderOrError(secs, loadVersions, lectionary, display, cfg.UILanguage, dayInfo, err) + // No version selected -> fetch nothing and show nothing (empty pane, no + // day-info/headings); loadVersions stays nil so no box is checked. + var reading template.HTML + var loadVersions []string + if len(versions) > 0 { + secs, dayInfo, lv, err := loadSections(cfg, lectionary, date, all, versions) + loadVersions = lv + reading = renderOrError(secs, lv, lectionary, display, cfg.UILanguage, dayInfo, err) + } // Check the boxes for the versions actually rendered (loadVersions), // not the raw request: traditional/offline substitute pl->wuj, so the @@ -264,8 +276,11 @@ func readingsHandler(cfg config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { date, lectionary, all, versions, display := resolveQuery(cfg, r) - secs, dayInfo, loadVersions, err := loadSections(cfg, lectionary, date, all, versions) - reading := renderOrError(secs, loadVersions, lectionary, display, cfg.UILanguage, dayInfo, err) + var reading template.HTML + if len(versions) > 0 { + secs, dayInfo, loadVersions, err := loadSections(cfg, lectionary, date, all, versions) + reading = renderOrError(secs, loadVersions, lectionary, display, cfg.UILanguage, dayInfo, err) + } w.Header().Set("Content-Type", "text/html; charset=utf-8") io.WriteString(w, string(reading)) diff --git a/internal/web/server_test.go b/internal/web/server_test.go index 638eb2b..925ea18 100644 --- a/internal/web/server_test.go +++ b/internal/web/server_test.go @@ -407,6 +407,36 @@ func TestChooseListener(t *testing.T) { }) } +// TestVsetEmptyShowsNothing guards the "uncheck all -> show nothing" behavior: +// a form submit (vset present) with no v param yields an empty pane, while a +// fresh visit (no vset) checks the config default and renders it. +func TestVsetEmptyShowsNothing(t *testing.T) { + srv := NewServer(config.Default()) + + // Form submit, every box unchecked: empty pane, nothing checked. + empty := httptest.NewRecorder() + srv.ServeHTTP(empty, httptest.NewRequest("GET", "/readings?vset=1&lectionary=traditional", nil)) + if b := strings.TrimSpace(empty.Body.String()); b != "" { + t.Errorf("readings with vset and no v should be empty, got %q", b) + } + + // Fresh visit (no vset): config default (bt for modern) box is checked. + fresh := httptest.NewRecorder() + srv.ServeHTTP(fresh, httptest.NewRequest("GET", "/", nil)) + if !strings.Contains(fresh.Body.String(), `value="bt" checked`) { + t.Errorf("fresh visit should check the config default (bt) version box") + } + + // Full page with vset and no v: no VERSION box checked (mono may be). + idx := httptest.NewRecorder() + srv.ServeHTTP(idx, httptest.NewRequest("GET", "/?vset=1", nil)) + for _, v := range bibleVersions { + if strings.Contains(idx.Body.String(), `value="`+v+`" checked`) { + t.Errorf("index with vset and no v: %q box should not be checked", v) + } + } +} + // TestReaderPaneOutsideForm guards the mono fix: #pane must render AFTER the // controls </form> so its reading text inherits body's --font-reading (which // the mono toggle flips) instead of the form's --font-ui. diff --git a/internal/web/templates/index.html b/internal/web/templates/index.html index 5dbe7da..6920fcb 100644 --- a/internal/web/templates/index.html +++ b/internal/web/templates/index.html @@ -24,6 +24,9 @@ <div class="page"> <form id="controls" class="controls" hx-get="/readings" hx-target="#pane" hx-trigger="change"> + {{/* Always-present marker so the server can tell a form submit with every + 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> |
