diff options
| author | Factiven <[email protected]> | 2023-06-15 00:29:21 +0700 |
|---|---|---|
| committer | Factiven <[email protected]> | 2023-06-15 00:29:21 +0700 |
| commit | 8147e85ca9fdc88fe6af86bb47e954551ba8fe86 (patch) | |
| tree | 781ed680ea9189e719e68b7cafd9f0d08d6aa089 /pages | |
| parent | Added episodes selector dropdown (#23) (diff) | |
| download | moopa-8147e85ca9fdc88fe6af86bb47e954551ba8fe86.tar.xz moopa-8147e85ca9fdc88fe6af86bb47e954551ba8fe86.zip | |
Fixed Error: Missing "key" prop for element in iterator
Diffstat (limited to 'pages')
| -rw-r--r-- | pages/anime/[...id].js | 360 |
1 files changed, 187 insertions, 173 deletions
diff --git a/pages/anime/[...id].js b/pages/anime/[...id].js index c878652..2d68bd4 100644 --- a/pages/anime/[...id].js +++ b/pages/anime/[...id].js @@ -32,23 +32,22 @@ import { GET_MEDIA_INFO } from "../../queries"; // console.log(GET_MEDIA_USER); export default function Info({ info, color }) { - // Episodes dropdown - const [firstEpisodeIndex,setFirstEpisodeIndex ] = useState(0); - const [lastEpisodeIndex,setLastEpisodeIndex ] = useState(); - const [selectedRange,setSelectedRange ] = useState("All"); + const [firstEpisodeIndex, setFirstEpisodeIndex] = useState(0); + const [lastEpisodeIndex, setLastEpisodeIndex] = useState(); + const [selectedRange, setSelectedRange] = useState("All"); function onEpisodeIndexChange(e) { - if(e.target.value==="All"){ + if (e.target.value === "All") { setFirstEpisodeIndex(0); setLastEpisodeIndex(); setSelectedRange("All"); return; } - setFirstEpisodeIndex(e.target.value.split("-")[0]-1); + setFirstEpisodeIndex(e.target.value.split("-")[0] - 1); setLastEpisodeIndex(e.target.value.split("-")[1]); setSelectedRange(e.target.value); } - + const { data: session } = useSession(); const [episode, setEpisode] = useState(null); const [loading, setLoading] = useState(false); @@ -83,14 +82,13 @@ export default function Info({ info, color }) { localStorage.setItem("provider", e.target.value); } - //for episodes dropdown + //for episodes dropdown useEffect(() => { setFirstEpisodeIndex(0); setLastEpisodeIndex(); setSelectedRange("All"); - }, [info,prvValue]); - - + }, [info, prvValue]); + useEffect(() => { handleClose(); async function fetchData() { @@ -673,44 +671,54 @@ export default function Info({ info, color }) { }`} > <div className="flex items-end gap-3"> - <div className="relative flex gap-2 items-center"> - <p className="hidden md:block">Provider</p> - <select - onChange={handleProvider} - value={prvValue} - className="flex items-center text-sm gap-5 rounded-[3px] bg-secondary py-1 px-3 pr-8 font-karla appearance-none cursor-pointer outline-none focus:ring-1 focus:ring-action" - > - <option value="gogoanime">Gogoanime</option> - <option value="zoro">Zoro</option> - <option value="enime">Enime</option> - </select> - <ChevronDownIcon className="absolute right-2 top-1/2 transform -translate-y-1/2 w-5 h-5 pointer-events-none" /> - </div> - { episode?.length>50 && ( - <div className="relative flex gap-2 items-center"> - <p className="hidden md:block">Episodes</p> - <select onChange={onEpisodeIndexChange} value={selectedRange} - className="flex items-center text-sm gap-5 rounded-[3px] bg-secondary py-1 px-3 pr-8 font-karla appearance-none cursor-pointer outline-none focus:ring-1 focus:ring-action scrollbar-thin scrollbar-thumb-secondary scrollbar-thumb-rounded-lg" - > - <option value="All">All</option> - { - [...Array(Math.ceil(episode?.length / 50))].map((_, index) => { - const start = index * 50 + 1; - const end = Math.min(start + 50 - 1, episode?.length); - const optionLabel = `${start} to ${end}`; - if(episode[0]?.number!==1){ - var valueLabel=`${episode.length-end+1}-${episode.length-start+1}`; - } - else{ - var valueLabel=`${start}-${end}`; - } - return <option value={valueLabel}>{optionLabel}</option>; - }) - } - </select> - <ChevronDownIcon className="absolute right-2 top-1/2 transform -translate-y-1/2 w-5 h-5 pointer-events-none" /> - </div>) - } + <div className="relative flex gap-2 items-center"> + <p className="hidden md:block">Provider</p> + <select + onChange={handleProvider} + value={prvValue} + className="flex items-center text-sm gap-5 rounded-[3px] bg-secondary py-1 px-3 pr-8 font-karla appearance-none cursor-pointer outline-none focus:ring-1 focus:ring-action" + > + <option value="gogoanime">Gogoanime</option> + <option value="zoro">Zoro</option> + <option value="enime">Enime</option> + </select> + <ChevronDownIcon className="absolute right-2 top-1/2 transform -translate-y-1/2 w-5 h-5 pointer-events-none" /> + </div> + {episode?.length > 50 && ( + <div className="relative flex gap-2 items-center"> + <p className="hidden md:block">Episodes</p> + <select + onChange={onEpisodeIndexChange} + value={selectedRange} + className="flex items-center text-sm gap-5 rounded-[3px] bg-secondary py-1 px-3 pr-8 font-karla appearance-none cursor-pointer outline-none focus:ring-1 focus:ring-action scrollbar-thin scrollbar-thumb-secondary scrollbar-thumb-rounded-lg" + > + <option value="All">All</option> + {[...Array(Math.ceil(episode?.length / 50))].map( + (_, index) => { + const start = index * 50 + 1; + const end = Math.min( + start + 50 - 1, + episode?.length + ); + const optionLabel = `${start} to ${end}`; + if (episode[0]?.number !== 1) { + var valueLabel = `${ + episode.length - end + 1 + }-${episode.length - start + 1}`; + } else { + var valueLabel = `${start}-${end}`; + } + return ( + <option key={valueLabel} value={valueLabel}> + {optionLabel} + </option> + ); + } + )} + </select> + <ChevronDownIcon className="absolute right-2 top-1/2 transform -translate-y-1/2 w-5 h-5 pointer-events-none" /> + </div> + )} </div> <div className="flex gap-3 rounded-sm items-center p-2"> <div @@ -841,70 +849,25 @@ export default function Info({ info, color }) { }`} > {epiView === "1" - ? episode.slice(firstEpisodeIndex,lastEpisodeIndex)?.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}/${prvValue}`} - 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.slice(firstEpisodeIndex,lastEpisodeIndex).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}/${prvValue}`} - 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" - > - <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%]" - /> + ? episode + .slice(firstEpisodeIndex, lastEpisodeIndex) + ?.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}/${prvValue}`} + 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-0 left-0 h-[3px] bg-red-700`} + className={`absolute bottom-7 left-0 h-1 bg-red-600`} style={{ width: progress && @@ -913,76 +876,127 @@ export default function Info({ info, color }) { ? "100%" : artStorage?.[epi?.id] ? `${prog}%` - : "0", + : "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 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 + .slice(firstEpisodeIndex, lastEpisodeIndex) + .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}/${prvValue}`} + 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" + > + <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> + <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> + ); + })} + {epiView === "3" && + episode + .slice(firstEpisodeIndex, lastEpisodeIndex) + .map((epi, index) => { + return ( <div - className={`w-[70%] h-full select-none p-4 flex flex-col justify-center gap-5 ${ - epi?.id == id ? "text-[#7a7a7a]" : "" - }`} + key={index} + className="flex flex-col gap-3 px-2" > - <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> + <Link + href={`/anime/watch/${epi.id}/${info.id}/${prvValue}`} + 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> - </Link> - ); - })} - {epiView === "3" && - episode.slice(firstEpisodeIndex,lastEpisodeIndex).map((epi, index) => { - return ( - <div - key={index} - className="flex flex-col gap-3 px-2" - > - <Link - href={`/anime/watch/${epi.id}/${info.id}/${prvValue}`} - 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> |