From 5d07a4bb56235ebb4f89082df712c24ac91e7577 Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:51:21 -0400 Subject: [PATCH 01/13] Update App.tsx --- src/setup/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/setup/App.tsx b/src/setup/App.tsx index 97983c7b2..322d66581 100644 --- a/src/setup/App.tsx +++ b/src/setup/App.tsx @@ -134,6 +134,7 @@ function App() { } /> + } /> } /> } /> From 3c214ce4615d3143ce975719ce4e2ed914dce0de Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:53:35 -0400 Subject: [PATCH 02/13] Update Episodes.tsx --- src/components/player/atoms/Episodes.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/player/atoms/Episodes.tsx b/src/components/player/atoms/Episodes.tsx index fa36a6e9c..e5422c179 100644 --- a/src/components/player/atoms/Episodes.tsx +++ b/src/components/player/atoms/Episodes.tsx @@ -118,8 +118,6 @@ function EpisodesView({ const newData = setPlayerMeta(loadingState.value.fullData, episodeId); if (newData) onChange?.(newData); } - // prevent router clear here, otherwise its done double - // player already switches route after meta change router.close(true); }, [setPlayerMeta, loadingState, router, onChange], From 590bcf7ef1aa5278c06648c7c952cc87c6299d3b Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:54:10 -0400 Subject: [PATCH 03/13] Update ModalEpisodeSelector.tsx --- src/components/media/ModalEpisodeSelector.tsx | 59 ++++++++++++------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/components/media/ModalEpisodeSelector.tsx b/src/components/media/ModalEpisodeSelector.tsx index e19b65564..fa3ce58b1 100644 --- a/src/components/media/ModalEpisodeSelector.tsx +++ b/src/components/media/ModalEpisodeSelector.tsx @@ -9,16 +9,25 @@ interface ModalEpisodeSelectorProps { mediaTitle: string; } +interface Season { + season_number: number; + id: number; +} + +interface ShowDetails { + seasons: Season[]; +} + export function EpisodeSelector({ tmdbId, mediaTitle, }: ModalEpisodeSelectorProps) { - const [seasonsData, setSeasonsData] = useState([]); + const [seasonsData, setSeasonsData] = useState([]); const [selectedSeason, setSelectedSeason] = useState(null); const navigate = useNavigate(); const handleSeasonSelect = useCallback( - async (season: any) => { + async (season: Season) => { try { const seasonDetails = await get( `/tv/${tmdbId}/season/${season.season_number}`, @@ -27,7 +36,11 @@ export function EpisodeSelector({ language: "en-US", }, ); - setSelectedSeason(seasonDetails); + setSelectedSeason({ + ...seasonDetails, + season_number: season.season_number, + id: season.id, + }); } catch (err) { console.error(err); } @@ -38,16 +51,18 @@ export function EpisodeSelector({ useEffect(() => { const fetchSeasons = async () => { try { - const showDetails = await get(`/tv/${tmdbId}`, { + const showDetails = await get(`/tv/${tmdbId}`, { api_key: conf().TMDB_READ_API_KEY, language: "en-US", }); setSeasonsData(showDetails.seasons); - if (showDetails.seasons[0] === 0) { - // Default to first season + const regularSeasons = showDetails.seasons.filter( + (season: Season) => season.season_number > 0, + ); + if (regularSeasons.length > 0) { + handleSeasonSelect(regularSeasons[0]); + } else if (showDetails.seasons.length > 0) { handleSeasonSelect(showDetails.seasons[0]); - } else { - handleSeasonSelect(showDetails.seasons[1]); } } catch (err) { console.error(err); @@ -59,13 +74,12 @@ export function EpisodeSelector({ return (
- {seasonsData.map((season) => ( + {seasonsData.map((season: Season) => (
handleSeasonSelect(season)} className={`cursor-pointer p-1 text-center rounded transition-transform duration-200 ${ - selectedSeason && - season.season_number === selectedSeason.season_number + selectedSeason && season.id === selectedSeason.id ? "bg-search-background" : "hover:bg-search-background hover:scale-95" }`} @@ -84,24 +98,29 @@ export function EpisodeSelector({ episode_number: number; name: string; still_path: string; - show_id: number; id: number; }) => (
- navigate( - `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${episode.show_id}/${episode.id}`, - ) - } + key={episode.id} + onClick={() => { + const url = `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${selectedSeason.id}/${episode.id}`; + // eslint-disable-next-line no-console + console.log(`Navigating to: ${url}`); + // eslint-disable-next-line no-console + console.log( + `Season ID: ${selectedSeason.id}, Episode ID: ${episode.id}`, + ); + navigate(url); + }} className="bg-mediaCard-hoverBackground rounded p-2 hover:scale-95 transition-transform transition-border-color duration-[0.28s] ease-in-out transform-origin-center" > {episode.name}

- {episode.name} + {`S${selectedSeason.season_number}E${episode.episode_number}: ${episode.name}`}

), From 67d973e73e793075b15b3dbfc0c99ffcba8272e5 Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:54:34 -0400 Subject: [PATCH 04/13] Update PopupModal.tsx --- src/components/media/PopupModal.tsx | 77 ++++++++++++++++------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/components/media/PopupModal.tsx b/src/components/media/PopupModal.tsx index 3274c31d1..a9d9bc1bd 100644 --- a/src/components/media/PopupModal.tsx +++ b/src/components/media/PopupModal.tsx @@ -20,6 +20,29 @@ interface PopupModalProps { media: MediaItem; } +interface MediaData { + backdrop_path?: string; + title?: string; + name?: string; + runtime?: number; + release_date?: string; + first_air_date?: string; + vote_average?: number; + genres?: Array<{ name: string }>; + overview?: string; +} + +interface MediaInfo { + results?: Array<{ + iso_3166_1: string; + rating?: string; + release_dates?: Array<{ + certification: string; + release_date: string; + }>; + }>; +} + type StyleState = { opacity: number; visibility: "visible" | "hidden" | undefined; @@ -46,11 +69,10 @@ export function PopupModal({ opacity: 0, visibility: "hidden", }); - const [data, setData] = useState(null); - const [mediaInfo, setMediaInfo] = useState(null); + const [data, setData] = useState(null); + const [mediaInfo, setMediaInfo] = useState(null); const [error, setError] = useState(null); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [menuOpen, setMenuOpen] = useState(false); // Added definition for menuOpen + // const [menuOpen, setMenuOpen] = useState(false); const navigate = useNavigate(); useEffect(() => { @@ -62,7 +84,6 @@ export function PopupModal({ onClose(); } } - document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); @@ -83,7 +104,7 @@ export function PopupModal({ try { const mediaTypePath = media.type === "show" ? "tv" : media.type; - const result = await get(`/${mediaTypePath}/${media.id}`, { + const result = await get(`/${mediaTypePath}/${media.id}`, { api_key: conf().TMDB_READ_API_KEY, language: "en-US", }); @@ -107,7 +128,7 @@ export function PopupModal({ const mediaTypeForAPI = media.type === "show" ? "tv" : media.type; const endpointSuffix = media.type === "show" ? "content_ratings" : "release_dates"; - const result = await get( + const result = await get( `/${mediaTypeForAPI}/${media.id}/${endpointSuffix}`, { api_key: conf().TMDB_READ_API_KEY, @@ -126,10 +147,7 @@ export function PopupModal({ }, [media.id, media.type, isVisible]); if (!isVisible && style.visibility === "hidden") return null; - - if (error) { - return
Error: {error}
; - } + if (error) return
Error: {error}
; const isTVShow = media.type === "show"; const usReleaseInfo = mediaInfo?.results?.find( @@ -158,11 +176,7 @@ export function PopupModal({
@@ -172,9 +186,7 @@ export function PopupModal({ alt={media.poster ? "" : "failed to fetch :("} className="rounded-xl object-cover w-full h-full" loading="lazy" - style={{ - maxHeight: "60vh", - }} + style={{ maxHeight: "60vh" }} /> ) : ( @@ -239,19 +251,17 @@ export function PopupModal({
- {Array.from({ length: 5 }, (_, index) => { - return ( - - {index < Math.round(Number(data?.vote_average) / 2) ? ( - - ) : ( - - )} - - ); - })} + {Array.from({ length: 5 }, (_, index) => ( + + {index < Math.round(Number(data?.vote_average) / 2) ? ( + + ) : ( + + )} + + ))}
- {data?.genres?.length > 0 + {data?.genres && data.genres.length > 0 ? data.genres.map((genre: { name: string }) => (
@@ -259,8 +269,9 @@ export function PopupModal({
)) - : Array.from({ length: 3 }).map((_) => ( -
+ : Array.from({ length: 3 }).map((_, idx) => ( + // eslint-disable-next-line react/no-array-index-key +
))} From 49b0a9fc007fa6b7eb95a6d555b0d346a31a7561 Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:55:18 -0400 Subject: [PATCH 05/13] Update tmdb.ts --- src/backend/metadata/tmdb.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/backend/metadata/tmdb.ts b/src/backend/metadata/tmdb.ts index 28c716d9e..a265b0515 100644 --- a/src/backend/metadata/tmdb.ts +++ b/src/backend/metadata/tmdb.ts @@ -91,14 +91,28 @@ export function formatTMDBMeta( export function formatTMDBMetaToMediaItem(media: TMDBMediaResult): MediaItem { const type = TMDBMediaToMediaItemType(media.object_type); - return { + // Define the basic structure of MediaItem + const mediaItem: MediaItem = { title: media.title, id: media.id.toString(), year: media.original_release_date?.getFullYear() ?? 0, release_date: media.original_release_date, poster: media.poster, type, + seasons: undefined, }; + + // If it's a TV show, include the seasons information + if (type === "show") { + const seasons = media.seasons?.map((season) => ({ + title: season.title, + id: season.id.toString(), + number: season.season_number, + })); + mediaItem.seasons = seasons as MWSeasonMeta[]; + } + + return mediaItem; } export function TMDBIdToUrlId( From 0b9ce5867ca55f71ebe0a0625c127bbcac80714e Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:29:35 -0400 Subject: [PATCH 06/13] Update ModalEpisodeSelector.tsx From 47d4dee0cec5e08a44e62a975d4f41ac3dfd7c9f Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:30:16 -0400 Subject: [PATCH 07/13] Update PopupModal.tsx From 975c9e7d851f0fd216949b18bc8dc4d987d98080 Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:44:42 -0400 Subject: [PATCH 08/13] Flaire --- src/components/media/ModalEpisodeSelector.tsx | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/components/media/ModalEpisodeSelector.tsx b/src/components/media/ModalEpisodeSelector.tsx index fa3ce58b1..c2510f1d3 100644 --- a/src/components/media/ModalEpisodeSelector.tsx +++ b/src/components/media/ModalEpisodeSelector.tsx @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { get } from "@/backend/metadata/tmdb"; +import { Flare } from "@/components/utils/Flare"; import { conf } from "@/setup/config"; interface ModalEpisodeSelectorProps { @@ -100,29 +101,35 @@ export function EpisodeSelector({ still_path: string; id: number; }) => ( -
{ const url = `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${selectedSeason.id}/${episode.id}`; - // eslint-disable-next-line no-console console.log(`Navigating to: ${url}`); - // eslint-disable-next-line no-console console.log( `Season ID: ${selectedSeason.id}, Episode ID: ${episode.id}`, ); navigate(url); }} - className="bg-mediaCard-hoverBackground rounded p-2 hover:scale-95 transition-transform transition-border-color duration-[0.28s] ease-in-out transform-origin-center" + className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-[0.28s]" > - {episode.name} -

- {`S${selectedSeason.season_number}E${episode.episode_number}: ${episode.name}`} -

-
+
+ {episode.name} +

+ {`S${selectedSeason.season_number}E${episode.episode_number}: ${episode.name}`} +

+
+ ), ) ) : ( From cd32e5205957aa47508056c57e6edec920835a6f Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:51:48 -0400 Subject: [PATCH 09/13] Update ModalEpisodeSelector.tsx --- src/components/media/ModalEpisodeSelector.tsx | 67 +++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/src/components/media/ModalEpisodeSelector.tsx b/src/components/media/ModalEpisodeSelector.tsx index c2510f1d3..c2912cbf2 100644 --- a/src/components/media/ModalEpisodeSelector.tsx +++ b/src/components/media/ModalEpisodeSelector.tsx @@ -10,25 +10,16 @@ interface ModalEpisodeSelectorProps { mediaTitle: string; } -interface Season { - season_number: number; - id: number; -} - -interface ShowDetails { - seasons: Season[]; -} - export function EpisodeSelector({ tmdbId, mediaTitle, }: ModalEpisodeSelectorProps) { - const [seasonsData, setSeasonsData] = useState([]); + const [seasonsData, setSeasonsData] = useState([]); const [selectedSeason, setSelectedSeason] = useState(null); const navigate = useNavigate(); const handleSeasonSelect = useCallback( - async (season: Season) => { + async (season: any) => { try { const seasonDetails = await get( `/tv/${tmdbId}/season/${season.season_number}`, @@ -37,11 +28,7 @@ export function EpisodeSelector({ language: "en-US", }, ); - setSelectedSeason({ - ...seasonDetails, - season_number: season.season_number, - id: season.id, - }); + setSelectedSeason(seasonDetails); } catch (err) { console.error(err); } @@ -52,18 +39,16 @@ export function EpisodeSelector({ useEffect(() => { const fetchSeasons = async () => { try { - const showDetails = await get(`/tv/${tmdbId}`, { + const showDetails = await get(`/tv/${tmdbId}`, { api_key: conf().TMDB_READ_API_KEY, language: "en-US", }); setSeasonsData(showDetails.seasons); - const regularSeasons = showDetails.seasons.filter( - (season: Season) => season.season_number > 0, - ); - if (regularSeasons.length > 0) { - handleSeasonSelect(regularSeasons[0]); - } else if (showDetails.seasons.length > 0) { + if (showDetails.seasons[0] === 0) { + // Default to first season handleSeasonSelect(showDetails.seasons[0]); + } else { + handleSeasonSelect(showDetails.seasons[1]); } } catch (err) { console.error(err); @@ -73,14 +58,15 @@ export function EpisodeSelector({ }, [handleSeasonSelect, tmdbId]); return ( -
-
- {seasonsData.map((season: Season) => ( +
+
+ {seasonsData.map((season) => (
handleSeasonSelect(season)} className={`cursor-pointer p-1 text-center rounded transition-transform duration-200 ${ - selectedSeason && season.id === selectedSeason.id + selectedSeason && + season.season_number === selectedSeason.season_number ? "bg-search-background" : "hover:bg-search-background hover:scale-95" }`} @@ -91,27 +77,25 @@ export function EpisodeSelector({
))}
-
-
+
+
{selectedSeason ? ( selectedSeason.episodes.map( (episode: { episode_number: number; name: string; still_path: string; + show_id: number; id: number; }) => ( { - const url = `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${selectedSeason.id}/${episode.id}`; - console.log(`Navigating to: ${url}`); - console.log( - `Season ID: ${selectedSeason.id}, Episode ID: ${episode.id}`, - ); - navigate(url); - }} - className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-[0.28s]" + key={episode.episode_number} + onClick={() => + navigate( + `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${episode.show_id}/${episode.id}`, + ) + } + className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-[0.28s] flex-shrink-0 w-48 sm:w-auto mr-2 sm:mr-0" >

- {`S${selectedSeason.season_number}E${episode.episode_number}: ${episode.name}`} + {episode.name}

From fd51162957e450eacdba08bfe9dd70fbb9782801 Mon Sep 17 00:00:00 2001 From: Abdullah Date: Fri, 21 Jun 2024 00:52:11 -0400 Subject: [PATCH 10/13] fixed modal --- src/components/media/ModalEpisodeSelector.tsx | 92 +++++++++---------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/src/components/media/ModalEpisodeSelector.tsx b/src/components/media/ModalEpisodeSelector.tsx index fa3ce58b1..c2912cbf2 100644 --- a/src/components/media/ModalEpisodeSelector.tsx +++ b/src/components/media/ModalEpisodeSelector.tsx @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { get } from "@/backend/metadata/tmdb"; +import { Flare } from "@/components/utils/Flare"; import { conf } from "@/setup/config"; interface ModalEpisodeSelectorProps { @@ -9,25 +10,16 @@ interface ModalEpisodeSelectorProps { mediaTitle: string; } -interface Season { - season_number: number; - id: number; -} - -interface ShowDetails { - seasons: Season[]; -} - export function EpisodeSelector({ tmdbId, mediaTitle, }: ModalEpisodeSelectorProps) { - const [seasonsData, setSeasonsData] = useState([]); + const [seasonsData, setSeasonsData] = useState([]); const [selectedSeason, setSelectedSeason] = useState(null); const navigate = useNavigate(); const handleSeasonSelect = useCallback( - async (season: Season) => { + async (season: any) => { try { const seasonDetails = await get( `/tv/${tmdbId}/season/${season.season_number}`, @@ -36,11 +28,7 @@ export function EpisodeSelector({ language: "en-US", }, ); - setSelectedSeason({ - ...seasonDetails, - season_number: season.season_number, - id: season.id, - }); + setSelectedSeason(seasonDetails); } catch (err) { console.error(err); } @@ -51,18 +39,16 @@ export function EpisodeSelector({ useEffect(() => { const fetchSeasons = async () => { try { - const showDetails = await get(`/tv/${tmdbId}`, { + const showDetails = await get(`/tv/${tmdbId}`, { api_key: conf().TMDB_READ_API_KEY, language: "en-US", }); setSeasonsData(showDetails.seasons); - const regularSeasons = showDetails.seasons.filter( - (season: Season) => season.season_number > 0, - ); - if (regularSeasons.length > 0) { - handleSeasonSelect(regularSeasons[0]); - } else if (showDetails.seasons.length > 0) { + if (showDetails.seasons[0] === 0) { + // Default to first season handleSeasonSelect(showDetails.seasons[0]); + } else { + handleSeasonSelect(showDetails.seasons[1]); } } catch (err) { console.error(err); @@ -72,14 +58,15 @@ export function EpisodeSelector({ }, [handleSeasonSelect, tmdbId]); return ( -
-
- {seasonsData.map((season: Season) => ( +
+
+ {seasonsData.map((season) => (
handleSeasonSelect(season)} className={`cursor-pointer p-1 text-center rounded transition-transform duration-200 ${ - selectedSeason && season.id === selectedSeason.id + selectedSeason && + season.season_number === selectedSeason.season_number ? "bg-search-background" : "hover:bg-search-background hover:scale-95" }`} @@ -90,39 +77,42 @@ export function EpisodeSelector({
))}
-
-
+
+
{selectedSeason ? ( selectedSeason.episodes.map( (episode: { episode_number: number; name: string; still_path: string; + show_id: number; id: number; }) => ( -
{ - const url = `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${selectedSeason.id}/${episode.id}`; - // eslint-disable-next-line no-console - console.log(`Navigating to: ${url}`); - // eslint-disable-next-line no-console - console.log( - `Season ID: ${selectedSeason.id}, Episode ID: ${episode.id}`, - ); - navigate(url); - }} - className="bg-mediaCard-hoverBackground rounded p-2 hover:scale-95 transition-transform transition-border-color duration-[0.28s] ease-in-out transform-origin-center" + + navigate( + `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${episode.show_id}/${episode.id}`, + ) + } + className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-[0.28s] flex-shrink-0 w-48 sm:w-auto mr-2 sm:mr-0" > - {episode.name} -

- {`S${selectedSeason.season_number}E${episode.episode_number}: ${episode.name}`} -

-
+
+ +

+ {episode.name} +

+
+ ), ) ) : ( From 443f80fc551a68eb851c41b998f27aac56c38ca1 Mon Sep 17 00:00:00 2001 From: Abdullah Khan <85450222+AbdullahDaGoat@users.noreply.github.com> Date: Fri, 21 Jun 2024 01:06:09 -0400 Subject: [PATCH 11/13] Update tmdb.ts From 90ff0f8a651dc15a17fe45d01cf553c465bf71e1 Mon Sep 17 00:00:00 2001 From: Abdullah Date: Fri, 21 Jun 2024 01:12:07 -0400 Subject: [PATCH 12/13] huh --- src/utils/mediaTypes.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/mediaTypes.ts b/src/utils/mediaTypes.ts index c81b1ac09..3a7e2d443 100644 --- a/src/utils/mediaTypes.ts +++ b/src/utils/mediaTypes.ts @@ -1,4 +1,5 @@ export interface MediaItem { + seasons: import("c:/Users/huzei/OneDrive/Desktop/Sudo-Flix/src/backend/metadata/types/mw").MWSeasonMeta[]; id: string; title: string; year?: number; From 7b4f5e2fe75fab436c3b62129455ea4ebe5ba164 Mon Sep 17 00:00:00 2001 From: Abdullah Date: Fri, 21 Jun 2024 01:14:45 -0400 Subject: [PATCH 13/13] WOW!! --- src/components/media/ModalEpisodeSelector.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/media/ModalEpisodeSelector.tsx b/src/components/media/ModalEpisodeSelector.tsx index c2912cbf2..a5e5c7272 100644 --- a/src/components/media/ModalEpisodeSelector.tsx +++ b/src/components/media/ModalEpisodeSelector.tsx @@ -77,7 +77,7 @@ export function EpisodeSelector({
))}
-
+
{selectedSeason ? ( selectedSeason.episodes.map(