diff options
Diffstat (limited to 'components/anime/watch')
| -rw-r--r-- | components/anime/watch/primary/details.js | 185 | ||||
| -rw-r--r-- | components/anime/watch/primarySide.js | 276 | ||||
| -rw-r--r-- | components/anime/watch/secondarySide.js | 134 |
3 files changed, 0 insertions, 595 deletions
diff --git a/components/anime/watch/primary/details.js b/components/anime/watch/primary/details.js deleted file mode 100644 index f092879..0000000 --- a/components/anime/watch/primary/details.js +++ /dev/null @@ -1,185 +0,0 @@ -import { useEffect, useState } from "react"; -import { useAniList } from "../../../../lib/anilist/useAnilist"; -import Skeleton from "react-loading-skeleton"; -import DisqusComments from "../../../disqus"; -import Image from "next/image"; - -export default function Details({ - info, - session, - epiNumber, - description, - id, - onList, - setOnList, - handleOpen, - disqus, -}) { - const [showComments, setShowComments] = useState(false); - const { markPlanning } = useAniList(session); - const [url, setUrl] = useState(null); - - function handlePlan() { - if (onList === false) { - markPlanning(info.id); - setOnList(true); - } - } - - useEffect(() => { - const url = window.location.href; - setShowComments(false); - setUrl(url); - }, [id]); - - return ( - <div className="flex flex-col gap-2"> - <div className="px-4 pt-7 pb-4 h-full flex"> - <div className="aspect-[9/13] h-[240px]"> - {info ? ( - <Image - src={info.coverImage.extraLarge} - alt="Anime Cover" - width={1000} - height={1000} - priority - className="object-cover aspect-[9/13] h-[240px] rounded-md" - /> - ) : ( - <Skeleton height={240} /> - )} - </div> - <div - className="grid w-full pl-5 gap-3 h-[240px]" - data-episode={info?.episodes || "0"} - > - <div className="grid grid-cols-2 gap-1 items-center"> - <h2 className="text-sm font-light font-roboto text-[#878787]"> - Studios - </h2> - <div className="row-start-2"> - {info ? info.studios.edges[0].node.name : <Skeleton width={80} />} - </div> - <div className="hidden xxs:grid col-start-2 place-content-end relative"> - <div> - <svg - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - strokeWidth={1.5} - stroke="currentColor" - onClick={() => { - session ? handlePlan() : handleOpen(); - }} - className={`w-8 h-8 hover:fill-white text-white hover:cursor-pointer ${ - onList ? "fill-white" : "" - }`} - > - <path - strokeLinecap="round" - strokeLinejoin="round" - d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z" - /> - </svg> - </div> - </div> - </div> - <div className="grid gap-1 items-center"> - <h2 className="text-sm font-light font-roboto text-[#878787]"> - Status - </h2> - <div>{info ? info.status : <Skeleton width={75} />}</div> - </div> - <div className="grid gap-1 items-center overflow-y-hidden"> - <h2 className="text-sm font-light font-roboto text-[#878787]"> - Titles - </h2> - <div className="grid grid-flow-dense grid-cols-2 gap-2 h-full w-full"> - {info ? ( - <> - <div className="title-rm line-clamp-3"> - {info.title?.romaji || ""} - </div> - <div className="title-en line-clamp-3"> - {info.title?.english || ""} - </div> - <div className="title-nt line-clamp-3"> - {info.title?.native || ""} - </div> - </> - ) : ( - <Skeleton width={200} height={50} /> - )} - </div> - </div> - </div> - </div> - <div className="flex flex-wrap gap-3 px-4 pt-3"> - {info && - info.genres?.map((item, index) => ( - <div - key={index} - className="border border-action text-gray-100 py-1 px-2 rounded-md font-karla text-sm" - > - {item} - </div> - ))} - </div> - <div className={`bg-secondary rounded-md mt-3 mx-3`}> - {info && ( - <p - dangerouslySetInnerHTML={{ __html: description }} - className={`p-5 text-sm font-light font-roboto text-[#e4e4e4] `} - /> - )} - </div> - {/* {<div className="mt-5 px-5"></div>} */} - {!showComments && ( - <div className="w-full flex justify-center py-2 font-karla px-3 lg:px-0"> - <button - onClick={() => setShowComments(true)} - className={ - showComments - ? "hidden" - : "flex-center gap-2 h-10 bg-secondary rounded w-full lg:w-[50%]" - } - > - Load Disqus{" "} - <svg - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - strokeWidth="1.5" - stroke="currentColor" - className="w-5 h-5" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 01-.825-.242m9.345-8.334a2.126 2.126 0 00-.476-.095 48.64 48.64 0 00-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0011.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155" - /> - </svg> - </button> - </div> - )} - {showComments && ( - <div> - {info && url && ( - <div className="mt-5 px-5"> - <DisqusComments - key={id} - post={{ - id: id, - title: info.title.romaji, - url: url, - episode: epiNumber, - name: disqus, - }} - /> - </div> - )} - </div> - )} - </div> - ); -} diff --git a/components/anime/watch/primarySide.js b/components/anime/watch/primarySide.js deleted file mode 100644 index a3d9f4f..0000000 --- a/components/anime/watch/primarySide.js +++ /dev/null @@ -1,276 +0,0 @@ -import { useEffect, useState } from "react"; -import { ChevronDownIcon } from "@heroicons/react/20/solid"; -import { ForwardIcon } from "@heroicons/react/24/solid"; -import { useRouter } from "next/router"; -import { signIn } from "next-auth/react"; -import Details from "./primary/details"; -import VideoPlayer from "../../videoPlayer"; -import Link from "next/link"; -import Skeleton from "react-loading-skeleton"; -import Modal from "../../modal"; -import AniList from "../../media/aniList"; - -export default function PrimarySide({ - info, - session, - epiNumber, - navigation, - providerId, - watchId, - onList, - proxy, - disqus, - setOnList, - episodeList, - timeWatched, - dub, -}) { - const [episodeData, setEpisodeData] = useState(); - const [open, setOpen] = useState(false); - const [skip, setSkip] = useState(); - - const [loading, setLoading] = useState(true); - - const router = useRouter(); - - useEffect(() => { - setLoading(true); - async function fetchData() { - if (info) { - const anify = await fetch("/api/v2/source", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - source: - providerId === "gogoanime" && !watchId.startsWith("/") - ? "consumet" - : "anify", - providerId: providerId, - watchId: watchId, - episode: epiNumber, - id: info.id, - sub: dub ? "dub" : "sub", - }), - }).then((res) => res.json()); - - const skip = await fetch( - `https://api.aniskip.com/v2/skip-times/${info.idMal}/${parseInt( - epiNumber - )}?types[]=ed&types[]=mixed-ed&types[]=mixed-op&types[]=op&types[]=recap&episodeLength=` - ).then((res) => { - if (!res.ok) { - switch (res.status) { - case 404: { - return null; - } - } - } - return res.json(); - }); - - const op = - skip?.results?.find((item) => item.skipType === "op") || null; - const ed = - skip?.results?.find((item) => item.skipType === "ed") || null; - - setSkip({ op, ed }); - - setEpisodeData(anify); - setLoading(false); - } - } - - fetchData(); - return () => { - setEpisodeData(); - setSkip(); - }; - }, [providerId, watchId, info]); - - useEffect(() => { - const mediaSession = navigator.mediaSession; - if (!mediaSession) return; - - const now = navigation?.playing; - const poster = now?.image || info?.bannerImage; - const title = now?.title || info?.title?.romaji; - - const artwork = poster - ? [{ src: poster, sizes: "512x512", type: "image/jpeg" }] - : undefined; - - mediaSession.metadata = new MediaMetadata({ - title: title, - artist: `Moopa ${ - title === info?.title?.romaji - ? "- Episode " + epiNumber - : `- ${info?.title?.romaji || info?.title?.english}` - }`, - artwork, - }); - }, [navigation, info, epiNumber]); - - function handleOpen() { - setOpen(true); - document.body.style.overflow = "hidden"; - } - - function handleClose() { - setOpen(false); - document.body.style.overflow = "auto"; - } - - return ( - <> - <Modal open={open} onClose={() => handleClose()}> - {!session && ( - <div className="flex-center flex-col gap-5 px-10 py-5 bg-secondary rounded-md"> - <h1 className="text-md font-extrabold font-karla"> - Edit your list - </h1> - <button - className="flex items-center bg-[#363642] rounded-md text-white p-1" - onClick={() => signIn("AniListProvider")} - > - <h1 className="px-1 font-bold font-karla">Login with AniList</h1> - <div className="scale-[60%] pb-[1px]"> - <AniList /> - </div> - </button> - </div> - )} - </Modal> - <div className="w-full h-full"> - <div key={watchId} className="w-full aspect-video bg-black"> - {!loading ? ( - navigation && episodeData?.sources?.length !== 0 ? ( - <VideoPlayer - session={session} - info={info} - data={episodeData} - provider={providerId} - id={watchId} - progress={epiNumber} - skip={skip} - proxy={proxy} - aniId={info.id} - aniTitle={info.title?.romaji || info.title?.english} - track={navigation} - timeWatched={timeWatched} - dub={dub} - /> - ) : ( - <p className="h-full flex-center"> - Video is not available, please try other providers - </p> - ) - ) : ( - <div className="flex-center aspect-video bg-black"> - <div className="lds-ellipsis"> - <div></div> - <div></div> - <div></div> - <div></div> - </div> - </div> - )} - </div> - <div className="flex flex-col divide-y divide-white/20"> - {info && episodeList ? ( - <div className="flex items-center justify-between py-3 px-3"> - <div className="flex flex-col gap-2 w-[60%]"> - <h1 className="text-xl font-outfit font-semibold line-clamp-1"> - <Link - href={`/en/anime/${info.id}`} - className="hover:underline" - title={navigation?.playing?.title || info.title?.romaji} - > - {navigation?.playing?.title || info.title?.romaji} - </Link> - </h1> - <h3 className="text-sm font-karla font-light"> - Episode {epiNumber} - </h3> - </div> - <div className="flex gap-4 items-center justify-end"> - <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={epiNumber} - onChange={(e) => { - const selectedEpisode = episodeList.find( - (episode) => episode.number === parseInt(e.target.value) - ); - router.push( - `/en/anime/watch/${info.id}/${providerId}?id=${ - selectedEpisode.id - }&num=${selectedEpisode.number}${ - dub ? `&dub=${dub}` : "" - }` - ); - }} - > - {episodeList.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 - disabled={!navigation?.next} - className={`${ - !navigation?.next ? "pointer-events-none" : "" - }relative group`} - onClick={() => { - router.push( - `/en/anime/watch/${info.id}/${providerId}?id=${ - navigation?.next.id - }&num=${navigation?.next.number}${ - dub ? `&dub=${dub}` : "" - }` - ); - }} - > - <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 ${ - !navigation?.next ? "text-[#282828]" : "" - }`} - /> - </button> - </div> - </div> - ) : ( - <div className="py-3 px-4"> - <div className="text-xl font-outfit font-semibold line-clamp-2"> - <div className="inline hover:underline"> - <Skeleton width={240} /> - </div> - </div> - <h4 className="text-sm font-karla font-light"> - <Skeleton width={75} /> - </h4> - </div> - )} - <Details - info={info} - session={session} - description={navigation?.playing?.description || info?.description} - epiNumber={epiNumber} - id={watchId} - onList={onList} - setOnList={setOnList} - handleOpen={handleOpen} - disqus={disqus} - /> - </div> - </div> - </> - ); -} diff --git a/components/anime/watch/secondarySide.js b/components/anime/watch/secondarySide.js deleted file mode 100644 index c9ef684..0000000 --- a/components/anime/watch/secondarySide.js +++ /dev/null @@ -1,134 +0,0 @@ -import Skeleton from "react-loading-skeleton"; -import Image from "next/image"; -import Link from "next/link"; - -export default function SecondarySide({ - info, - map, - providerId, - watchId, - episode, - artStorage, - dub, -}) { - const progress = info.mediaListEntry?.progress; - return ( - <div className="lg:w-[35%] shrink-0 w-screen"> - <h1 className="text-xl font-karla pl-4 pb-5 font-semibold">Up Next</h1> - <div className="flex flex-col gap-5 lg:pl-5 py-2 scrollbar-thin px-2 scrollbar-thumb-[#313131] scrollbar-thumb-rounded-full"> - {episode && episode.length > 0 ? ( - map?.some((item) => item.title && item.description) > 0 ? ( - episode.map((item) => { - const time = artStorage?.[item.id]?.timeWatched; - const duration = artStorage?.[item.id]?.duration; - let prog = (time / duration) * 100; - if (prog > 90) prog = 100; - - const mapData = map?.find((i) => i.number === item.number); - return ( - <Link - href={`/en/anime/watch/${ - info.id - }/${providerId}?id=${encodeURIComponent(item.id)}&num=${ - item.number - }${dub ? `&dub=${dub}` : ""}`} - key={item.id} - className={`bg-secondary flex w-full h-[110px] rounded-lg scale-100 transition-all duration-300 ease-out ${ - item.id == watchId - ? "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"> - {/* {mapData?.image && ( */} - <Image - src={mapData?.image || info?.coverImage?.extraLarge} - alt="Anime Cover" - width={1000} - height={1000} - className={`object-cover z-30 rounded-lg h-[110px] ${ - item.id == watchId - ? "brightness-[30%]" - : "brightness-75" - }`} - /> - {/* )} */} - <span - className={`absolute bottom-0 left-0 h-[2px] 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-bold text-sm"> - Episode {item?.number} - </span> - {item.id == watchId && ( - <div className="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" - > - <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-full h-full overflow-x-hidden select-none p-4 flex flex-col gap-2 ${ - item.id == watchId ? "text-[#7a7a7a]" : "" - }`} - > - <h1 className="font-karla font-bold italic line-clamp-1"> - {mapData?.title} - </h1> - <p className="line-clamp-2 text-xs italic font-outfit font-extralight"> - {mapData?.description} - </p> - </div> - </Link> - ); - }) - ) : ( - episode.map((item) => { - return ( - <Link - href={`/en/anime/watch/${ - info.id - }/${providerId}?id=${encodeURIComponent(item.id)}&num=${ - item.number - }${dub ? `&dub=${dub}` : ""}`} - key={item.id} - className={`bg-secondary flex-center w-full h-[50px] rounded-lg scale-100 transition-all duration-300 ease-out ${ - item.id == watchId - ? "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) => ( - <Skeleton - key={item} - className="bg-secondary flex w-full h-[110px] rounded-lg scale-100 transition-all duration-300 ease-out" - /> - ))} - </> - )} - </div> - </div> - ); -} |