Replaces the fixed-position reader with a sticky layout that works correctly on iPhone Safari and Edge, while also auto-appending the next chapter's pages when the current one finishes. Layout - Swap all position:fixed for sticky (Header, BottomNav, reader top nav) — fixed-positioning quirks broke the bottom nav in Edge and prevented Safari's URL bar from collapsing on scroll - Viewport: viewport-fit=cover + interactiveWidget=overlays-content so manga extends edge-to-edge and the URL bar overlays content without resizing the viewport - Add pt-safe / pb-safe utilities; apply on nav bars so chrome respects the notch and home-indicator - Drop fixed-positioning bottom padding now that BottomNav is in flow Continuous reading - PageReader now receives the full chapter manifest (id + totalPages) and auto-fetches the next chapter when the current one is done - Subtle chapter divider strip appears between chapters in the scroll - Top nav chapter title updates as the user scrolls into a new chapter (rAF-throttled scroll listener, cached offsetTop) - Double-tap on left/right viewport half navigates prev/next chapter - End-of-manga footer fills the viewport with a Back-to-Manga action Theme polish - Light theme: white body/background, blue accent preserved for chapter numbers, badges, active states - Modern chapter drawer: white sheet, rounded-t-3xl, two-column rows with chapter-number badge, blue highlight for current chapter - Suppress hydration warnings for extension-injected attributes on <html> and the search input - Manga detail CTA localized to 开始阅读 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import { SearchBar } from "./SearchBar";
|
|
|
|
const navLinks = [
|
|
{ href: "/", label: "Home" },
|
|
{ href: "/genre", label: "Genres" },
|
|
];
|
|
|
|
export function Header() {
|
|
const pathname = usePathname();
|
|
|
|
// Hide header on chapter reader for immersive reading
|
|
if (pathname.match(/^\/manga\/[^/]+\/\d+$/)) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<header className="sticky top-0 z-40 bg-background text-foreground backdrop-blur-xl shadow-sm pt-safe">
|
|
{/* Top row: logo + search */}
|
|
<div className="max-w-6xl mx-auto px-4 h-14 flex items-center gap-3">
|
|
<Link href="/" className="flex items-center gap-2.5 shrink-0">
|
|
<div className="w-8 h-8 rounded-lg bg-accent flex items-center justify-center">
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
className="w-5 h-5 text-white"
|
|
stroke="currentColor"
|
|
strokeWidth={2.5}
|
|
>
|
|
<path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20" />
|
|
</svg>
|
|
</div>
|
|
<span className="text-lg font-extrabold tracking-tight">
|
|
SunnyMH
|
|
</span>
|
|
</Link>
|
|
|
|
{/* Desktop nav links */}
|
|
<nav className="hidden sm:flex items-center gap-1 ml-4">
|
|
{navLinks.map((link) => {
|
|
const isActive =
|
|
link.href === "/"
|
|
? pathname === "/"
|
|
: pathname.startsWith(link.href);
|
|
return (
|
|
<Link
|
|
key={link.href}
|
|
href={link.href}
|
|
className={`px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
|
|
isActive
|
|
? "text-accent bg-accent/10"
|
|
: "text-muted hover:text-foreground hover:bg-surface"
|
|
}`}
|
|
>
|
|
{link.label}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
|
|
<div className="flex-1" />
|
|
<SearchBar />
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|