import React, { useState } from "react" import PropTypes from "prop-types" import { Map } from "immutable" import { connect } from "react-redux" import { withRouter } from "react-router" import { addTorrent } from "../../actions/torrents" import { refreshSubtitles } from "../../actions/subtitles" import { addShowToWishlist, deleteShowFromWishlist, getEpisodeDetails, fetchShowDetails } from "../../actions/shows" import Loader from "../loader/loader" import DownloadButton from "../buttons/download" import SubtitlesButton from "../buttons/subtitles" import ImdbButton from "../buttons/imdb" import RefreshIndicator from "../buttons/refresh" import Tooltip from "react-bootstrap/Tooltip" import OverlayTrigger from "react-bootstrap/OverlayTrigger" import Dropdown from "react-bootstrap/Dropdown" import SplitButton from "react-bootstrap/SplitButton" // Helper to change 1 to 01 const pad = (d) => (d < 10) ? "0" + d.toString() : d.toString(); function mapStateToProps(state) { return { loading: state.showStore.get("loading"), show: state.showStore.get("show"), }; } const mapDispatchToProps = { addTorrent, addShowToWishlist, deleteShowFromWishlist, fetchShowDetails, getEpisodeDetails, refreshSubtitles, }; const ShowDetails = (props) => { if (props.loading) { return (); } return (
); } ShowDetails.propTypes = { loading: PropTypes.bool, show: PropTypes.instanceOf(Map), deleteShowFromWishlist: PropTypes.func, addShowToWishlist: PropTypes.func, addTorrent: PropTypes.func, refreshSubtitles: PropTypes.func, getEpisodeDetails: PropTypes.func, }; export default connect(mapStateToProps, mapDispatchToProps)(ShowDetails); const Fanart = (props) => (
) Fanart.propTypes = { url: PropTypes.string, } const Header = (props) => (
{props.data.get("title")}

{props.data.get("year")}

{props.data.get("rating")}

{props.data.get("plot")}

); Header.propTypes = { data: PropTypes.instanceOf(Map), deleteFromWishlist: PropTypes.func, addToWishlist: PropTypes.func, }; const SeasonsList = (props) => (
{props.data.get("seasons").entrySeq().map(function([season, data]) { return ( ); })}
); SeasonsList.propTypes = { data: PropTypes.instanceOf(Map), addToWishlist: PropTypes.func, addTorrent: PropTypes.func, refreshSubtitles: PropTypes.func, getEpisodeDetails: PropTypes.func, }; const Season = (props) => { const [show, setShow] = useState(false); const visibility = show ? "d-flex flex-column" : "d-none"; const icon = show ? "down" : "left" return (
setShow(!show)}>
Season {props.season} — ({props.data.toList().size} episodes)
{props.data.toList().map(function(episode) { let key = `${episode.get("season")}-${episode.get("episode")}`; return ( ) })}
) } Season.propTypes = { data: PropTypes.instanceOf(Map), season: PropTypes.number, showName: PropTypes.string, addToWishlist: PropTypes.func, addTorrent: PropTypes.func, refreshSubtitles: PropTypes.func, getEpisodeDetails: PropTypes.func, }; const PolochonMetadata = (props) => { if (!props.quality || props.quality === "") { return null } return ( {props.quality} {props.container} {props.videoCodec} {props.audioCodec} {props.releaseGroup} ); } PolochonMetadata.propTypes = { quality: PropTypes.string, container: PropTypes.string, videoCodec: PropTypes.string, audioCodec: PropTypes.string, releaseGroup: PropTypes.string, }; const Episode = (props) => (
{props.data.get("episode")} {props.data.get("title")}
{props.data.get("polochon_url") !== "" && } {props.data.get("torrents") && props.data.get("torrents").toList().map(function(torrent) { let key = `${props.data.get("season")}-${props.data.get("episode")}-${torrent.get("source")}-${torrent.get("quality")}`; return ( ) })}
) Episode.propTypes = { data: PropTypes.instanceOf(Map), season: PropTypes.number, showName: PropTypes.string, addToWishlist: PropTypes.func, addTorrent: PropTypes.func, refreshSubtitles: PropTypes.func, getEpisodeDetails: PropTypes.func, }; const Torrent = (props) => ( ) Torrent.propTypes = { data: PropTypes.instanceOf(Map), addTorrent: PropTypes.func, }; const TrackHeader = (props) => { const trackedSeason = props.data.get("tracked_season"); const trackedEpisode = props.data.get("tracked_episode"); const imdbId = props.data.get("imdb_id"); const wishlisted = (trackedSeason !== null && trackedEpisode !== null); const handleClick = () => { if (wishlisted) { props.deleteFromWishlist(imdbId); } else { props.addToWishlist(imdbId); } } if (wishlisted) { const msg = (trackedSeason !== 0 && trackedEpisode !== 0) ? (

Show tracked from season {trackedSeason} episode {trackedEpisode}

) : (

Whole show tracked

); return ( {msg} Untrack the show ); } return (

Tracking inactive

handleClick(e)}> Track the whole show
); } TrackHeader.propTypes = { data: PropTypes.instanceOf(Map), addToWishlist: PropTypes.func, deleteFromWishlist: PropTypes.func, }; const TrackButton = (props) => { const imdbId = props.data.get("show_imdb_id"); const season = props.data.get("season"); const episode = props.data.get("episode"); const tooltipId = `tooltip-${props.data.season}-${props.data.episode}`; const tooltip = ( Track show from here ); return ( props.addToWishlist(imdbId, season, episode)}> ); } TrackButton.propTypes = { data: PropTypes.instanceOf(Map), addToWishlist: PropTypes.func, }; const GetDetailsButton = (props) => { const imdbId = props.data.get("show_imdb_id"); const season = props.data.get("season"); const episode = props.data.get("episode"); const id = `${imdbId}-${season}-${episode}-refresh-dropdown`; const handleFetchClick = () => { if (props.data.get("fetching")) { return } props.getEpisodeDetails(imdbId, season, episode); } const handleAdvanceTorrentSearchClick = () => { const search = `${props.showName} S${pad(season)}E${pad(episode)}`; const url = `/torrents/search/shows/${encodeURI(search)}`; props.history.push(url); } return ( } size="sm" id={`refresh-${id}`} onClick={handleFetchClick}> Advanced torrent search ); } GetDetailsButton.propTypes = { data: PropTypes.instanceOf(Map).isRequired, history: PropTypes.object.isRequired, showName: PropTypes.string.isRequired, getEpisodeDetails: PropTypes.func.isRequired, }; const GetDetailsButtonWithRouter = withRouter(GetDetailsButton);