aboutsummaryrefslogtreecommitdiff
path: root/pages/en/manga
diff options
context:
space:
mode:
authorFactiven <[email protected]>2023-07-16 22:35:39 +0700
committerFactiven <[email protected]>2023-07-16 22:35:39 +0700
commit1eee181e219dfd993d396ac3169e7aad3dd285eb (patch)
tree23fe54e9c3f8810f3ac9ab6b29070b4f0d4b9d20 /pages/en/manga
parentremoved console.log (diff)
downloadmoopa-1eee181e219dfd993d396ac3169e7aad3dd285eb.tar.xz
moopa-1eee181e219dfd993d396ac3169e7aad3dd285eb.zip
Update v3.6.4
- Added Manga page with a working tracker for AniList user - Added schedule component to home page - Added disqus comment section so you can fight on each other (not recommended) - Added /id and /en route for english and indonesian subs (id route still work in progress)
Diffstat (limited to 'pages/en/manga')
-rw-r--r--pages/en/manga/[id].js172
-rw-r--r--pages/en/manga/read/[...params].js262
2 files changed, 434 insertions, 0 deletions
diff --git a/pages/en/manga/[id].js b/pages/en/manga/[id].js
new file mode 100644
index 0000000..5e46599
--- /dev/null
+++ b/pages/en/manga/[id].js
@@ -0,0 +1,172 @@
+import dotenv from "dotenv";
+import ChapterSelector from "../../../components/manga/chapters";
+import HamburgerMenu from "../../../components/manga/mobile/hamburgerMenu";
+import Navbar from "../../../components/navbar";
+import TopSection from "../../../components/manga/info/topSection";
+import Footer from "../../../components/footer";
+import Head from "next/head";
+import { useEffect, useState } from "react";
+import { setCookie } from "nookies";
+import { getServerSession } from "next-auth";
+import { authOptions } from "../../api/auth/[...nextauth]";
+
+export default function Manga({ info, userManga, chapters }) {
+ const [domainUrl, setDomainUrl] = useState("");
+ const [firstEp, setFirstEp] = useState();
+ const chaptersData =
+ info.chapters.data.length === 0 ? chapters : info.chapters.data;
+
+ useEffect(() => {
+ setDomainUrl(window.location.origin);
+ }, []);
+
+ return (
+ <>
+ <Head>
+ <title>
+ {info
+ ? `Manga - ${
+ info.title.romaji || info.title.english || info.title.native
+ }`
+ : "Getting Info..."}
+ </title>
+ <meta name="twitter:card" content="summary_large_image" />
+ <meta
+ name="twitter:title"
+ content={`Moopa - ${info.title.romaji || info.title.english}`}
+ />
+ <meta
+ name="twitter:description"
+ content={`${info.description?.slice(0, 180)}...`}
+ />
+ <meta
+ name="twitter:image"
+ content={`${domainUrl}/api/og?title=${
+ info.title.romaji || info.title.english
+ }&image=${info.bannerImage || info.coverImage}`}
+ />
+ </Head>
+ <div className="min-h-screen w-screen flex flex-col items-center relative">
+ <HamburgerMenu />
+ <Navbar className="absolute top-0 w-full z-40" />
+ <div className="flex flex-col w-screen items-center gap-5 md:gap-10 py-10 pt-nav">
+ <div className="flex-center w-full relative z-30">
+ <TopSection info={info} firstEp={firstEp} setCookie={setCookie} />
+ <>
+ <div className="absolute hidden md:block z-20 bottom-0 h-1/2 w-full bg-secondary" />
+ <div className="absolute hidden md:block z-20 top-0 h-1/2 w-full bg-transparent" />
+ </>
+ </div>
+ <div className="w-[90%] xl:w-[70%] min-h-[35vh] z-40">
+ {chaptersData.length > 0 ? (
+ <ChapterSelector
+ chaptersData={chaptersData}
+ data={info}
+ setFirstEp={setFirstEp}
+ setCookie={setCookie}
+ userManga={userManga}
+ />
+ ) : (
+ <p>No Chapter Available :(</p>
+ )}
+ </div>
+ </div>
+ <Footer />
+ </div>
+ </>
+ );
+}
+
+export async function getServerSideProps(context) {
+ dotenv.config();
+
+ const session = await getServerSession(context.req, context.res, authOptions);
+
+ const { id } = context.query;
+ const key = process.env.API_KEY;
+ const res = await fetch(`https://api.anify.tv/info/${id}?apikey=${key}`);
+ const data = await res.json();
+
+ let userManga = null;
+
+ if (session) {
+ const response = await fetch("https://graphql.anilist.co/", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ query: `
+ query ($username: String, $status: MediaListStatus) {
+ MediaListCollection(userName: $username, type: MANGA, status: $status, sort: SCORE_DESC) {
+ user {
+ id
+ name
+ }
+ lists {
+ status
+ name
+ entries {
+ id
+ mediaId
+ status
+ progress
+ score
+ progressVolumes
+ media {
+ id
+ status
+ title {
+ english
+ romaji
+ }
+ episodes
+ coverImage {
+ large
+ }
+ }
+ }
+ }
+ }
+ }
+ `,
+ variables: {
+ username: session?.user?.name,
+ },
+ }),
+ });
+ const data = await response.json();
+ const user = data?.data?.MediaListCollection;
+ const userListsCurrent = user?.lists.find((X) => X.status === "CURRENT");
+ const matched = userListsCurrent?.entries.find(
+ (x) => x.mediaId === parseInt(id)
+ );
+ if (matched) {
+ userManga = matched;
+ }
+ }
+
+ if (!data?.chapters) {
+ return {
+ notFound: true,
+ };
+ }
+
+ let chapter = null;
+
+ if (data?.chapters?.data.length === 0) {
+ const res2 = await fetch(
+ `https://api.anify.tv/chapters/${id}?apikey=${key}`
+ );
+ const data2 = await res2.json();
+ chapter = data2;
+ }
+
+ return {
+ props: {
+ info: data,
+ userManga,
+ chapters: chapter || null,
+ },
+ };
+}
diff --git a/pages/en/manga/read/[...params].js b/pages/en/manga/read/[...params].js
new file mode 100644
index 0000000..0c6372d
--- /dev/null
+++ b/pages/en/manga/read/[...params].js
@@ -0,0 +1,262 @@
+import dotenv from "dotenv";
+import { useEffect, useRef, useState } from "react";
+import { LeftBar } from "../../../../components/manga/leftBar";
+import { useRouter } from "next/router";
+import RightBar from "../../../../components/manga/rightBar";
+import FirstPanel from "../../../../components/manga/panels/firstPanel";
+import SecondPanel from "../../../../components/manga/panels/secondPanel";
+import ThirdPanel from "../../../../components/manga/panels/thirdPanel";
+import { getServerSession } from "next-auth";
+import { authOptions } from "../../../api/auth/[...nextauth]";
+import BottomBar from "../../../../components/manga/mobile/bottomBar";
+import TopBar from "../../../../components/manga/mobile/topBar";
+import { ToastContainer } from "react-toastify";
+import Head from "next/head";
+import nookies from "nookies";
+import ShortCutModal from "../../../../components/manga/modals/shortcutModal";
+import ChapterModal from "../../../../components/manga/modals/chapterModal";
+
+export default function Read({ data, currentId, sessions }) {
+ const [info, setInfo] = useState();
+ const [chapter, setChapter] = useState([]);
+ const [layout, setLayout] = useState(1);
+
+ const [visible, setVisible] = useState(true);
+ const [mobileVisible, setMobileVisible] = useState(true);
+ const [isKeyOpen, setIsKeyOpen] = useState(false);
+ const [isChapOpen, setIsChapOpen] = useState(false);
+
+ const [seekPage, setSeekPage] = useState(0);
+
+ const [paddingX, setPaddingX] = useState(208);
+ const [scaleImg, setScaleImg] = useState(1);
+
+ const [nextChapterId, setNextChapterId] = useState(null);
+ const [prevChapterId, setPrevChapterId] = useState(null);
+
+ const [currentChapter, setCurrentChapter] = useState(null);
+ const [currentPage, setCurrentPage] = useState(0);
+
+ const hasRun = useRef(false);
+
+ const router = useRouter();
+
+ // console.log(cookies);
+
+ useEffect(() => {
+ hasRun.current = false;
+ }, [currentId]);
+
+ useEffect(() => {
+ const get = JSON.parse(localStorage.getItem("manga"));
+ const chapters = get.manga;
+ const currentChapter = chapters.chapters?.find((x) => x.id === currentId);
+
+ setCurrentChapter(currentChapter);
+ setInfo(get.data);
+ setChapter(chapters);
+
+ if (Array.isArray(chapters?.chapters)) {
+ const currentIndex = chapters.chapters.findIndex(
+ (chapter) => chapter.id === currentId
+ );
+ if (currentIndex !== -1) {
+ const nextChapter = chapters.chapters[currentIndex - 1];
+ const prevChapter = chapters.chapters[currentIndex + 1];
+ setNextChapterId(nextChapter ? nextChapter.id : null);
+ setPrevChapterId(prevChapter ? prevChapter.id : null);
+ }
+ }
+ }, [currentId]);
+
+ useEffect(() => {
+ const handleKeyDown = (event) => {
+ if (event.key === "ArrowRight" && event.ctrlKey && nextChapterId) {
+ router.push(
+ `/en/manga/read/${chapter.providerId}?id=${
+ info.id
+ }&chapterId=${encodeURIComponent(nextChapterId)}`
+ );
+ } else if (event.key === "ArrowLeft" && event.ctrlKey && prevChapterId) {
+ router.push(
+ `/en/manga/read/${chapter.providerId}?id=${
+ info.id
+ }&chapterId=${encodeURIComponent(prevChapterId)}`
+ );
+ }
+ if (event.code === "Slash" && event.ctrlKey) {
+ setIsKeyOpen(!isKeyOpen);
+ }
+ if (event.key === "f" || event.key === "F") {
+ setVisible(!visible);
+ }
+ if (event.code === "ArrowUp" && event.shiftKey) {
+ setPaddingX(paddingX - 50);
+ } else if (event.code === "ArrowDown" && event.shiftKey) {
+ setPaddingX(paddingX + 50);
+ }
+ };
+
+ window.addEventListener("keydown", handleKeyDown);
+
+ return () => {
+ window.removeEventListener("keydown", handleKeyDown);
+ };
+ }, [nextChapterId, prevChapterId, visible, isKeyOpen, paddingX]);
+
+ return (
+ <>
+ <Head>
+ <title>
+ {info
+ ? `Manga - ${
+ info.title.romaji || info.title.english || info.title.native
+ }`
+ : "Getting Info..."}
+ </title>
+ </Head>
+ <div className="w-screen flex justify-evenly relative">
+ <ToastContainer pauseOnFocusLoss={false} />
+ <ShortCutModal isOpen={isKeyOpen} setIsOpen={setIsKeyOpen} />
+ <ChapterModal
+ id={info?.id}
+ currentId={currentId}
+ data={chapter}
+ isOpen={isChapOpen}
+ setIsOpen={setIsChapOpen}
+ />
+
+ {mobileVisible && (
+ <>
+ <TopBar info={info} />
+ <BottomBar
+ id={info?.id}
+ prevChapter={prevChapterId}
+ nextChapter={nextChapterId}
+ currentPage={currentPage}
+ chapter={chapter}
+ page={data}
+ setSeekPage={setSeekPage}
+ setIsOpen={setIsChapOpen}
+ />
+ </>
+ )}
+ {visible && (
+ <LeftBar
+ data={chapter}
+ page={data}
+ info={info}
+ currentId={currentId}
+ setSeekPage={setSeekPage}
+ />
+ )}
+ {layout === 1 && (
+ <FirstPanel
+ aniId={info?.id}
+ data={data}
+ hasRun={hasRun}
+ currentId={currentId}
+ seekPage={seekPage}
+ setSeekPage={setSeekPage}
+ visible={visible}
+ setVisible={setVisible}
+ chapter={chapter}
+ nextChapter={nextChapterId}
+ prevChapter={prevChapterId}
+ paddingX={paddingX}
+ session={sessions}
+ mobileVisible={mobileVisible}
+ setMobileVisible={setMobileVisible}
+ setCurrentPage={setCurrentPage}
+ />
+ )}
+ {layout === 2 && (
+ <SecondPanel
+ aniId={info?.id}
+ data={data}
+ hasRun={hasRun}
+ currentChapter={currentChapter}
+ currentId={currentId}
+ seekPage={seekPage}
+ setSeekPage={setSeekPage}
+ visible={visible}
+ setVisible={setVisible}
+ session={sessions}
+ />
+ )}
+ {layout === 3 && (
+ <ThirdPanel
+ aniId={info?.id}
+ data={data}
+ hasRun={hasRun}
+ currentId={currentId}
+ currentChapter={currentChapter}
+ seekPage={seekPage}
+ setSeekPage={setSeekPage}
+ visible={visible}
+ setVisible={setVisible}
+ session={sessions}
+ scaleImg={scaleImg}
+ setMobileVisible={setMobileVisible}
+ mobileVisible={mobileVisible}
+ />
+ )}
+ {visible && (
+ <RightBar
+ id={info?.id}
+ hasRun={hasRun}
+ session={sessions}
+ data={chapter}
+ currentId={currentId}
+ currentChapter={currentChapter}
+ layout={layout}
+ setLayout={setLayout}
+ paddingX={paddingX}
+ setPaddingX={setPaddingX}
+ setIsKeyOpen={setIsKeyOpen}
+ scaleImg={scaleImg}
+ setScaleImg={setScaleImg}
+ />
+ )}
+ </div>
+ </>
+ );
+}
+
+export async function getServerSideProps(context) {
+ dotenv.config();
+
+ const cookies = nookies.get(context);
+
+ const query = context.query;
+ const providerId = query.params[0];
+ const chapterId = query.chapterId;
+ const mediaId = query.id;
+
+ if (!cookies.manga || cookies.manga !== mediaId) {
+ return {
+ redirect: {
+ destination: `/en/manga/${mediaId}`,
+ },
+ };
+ }
+
+ const session = await getServerSession(context.req, context.res, authOptions);
+
+ const key = process.env.API_KEY;
+ const res = await fetch(
+ `https://api.anify.tv/pages?providerId=${providerId}&readId=${encodeURIComponent(
+ chapterId
+ )}&apikey=${key}`
+ );
+
+ const data = await res.json();
+
+ return {
+ props: {
+ data: data,
+ currentId: chapterId,
+ sessions: session,
+ },
+ };
+}