fix(reader): clean chapter title display and declutter audio panel

- Strip leading digit prefix (e.g. "6Chapter 6 → Chapter 6") and
  content after first newline (scraped date artifacts) from chapter titles
- Add "CHAPTER N" eyebrow label above the h1 for clear hierarchy
- Show date_label as small muted text in the meta row
- Remove double-border / mt-6 gap from standard AudioPlayer inside the
  chapter page's collapsible panel (was rendering two nested boxes)
- Remove redundant "Audio Narration" label (toggle already says "Listen")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Admin
2026-04-05 23:18:17 +05:00
parent 59794e3694
commit 8279bd5caa
2 changed files with 20 additions and 12 deletions

View File

@@ -1024,15 +1024,8 @@
</div>
{:else}
<!-- ── Standard player ─────────────────────────────────────────────────────── -->
<div class="mt-6 p-4 rounded-lg bg-(--color-surface-2) border border-(--color-border)">
<div class="flex items-center justify-between gap-2 mb-3">
<div class="flex items-center gap-2">
<svg class="w-4 h-4 text-(--color-brand)" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 3v10.55A4 4 0 1014 17V7h4V3h-6z"/>
</svg>
<span class="text-sm text-(--color-text) font-medium">{m.reader_audio_narration()}</span>
</div>
<div class="p-4">
<div class="flex items-center justify-end gap-2 mb-3">
<!-- Voice selector button -->
{#if voices.length > 0}
<Button

View File

@@ -287,6 +287,15 @@
html ? (html.replace(/<[^>]*>/g, '').match(/\S+/g)?.length ?? 0) : 0
);
// Strip scraper artifacts from chapter titles:
// - Leading digit(s) prefixed before "Chapter" (e.g. "6Chapter 6 : ...")
// - Everything after the first newline (often includes a scraped date)
const cleanTitle = $derived.by(() => {
let t = (data.chapter.title || '').split('\n')[0].trim();
t = t.replace(/^\d+(?=Chapter)/i, '').trim();
return t || `Chapter ${data.chapter.number}`;
});
// Audio panel: auto-open if this chapter is already loaded/playing in the store
// svelte-ignore state_referenced_locally
let audioExpanded = $state(
@@ -301,7 +310,7 @@
</script>
<svelte:head>
<title>{data.chapter.title || m.reader_chapter_n({ n: String(data.chapter.number) })}{data.book.title} — libnovel</title>
<title>{cleanTitle}{data.book.title} — libnovel</title>
</svelte:head>
<!-- Reading progress bar (scroll mode, fixed at top of viewport) -->
@@ -364,8 +373,11 @@
<!-- Chapter heading + meta + language switcher -->
<div class="mb-6">
<p class="text-xs font-semibold text-(--color-brand) uppercase tracking-widest mb-1.5">
{m.reader_chapter_n({ n: String(data.chapter.number) })}
</p>
<h1 class="text-xl font-bold text-(--color-text) leading-snug">
{data.chapter.title || m.reader_chapter_n({ n: String(data.chapter.number) })}
{cleanTitle}
</h1>
<div class="flex items-center flex-wrap gap-x-3 gap-y-1.5 mt-2">
{#if wordCount > 0}
@@ -375,6 +387,9 @@
~{Math.max(1, Math.round(wordCount / 200))} min
</p>
{/if}
{#if data.chapter.date_label}
<span class="text-(--color-muted) text-xs opacity-60">{data.chapter.date_label}</span>
{/if}
<!-- Language switcher (inline, compact) -->
{#if !data.isPreview}
@@ -483,7 +498,7 @@
<AudioPlayer
slug={data.book.slug}
chapter={data.chapter.number}
chapterTitle={data.chapter.title || m.reader_chapter_n({ n: String(data.chapter.number) })}
chapterTitle={cleanTitle}
bookTitle={data.book.title}
cover={data.book.cover}
nextChapter={data.next}