- Remove play button and gear icon from chapter nav bar
- Show bottom mini-player bar always (not slide-up on play)
- Remove duplicate collapsed-bar seek track; keep only expanded panel scrub bar
- Move gear/settings button into the bottom mini-player bar
- Move settings panel into mini-player aside, opening upward
- Clean up JS: remove navBtn/navIcon refs, showPlayer/hidePlayer, playerSeekTrack refs
html/template's context-aware parser was treating the backslash-escaped
quote in the inline onclick regex literal as an HTML attribute terminator,
causing template execution to produce an empty/broken output.
Move the summary paragraph-splitting logic into a named window.openSummary
function in the script block, and call it via a clean onclick=openSummary(this)
attribute with no inline regex literals.
- Make overlay scroll within the viewport instead of being clipped (overflow-y-auto on backdrop, items-start alignment)
- Split summary text into paragraphs in the zoom overlay (newline-split with sentence-boundary fallback)
- Add Summary heading in overlay for context
- Remove old merge-poller JS; simplify generateAudio to use data.url directly (Kokoro backend rewrite cleanup)
Embed the complete ranking JSON into the page and replace the DOM-only
filter with a client-side search over ALL_ITEMS. When a filter is active
the grid is re-rendered from the full dataset; clearing filters restores
the server-paginated view. Also adds summary zoom overlay on the book page.
- Home page book cards show downloaded chapter count (amber badge) via new CountChapters method
- Book page cover image is clickable to zoom into a fullscreen overlay; click anywhere to dismiss
- Book page shows a 'Latest Chapter' button for unstarted books linking to the last downloaded chapter
- Continue-reading cards on home page have a dismiss (×) button that removes progress from localStorage and slides the card out to the left
- Remove Scrape form/button and Source text link from non-local ranking cards
- First click on a card highlights it amber and shows 'Click again to scrape' hint
- Second click POSTs to /ui/scrape/book and replaces card with polling status badge
- Pending state auto-cancels after 3 s or when clicking outside
- Source icon (external link SVG) retained but dimmed; stops click propagation
- Extract scrape form and autocomplete JS from homeTmpl into new scrapeTmpl
- Add handleScrape GET handler serving /scrape with ranking autocomplete
- Register GET /scrape route in server.go
- Replace inline scrape form on home page with '+ Add' flat button in header
- handleHome no longer loads ranking items (only needed on /scrape)
rankingPageNums now takes a current page parameter and always renders
first 2, last 2, and current±2 — so navigating to page 3 shows
1 2 3 4 5 … 80 81 instead of only the fixed quarter-mark anchors.
- Server collects distinct genres and statuses from all cached items and
passes them as AllGenres/AllStatuses slices to the template
- Facet chips rendered as pill toggles below the text search bar
- Cards gain data-status, data-genres (pipe-delimited), data-local attributes
- JS filter engine: AND between facets, OR within status facet (a book has
one status), AND within genre facet (all selected genres must be present)
- Pagination row hidden while any filter is active; restored on clear
- 'Clear filters' button appears when any filter is active
- sortedKeys helper added to produce stable sorted facet chip order
All filled/pill buttons across home, ranking, book detail, and chapter
pages now use transparent backgrounds with colored text only, consistent
with the chapter reader nav bar style:
- Home: Browse Rankings (amber text), Scrape (amber text)
- Ranking: View Markdown, page numbers, fetch buttons, Scrape/Source on cards
- Book detail: Source, Refresh, Resume, chapter pagination
- Chapter: bottom Prev/Next nav, article-end nav links
An <a> element nested inside the card's outer <a> is invalid HTML — browsers
auto-close the outer anchor before the inner one, causing the card to be split
across two grid cells visually. Replace with a <button> that calls window.open()
with event.preventDefault/stopPropagation to avoid interfering with card navigation.
- 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
The previous selectors were based on a hypothetical structure that does not
match the actual site. The real novelfire.net popular listing uses:
<li class="novel-item"> (not <div>)
<a href="/book/slug" title="Title">
<figure class="novel-cover"><img data-src="/path.jpg"></figure>
<h4 class="novel-title text2row">Title</h4>
</a>
</li>
And pagination uses <a rel="next"> (not <a class="next">).
Changes:
- ScrapeRanking: use li.novel-item, h4.novel-title, figure.novel-cover,
img[data-src]; strip base64 placeholder covers
- hasNextPageLink(): new helper walking all <a> nodes for rel="next"
- Import golang.org/x/net/html for Node.Attr access
- Test fixtures rewritten to match real structure (li/h4/rel=next)
- Status and genres removed from ranking items (not present on listing page)
Verified end-to-end: ranking.json written with 24 items on first fetch
Previously all cached ranking items were dumped into one page and the
page buttons only triggered refetches from novelfire — not navigation.
- handleRanking now reads ?page=N query param (default 1)
- Items sliced server-side at 20 per page (rankingPageSize constant)
- Template receives DisplayNums/CurrentPage/TotalPages for browse nav
- Display pagination bar renders GET /ranking?page=N HTMX links with
the active page highlighted in amber; hidden when only 1 page
- Fetch section collapsed into a <details> to reduce visual noise
- FetchNums replaces old PageNums field name in template data
- selectItem() now sets the visible input to source_url (not the title), so the user can see and copy the link before scraping
- Keyboard navigation (ArrowUp/Down) also previews the URL in the input
- Added URL hint line inside each dropdown item showing the full source_url
- Genres included in search haystack (was missing before)
- Deduplicated filter logic into filterRanking() helper
- Raised max results from 8 to 10