diff options
| author | real-zephex <[email protected]> | 2024-05-19 08:08:57 +0530 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-05-19 08:08:57 +0530 |
| commit | a8e9ca0c14bcd6a8b2aa8cfe5b95a4e98dbcebfe (patch) | |
| tree | 98fa3f6cbdd690648c7d31a79c7d381624f38530 /src/app/web-series/components | |
| parent | minor changes to the manga page (diff) | |
| parent | added series support (diff) | |
| download | dramalama-a8e9ca0c14bcd6a8b2aa8cfe5b95a4e98dbcebfe.tar.xz dramalama-a8e9ca0c14bcd6a8b2aa8cfe5b95a4e98dbcebfe.zip | |
Merge pull request #28 from real-zephex/improvement-2
added series support
Diffstat (limited to 'src/app/web-series/components')
| -rw-r--r-- | src/app/web-series/components/HomePageModules.jsx | 56 | ||||
| -rw-r--r-- | src/app/web-series/components/cacher.js | 19 | ||||
| -rw-r--r-- | src/app/web-series/components/data-fetch.js | 87 | ||||
| -rw-r--r-- | src/app/web-series/components/searchBar.jsx | 49 | ||||
| -rw-r--r-- | src/app/web-series/components/searchResults.jsx | 35 | ||||
| -rw-r--r-- | src/app/web-series/components/videoPlayer.jsx | 66 |
6 files changed, 312 insertions, 0 deletions
diff --git a/src/app/web-series/components/HomePageModules.jsx b/src/app/web-series/components/HomePageModules.jsx new file mode 100644 index 0000000..90af2f8 --- /dev/null +++ b/src/app/web-series/components/HomePageModules.jsx @@ -0,0 +1,56 @@ +import { POPULAR_SHOWS, TRENDING_SHOWS, TOP_SHOWS } from "./data-fetch"; +import styles from "../styles/pages.module.css"; +import Image from "next/image"; +import Link from "next/link"; +import PreFecthSeriesInfo from "./cacher"; + +const HomepageUtils = async (type) => { + const fetchFunctions = { + popular: POPULAR_SHOWS, + trending: TRENDING_SHOWS, + top: TOP_SHOWS, + }; + + const fetchData = fetchFunctions[type]; + + if (fetchData) { + return await fetchData(); + } else { + return; + } +}; + +const Pages = async ({ type: type }) => { + const data = await HomepageUtils(type); + PreFecthSeriesInfo(data); + return ( + <main className={styles.main}> + <h2>{type} series</h2> + <section className={styles.SeriesContainer}> + {data && + data.results.length > 0 && + data.results.map((item, index) => ( + <Link + key={index} + href={`/web-series/${item.id}`} + style={{ textDecoration: "none", color: "white" }} + title={item.name} + > + <section className={styles.SeriesEntry}> + <Image + src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`} + width={167} + height={267} + alt="Series Poster" + priority + /> + <p>{item.name || "Not sure"}</p> + </section> + </Link> + ))} + </section> + </main> + ); +}; + +export default Pages; diff --git a/src/app/web-series/components/cacher.js b/src/app/web-series/components/cacher.js new file mode 100644 index 0000000..3e2a197 --- /dev/null +++ b/src/app/web-series/components/cacher.js @@ -0,0 +1,19 @@ +import { SERIES_INFO } from "./data-fetch"; + +const PreFecthSeriesInfo = async (data) => { + try { + const fetchPromises = data.results.map(async (element) => { + await SERIES_INFO(element.id); + }); + + await Promise.all(fetchPromises); + console.log("Series info pre-fetched successfully!"); + } catch (error) { + console.error( + "Error occurred while pre-fetching series info page:", + error + ); + } +}; + +export default PreFecthSeriesInfo; diff --git a/src/app/web-series/components/data-fetch.js b/src/app/web-series/components/data-fetch.js new file mode 100644 index 0000000..e0feca5 --- /dev/null +++ b/src/app/web-series/components/data-fetch.js @@ -0,0 +1,87 @@ +"use server"; + +import { + popular_tv_shows, + trending_tv_shows, + top_rated_shows, + recommended_shows, + crew_details, + tv_info, + search_tv, +} from "../../../../utils/series_urls"; + +export const POPULAR_SHOWS = async () => { + try { + const res = await fetch(popular_tv_shows(), { + next: { + revalidate: 21600, + }, + }); + const data = await res.json(); + return data; + } catch (error) { + throw new Error(error.message); + } +}; + +export const TRENDING_SHOWS = async () => { + try { + const res = await fetch(trending_tv_shows(), { + next: { + revalidate: 21600, + }, + }); + const data = await res.json(); + return data; + } catch (error) { + throw new Error(error.message); + } +}; + +export const TOP_SHOWS = async () => { + try { + const res = await fetch(top_rated_shows(), { + next: { + revalidate: 21600, + }, + }); + const data = await res.json(); + return data; + } catch (error) { + throw new Error(error.message); + } +}; + +export const SERIES_INFO = async (id) => { + try { + const res = await fetch(tv_info(id), { next: { revalidate: 21600 } }); + const data = await res.json(); + return data; + } catch (error) { + throw new Error(error.message); + } +}; + +export const CREW_DETAILS = async (id) => { + try { + const res = await fetch(crew_details(id), { + next: { revalidate: 21600 }, + }); + const data = await res.json(); + return data; + } catch (error) { + throw new Error(error.message); + } +}; + +export const SEARCH_TV = async (title) => { + try { + const res = await fetch(search_tv(title), { + next: { revalidate: 21600 }, + }); + const data = await res.json(); + return data; + } catch (error) { + throw new Error(error.message); + } +}; diff --git a/src/app/web-series/components/searchBar.jsx b/src/app/web-series/components/searchBar.jsx new file mode 100644 index 0000000..81dd25f --- /dev/null +++ b/src/app/web-series/components/searchBar.jsx @@ -0,0 +1,49 @@ +"use client"; +import styles from "../styles/search.module.css"; +import { FaSearch } from "react-icons/fa"; +import { useState } from "react"; + +import { SEARCH_TV } from "./data-fetch"; +import SearchResults from "./searchResults"; + +const SearchBar = () => { + const [title, setTitle] = useState(""); + const [result, setResults] = useState(null); + const [loading, setloading] = useState(false); + + const fetch_results = async (title) => { + setloading(true); + setResults(await SearchResults(await SEARCH_TV(title))); + setloading(false); + }; + + return ( + <main className={styles.Main}> + <section className={styles.InputContainer}> + <FaSearch + color="white" + className={styles.SearchIcon} + size={17} + /> + <input + placeholder="Enter series title here" + onChange={(event) => setTitle(event.target.value)} + onKeyDown={async (e) => { + if ((e.key === "Enter" || e.code === 13) && title) { + await fetch_results(e.target.value); + } + }} + ></input> + </section> + + {loading && ( + <p style={{ color: "white", textAlign: "center" }}> + Please wait while we crunch up all the data + </p> + )} + <section className={styles.SearchResults}>{result}</section> + </main> + ); +}; + +export default SearchBar; diff --git a/src/app/web-series/components/searchResults.jsx b/src/app/web-series/components/searchResults.jsx new file mode 100644 index 0000000..d1564e0 --- /dev/null +++ b/src/app/web-series/components/searchResults.jsx @@ -0,0 +1,35 @@ +"use server"; + +import Link from "next/link"; +import Image from "next/image"; +import styles from "../styles/search.module.css"; +import PreFecthSeriesInfo from "./cacher"; + +const SearchResults = async (data) => { + PreFecthSeriesInfo(data); + return ( + <div className={styles.SearchedSeriesContainer}> + {data && + data.results.map((item, index) => ( + <Link + key={index} + style={{ color: "white", textDecoration: "none" }} + href={`/web-series/${item.id}`} + title={item.name} + > + <div className={styles.SearchedSeriesEntry}> + <Image + src={`https://sup-proxy.zephex0-f6c.workers.dev/api-content?url=https://image.tmdb.org/t/p/original${item.poster_path}`} + width={160} + height={247} + alt="Searched Series Poster" + /> + <p>{item.name}</p> + </div> + </Link> + ))} + </div> + ); +}; + +export default SearchResults; diff --git a/src/app/web-series/components/videoPlayer.jsx b/src/app/web-series/components/videoPlayer.jsx new file mode 100644 index 0000000..cc8feb3 --- /dev/null +++ b/src/app/web-series/components/videoPlayer.jsx @@ -0,0 +1,66 @@ +"use client"; + +import { useState } from "react"; +import styles from "../styles/videoPlayer.module.css"; + +const SeriesPlayer = ({ id: id }) => { + const [iframe, iframeContent] = useState(null); + const [episode, setEpisode] = useState(""); + const [season, setSeason] = useState(""); + + async function VideoPlayerInitialize() { + if (!episode || !season) { + alert("Please provide the required episode and season number."); + return; + } + iframeContent(await iframeGenerator(id, season, episode)); + document.getElementById("video-player").style.display = "none"; + } + + return ( + <main className={styles.Main}> + <div className={styles.EpisodeSeasonInput}> + <input + name="Season" + type="number" + placeholder="Season Number" + onChange={(e) => { + if (Number(e.target.value) > 0) { + setSeason(e.target.value); + } + }} + ></input> + <input + name="Episode" + type="number" + placeholder="Episode Number" + onChange={(e) => { + if (Number(e.target.value) > 0) { + setEpisode(e.target.value); + } + }} + ></input> + + <button onClick={() => VideoPlayerInitialize(id)}> + Search + </button> + </div> + + <div className={styles.VideoPlayer}> + {iframe} + <p id="video-player"> + Please use adblockers to prevent ads and redirects. We have + no control over the amount of ads or the type of ads which + you might encounter. + </p> + </div> + </main> + ); +}; + +const iframeGenerator = async (id, seasonNumber, episodeNumber) => { + const url = `https://vidsrc.pro/embed/tv/${id}/${seasonNumber}/${episodeNumber}`; + return <iframe src={url} allowFullScreen referrerPolicy="origin"></iframe>; +}; + +export default SeriesPlayer; |