Skip to content

Commit

Permalink
Optimizing Watch Page
Browse files Browse the repository at this point in the history
  • Loading branch information
siwachs committed Sep 4, 2024
1 parent 894a028 commit 079fcb1
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 925 deletions.
5 changes: 2 additions & 3 deletions env.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ AUTH_URL=http://localhost:3000

BASE_URL=http://localhost:3000

API_ENDPOINT_CHAPTERS=/api/chapters
API_ENDPOINT_COMMENTS="/api/comments"
NEXT_PUBLIC_API_ENDPOINT_COMMENTS="/api/comments"
API_ENDPOINT_COMMENTS="/api/v1/comments"
NEXT_PUBLIC_API_ENDPOINT_COMMENTS="/api/v1/comments"

NEXT_PUBLIC_API_ENDPOINT_CHECK_USERNAME="/api/v1/accounts/usernames/check"
NEXT_PUBLIC_API_ENDPOINT_CLAIM_USERNAME="/api/v1/accounts/username/claim"
Expand Down
38 changes: 38 additions & 0 deletions src/app/(watch)/_components/chapterSelectDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Chapter } from "@/types";
import ChapterLink from "@/components/buttons/chapterLink";

const ChapterSelectDropDown: React.FC<{
chapterSelectContainerRef: React.RefObject<HTMLDivElement>;
isChapterSelectOpen: boolean;
chapters: Chapter[];
contentId: string;
}> = ({
chapterSelectContainerRef,
isChapterSelectOpen,
chapters,
contentId,
}) => {
return (
<div
ref={chapterSelectContainerRef}
className={
isChapterSelectOpen
? "fixed left-1/2 z-10 h-[calc(100vh-60px)] w-full max-w-[1220px] -translate-x-1/2 bg-[var(--app-bg-color-primary)] md:h-72"
: "hidden"
}
>
<div className="hide-scrollbar h-full flex-wrap justify-between overflow-auto p-[6px_3vw] md:flex">
{chapters.map((chapter) => (
<ChapterLink
key={chapter.id}
title={chapter.title}
releaseDate={chapter.createdAt}
href={`/watch/${contentId}/${chapter.id}`}
/>
))}
</div>
</div>
);
};

export default ChapterSelectDropDown;
47 changes: 27 additions & 20 deletions src/app/(watch)/_components/header/index.tsx → src/app/(watch)/_components/header.tsx
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,37 @@ import { FaTimesCircle } from "react-icons/fa";
const rightSectionButtonClasses =
"box-content hidden h-[35px] w-[95px] items-center justify-center gap-[5px] rounded-[100px] border border-[var(--app-text-color-pinkish-red)] lg:inline-flex";

const Header: React.FC<{ chapters: Chapter[] }> = ({ chapters }) => {
const Header: React.FC<{
chapters: Chapter[];
contentId: string;
contentTitle: string;
chapterTitle: string;
}> = ({ chapters, contentId, contentTitle, chapterTitle }) => {
const [isChapterSelectOpen, setIsChapterSelectOpen] = useState(false);

const headerContainerRef = useRef<HTMLDivElement>(null);
const chapterSelectContainerRef = useRef<HTMLDivElement>(null);
const toogleChapterSelect = () => setIsChapterSelectOpen((prev) => !prev);

useBodyOverflow(isChapterSelectOpen);
useOutsideClick(chapterSelectContainerRef, isChapterSelectOpen, () => {
setIsChapterSelectOpen(false);
});
useOutsideClick(
chapterSelectContainerRef,
isChapterSelectOpen,
toogleChapterSelect,
);

useEffect(() => {
const handleScroll = () => {
if (!headerContainerRef.current) return;
const hideHeaderOnScroll = () => {
const headerContainer = headerContainerRef.current;
if (!headerContainer) return;

if (window.scrollY >= 60) headerContainerRef.current.style.top = "-100px";
else headerContainerRef.current.style.top = "0";
if (window.scrollY >= 60) headerContainer.style.top = "-100px";
else headerContainer.style.top = "0";
};

handleScroll();
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
hideHeaderOnScroll();
window.addEventListener("scroll", hideHeaderOnScroll);
return () => window.removeEventListener("scroll", hideHeaderOnScroll);
}, []);

return (
Expand All @@ -50,7 +59,9 @@ const Header: React.FC<{ chapters: Chapter[] }> = ({ chapters }) => {
>
<div className="mx-auto flex h-[60px] max-w-[1600px] items-center justify-between md:h-[100px]">
<div className="ml-5 flex-1 md:flex md:items-center">
<Link href="/">
<Link
href={`/${encodeURIComponent(contentTitle?.toLowerCase().replaceAll(" ", "-"))}?content_id=${contentId}`}
>
<FaChevronLeft
className="size-[18px] md:hidden md:size-[26px] md:text-[var(--app-text-color-crimson)]"
color="grey"
Expand All @@ -73,13 +84,10 @@ const Header: React.FC<{ chapters: Chapter[] }> = ({ chapters }) => {
<div className="w-1/2">
<div className="mt-0.5 flex items-center justify-center gap-[7px] font-medium md:gap-3">
<div className="truncate text-[15px] text-black md:text-xl">
Episode 1
{chapterTitle}
</div>

<button
onClick={() => setIsChapterSelectOpen((prev) => !prev)}
className="size-3 md:size-4"
>
<button onClick={toogleChapterSelect} className="size-3 md:size-4">
{isChapterSelectOpen ? (
<FaTimesCircle className="size-[inherit]" color="grey" />
) : (
Expand All @@ -89,8 +97,7 @@ const Header: React.FC<{ chapters: Chapter[] }> = ({ chapters }) => {
</div>

<p className="md:font-noto-sans-sc truncate text-center text-[10px]/[20px] font-medium text-neutral-400 md:text-sm/[16px] md:font-normal">
Isekai Shoukan Sareta Kita Seijo-sama ga &apos;Kareshi ga
Shinda&apos; to Naku Bakari de Hataraite kuremasen
{contentTitle}
</p>
</div>

Expand Down Expand Up @@ -128,7 +135,7 @@ const Header: React.FC<{ chapters: Chapter[] }> = ({ chapters }) => {
key={chapter.id}
title={chapter.title}
releaseDate={chapter.createdAt}
href={`/watch/${chapter.contentId}/${chapter.id}`}
href={`/watch/${contentId}/${chapter.id}`}
/>
))}
</div>
Expand Down
44 changes: 25 additions & 19 deletions src/app/(watch)/watch/[content_id]/[chapter_id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,26 @@ import {
ERROR_500_PAGE_HEADER_TITLE,
} from "@/constants";

import {
getContentChapter,
getContentChapters,
} from "@/libs/dbCRUD/getContent";
import getChapters, { getChapter } from "@/libs/dbCRUD/getChapters";
import { getContentTitleAndDescription } from "@/libs/dbCRUD/getContent";

export async function generateMetadata(
{ params }: WatchPageReqObj,
parent: ResolvingMetadata,
): Promise<Metadata> {
const { content_id, chapter_id } = params;
const { chapter, status, error } = await getContentChapter(
content_id,
chapter_id,
{ withDescription: true },
);
const title =
status === 404
? ERROR_404_PAGE_HEADER_TITLE
: error
? ERROR_500_PAGE_HEADER_TITLE
: chapter?.title;
const { chapter, status, error } = await getChapter(content_id, chapter_id, {
withDescription: true,
});
let title;

if (status === 404) {
title = ERROR_404_PAGE_HEADER_TITLE;
} else if (error) {
title = ERROR_500_PAGE_HEADER_TITLE;
} else {
title = chapter?.title;
}

return {
title: `${title} - MangaReader`,
Expand All @@ -50,11 +49,13 @@ type WatchPageReqObj = {

export default async function WatchPage(req: Readonly<WatchPageReqObj>) {
const { content_id, chapter_id } = req.params;
const { chapters } = await getContentChapters(content_id, {

const { title } = await getContentTitleAndDescription(content_id);
const { chapters } = await getChapters(content_id, {
forClientComponent: true,
});

const { status, chapter, error, errorMessage } = await getContentChapter(
const { status, chapter, error, errorMessage } = await getChapter(
content_id,
chapter_id,
{ withImages: true },
Expand All @@ -64,14 +65,19 @@ export default async function WatchPage(req: Readonly<WatchPageReqObj>) {

return (
<>
<Header chapters={chapters} />
<Header
chapters={chapters}
contentId={content_id}
contentTitle={title!}
chapterTitle={chapter?.title!}
/>
<main id="page-content">
{error && (
<ErrorMessage>{`Unable to load Watch page because ${errorMessage}`}</ErrorMessage>
)}

<ChaptersPagination />
<div className="mx-auto grid min-h-[calc(100vh-220px)] max-w-[800px] place-items-center md:min-h-[calc(100vh-360px)]">
<div className="mx-auto mb-5 grid min-h-[calc(100vh-220px)] max-w-[800px] place-items-center md:min-h-[calc(100vh-360px)]">
{chapter?.images.map((image, index) => (
<Image
quality={100}
Expand Down
Loading

0 comments on commit 079fcb1

Please sign in to comment.