diff options
| author | Factiven <[email protected]> | 2023-05-25 22:56:21 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-05-25 22:56:21 +0700 |
| commit | 8dcb5cb96819547e574d4ca619c54c6f902b8860 (patch) | |
| tree | 492e9147c106d7ddb7706c7ba2127f6d04ac49ce /pages | |
| parent | Update videoPlayer.js (diff) | |
| download | moopa-8dcb5cb96819547e574d4ca619c54c6f902b8860.tar.xz moopa-8dcb5cb96819547e574d4ca619c54c6f902b8860.zip | |
Update v3.6.1
> Added Thumbnail to info page
> Temporarily removed Manga from website until the page is finished
Diffstat (limited to 'pages')
| -rw-r--r-- | pages/anime/[...id].js | 604 | ||||
| -rw-r--r-- | pages/anime/watch/[...info].js | 355 | ||||
| -rw-r--r-- | pages/manga/chapter/[chapter].js | 460 | ||||
| -rw-r--r-- | pages/manga/detail/id.js | 267 |
4 files changed, 531 insertions, 1155 deletions
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 }) { )} </div> </div> - <div className="z-20 flex flex-col gap-10 p-3 lg:p-0"> - <div className="flex items-center lg:gap-10 gap-7"> - {info && ( - <h1 className="text-[20px] lg:text-2xl font-bold font-karla"> - Episodes - </h1> - )} - {info?.nextAiringEpisode && ( - <div className="flex items-center gap-2"> - <div className="flex items-center gap-4 text-[10px] xxs:text-sm lg:text-base"> - <h1>Next :</h1> - <div - className="px-5 rounded-sm font-karla font-bold bg-white text-black" - > - {time} + <div className="flex flex-col gap-5 lg:gap-10 p-3 lg:p-0"> + <div className="flex sm:flex-row flex-col gap-5 md:gap-0 justify-between "> + <div className="flex items-center lg:gap-10 gap-7"> + {info && ( + <h1 className="text-[20px] lg:text-2xl font-bold font-karla"> + Episodes + </h1> + )} + {info?.nextAiringEpisode && ( + <div className="flex items-center gap-2"> + <div className="flex items-center gap-4 text-[10px] xxs:text-sm lg:text-base"> + <h1>Next :</h1> + <div className="px-4 rounded-sm font-karla font-bold bg-white text-black"> + {time} + </div> + </div> + <div className="h-6 w-6"> + <ClockIcon /> </div> </div> - <div className="h-6 w-6"> - <ClockIcon /> - </div> + )} + </div> + <div className="flex gap-3 rounded-sm items-center p-2"> + <div + className={ + episode?.length > 0 + ? episode?.some((item) => item?.title === null) + ? "pointer-events-none" + : "cursor-pointer" + : "pointer-events-none" + } + onClick={() => { + setEpiView("1"); + localStorage.setItem("epiView", "1"); + }} + > + <svg + xmlns="http://www.w3.org/2000/svg" + width="31" + height="20" + fill="none" + viewBox="0 0 31 20" + > + <rect + width="31" + height="20" + className={`${ + episode?.length > 0 + ? episode?.some((item) => item?.title === null) + ? "fill-[#1c1c22]" + : epiView === "1" + ? "fill-action" + : "fill-[#3A3A44]" + : "fill-[#1c1c22]" + }`} + rx="3" + ></rect> + </svg> </div> - )} + <div + className={ + episode?.length > 0 + ? episode?.some((item) => item?.title === null) + ? "pointer-events-none" + : "cursor-pointer" + : "pointer-events-none" + } + onClick={() => { + setEpiView("2"); + localStorage.setItem("epiView", "2"); + }} + > + <svg + xmlns="http://www.w3.org/2000/svg" + width="33" + height="20" + fill="none" + className={`${ + episode?.length > 0 + ? episode?.some((item) => item?.title === null) + ? "fill-[#1c1c22]" + : epiView === "2" + ? "fill-action" + : "fill-[#3A3A44]" + : "fill-[#1c1c22]" + }`} + viewBox="0 0 33 20" + > + <rect width="33" height="7" y="1" rx="3"></rect> + <rect width="33" height="7" y="12" rx="3"></rect> + </svg> + </div> + <div + className={ + episode?.length > 0 + ? `cursor-pointer` + : "pointer-events-none" + } + onClick={() => { + setEpiView("3"); + localStorage.setItem("epiView", "3"); + }} + > + <svg + xmlns="http://www.w3.org/2000/svg" + width="33" + height="20" + fill="none" + className={`${ + episode?.length > 0 + ? epiView === "3" + ? "fill-action" + : "fill-[#3A3A44]" + : "fill-[#1c1c22]" + }`} + viewBox="0 0 33 20" + > + <rect width="29" height="4" x="2" y="2" rx="2"></rect> + <rect width="29" height="4" x="2" y="8" rx="2"></rect> + <rect width="16" height="4" x="2" y="14" rx="2"></rect> + </svg> + </div> + </div> </div> {!loading ? ( episode && ( - <div className="flex h-[640px] flex-col gap-5 scrollbar-thin scrollbar-thumb-[#1b1c21] scrollbar-thumb-rounded-full overflow-y-scroll hover:scrollbar-thumb-[#2e2f37]"> - { - episode?.length !== 0 && episode ? ( - episode?.map((epi, index) => { - return ( - <div - key={index} - className="flex flex-col gap-3 px-2" - > + <div + className={`${ + epiView === "3" && + "scrollbar-thin scrollbar-thumb-[#1b1c21] scrollbar-thumb-rounded-full overflow-y-scroll hover:scrollbar-thumb-[#2e2f37] h-[640px]" + }`} + > + {episode?.length !== 0 && episode ? ( + <div + className={`grid ${ + epiView === "1" + ? "grid-auto-fit gap-5 lg:gap-8" + : "flex flex-col gap-5" + } pb-5 ${ + epiView === "3" ? "" : "place-items-center" + }`} + > + {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 ( + <Link + key={index} + href={`/anime/watch/${epi.id}/${info.id}`} + className="transition-all duration-200 ease-out lg:hover:scale-105 hover:ring-1 hover:ring-white cursor-pointer bg-secondary shrink-0 relative w-full h-[180px] sm:h-[130px] subpixel-antialiased rounded-md overflow-hidden" + > + <span className="absolute text-sm z-40 bottom-1 left-2 font-karla font-semibold text-white"> + Episode {epi?.number} + </span> + <span + className={`absolute bottom-7 left-0 h-1 bg-red-600`} + style={{ + width: + progress && + artStorage && + epi?.number <= progress + ? "100%" + : artStorage?.[epi?.id] + ? `${prog}%` + : "0%", + }} + /> + <div className="absolute inset-0 bg-black z-30 opacity-20" /> + <Image + src={epi?.image} + alt="epi image" + width={500} + height={500} + className="object-cover w-full h-[150px] sm:h-[100px] z-20" + /> + </Link> + ); + }) + : ""} + {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 ( <Link + key={index} href={`/anime/watch/${epi.id}/${info.id}`} - className={`text-start text-sm lg:text-lg ${ - progress && epi.number <= progress - ? "text-[#5f5f5f]" - : "text-white" - }`} + className="flex group h-[110px] lg:h-[160px] w-full rounded-lg transition-all duration-300 ease-out bg-secondary cursor-pointer hover:scale-[1.02] ring-0 hover:ring-1 hover:shadow-lg ring-white" > - <p>Episode {epi.number}</p> - {epi.title && ( - <p - className={`text-xs lg:text-sm ${ - progress && epi.number <= progress - ? "text-[#5f5f5f]" - : "text-[#b1b1b1]" - } italic`} - > - "{epi.title}" - </p> - )} + <div className="w-[43%] lg:w-[30%] relative shrink-0 z-40 rounded-lg overflow-hidden shadow-[4px_0px_5px_0px_rgba(0,0,0,0.3)]"> + <div className="relative"> + <Image + src={epi?.image} + alt="Anime Cover" + width={1000} + height={1000} + className="object-cover z-30 rounded-lg h-[110px] lg:h-[160px] brightness-[65%]" + /> + <span + className={`absolute bottom-0 left-0 h-[3px] bg-red-700`} + style={{ + width: + progress && + artStorage && + epi?.number <= progress + ? "100%" + : artStorage?.[epi?.id] + ? `${prog}%` + : "0", + }} + /> + <span className="absolute bottom-2 left-2 font-karla font-semibold text-sm lg:text-lg"> + Episode {epi?.number} + </span> + <div className="z-[9999] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 scale-[1.5]"> + <svg + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 20 20" + fill="currentColor" + className="w-5 h-5 invisible group-hover:visible" + > + <path d="M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z" /> + </svg> + </div> + </div> + </div> + + <div + className={`w-[70%] h-full select-none p-4 flex flex-col justify-center gap-5 ${ + epi?.id == id ? "text-[#7a7a7a]" : "" + }`} + > + <h1 className="font-karla font-bold text-base lg:text-lg xl:text-xl italic line-clamp-1"> + {epi?.title} + </h1> + {epi?.description && ( + <p className="line-clamp-2 text-xs lg:text-md xl:text-lg italic font-outfit font-extralight"> + {epi?.description} + </p> + )} + </div> </Link> - {index !== episode?.length - 1 && ( - <span className="h-[1px] bg-white" /> - )} - </div> - ); - }) - ) : ( - <p>No Episodes Available</p> - ) - } + ); + })} + {epiView === "3" && + episode?.map((epi, index) => { + return ( + <div + key={index} + className="flex flex-col gap-3 px-2" + > + <Link + href={`/anime/watch/${epi.id}/${info.id}`} + className={`text-start text-sm lg:text-lg ${ + progress && epi.number <= progress + ? "text-[#5f5f5f]" + : "text-white" + }`} + > + <p>Episode {epi.number}</p> + {epi.title && ( + <p + className={`text-xs lg:text-sm ${ + progress && epi.number <= progress + ? "text-[#5f5f5f]" + : "text-[#b1b1b1]" + } italic`} + > + "{epi.title}" + </p> + )} + </Link> + {index !== episode?.length - 1 && ( + <span className="h-[1px] bg-white" /> + )} + </div> + ); + })} + </div> + ) : ( + <p>No Episodes Available</p> + )} </div> ) ) : ( @@ -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 }) { <div className="aspect-video bg-black" /> )} <div> - { - data && data?.episodes.length > 0 ? ( - data.episodes - .filter((items) => items.id == id) - .map((item, index) => ( - <div className="flex justify-between" key={index}> - <div key={item.id} className="p-3 grid gap-2 w-[60%]"> - <div className="text-xl font-outfit font-semibold line-clamp-1"> - <Link - href={`/anime/${data.id}`} - className="inline hover:underline" - > - {item.title || - data.title.romaji || - data.title.english} - </Link> - </div> - <h4 className="text-sm font-karla font-light"> - Episode {item.number} - </h4> + {data && data?.episodes.length > 0 ? ( + data.episodes + .filter((items) => items.id == id) + .map((item, index) => ( + <div className="flex justify-between" key={index}> + <div key={item.id} className="p-3 grid gap-2 w-[60%]"> + <div className="text-xl font-outfit font-semibold line-clamp-1"> + <Link + href={`/anime/${data.id}`} + className="inline hover:underline" + > + {item.title || + data.title.romaji || + data.title.english} + </Link> </div> - <div className="w-[50%] flex gap-4 items-center justify-end px-4"> - <div className="relative"> - <select - className="flex items-center gap-5 rounded-[3px] bg-secondary py-1 px-3 pr-8 font-karla appearance-none cursor-pointer" - value={item.number} - onChange={(e) => { - const selectedEpisode = data.episodes.find( - (episode) => - episode.number === - parseInt(e.target.value) - ); - router.push( - `/anime/watch/${selectedEpisode.id}/${data.id}` - ); - }} - > - {data.episodes.map((episode) => ( - <option - key={episode.number} - value={episode.number} - > - Episode {episode.number} - </option> - ))} - </select> - <ChevronDownIcon className="absolute right-2 top-1/2 transform -translate-y-1/2 w-5 h-5 pointer-events-none" /> - </div> - <button - className={`${ - item.number === data.episodes.length - ? "pointer-events-none" - : "" - } relative group`} - onClick={() => { - const currentEpisodeIndex = - data.episodes.findIndex( - (episode) => episode.number === item.number - ); - if ( - currentEpisodeIndex !== -1 && - currentEpisodeIndex < data.episodes.length - 1 - ) { - const nextEpisode = - data.episodes[currentEpisodeIndex + 1]; - router.push( - `/anime/watch/${nextEpisode.id}/${data.id}` - ); - } + <h4 className="text-sm font-karla font-light"> + Episode {item.number} + </h4> + </div> + <div className="w-[50%] flex gap-4 items-center justify-end px-4"> + <div className="relative"> + <select + className="flex items-center gap-5 rounded-[3px] bg-secondary py-1 px-3 pr-8 font-karla appearance-none cursor-pointer" + value={item.number} + onChange={(e) => { + const selectedEpisode = data.episodes.find( + (episode) => + episode.number === parseInt(e.target.value) + ); + router.push( + `/anime/watch/${selectedEpisode.id}/${data.id}` + ); }} > - <span className="absolute z-[9999] -left-11 -top-14 p-2 shadow-xl rounded-md transform transition-all whitespace-nowrap bg-secondary lg:group-hover:block group-hover:opacity-1 hidden font-karla font-bold"> - Next Episode - </span> - <ForwardIcon className="w-6 h-6" /> - </button> + {data.episodes.map((episode) => ( + <option + key={episode.number} + value={episode.number} + > + Episode {episode.number} + </option> + ))} + </select> + <ChevronDownIcon className="absolute right-2 top-1/2 transform -translate-y-1/2 w-5 h-5 pointer-events-none" /> </div> + <button + className={`${ + item.number === data.episodes.length + ? "pointer-events-none" + : "" + } relative group`} + onClick={() => { + const currentEpisodeIndex = + data.episodes.findIndex( + (episode) => episode.number === item.number + ); + if ( + currentEpisodeIndex !== -1 && + currentEpisodeIndex < data.episodes.length - 1 + ) { + const nextEpisode = + data.episodes[currentEpisodeIndex + 1]; + router.push( + `/anime/watch/${nextEpisode.id}/${data.id}` + ); + } + }} + > + <span className="absolute z-[9999] -left-11 -top-14 p-2 shadow-xl rounded-md transform transition-all whitespace-nowrap bg-secondary lg:group-hover:block group-hover:opacity-1 hidden font-karla font-bold"> + Next Episode + </span> + <ForwardIcon className="w-6 h-6" /> + </button> </div> - )) + </div> + )) ) : ( <div className="p-3 grid gap-2"> <div className="text-xl font-outfit font-semibold line-clamp-2"> @@ -473,38 +429,53 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { Up Next </h1> <div className="flex flex-col gap-5 lg:pl-5 px-2 py-2 scrollbar-thin scrollbar-thumb-[#313131] scrollbar-thumb-rounded-full"> - { - data && data?.episodes.length > 0 ? ( - data.episodes.some( - (item) => item.title && item.description - ) ? ( - episodes.map((item) => { - return ( - <Link - href={`/anime/watch/${item.id}/${data.id}${ - provider ? "/9anime" : "" - }`} - key={item.id} - className={`bg-secondary flex w-full h-[110px] rounded-lg scale-100 transition-all duration-300 ease-out ${ - item.id == id - ? "pointer-events-none ring-1 ring-action" - : "cursor-pointer hover:scale-[1.02] ring-0 hover:ring-1 hover:shadow-lg ring-white" - }`} - > - <div className="w-[40%] h-[110px] relative "> - <div className=""> - <Image - src={item.image} - alt="Anime Cover" - width={1000} - height={1000} - className={`object-cover rounded-lg w-[240px] h-[110px] shadow-[4px_0px_5px_0px_rgba(0,0,0,0.3)] ${ - item.id == id - ? "brightness-[30%]" - : "brightness-75" - }`} - /> - </div> + {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 ( + <Link + href={`/anime/watch/${item.id}/${data.id}${ + provider ? "/9anime" : "" + }`} + key={item.id} + className={`bg-secondary flex w-full h-[110px] rounded-lg scale-100 transition-all duration-300 ease-out ${ + item.id == id + ? "pointer-events-none ring-1 ring-action" + : "cursor-pointer hover:scale-[1.02] ring-0 hover:ring-1 hover:shadow-lg ring-white" + }`} + > + <div className="w-[43%] lg:w-[40%] h-[110px] relative rounded-lg z-40 shrink-0 overflow-hidden shadow-[4px_0px_5px_0px_rgba(0,0,0,0.3)]"> + <div className="relative"> + <Image + src={item.image} + alt="Anime Cover" + width={1000} + height={1000} + className={`object-cover z-30 rounded-lg h-[110px] ${ + item.id == id + ? "brightness-[30%]" + : "brightness-75" + }`} + /> + <span + className={`absolute bottom-0 left-0 h-[3px] bg-red-700`} + style={{ + width: + progress && + artStorage && + item?.number <= progress + ? "100%" + : artStorage?.[item?.id] + ? `${prog}%` + : "0", + }} + /> <span className="absolute bottom-2 left-2 font-karla font-light text-sm"> Episode {item.number} </span> @@ -521,40 +492,41 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { </div> )} </div> - <div - className={`w-[70%] h-full select-none p-4 flex flex-col gap-2 ${ - item.id == id ? "text-[#7a7a7a]" : "" - }`} - > - <h1 className="font-karla font-bold italic line-clamp-1"> - {item.title} - </h1> - <p className="line-clamp-2 text-xs italic font-outfit font-extralight"> - {item.description} - </p> - </div> - </Link> - ); - }) - ) : ( - data.episodes.map((item) => { - return ( - <Link - href={`/anime/watch/${item.id}/${data.id}${ - provider ? "/9anime" : "" - }`} - key={item.id} - className={`bg-secondary flex-center w-full h-[50px] rounded-lg scale-100 transition-all duration-300 ease-out ${ - item.id == id - ? "pointer-events-none ring-1 ring-action text-[#5d5d5d]" - : "cursor-pointer hover:scale-[1.02] ring-0 hover:ring-1 hover:shadow-lg ring-white" + </div> + <div + className={`w-[70%] h-full select-none p-4 flex flex-col gap-2 ${ + item.id == id ? "text-[#7a7a7a]" : "" }`} > - Episode {item.number} - </Link> - ); - }) - ) + <h1 className="font-karla font-bold italic line-clamp-1"> + {item.title} + </h1> + <p className="line-clamp-2 text-xs italic font-outfit font-extralight"> + {item.description} + </p> + </div> + </Link> + ); + }) + ) : ( + data.episodes.map((item) => { + return ( + <Link + href={`/anime/watch/${item.id}/${data.id}${ + provider ? "/9anime" : "" + }`} + key={item.id} + className={`bg-secondary flex-center w-full h-[50px] rounded-lg scale-100 transition-all duration-300 ease-out ${ + item.id == id + ? "pointer-events-none ring-1 ring-action text-[#5d5d5d]" + : "cursor-pointer hover:scale-[1.02] ring-0 hover:ring-1 hover:shadow-lg ring-white" + }`} + > + Episode {item.number} + </Link> + ); + }) + ) ) : ( <> {[1].map((item) => ( @@ -568,6 +540,7 @@ export default function Info({ sessions, id, aniId, provider, proxy }) { </div> </div> </div> + <Footer /> </div> </SkeletonTheme> </> 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 ( - <> - <Head> - <title>{title}</title> - <meta name="info" content="More detailed info about the Manga" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="icon" href="/c.svg" /> - </Head> - <Navbar /> - <ScrollTracker data={currentChapter} id={aniId} /> - - <div className="flex h-full min-h-screen w-screen flex-col items-center text-white"> - <div className="lg:pt-nav pt-5 text-3xl font-semibold"> - {isLoading ? ( - <div /> - ) : currentChapter && currentChapter.chapter ? ( - <p>Chapter {currentChapter.chapter}</p> - ) : ( - <p>{currentChapter.title}</p> - )} - </div> - - {isLoading ? ( - <p className="pt-nav">Loading...</p> - ) : ( - <div className="pointer-events-none z-10 flex min-h-screen w-screen flex-col items-center pt-nav"> - {datas.length > 0 && - datas.map((item, index) => ( - <img - draggable={false} - key={index} - src={item.img} - alt={`Page ${item.page}`} - /> - ))} - </div> - )} - {isLoading ? ( - <div /> - ) : ( - <> - <div className="sticky bottom-9 z-40 my-5 mr-[20rem] flex gap-6 lg:mr-0 lg:gap-10"> - <div - className={`cursor-pointer rounded-md bg-[#121212] p-2 text-center text-xl hover:bg-[#2d303a] ${ - prevChapter ? `` : `pointer-events-none` - }`} - onClick={getPrevChapter} - > - <svg - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - strokeWidth="1.5" - stroke={`${prevChapter ? `currentColor` : `#919191`}`} - className="h-6 w-6" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - d="M15.75 19.5L8.25 12l7.5-7.5" - /> - </svg> - </div> - <div - className={`cursor-pointer ${ - nextChapter ? `` : `pointer-events-none` - } rounded-md bg-[#121212] p-2 text-center text-xl hover:bg-[#2d303a]`} - onClick={getNextChapter} - > - <svg - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 24 24" - fill="none" - strokeWidth="1.5" - stroke={`${nextChapter ? `currentColor` : `#919191`}`} - className={`h-6 w-6`} - > - <path - strokeLinecap="round" - strokeLinejoin="round" - d="M8.25 4.5l7.5 7.5-7.5 7.5" - /> - </svg> - </div> - </div> - - <div className="z-30 w-screen bg-[#1e2023] px-5 py-[3px] text-xl lg:w-[30%] lg:bg-transparent lg:text-center"> - {nextChapter ? ( - nextChapter.chapter ? ( - <p>Next Chapter {nextChapter.chapter}</p> - ) : ( - <p>Next Chapter {nextChapter.title}</p> - ) - ) : ( - <p>End of Chapter</p> - )} - </div> - </> - )} - </div> - <Footer /> - </> - ); -} - -export async function getServerSideProps(context) { - const { id, title, provider, aniId } = context.query; - const urls = [ - `https://api.moopa.my.id/meta/anilist-manga/read?chapterId=${id}&provider=${provider}`, - ]; - const results = await axios.get(urls); - - if (provider === "mangakakalot") { - const data = results.data; - 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, - })); - return { - props: { - aniId, - id, - title, - data: datas, - provider, - }, - }; - } - - if (!results.data) { - return { - notFound: true, - }; - } - - const data = results.data; - 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, - })); - - return { - props: { - aniId, - id, - title, - data: dat, - provider, - }, - }; -} diff --git a/pages/manga/detail/id.js b/pages/manga/detail/id.js deleted file mode 100644 index 29cacb1..0000000 --- a/pages/manga/detail/id.js +++ /dev/null @@ -1,267 +0,0 @@ -import axios from "axios"; -import Head from "next/head"; -import Image from "next/image"; -import Link from "next/link"; -import { useEffect, useState } from "react"; -import Layout from "../../../components/layout"; - -// { `Don't touch this` } - -// import { useUser } from "@auth0/nextjs-auth0/client"; -// import { -// arrayRemove, -// arrayUnion, -// collection, -// doc, -// getDoc, -// getDocs, -// setDoc, -// updateDoc, -// } from "firebase/firestore"; -// import db from "../../../lib/firebase"; - -const options = [ - "mangadex", - "mangahere", - "mangakakalot", - "mangapark", - "mangapill", - "mangareader", - "mangasee123", -]; - -export default function MangaDetail({ data, manga, aniId, provider }) { - const [selectOption, setSelectedOption] = useState(options[0]); - const [recentWatch, setRecentWatch] = useState(); - - const [load, setLoad] = useState(true); - - useEffect(() => { - function getRecent() { - const recentWatch = JSON.parse(localStorage.getItem("watchedManga"))?.map( - (data) => data.id - ); - setRecentWatch(recentWatch); - } - getRecent(); - }, []); - - function handleLoad() { - setLoad(false); - } - - const relation = data?.relations.filter( - (relation) => relation.malId !== null - ); - - const mangan = JSON.stringify(manga); - - async function clickDeez(props) { - localStorage.setItem("chapters", mangan); - localStorage.setItem("currentChapterId", props); - } - - return ( - <> - <Head> - <title>{data.title?.english || data.title.romaji}</title> - <meta name="info" content="More detailed info about the Manga" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="icon" href="/c.svg" /> - </Head> - <div className="w-screen"> - <Layout> - <div className="flex w-screen justify-center pt-[10rem] "> - {data ? ( - <div className="flex w-[85%] flex-col gap-10 "> - <div className="flex gap-10"> - <div className="relative h-[358px] w-[230px]"> - <Image - src={data.image} - alt="CoverImage" - fill - className="object-cover" - /> - </div> - <div className="flex w-[77%] flex-col gap-10"> - <h1 className="font-karla text-3xl font-bold"> - {data.title?.english} - </h1> - <p dangerouslySetInnerHTML={{ __html: data.description }} /> - </div> - </div> - {relation?.length > 0 ? ( - <div className="p-3 lg:p-0"> - <h1 className="items-start py-5 text-2xl font-bold"> - Relations - </h1> - <div - className={`grid grid-cols-1 justify-items-center py-5 px-5 lg:grid-cols-3 ${ - load ? "h-[290px] overflow-y-clip" : "" - }`} - > - {relation && - relation.map((relation, index) => { - return ( - <div key={index} className="w-full gap-6 p-5 "> - <Link - href={ - relation.type === "MANGA" || - relation.type === "NOVEL" - ? `/manga/detail/id?aniId=${relation.id}` - : `/anime/${relation.id}` - } - className={`flex w-full justify-between rounded-md bg-[#282828] p-2 shadow-lg duration-300 ease-out hover:scale-105 ${ - relation.type === "TV" || - relation.type === "OVA" || - relation.type === "MOVIE" || - relation.type === "SPECIAL" || - relation.type === "ONA" || - relation.type === "MANGA" || - relation.type === "TV_SHORT" - ? `` - : "pointer-events-none" - }`} - > - <div className="flex flex-col justify-between"> - <div className="font-bold text-[#FF7F57]"> - {relation.relationType} - </div> - <div className="text-lg font-bold text-white"> - {relation.title.romaji || - relation.title.english || - relation.title.userPreferred} - </div> - <div className="flex"> - <p className="dynamic-text rounded-lg p-1 font-outfit text-sm font-semibold"> - {relation.type} - </p> - </div> - </div> - <div className="relative h-[200px] w-[140px] shrink-0"> - <Image - fill - src={relation.image} - alt={`Cover Image for ${relation.title}`} - className=" bg-slate-400 object-cover" - /> - </div> - </Link> - </div> - ); - })} - </div> - {relation.length > 3 && ( - <button - type="button" - className="w-full" - onClick={handleLoad} - > - {load ? "Load More" : ""} - </button> - )} - </div> - ) : ( - <p>No Relations</p> - )} - <div className="flex flex-col gap-10"> - <h1 className="text-3xl font-bold">Chapters</h1> - <div className="flex h-[640px] flex-col gap-10 overflow-y-scroll scrollbar-thin scrollbar-thumb-slate-800 scrollbar-thumb-rounded-full hover:scrollbar-thumb-slate-600"> - {manga?.map((chapter, index) => { - return ( - <div - key={index} - onClick={() => clickDeez(chapter.id)} - className={`${ - recentWatch?.includes(chapter.id) - ? "text-gray-400" - : "" - }`} - > - <Link - // href="#" - href={`/manga/chapter/[chapter]`} - as={`/manga/chapter/read?id=${chapter.id}&title=${ - data.title?.english || data.title?.romaji - }&provider=${provider}&aniId=${aniId}`} - > - {typeof chapter.title === "string" && - !isNaN(Number(chapter.title)) ? ( - <div>Chapter {Number(chapter.title)}</div> - ) : ( - <div> - {chapter.chapter ? ( - <p>Chapter {chapter.chapter}</p> - ) : ( - <p>{chapter.title}</p> - )} - </div> - )} - </Link> - </div> - ); - })} - </div> - </div> - </div> - ) : ( - <p>Oops no data found :(</p> - )} - </div> - </Layout> - </div> - </> - ); -} - -export const getServerSideProps = async (context) => { - context.res.setHeader("Cache-Control", "public, max-age=3600"); - const { aniId, aniTitle } = context.query; - const prv = "mangahere"; - - try { - const info = await axios.get( - `https://api.moopa.my.id/meta/anilist-manga/info/${aniId}?provider=${prv}` - ); - const result = info.data; - const manga = result.chapters; - - return { - props: { - data: result, - aniId: aniId, - provider: prv, - manga, - }, - }; - } catch (error) { - if (error.response && error.response.status === 404) { - try { - const prv = "mangakakalot"; - const manga = await axios.get( - `https://api.moopa.my.id/meta/anilist-manga/info/${aniId}?provider=${prv}` - ); - const results = manga.data; - - return { - props: { - data: results, - aniId: aniId, - manga: results.chapters, - provider: prv, - }, - }; - } catch (error) { - console.error(error); - return { - notFound: true, - }; - } - } else { - console.error(error); - return { - notFound: true, - }; - } - } -}; |