diff --git a/src/public/js/actions/actionCreators.js b/src/public/js/actions/actionCreators.js index 3200f63..0ef97ca 100644 --- a/src/public/js/actions/actionCreators.js +++ b/src/public/js/actions/actionCreators.js @@ -188,6 +188,25 @@ export function getShowDetails(imdbId) { ) } + +export function getEpisodeDetails(imdbId, season, episode) { + return request( + 'EPISODE_GET_DETAILS', + configureAxios().post(`/shows/${imdbId}/seasons/${season}/episodes/${episode}`), + ) +} + +export function updateEpisodeDetailsStore(imdbId, season, episode) { + return { + type: 'EPISODE_GET_DETAILS', + payload: { + imdbId, + season, + episode, + }, + } +} + export function fetchShowDetails(imdbId) { return request( 'SHOW_FETCH_DETAILS', diff --git a/src/public/js/components/shows/details.js b/src/public/js/components/shows/details.js index 3a125dd..e011a88 100644 --- a/src/public/js/components/shows/details.js +++ b/src/public/js/components/shows/details.js @@ -23,6 +23,8 @@ export default class ShowDetails extends React.Component { data={this.props.showStore.show} addTorrent={this.props.addTorrent} addToWishlist={this.props.addShowToWishlist} + getEpisodeDetails={this.props.getEpisodeDetails} + updateEpisodeDetailsStore={this.props.updateEpisodeDetailsStore} /> ); @@ -94,6 +96,8 @@ function SeasonsList(props){ data={season} addTorrent={props.addTorrent} addToWishlist={props.addToWishlist} + getEpisodeDetails={props.getEpisodeDetails} + updateEpisodeDetailsStore={props.updateEpisodeDetailsStore} /> ) @@ -138,6 +142,8 @@ class Season extends React.Component { data={episode} addTorrent={this.props.addTorrent} addToWishlist={this.props.addToWishlist} + getEpisodeDetails={this.props.getEpisodeDetails} + updateEpisodeDetailsStore={this.props.updateEpisodeDetailsStore} /> ) }, this)} @@ -173,6 +179,11 @@ function Episode(props) { ) })} + @@ -297,3 +308,36 @@ function DownloadButton(props) { ); } + +class GetDetailsButton extends React.Component { + constructor(props) { + super(props); + this.handleClick = this.handleClick.bind(this); + } + handleClick(e, url) { + e.preventDefault(); + if (this.props.data.fetching) { + return + } + this.props.updateEpisodeDetailsStore(this.props.data.show_imdb_id, this.props.data.season, this.props.data.episode); + this.props.getEpisodeDetails(this.props.data.show_imdb_id, this.props.data.season, this.props.data.episode); + } + render() { + return ( + + this.handleClick(e)}> + {this.props.data.fetching || + + Refresh + + } + {this.props.data.fetching && + + Refreshing + + } + + + ); + } +} diff --git a/src/public/js/reducers/shows.js b/src/public/js/reducers/shows.js index c50c774..f817644 100644 --- a/src/public/js/reducers/shows.js +++ b/src/public/js/reducers/shows.js @@ -46,6 +46,14 @@ export default function showStore(state = defaultState, action) { show: sortEpisodes(action.payload.data), loading: false, }) + case 'EPISODE_GET_DETAILS': + return Object.assign({}, state, { + show: updateEpisode(Object.assign({}, state.show), true, action.payload), + }) + case 'EPISODE_GET_DETAILS_FULFILLED': + return Object.assign({}, state, { + show: updateEpisode(Object.assign({}, state.show), false, action.payload.data), + }) case 'SEARCH_SHOWS_PENDING': return Object.assign({}, state, { loading: true, @@ -74,6 +82,16 @@ export default function showStore(state = defaultState, action) { } } +function updateEpisode(show, fetching, data) { + let seasonIndex = show.seasons.map((el) => el.season).indexOf(data.season.toString()); + let episodeIndex = show.seasons[seasonIndex].episodes.map((el) => el.episode).indexOf(data.episode); + if ('id' in data) { + show.seasons[seasonIndex].episodes[episodeIndex] = data; + } + show.seasons[seasonIndex].episodes[episodeIndex].fetching = fetching; + return show +} + function sortEpisodes(show) { let episodes = show.episodes; delete show["episodes"]; @@ -85,6 +103,7 @@ function sortEpisodes(show) { // Extract the seasons let seasons = {}; for (let ep of episodes) { + ep.fetching = false; if (!seasons[ep.season]) { seasons[ep.season] = { episodes: [] }; }