/* eslint-disable react/prop-types */ import { useEffect, useRef, useState } from "react"; import { useLocation, useParams, Link, useNavigate } from "react-router-dom"; import { useLanguage } from "@/src/context/LanguageContext"; import { useHomeInfo } from "@/src/context/HomeInfoContext"; import { useWatch } from "@/src/hooks/useWatch"; import BouncingLoader from "@/src/components/ui/bouncingloader/Bouncingloader"; import IframePlayer from "@/src/components/player/IframePlayer"; import Episodelist from "@/src/components/episodelist/Episodelist"; import website_name from "@/src/config/website"; import Sidecard from "@/src/components/sidecard/Sidecard"; import CategoryCard from "@/src/components/categorycard/CategoryCard"; import { faClosedCaptioning, faMicrophone, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import Servers from "@/src/components/servers/Servers"; import CategoryCardLoader from "@/src/components/Loader/CategoryCard.loader"; import { Skeleton } from "@/src/components/ui/Skeleton/Skeleton"; import SidecardLoader from "@/src/components/Loader/Sidecard.loader"; import Voiceactor from "@/src/components/voiceactor/Voiceactor"; import Watchcontrols from "@/src/components/watchcontrols/Watchcontrols"; import useWatchControl from "@/src/hooks/useWatchControl"; import Player from "@/src/components/player/Player"; export default function Watch() { const location = useLocation(); const navigate = useNavigate(); const { id: animeId } = useParams(); const queryParams = new URLSearchParams(location.search); let initialEpisodeId = queryParams.get("ep"); const [tags, setTags] = useState([]); const { language } = useLanguage(); const { homeInfo } = useHomeInfo(); const isFirstSet = useRef(true); const [showNextEpisodeSchedule, setShowNextEpisodeSchedule] = useState(true); const { // error, buffering, streamInfo, streamUrl, animeInfo, episodes, nextEpisodeSchedule, animeInfoLoading, totalEpisodes, isFullOverview, intro, outro, subtitles, thumbnail, setIsFullOverview, activeEpisodeNum, seasons, episodeId, setEpisodeId, activeServerId, setActiveServerId, servers, serverLoading, activeServerType, setActiveServerType, activeServerName, setActiveServerName } = useWatch(animeId, initialEpisodeId); const { autoPlay, setAutoPlay, autoSkipIntro, setAutoSkipIntro, autoNext, setAutoNext, } = useWatchControl(); useEffect(() => { if (!episodes || episodes.length === 0) return; const isValidEpisode = episodes.some(ep => { const epNumber = ep.id.split('ep=')[1]; return epNumber === episodeId; }); // If missing or invalid episodeId, fallback to first if (!episodeId || !isValidEpisode) { const fallbackId = episodes[0].id.match(/ep=(\d+)/)?.[1]; if (fallbackId && fallbackId !== episodeId) { setEpisodeId(fallbackId); } return; } const newUrl = `/watch/${animeId}?ep=${episodeId}`; if (isFirstSet.current) { navigate(newUrl, { replace: true }); isFirstSet.current = false; } else { navigate(newUrl); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [episodeId, animeId, navigate, episodes]); // Update document title useEffect(() => { if (animeInfo) { document.title = `Watch ${animeInfo.title} English Sub/Dub online Free on ${website_name}`; } return () => { document.title = `${website_name} | Free anime streaming platform`; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [animeId]); // Redirect if no episodes useEffect(() => { if (totalEpisodes !== null && totalEpisodes === 0) { navigate(`/${animeId}`); } }, [streamInfo, episodeId, animeId, totalEpisodes, navigate]); useEffect(() => { const adjustHeight = () => { if (window.innerWidth > 1200) { const player = document.querySelector(".player"); const episodes = document.querySelector(".episodes"); if (player && episodes) { episodes.style.height = `${player.clientHeight}px`; } } else { const episodes = document.querySelector(".episodes"); if (episodes) { episodes.style.height = "auto"; } } }; adjustHeight(); window.addEventListener("resize", adjustHeight); return () => { window.removeEventListener("resize", adjustHeight); }; }); function Tag({ bgColor, index, icon, text }) { return (
{icon && }

{text}

); } useEffect(() => { setTags([ { condition: animeInfo?.animeInfo?.tvInfo?.rating, bgColor: "#ffffff", text: animeInfo?.animeInfo?.tvInfo?.rating, }, { condition: animeInfo?.animeInfo?.tvInfo?.quality, bgColor: "#FFBADE", text: animeInfo?.animeInfo?.tvInfo?.quality, }, { condition: animeInfo?.animeInfo?.tvInfo?.sub, icon: faClosedCaptioning, bgColor: "#B0E3AF", text: animeInfo?.animeInfo?.tvInfo?.sub, }, { condition: animeInfo?.animeInfo?.tvInfo?.dub, icon: faMicrophone, bgColor: "#B9E7FF", text: animeInfo?.animeInfo?.tvInfo?.dub, }, ]); }, [animeId, animeInfo]); return (
{`${animeInfo?.title}
{animeInfo && (
    {[ ["Home", "home"], [animeInfo?.showType, animeInfo?.showType], ].map(([text, link], index) => (
  • {text}
  • ))}

    Watching{" "} {language === "EN" ? animeInfo?.title : animeInfo?.japanese_title}

)}
{!episodes ? ( ) : ( setEpisodeId(id)} totalEpisodes={totalEpisodes} /> )}
{!buffering ? (( activeServerName.toLowerCase()==="hd-1" || activeServerName.toLowerCase()==="hd-2" || activeServerName.toLowerCase()==="hd-3" || activeServerName.toLowerCase()==="hd-4") ? setEpisodeId(id)} autoNext={autoNext} />: setEpisodeId(id)} animeInfo={animeInfo} episodeNum={activeEpisodeNum} streamInfo={streamInfo} /> ) : (
)}

{!buffering && !activeServerType ? ( servers ? ( <> Probably this server is down, try other servers
Either reload or try again after sometime ) : ( <> Probably streaming server is down
Either reload or try again after sometime ) ) : null}

{!buffering && ( setEpisodeId(id)} /> )} {seasons?.length > 0 && (

Watch more seasons of this anime

{seasons.map((season, index) => (

{season.season}

))}
)} {nextEpisodeSchedule?.nextEpisodeSchedule && showNextEpisodeSchedule && (
🚀 {" Estimated the next episode will come at "} {new Date( new Date( nextEpisodeSchedule.nextEpisodeSchedule ).getTime() - new Date().getTimezoneOffset() * 60000 ).toLocaleDateString("en-GB", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: true, })}
setShowNextEpisodeSchedule(false)} > ×
)}
{animeInfo && animeInfo?.poster ? ( ) : ( )}
{animeInfo && animeInfo?.title ? (

{language ? animeInfo?.title : animeInfo?.japanese_title}

) : ( )}
{animeInfo ? ( tags.map( ({ condition, icon, bgColor, text }, index) => condition && ( ) ) ) : ( )}
{[ animeInfo?.animeInfo?.tvInfo?.showType, animeInfo?.animeInfo?.tvInfo?.duration, ].map( (item, index) => item && (

{item}

) )}
{animeInfo ? ( animeInfo?.animeInfo?.Overview && (

{animeInfo?.animeInfo?.Overview.length > 270 ? ( <> {isFullOverview ? animeInfo?.animeInfo?.Overview : `${animeInfo?.animeInfo?.Overview.slice( 0, 270 )}...`} setIsFullOverview(!isFullOverview)} > {isFullOverview ? "- Less" : "+ More"} ) : ( animeInfo?.animeInfo?.Overview )}

) ) : (
)}

{`${website_name} is the best site to watch `} {language ? animeInfo?.title : animeInfo?.japanese_title} {` SUB online, or you can even watch `} {language ? animeInfo?.title : animeInfo?.japanese_title} {` DUB in HD quality.`}

View detail
Share Anime

Share Anime

to your friends

{animeInfo?.charactersVoiceActors.length > 0 && ( )} {animeInfo?.recommended_data.length > 0 ? ( ) : ( )}
{animeInfo && animeInfo.related_data ? ( ) : ( )} {homeInfo && homeInfo.most_popular && ( )}
); }