From 8dcb5cb96819547e574d4ca619c54c6f902b8860 Mon Sep 17 00:00:00 2001 From: Factiven Date: Thu, 25 May 2023 22:56:21 +0700 Subject: Update v3.6.1 > Added Thumbnail to info page > Temporarily removed Manga from website until the page is finished --- pages/anime/[...id].js | 604 ++++++++++++++++++++++++--------------- pages/anime/watch/[...info].js | 355 +++++++++++------------ pages/manga/chapter/[chapter].js | 460 ----------------------------- pages/manga/detail/id.js | 267 ----------------- 4 files changed, 531 insertions(+), 1155 deletions(-) delete mode 100644 pages/manga/chapter/[chapter].js delete mode 100644 pages/manga/detail/id.js (limited to 'pages') diff --git a/pages/anime/[...id].js b/pages/anime/[...id].js index 867e429..200a7f4 100644 --- a/pages/anime/[...id].js +++ b/pages/anime/[...id].js @@ -21,124 +21,11 @@ import { signIn, useSession } from "next-auth/react"; import AniList from "../../components/media/aniList"; import ListEditor from "../../components/listEditor"; -const query = ` - query ($username: String, $status: MediaListStatus) { - MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { - user { - id - name - about (asHtml: true) - createdAt - avatar { - large - } - statistics { - anime { - count - episodesWatched - meanScore - minutesWatched - } - } - bannerImage - mediaListOptions { - animeList { - sectionOrder - } - } - } - lists { - status - name - entries { - id - mediaId - status - progress - score - media { - id - status - title { - english - romaji - } - episodes - coverImage { - large - } - } - } - } - } - } - `; - -const infoQuery = `query ($id: Int) { - Media(id: $id) { - id - type - title { - romaji - english - native - } - coverImage { - extraLarge - large - color - } - bannerImage - description - episodes - nextAiringEpisode { - episode - airingAt - } - averageScore - popularity - status - startDate { - year - } - duration - genres - relations { - edges { - relationType - node { - id - type - status - title { - romaji - english - userPreferred - } - coverImage { - extraLarge - large - color - } - } - } - } - recommendations { - nodes { - mediaRecommendation { - id - title { - romaji - } - coverImage { - extraLarge - large - } - } - } - } - } -}`; +import { GET_MEDIA_USER } from "../../queries"; +import { GET_MEDIA_INFO } from "../../queries"; + +// import { aniInfo } from "../../components/devComp/data"; +// console.log(GET_MEDIA_USER); export default function Info({ info, color }) { const { data: session } = useSession(); @@ -147,99 +34,119 @@ export default function Info({ info, color }) { const [progress, setProgress] = useState(0); const [statuses, setStatuses] = useState(null); const [domainUrl, setDomainUrl] = useState(""); - const [showAll, setShowAll] = useState(false); const [open, setOpen] = useState(false); - const [time, setTime] = useState(0); const { id } = useRouter().query; - const rec = info?.recommendations?.nodes.map( + const [epiView, setEpiView] = useState("3"); + + const [artStorage, setArtStorage] = useState(null); + + const rec = info?.recommendations?.nodes?.map( (data) => data.mediaRecommendation ); useEffect(() => { - const { protocol, host } = window.location; - const url = `${protocol}//${host}`; - setDomainUrl(url); - + handleClose(); async function fetchData() { setLoading(true); if (id) { try { - setEpisode(null) - const res = await fetch(`https://api.moopa.my.id/meta/anilist/info/${info.id}`) - const data = await res.json(); + const { protocol, host } = window.location; + const url = `${protocol}//${host}`; - if (res.status === 500) { - setEpisode([]); - } else if (res.status === 404) { - window.location.href("/404"); - } else if (!data || data?.episodes?.length === 0) { + const view = localStorage.getItem("epiView"); + + setDomainUrl(url); + + setArtStorage(JSON.parse(localStorage.getItem("artplayer_settings"))); + + setEpisode(null); + setProgress(0); + setStatuses(null); + + const res = await fetch( + `https://api.moopa.my.id/meta/anilist/info/${info.id}` + ); + // const res = true; + if (res.status === 500 || res.status === 404) { + // if (res === false) { setEpisode([]); } else { - setEpisode(data.episodes?.reverse()); - } + const data = await res.json(); + // const data = aniInfo; + if (!data || data?.episodes?.length === 0) { + setEpisode([]); + } else { + if (data.episodes?.some((i) => i.title === null)) { + setEpiView("3"); + } else if (view) { + setEpiView(view); + } else { + setEpiView("3"); + } + setEpisode(data?.episodes.reverse()); + } - if (session?.user?.name) { - const response = await fetch("https://graphql.anilist.co/", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - query: query, - variables: { - username: session?.user?.name, + if (session?.user?.name) { + const response = await fetch("https://graphql.anilist.co/", { + method: "POST", + headers: { + "Content-Type": "application/json", }, - }), - }); - - const dat = await response.json(); - - const prog = dat.data.MediaListCollection; - - const gat = prog.lists.map((item) => item.entries); - const git = gat.map((item) => - item.find((item) => item.mediaId === parseInt(id[0])) - ); - const gut = git?.find((item) => item?.mediaId === parseInt(id[0])); - - if (gut) { - setProgress(gut?.progress); - if (gut.status === "CURRENT") { - setStatuses({ name: "Watching", value: "CURRENT" }); - } else if (gut.status === "PLANNING") { - setStatuses({ name: "Plan to watch", value: "PLANNING" }); - } else if (gut.status === "COMPLETED") { - setStatuses({ name: "Completed", value: "COMPLETED" }); - } else if (gut.status === "DROPPED") { - setStatuses({ name: "Dropped", value: "DROPPED" }); - } else if (gut.status === "PAUSED") { - setStatuses({ name: "Paused", value: "PAUSED" }); - } else if (gut.status === "REPEATING") { - setStatuses({ name: "Rewatching", value: "REPEATING" }); + body: JSON.stringify({ + query: GET_MEDIA_USER, + variables: { + username: session?.user?.name, + }, + }), + }); + + const responseData = await response.json(); + + const prog = responseData?.data?.MediaListCollection; + + if (prog && prog.lists.length > 0) { + const gut = prog.lists + .flatMap((item) => item.entries) + .find((item) => item.mediaId === parseInt(id[0])); + + if (gut) { + setProgress(gut.progress); + const statusMapping = { + CURRENT: { name: "Watching", value: "CURRENT" }, + PLANNING: { name: "Plan to watch", value: "PLANNING" }, + COMPLETED: { name: "Completed", value: "COMPLETED" }, + DROPPED: { name: "Dropped", value: "DROPPED" }, + PAUSED: { name: "Paused", value: "PAUSED" }, + REPEATING: { name: "Rewatching", value: "REPEATING" }, + }; + setStatuses(statusMapping[gut.status]); + } } } - } - if (data.nextAiringEpisode) { - setTime( - convertSecondsToTime(data.nextAiringEpisode.timeUntilAiring) - ); + if (data.nextAiringEpisode) { + setTime( + convertSecondsToTime(data.nextAiringEpisode.timeUntilAiring) + ); + } } - - setLoading(false); } catch (error) { - console.log(error); + console.error(error); setTimeout(() => { window.location.reload(); }, 1000); + } finally { + setLoading(false); } } } fetchData(); - }, [id, session?.user?.name, info]); + }, [id, info, session?.user?.name]); + + // console.log(); function handleOpen() { setOpen(true); @@ -601,71 +508,294 @@ export default function Info({ info, color }) { )} -
-
- {info && ( -

- Episodes -

- )} - {info?.nextAiringEpisode && ( -
-
-

Next :

-
- {time} +
+
+
+ {info && ( +

+ Episodes +

+ )} + {info?.nextAiringEpisode && ( +
+
+

Next :

+
+ {time} +
+
+
+
-
- -
+ )} +
+
+
0 + ? episode?.some((item) => item?.title === null) + ? "pointer-events-none" + : "cursor-pointer" + : "pointer-events-none" + } + onClick={() => { + setEpiView("1"); + localStorage.setItem("epiView", "1"); + }} + > + + 0 + ? episode?.some((item) => item?.title === null) + ? "fill-[#1c1c22]" + : epiView === "1" + ? "fill-action" + : "fill-[#3A3A44]" + : "fill-[#1c1c22]" + }`} + rx="3" + > +
- )} +
0 + ? episode?.some((item) => item?.title === null) + ? "pointer-events-none" + : "cursor-pointer" + : "pointer-events-none" + } + onClick={() => { + setEpiView("2"); + localStorage.setItem("epiView", "2"); + }} + > + 0 + ? episode?.some((item) => item?.title === null) + ? "fill-[#1c1c22]" + : epiView === "2" + ? "fill-action" + : "fill-[#3A3A44]" + : "fill-[#1c1c22]" + }`} + viewBox="0 0 33 20" + > + + + +
+
0 + ? `cursor-pointer` + : "pointer-events-none" + } + onClick={() => { + setEpiView("3"); + localStorage.setItem("epiView", "3"); + }} + > + 0 + ? epiView === "3" + ? "fill-action" + : "fill-[#3A3A44]" + : "fill-[#1c1c22]" + }`} + viewBox="0 0 33 20" + > + + + + +
+
{!loading ? ( episode && ( -
- { - episode?.length !== 0 && episode ? ( - episode?.map((epi, index) => { - return ( -
+
+ {episode?.length !== 0 && episode ? ( +
+ {epiView === "1" + ? episode?.map((epi, index) => { + const time = artStorage?.[epi?.id]?.time; + const duration = + artStorage?.[epi?.id]?.duration; + let prog = (time / duration) * 100; + if (prog > 90) prog = 100; + return ( + + + Episode {epi?.number} + + +
+ epi image + + ); + }) + : ""} + {epiView === "2" && + episode?.map((epi, index) => { + const time = artStorage?.[epi?.id]?.time; + const duration = artStorage?.[epi?.id]?.duration; + let prog = (time / duration) * 100; + if (prog > 90) prog = 100; + return ( -

Episode {epi.number}

- {epi.title && ( -

- "{epi.title}" -

- )} +
+
+ Anime Cover + + + Episode {epi?.number} + +
+ + + +
+
+
+ +
+

+ {epi?.title} +

+ {epi?.description && ( +

+ {epi?.description} +

+ )} +
- {index !== episode?.length - 1 && ( - - )} -
- ); - }) - ) : ( -

No Episodes Available

- ) - } + ); + })} + {epiView === "3" && + episode?.map((epi, index) => { + return ( +
+ +

Episode {epi.number}

+ {epi.title && ( +

+ "{epi.title}" +

+ )} + + {index !== episode?.length - 1 && ( + + )} +
+ ); + })} +
+ ) : ( +

No Episodes Available

+ )}
) ) : ( @@ -705,7 +835,7 @@ export async function getServerSideProps(context) { "Content-Type": "application/json", }, body: JSON.stringify({ - query: infoQuery, + query: GET_MEDIA_INFO, variables: { id: id?.[0], }, diff --git a/pages/anime/watch/[...info].js b/pages/anime/watch/[...info].js index 1350ce8..b3d02cf 100644 --- a/pages/anime/watch/[...info].js +++ b/pages/anime/watch/[...info].js @@ -14,7 +14,10 @@ import { Navigasi } from "../.."; import { ChevronDownIcon, ForwardIcon } from "@heroicons/react/24/solid"; import { useRouter } from "next/router"; +import { GET_MEDIA_USER } from "../../../queries"; + import dotenv from "dotenv"; +import Footer from "../../../components/footer"; const VideoPlayer = dynamic(() => import("../../../components/videoPlayer", { ssr: false }) @@ -29,8 +32,10 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { const [loading, setLoading] = useState(false); const [playingTitle, setPlayingTitle] = useState(null); const [poster, setPoster] = useState(null); + const [progress, setProgress] = useState(0); const [episodes, setEpisodes] = useState([]); + const [artStorage, setArtStorage] = useState(null); const router = useRouter(); @@ -64,7 +69,6 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { }); const fetchData = async () => { - try { if (provider) { const res = await fetch( @@ -86,6 +90,7 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { } let aniData = null; + setArtStorage(JSON.parse(localStorage.getItem("artplayer_settings"))); if (provider) { const res = await fetch( @@ -138,58 +143,7 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { "Content-Type": "application/json", }, body: JSON.stringify({ - query: ` - query ($username: String, $status: MediaListStatus) { - MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { - user { - id - name - about (asHtml: true) - createdAt - avatar { - large - } - statistics { - anime { - count - episodesWatched - meanScore - minutesWatched - } - } - bannerImage - mediaListOptions { - animeList { - sectionOrder - } - } - } - lists { - status - name - entries { - id - mediaId - status - progress - score - media { - id - status - title { - english - romaji - } - episodes - coverImage { - large - } - } - } - } - } - } - `, + query: GET_MEDIA_USER, variables: { username: sessions?.user.name, }, @@ -206,6 +160,10 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { ); const gut = git?.find((item) => item?.media.id === parseInt(aniId)); + if (gut) { + setProgress(gut.progress); + } + if (gut?.status === "COMPLETED") { setStatusWatch("REPEATING"); } else if ( @@ -282,85 +240,83 @@ export default function Info({ sessions, id, aniId, provider, proxy }) {
)}
- { - data && data?.episodes.length > 0 ? ( - data.episodes - .filter((items) => items.id == id) - .map((item, index) => ( -
-
-
- - {item.title || - data.title.romaji || - data.title.english} - -
-

- Episode {item.number} -

+ {data && data?.episodes.length > 0 ? ( + data.episodes + .filter((items) => items.id == id) + .map((item, index) => ( +
+
+
+ + {item.title || + data.title.romaji || + data.title.english} +
-
-
- - -
-
+
+
+ +
+
- )) +
+ )) ) : (
@@ -473,38 +429,53 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { Up Next
- { - data && data?.episodes.length > 0 ? ( - data.episodes.some( - (item) => item.title && item.description - ) ? ( - episodes.map((item) => { - return ( - -
-
- Anime Cover -
+ {data && data?.episodes.length > 0 ? ( + data.episodes.some( + (item) => item.title && item.description + ) ? ( + episodes.map((item) => { + const time = artStorage?.[item.id]?.time; + const duration = artStorage?.[item.id]?.duration; + let prog = (time / duration) * 100; + if (prog > 90) prog = 100; + return ( + +
+
+ Anime Cover + Episode {item.number} @@ -521,40 +492,41 @@ export default function Info({ sessions, id, aniId, provider, proxy }) {
)}
-
-

- {item.title} -

-

- {item.description} -

-
- - ); - }) - ) : ( - data.episodes.map((item) => { - return ( - +
- Episode {item.number} - - ); - }) - ) +

+ {item.title} +

+

+ {item.description} +

+
+ + ); + }) + ) : ( + data.episodes.map((item) => { + return ( + + Episode {item.number} + + ); + }) + ) ) : ( <> {[1].map((item) => ( @@ -568,6 +540,7 @@ export default function Info({ sessions, id, aniId, provider, proxy }) {
+
diff --git a/pages/manga/chapter/[chapter].js b/pages/manga/chapter/[chapter].js deleted file mode 100644 index 14f04ca..0000000 --- a/pages/manga/chapter/[chapter].js +++ /dev/null @@ -1,460 +0,0 @@ -import axios from "axios"; -import Head from "next/head"; -import { useEffect, useState } from "react"; -import Navbar from "../../../components/navbar"; -import Footer from "../../../components/footer"; -import ScrollTracker from "../../../components/scrollTracker"; - -export default function Test({ title, id, aniId, data, provider }) { - const [isLoading, setIsLoading] = useState(true); - const [datas, setData] = useState(data); - const [currentChapter, setCurrentChapter] = useState(null); - const [nextChapter, setNextChapter] = useState(null); - const [prevChapter, setPrevChapter] = useState(null); - - useEffect(() => { - function storedData() { - const nowChap = localStorage.getItem("currentChapterId"); - const chapt = localStorage.getItem("chapters"); - const chapters = JSON.parse(chapt); - const currentChapter = chapters.find((chapter) => chapter.id === nowChap); - const currentIndex = chapters.findIndex( - (chapter) => chapter.id === nowChap - ); - - const nextIndex = currentIndex + 1; - - const nextChapter = chapters[nextIndex]; - const prevIndex = currentIndex - 1; - - setNextChapter(nextChapter); - setCurrentChapter(currentChapter); - setPrevChapter(chapters[prevIndex]); - setIsLoading(false); - } - storedData(); - }, []); - - function getNextChapter() { - window.scrollTo(0, 0); - setIsLoading(true); - const currentId = localStorage.getItem("currentChapterId"); - const scrollData = JSON.parse(localStorage.getItem("watchedManga")) || []; - const scroll = localStorage.getItem("scrollPercentage"); - if (scroll >= 5) { - const existingDataIndex = scrollData.findIndex( - (data) => data.id === currentId - ); - if (existingDataIndex !== -1) { - // Update existing data - scrollData[existingDataIndex].timestamp = Date.now(); - scrollData[existingDataIndex].percentage = parseFloat( - localStorage.getItem("scrollPercentage") - ); - } else { - // Add new data - scrollData.push({ - timestamp: Date.now(), - percentage: parseFloat(localStorage.getItem("scrollPercentage")), - id: currentId, - }); - } - - localStorage.setItem("watchedManga", JSON.stringify(scrollData)); - - const chapt = localStorage.getItem("chapters"); - const chapters = JSON.parse(chapt); - - const currentIndex = chapters.findIndex( - (chapter) => chapter.id === currentId - ); - - const nextIndex = currentIndex + 1; - - const nextChapter = chapters[nextIndex]; - const nexttChapter = chapters[nextIndex + 1]; - const prevChapter = chapters[nextIndex - 1]; - - setNextChapter(nexttChapter); - setCurrentChapter(nextChapter); - setPrevChapter(prevChapter); - - if (!nextChapter) { - return; - } - - fetch( - `https://api.moopa.my.id/meta/anilist-manga/read?chapterId=${nextChapter.id}&provider=${provider}` - ) - .then((response) => response.json()) - .then((data) => { - if (provider === "mangakakalot") { - const datas = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${item.img}&referer={Referer:'https://mangakakalot.com/'}`, - page: item.page, - title: item.title, - })); - // console.log(datas); - setData(datas); - } else { - const dat = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${encodeURIComponent( - item.img - )}&referer=${encodeURIComponent(item.headerForImage.Referer)}`, - page: item.page, - title: item.title || null, - })); - setData(dat); - } - }) - .finally(() => { - setIsLoading(false); - }); - - // Update the current chapter id in local storage - localStorage.setItem("currentChapterId", nextChapter.id); - } - - const chapt = localStorage.getItem("chapters"); - const chapters = JSON.parse(chapt); - - const currentIndex = chapters.findIndex( - (chapter) => chapter.id === currentId - ); - - const nextIndex = currentIndex + 1; - - const nextChapter = chapters[nextIndex]; - const nexttChapter = chapters[nextIndex + 1]; - const prevChapter = chapters[nextIndex - 1]; - - setNextChapter(nexttChapter); - setCurrentChapter(nextChapter); - setPrevChapter(prevChapter); - - if (!nextChapter) { - return; - } - - fetch( - `https://api.moopa.my.id/meta/anilist-manga/read?chapterId=${nextChapter.id}&provider=${provider}` - ) - .then((response) => response.json()) - .then((data) => { - if (provider === "mangakakalot") { - const datas = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${item.img}&referer={Referer:'https://mangakakalot.com/'}`, - page: item.page, - title: item.title, - })); - // console.log(datas); - setData(datas); - } else { - const dat = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${encodeURIComponent( - item.img - )}&referer=${encodeURIComponent(item.headerForImage.Referer)}`, - page: item.page, - title: item.title || null, - })); - setData(dat); - } - }) - .finally(() => { - setIsLoading(false); - }); - - // Update the current chapter id in local storage - localStorage.setItem("currentChapterId", nextChapter.id); - } - // console.log(data); - - function getPrevChapter() { - // Get the current id - window.scrollTo(0, 0); - setIsLoading(true); - - const currentId = localStorage.getItem("currentChapterId"); - const scrollData = JSON.parse(localStorage.getItem("watchedManga")) || []; - const scroll = localStorage.getItem("scrollPercentage"); - if (scroll >= 5) { - const existingDataIndex = scrollData.findIndex( - (data) => data.id === currentId - ); - if (existingDataIndex !== -1) { - // Update existing data - scrollData[existingDataIndex].timestamp = Date.now(); - scrollData[existingDataIndex].percentage = parseFloat( - localStorage.getItem("scrollPercentage") - ); - } else { - // Add new data - scrollData.push({ - timestamp: Date.now(), - percentage: parseFloat(localStorage.getItem("scrollPercentage")), - id: currentId, - }); - } - - localStorage.setItem("watchedManga", JSON.stringify(scrollData)); - - const chapt = localStorage.getItem("chapters"); - const chapters = JSON.parse(chapt); - - const currentIndex = chapters.findIndex( - (chapter) => chapter.id === currentId - ); - - const nextIndex = currentIndex + 1; - - const nextChapter = chapters[nextIndex]; - const nexttChapter = chapters[nextIndex + 1]; - const prevChapter = chapters[nextIndex - 1]; - - setNextChapter(nexttChapter); - setCurrentChapter(nextChapter); - setPrevChapter(prevChapter); - - if (!nextChapter) { - return; - } - - fetch( - `https://api.moopa.my.id/meta/anilist-manga/read?chapterId=${nextChapter.id}&provider=${provider}` - ) - .then((response) => response.json()) - .then((data) => { - if (provider === "mangakakalot") { - const datas = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${item.img}&referer={Referer:'https://mangakakalot.com/'}`, - page: item.page, - title: item.title, - })); - // console.log(datas); - setData(datas); - } else { - const dat = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${encodeURIComponent( - item.img - )}&referer=${encodeURIComponent(item.headerForImage.Referer)}`, - page: item.page, - title: item.title || null, - })); - setData(dat); - } - }) - .finally(() => { - setIsLoading(false); - }); - - // Update the current chapter id in local storage - localStorage.setItem("currentChapterId", nextChapter.id); - } - - const chapt = localStorage.getItem("chapters"); - const chapters = JSON.parse(chapt); - - const currentIndex = chapters.findIndex( - (chapter) => chapter.id === currentId - ); - - const prevIndex = currentIndex - 1; - - const prevChapter = chapters[prevIndex]; - const nextChapter = chapters[prevIndex + 1]; - const prevvChapter = chapters[prevIndex - 1]; - setCurrentChapter(prevChapter); - setNextChapter(nextChapter); - setPrevChapter(prevvChapter); - - fetch( - `https://api.moopa.my.id/meta/anilist-manga/read?chapterId=${prevChapter.id}&provider=${provider}` - ) - .then((response) => response.json()) - .then((data) => { - // console.log(data); - if (provider === "mangakakalot") { - const datas = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${item.img}&referer={Referer:'https://mangakakalot.com/'}`, - page: item.page, - title: item.title, - })); - // console.log(datas); - setData(datas); - } else { - const dat = data.map((item) => ({ - img: `https://api.consumet.org/utils/image-proxy?url=${encodeURIComponent( - item.img - )}&referer=${encodeURIComponent(item.headerForImage.Referer)}`, - page: item.page, - title: item.title || null, - })); - setData(dat); - } - }) - .finally(() => { - setIsLoading(false); - }); - - // Update the current chapter id in local storage - localStorage.setItem("currentChapterId", prevChapter.id); - } - // console.log({ PREV_CHAPTER: prevChapter }); - // console.log({ CURRENT_CHAPTER: currentChapter }); - // console.log({ NEXT_CHAPTER: nextChapter }); - - return ( - <> - - {title} - - - - - - - -
-
- {isLoading ? ( -
- ) : currentChapter && currentChapter.chapter ? ( -

Chapter {currentChapter.chapter}

- ) : ( -

{currentChapter.title}

- )} -
- - {isLoading ? ( -

Loading...

- ) : ( -
- {datas.length > 0 && - datas.map((item, index) => ( - {`Page - ))} -
- )} - {isLoading ? ( -
- ) : ( - <> -
-
- - - -
-
- - - -
-
- -
- {nextChapter ? ( - nextChapter.chapter ? ( -

Next Chapter {nextChapter.chapter}

- ) : ( -

Next Chapter {nextChapter.title}

- ) - ) : ( -

End of Chapter

- )} -
- - )} -
-