Split the store of the show

This commit is contained in:
Grégoire Delattre 2017-05-30 13:08:42 +02:00
parent e53306686f
commit 33137e0035
5 changed files with 157 additions and 143 deletions

View File

@ -3,7 +3,7 @@ import { connect } from 'react-redux'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import { addTorrent } from '../../actions/torrents' import { addTorrent } from '../../actions/torrents'
import { refreshSubtitles } from '../../actions/subtitles' import { refreshSubtitles } from '../../actions/subtitles'
import { addShowToWishlist, deleteFromWishlist, getEpisodeDetails, import { addShowToWishlist, deleteShowFromWishlist, getEpisodeDetails,
updateEpisodeDetailsStore, updateShowDetails } from '../../actions/shows' updateEpisodeDetailsStore, updateShowDetails } from '../../actions/shows'
import Loader from '../loader/loader' import Loader from '../loader/loader'
@ -19,7 +19,7 @@ function mapStateToProps(state) {
}; };
} }
const mapDispatchToProps = (dispatch) => const mapDispatchToProps = (dispatch) =>
bindActionCreators({addTorrent, addShowToWishlist, deleteFromWishlist, bindActionCreators({addTorrent, addShowToWishlist, deleteShowFromWishlist,
updateShowDetails, updateEpisodeDetailsStore, getEpisodeDetails, updateShowDetails, updateEpisodeDetailsStore, getEpisodeDetails,
refreshSubtitles }, dispatch) refreshSubtitles }, dispatch)

View File

@ -2,23 +2,23 @@ import React from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import { selectShow, addShowToWishlist, import { selectShow, addShowToWishlist,
deleteFromWishlist, getShowDetails } from '../../actions/shows' deleteShowFromWishlist, getShowDetails } from '../../actions/shows'
import ListDetails from '../list/details' import ListDetails from '../list/details'
import ListPosters from '../list/posters' import ListPosters from '../list/posters'
import ShowButtons from './listButtons' import ShowButtons from './listButtons'
function mapStateToProps(state) { function mapStateToProps(state) {
return { showStore: state.showStore }; return { showsStore: state.showsStore };
} }
const mapDispatchToProps = (dispatch) => const mapDispatchToProps = (dispatch) =>
bindActionCreators({ selectShow, addShowToWishlist, bindActionCreators({ selectShow, addShowToWishlist,
deleteFromWishlist, getShowDetails }, dispatch) deleteShowFromWishlist, getShowDetails }, dispatch)
class ShowList extends React.Component { class ShowList extends React.Component {
render() { render() {
const shows = this.props.showStore.shows; const shows = this.props.showsStore.shows;
const selectedShowId = this.props.showStore.selectedImdbId; const selectedShowId = this.props.showsStore.selectedImdbId;
let index = shows.map((el) => el.imdb_id).indexOf(selectedShowId); let index = shows.map((el) => el.imdb_id).indexOf(selectedShowId);
if (index === -1) { if (index === -1) {
index = 0; index = 0;
@ -30,17 +30,17 @@ class ShowList extends React.Component {
<ListPosters <ListPosters
data={shows} data={shows}
type="shows" type="shows"
formModel="showStore" formModel="showsStore"
filterControlModel="showStore.filter" filterControlModel="showsStore.filter"
filterControlPlaceHolder="Filter shows..." filterControlPlaceHolder="Filter shows..."
exploreOptions={this.props.showStore.exploreOptions} exploreOptions={this.props.showsStore.exploreOptions}
selectedImdbId={selectedShowId} selectedImdbId={selectedShowId}
filter={this.props.showStore.filter} filter={this.props.showsStore.filter}
perPage={this.props.showStore.perPage} perPage={this.props.showsStore.perPage}
onClick={this.props.selectShow} onClick={this.props.selectShow}
router={this.props.router} router={this.props.router}
params={this.props.params} params={this.props.params}
loading={this.props.showStore.loading} loading={this.props.showsStore.loading}
/> />
{selectedShow && {selectedShow &&
<ListDetails data={selectedShow} > <ListDetails data={selectedShow} >
@ -49,7 +49,7 @@ class ShowList extends React.Component {
deleteFromWishlist={this.props.deleteShowFromWishlist} deleteFromWishlist={this.props.deleteShowFromWishlist}
addToWishlist={this.props.addShowToWishlist} addToWishlist={this.props.addShowToWishlist}
getDetails={this.props.getShowDetails} getDetails={this.props.getShowDetails}
fetching={this.props.showStore.getDetails} fetching={this.props.showsStore.getDetails}
/> />
</ListDetails> </ListDetails>
} }

View File

@ -2,7 +2,8 @@ import { combineForms } from 'react-redux-form'
import { routerReducer } from 'react-router-redux' import { routerReducer } from 'react-router-redux'
import movieStore from './movies' import movieStore from './movies'
import showStore from './shows' import showsStore from './shows'
import showStore from './show'
import userStore from './users' import userStore from './users'
import alerts from './alerts' import alerts from './alerts'
import torrentStore from './torrents' import torrentStore from './torrents'
@ -13,6 +14,7 @@ import torrentStore from './torrents'
const rootReducer = combineForms({ const rootReducer = combineForms({
routing: routerReducer, routing: routerReducer,
movieStore, movieStore,
showsStore,
showStore, showStore,
userStore, userStore,
alerts, alerts,

View File

@ -0,0 +1,139 @@
const defaultState = {
loading: false,
show: {
seasons: [],
},
};
export default function showStore(state = defaultState, action) {
switch (action.type) {
case 'SHOW_FETCH_DETAILS_PENDING':
return Object.assign({}, state, {
loading: true,
})
case 'SHOW_FETCH_DETAILS_FULFILLED':
return Object.assign({}, state, {
show: sortEpisodes(action.payload.response.data),
loading: false,
})
case 'SHOW_UPDATE_STORE_WISHLIST':
return Object.assign({}, state, {
show: updateShowStoreWishlist(Object.assign({}, state.show), action.payload),
})
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.response.data),
})
case 'EPISODE_SUBTITLES_UPDATE_PENDING':
return Object.assign({}, state, {
show: updateEpisodeSubtitles(Object.assign({}, state.show), action.payload.main.season, action.payload.main.episode, true),
})
case 'EPISODE_SUBTITLES_UPDATE_FULFILLED':
console.log("payload :", action.payload);
return Object.assign({}, state, {
show: updateEpisodeSubtitles(Object.assign({}, state.show), action.payload.main.season, action.payload.main.episode, false, action.payload.response.data),
})
default:
return state
}
}
function updateEpisode(show, fetching, data = null) {
// Error handling for PouuleT
if (data === null) {
for (let seasonIndex of Object.keys(show.seasons)) {
for (let episodeIndex of Object.keys(show.seasons[seasonIndex].episodes)) {
show.seasons[seasonIndex].episodes[episodeIndex].fetching = false;
}
}
return show
}
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 ('imdb_id' in data) {
show.seasons[seasonIndex].episodes[episodeIndex] = data;
}
show.seasons[seasonIndex].episodes[episodeIndex].fetching = fetching;
return show
}
function updateEpisodeSubtitles(show, season, episode, fetching, data = null) {
let seasonIndex = show.seasons.map((el) => el.season).indexOf(season.toString());
let episodeIndex = show.seasons[seasonIndex].episodes.map((el) => el.episode).indexOf(episode);
if (data) {
show.seasons[seasonIndex].episodes[episodeIndex].subtitles = data;
}
show.seasons[seasonIndex].episodes[episodeIndex].fetchingSubtitles = fetching;
return show
}
function sortEpisodes(show) {
let episodes = show.episodes;
delete show["episodes"];
if (episodes.length == 0) {
return show;
}
// Extract the seasons
let seasons = {};
for (let ep of episodes) {
ep.fetching = false;
if (!seasons[ep.season]) {
seasons[ep.season] = { episodes: [] };
}
seasons[ep.season].episodes.push(ep);
}
if (seasons.length === 0) {
return show;
}
// Put all the season in an array
let sortedSeasons = [];
for (let season of Object.keys(seasons)) {
let seasonEpisodes = seasons[season].episodes;
// Order the episodes in each season
seasonEpisodes.sort((a,b) => (a.episode - b.episode))
// Add the season in the list
sortedSeasons.push({
season: season,
episodes: seasonEpisodes,
})
}
// Order the seasons
for (let i=0; i<sortedSeasons.length; i++) {
sortedSeasons.sort((a,b) => (a.season - b.season))
}
show.seasons = sortedSeasons;
return show;
}
// Update the store containing the current detailed show
function updateShowStoreWishlist(show, payload) {
if (show.seasons.length === 0) {
return show;
}
let season = payload.season;
let episode = payload.episode;
if (payload.wishlisted) {
if (season === null) {
season = 0;
}
if (episode === null) {
episode = 0;
}
}
show.tracked_season = season;
show.tracked_episode = episode;
return show
}

View File

@ -4,15 +4,12 @@ const defaultState = {
filter: "", filter: "",
perPage: 30, perPage: 30,
selectedImdbId: "", selectedImdbId: "",
show: {
seasons: [],
},
getDetails: false, getDetails: false,
lastShowsFetchUrl: "", lastShowsFetchUrl: "",
exploreOptions: {}, exploreOptions: {},
}; };
export default function showStore(state = defaultState, action) { export default function showsStore(state = defaultState, action) {
switch (action.type) { switch (action.type) {
case 'SHOW_LIST_FETCH_PENDING': case 'SHOW_LIST_FETCH_PENDING':
return Object.assign({}, state, { return Object.assign({}, state, {
@ -29,7 +26,6 @@ export default function showStore(state = defaultState, action) {
shows: action.payload.response.data, shows: action.payload.response.data,
selectedImdbId: selectedImdbId, selectedImdbId: selectedImdbId,
filter: defaultState.filter, filter: defaultState.filter,
perPage: defaultState.perPage,
loading: false, loading: false,
}) })
case 'SHOW_GET_DETAILS_PENDING': case 'SHOW_GET_DETAILS_PENDING':
@ -41,23 +37,6 @@ export default function showStore(state = defaultState, action) {
shows: updateShowDetails(state.shows.slice(), action.payload.response.data), shows: updateShowDetails(state.shows.slice(), action.payload.response.data),
getDetails: false, getDetails: false,
}) })
case 'SHOW_FETCH_DETAILS_PENDING':
return Object.assign({}, state, {
loading: true,
})
case 'SHOW_FETCH_DETAILS_FULFILLED':
return Object.assign({}, state, {
show: sortEpisodes(action.payload.response.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.response.data),
})
case 'EXPLORE_SHOWS_PENDING': case 'EXPLORE_SHOWS_PENDING':
return Object.assign({}, state, { return Object.assign({}, state, {
loading: true, loading: true,
@ -74,21 +53,11 @@ export default function showStore(state = defaultState, action) {
case 'SHOW_UPDATE_STORE_WISHLIST': case 'SHOW_UPDATE_STORE_WISHLIST':
return Object.assign({}, state, { return Object.assign({}, state, {
shows: updateShowsStoreWishlist(state.shows.slice(), action.payload), shows: updateShowsStoreWishlist(state.shows.slice(), action.payload),
show: updateShowStoreWishlist(Object.assign({}, state.show), action.payload),
}) })
case 'UPDATE_LAST_SHOWS_FETCH_URL': case 'UPDATE_LAST_SHOWS_FETCH_URL':
return Object.assign({}, state, { return Object.assign({}, state, {
lastShowsFetchUrl: action.payload.url, lastShowsFetchUrl: action.payload.url,
}) })
case 'EPISODE_SUBTITLES_UPDATE_PENDING':
return Object.assign({}, state, {
show: updateEpisodeSubtitles(Object.assign({}, state.show), action.payload.main.season, action.payload.main.episode, true),
})
case 'EPISODE_SUBTITLES_UPDATE_FULFILLED':
console.log("payload :", action.payload);
return Object.assign({}, state, {
show: updateEpisodeSubtitles(Object.assign({}, state.show), action.payload.main.season, action.payload.main.episode, false, action.payload.response.data),
})
case 'SELECT_SHOW': case 'SELECT_SHOW':
// Don't select the show if we're fetching another show's details // Don't select the show if we're fetching another show's details
if (state.fetchingDetails) { if (state.fetchingDetails) {
@ -103,82 +72,6 @@ export default function showStore(state = defaultState, action) {
} }
} }
function updateEpisode(show, fetching, data = null) {
// Error handling for PouuleT
if (data === null) {
for (let seasonIndex of Object.keys(show.seasons)) {
for (let episodeIndex of Object.keys(show.seasons[seasonIndex].episodes)) {
show.seasons[seasonIndex].episodes[episodeIndex].fetching = false;
}
}
return show
}
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 ('imdb_id' in data) {
show.seasons[seasonIndex].episodes[episodeIndex] = data;
}
show.seasons[seasonIndex].episodes[episodeIndex].fetching = fetching;
return show
}
function updateEpisodeSubtitles(show, season, episode, fetching, data = null) {
let seasonIndex = show.seasons.map((el) => el.season).indexOf(season.toString());
let episodeIndex = show.seasons[seasonIndex].episodes.map((el) => el.episode).indexOf(episode);
if (data) {
show.seasons[seasonIndex].episodes[episodeIndex].subtitles = data;
}
show.seasons[seasonIndex].episodes[episodeIndex].fetchingSubtitles = fetching;
return show
}
function sortEpisodes(show) {
let episodes = show.episodes;
delete show["episodes"];
if (episodes.length == 0) {
return show;
}
// Extract the seasons
let seasons = {};
for (let ep of episodes) {
ep.fetching = false;
if (!seasons[ep.season]) {
seasons[ep.season] = { episodes: [] };
}
seasons[ep.season].episodes.push(ep);
}
if (seasons.length === 0) {
return show;
}
// Put all the season in an array
let sortedSeasons = [];
for (let season of Object.keys(seasons)) {
let seasonEpisodes = seasons[season].episodes;
// Order the episodes in each season
seasonEpisodes.sort((a,b) => (a.episode - b.episode))
// Add the season in the list
sortedSeasons.push({
season: season,
episodes: seasonEpisodes,
})
}
// Order the seasons
for (let i=0; i<sortedSeasons.length; i++) {
sortedSeasons.sort((a,b) => (a.season - b.season))
}
show.seasons = sortedSeasons;
return show;
}
// Update the store containing all the shows // Update the store containing all the shows
function updateShowsStoreWishlist(shows, payload) { function updateShowsStoreWishlist(shows, payload) {
if (shows.length === 0) { if (shows.length === 0) {
@ -201,26 +94,6 @@ function updateShowsStoreWishlist(shows, payload) {
return shows return shows
} }
// Update the store containing the current detailed show
function updateShowStoreWishlist(show, payload) {
if (show.seasons.length === 0) {
return show;
}
let season = payload.season;
let episode = payload.episode;
if (payload.wishlisted) {
if (season === null) {
season = 0;
}
if (episode === null) {
episode = 0;
}
}
show.tracked_season = season;
show.tracked_episode = episode;
return show
}
function updateShowDetails(shows, data) { function updateShowDetails(shows, data) {
let index = shows.map((el) => el.imdb_id).indexOf(data.imdb_id); let index = shows.map((el) => el.imdb_id).indexOf(data.imdb_id);
shows[index] = data; shows[index] = data;