Fix chapter reader nav bar: use hamburger icon for back-to-book, show chapter date below title
Some checks failed
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

- Replace bare ← back-to-book link with ☰ (hamburger) icon to eliminate
  the visual double-arrow confusion with the ← Prev chapter button
- Export SplitChapterTitle in writer package and call it in handleChapter
  to split the raw heading into (title, date) — fixes concatenated title+date bug
- Display ChapterDate as a smaller muted line below the chapter title
  in the center nav button
- Bump nav bar height from h-12 to h-14 to accommodate two-line center button
This commit is contained in:
Admin
2026-03-01 22:03:47 +05:00
parent ca33f8c3cf
commit 7e4bb87da0
2 changed files with 18 additions and 12 deletions

View File

@@ -1379,19 +1379,19 @@ const chapterTmpl = `
<!-- aria-hidden keeps it out of accessibility trees / Reader Mode heuristics -->
<nav id="reader-header" aria-hidden="true"
style="position:sticky;top:0;z-index:50;background:#09090b;border-bottom:1px solid #27272a;">
<div class="max-w-2xl mx-auto px-4 flex items-center gap-2 h-12">
<div class="max-w-2xl mx-auto px-4 flex items-center gap-2 h-14">
<!-- Back to book -->
<!-- Back to book (book/list icon, visually distinct from ← Prev) -->
<a href="/books/{{.Slug}}"
hx-get="/books/{{.Slug}}"
hx-target="#main-content"
hx-push-url="true"
hx-swap="innerHTML"
title="Chapter list"
title="Back to chapter list"
aria-label="Back to chapter list"
style="flex-shrink:0;padding:0.375rem 0.5rem;border-radius:0.5rem;color:#a1a1aa;font-size:0.875rem;text-decoration:none;transition:color 0.15s;"
style="flex-shrink:0;padding:0.375rem 0.5rem;border-radius:0.5rem;color:#a1a1aa;font-size:1rem;text-decoration:none;transition:color 0.15s;line-height:1;"
onmouseover="this.style.color='#fbbf24'" onmouseout="this.style.color='#a1a1aa'">
&#8592;
&#9776;
</a>
<!-- Prev chapter -->
@@ -1416,8 +1416,11 @@ const chapterTmpl = `
onclick="toggleChapterList()"
title="Jump to chapter"
aria-label="Jump to chapter"
style="flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:0.375rem;overflow:hidden;background:transparent;border:none;cursor:pointer;padding:0.375rem 0.25rem;">
<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:0.8125rem;color:#a1a1aa;">{{.Title}}</span>
style="flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:0.375rem;overflow:hidden;background:transparent;border:none;cursor:pointer;padding:0.25rem 0.25rem;">
<span style="min-width:0;display:flex;flex-direction:column;align-items:center;overflow:hidden;">
<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:0.8125rem;color:#a1a1aa;max-width:100%;">{{.Title}}</span>
{{if .ChapterDate}}<span style="font-size:0.6875rem;color:#52525b;white-space:nowrap;">{{.ChapterDate}}</span>{{end}}
</span>
<span style="flex-shrink:0;font-size:0.625rem;color:#52525b;" aria-hidden="true">&#9660;</span>
</button>
@@ -2166,6 +2169,7 @@ func (s *Server) handleChapter(w http.ResponseWriter, r *http.Request) {
prevN, nextN := adjacentChapters(chapters, n)
title := firstHeading(raw, fmt.Sprintf("Chapter %d", n))
chapterTitle, chapterDate := writer.SplitChapterTitle(title)
t := template.Must(template.New("chapter").Parse(chapterTmpl))
var buf bytes.Buffer
@@ -2176,6 +2180,7 @@ func (s *Server) handleChapter(w http.ResponseWriter, r *http.Request) {
NextN int
ChapterN int
Title string
ChapterDate string
AllChapters interface{}
Voices []string
DefaultVoice string
@@ -2185,13 +2190,14 @@ func (s *Server) handleChapter(w http.ResponseWriter, r *http.Request) {
PrevN: prevN,
NextN: nextN,
ChapterN: n,
Title: title,
Title: chapterTitle,
ChapterDate: chapterDate,
AllChapters: chapters,
Voices: kokoroVoices,
DefaultVoice: s.kokoroVoice,
})
s.respond(w, r, title, buf.String())
s.respond(w, r, chapterTitle, buf.String())
}
// ─── helpers ──────────────────────────────────────────────────────────────────

View File

@@ -219,12 +219,12 @@ func chapterTitle(path string, n int) (title, date string) {
continue
}
line = strings.TrimPrefix(line, "# ")
return splitChapterTitle(line)
return SplitChapterTitle(line)
}
return fmt.Sprintf("Chapter %d", n), ""
}
// splitChapterTitle separates the human-readable chapter name from the
// SplitChapterTitle separates the human-readable chapter name from the
// trailing relative-date string that novelfire.net appends to the heading.
// Examples of raw heading text (after stripping "# "):
//
@@ -233,7 +233,7 @@ func chapterTitle(path string, n int) (title, date string) {
//
// The pattern is: optional leading number+whitespace, then the real title,
// then a date that matches /\d+\s+(second|minute|hour|day|week|month|year)s?\s+ago$/
func splitChapterTitle(raw string) (title, date string) {
func SplitChapterTitle(raw string) (title, date string) {
// Strip a leading chapter-number index that novelfire sometimes prepends.
// It looks like "1 " or "12 " at the very start.
raw = strings.TrimSpace(raw)