From 855859bdaac101e7e87d5cb0237b7c30f4f4b371 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Wed, 29 Jul 2026 14:24:16 +0200 Subject: 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. --- internal/web/server.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'internal/web/server.go') diff --git a/internal/web/server.go b/internal/web/server.go index 92cb758..7d9dfe5 100644 --- a/internal/web/server.go +++ b/internal/web/server.go @@ -72,7 +72,7 @@ func NewServer(cfg config.Config) http.Handler { mux.HandleFunc("GET /calendar", func(w http.ResponseWriter, r *http.Request) { calendarHandler(s.get())(w, r) }) mux.HandleFunc("GET /api/calendar.json", func(w http.ResponseWriter, r *http.Request) { apiCalendarJSONHandler(s.get())(w, r) }) mux.HandleFunc("GET /calendar.ics", func(w http.ResponseWriter, r *http.Request) { calendarICSHandler(s.get())(w, r) }) - mux.HandleFunc("GET /reader", func(w http.ResponseWriter, r *http.Request) { readerHandler(s.get(), s.table())(w, r) }) + mux.HandleFunc("GET /reader", func(w http.ResponseWriter, r *http.Request) { readerHandler(s.get(), s.table(), s.bm)(w, r) }) mux.HandleFunc("GET /theme.css", func(w http.ResponseWriter, r *http.Request) { themeCSSHandler(s.get())(w, r) }) mux.HandleFunc("GET /source", sourceHandler) mux.HandleFunc("GET /settings", settingsGet(s)) @@ -500,7 +500,7 @@ type chapOpt struct { // navigation and corpus-version compare, rendering the same reading-pane // templates/themes as the daily view. The controls form re-fetches /reader and // hx-selects #reader-root, so book/chapter/version selects stay in sync. -func readerHandler(cfg config.Config, tbl *bible.BookTable) http.HandlerFunc { +func readerHandler(cfg config.Config, tbl *bible.BookTable, bm *bookmarks.Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { books := tbl.Books(cfg.SiglaLang()) if len(books) == 0 { // defensive: embedded table always has books @@ -525,7 +525,18 @@ func readerHandler(cfg config.Config, tbl *bible.BookTable) http.HandlerFunc { theme = cfg.WebTheme } - reading := RenderPassage(info.Canonical, info.Name, chap, versions, display, cfg.UILanguage) + // Verses in this book+chapter that carry a bookmark get a red "*". + marked := map[string]bool{} + if bm != nil { + if all, err := bm.List(""); err == nil { + for _, b := range all { + if b.Book == info.Canonical && b.Chapter == chap { + marked[fmt.Sprintf("%d:%d", b.Chapter, b.Verse)] = true + } + } + } + } + reading := RenderPassage(info.Canonical, info.Name, chap, versions, display, cfg.UILanguage, marked) bookOpts := make([]bookOpt, 0, len(books)) for _, b := range books { @@ -807,11 +818,10 @@ func settingsPost(s *server) http.HandlerFunc { cfg.Versions = r.PostForm["versions"] cfg.WebVersions = r.PostForm["web_versions"] cfg.All = r.PostForm.Get("all") != "" - cfg.Offline = r.PostForm.Get("offline") != "" cfg.WebMono = r.PostForm.Get("web_mono") != "" - cfg.Width = atoiOr(r.PostForm.Get("width"), cfg.Width) cfg.WebPort = atoiOr(r.PostForm.Get("web_port"), cfg.WebPort) - cfg.Pager = r.PostForm.Get("pager") + // offline, width and pager are not web-editable; their config values are + // preserved (the form no longer carries those fields). booksText := r.PostForm.Get("books") -- cgit v1.3