Update the shows store to be immutable
This commit is contained in:
parent
80db4383a3
commit
9e5ae81f4e
@ -15,7 +15,9 @@ export function fetchShows(url) {
|
|||||||
export function getShowDetails(imdbId) {
|
export function getShowDetails(imdbId) {
|
||||||
return request(
|
return request(
|
||||||
'SHOW_GET_DETAILS',
|
'SHOW_GET_DETAILS',
|
||||||
configureAxios().post(`/shows/${imdbId}/refresh`)
|
configureAxios().post(`/shows/${imdbId}/refresh`),
|
||||||
|
null,
|
||||||
|
{ imdbId }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +38,9 @@ export function getEpisodeDetails(imdbId, season, episode) {
|
|||||||
export function fetchShowDetails(imdbId) {
|
export function fetchShowDetails(imdbId) {
|
||||||
return request(
|
return request(
|
||||||
'SHOW_FETCH_DETAILS',
|
'SHOW_FETCH_DETAILS',
|
||||||
configureAxios().get(`/shows/${imdbId}`)
|
configureAxios().get(`/shows/${imdbId}`),
|
||||||
|
null,
|
||||||
|
{ imdbId }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +52,6 @@ export function addShowToWishlist(imdbId, season = null, episode = null) {
|
|||||||
episode: episode,
|
episode: episode,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
addAlertOk("Show added to the wishlist"),
|
|
||||||
updateShowWishlistStore(imdbId, true, season, episode),
|
updateShowWishlistStore(imdbId, true, season, episode),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -59,7 +62,6 @@ export function deleteShowFromWishlist(imdbId) {
|
|||||||
'SHOW_DELETE_FROM_WISHLIST',
|
'SHOW_DELETE_FROM_WISHLIST',
|
||||||
configureAxios().delete(`/wishlist/shows/${imdbId}`),
|
configureAxios().delete(`/wishlist/shows/${imdbId}`),
|
||||||
[
|
[
|
||||||
addAlertOk("Show deleted from the wishlist"),
|
|
||||||
updateShowWishlistStore(imdbId, false),
|
updateShowWishlistStore(imdbId, false),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -87,9 +89,21 @@ export function getShowExploreOptions() {
|
|||||||
export function selectShow(imdbId) {
|
export function selectShow(imdbId) {
|
||||||
return {
|
return {
|
||||||
type: 'SELECT_SHOW',
|
type: 'SELECT_SHOW',
|
||||||
imdbId
|
payload: {
|
||||||
|
imdbId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateFilter(filter) {
|
||||||
|
return {
|
||||||
|
type: 'SHOWS_UPDATE_FILTER',
|
||||||
|
payload: {
|
||||||
|
filter,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function updateLastShowsFetchUrl(url) {
|
export function updateLastShowsFetchUrl(url) {
|
||||||
return {
|
return {
|
||||||
|
@ -16,7 +16,7 @@ export default function ListDetails(props) {
|
|||||||
|
|
||||||
const trackedSeason = props.data.get('tracked_season');
|
const trackedSeason = props.data.get('tracked_season');
|
||||||
const trackedEpisode = props.data.get('tracked_episode');
|
const trackedEpisode = props.data.get('tracked_episode');
|
||||||
if (trackedEpisode !== undefined && trackedSeason !== undefined) {
|
if (trackedEpisode !== null && trackedSeason !== null) {
|
||||||
if ((trackedSeason === 0) && (trackedEpisode === 0)) {
|
if ((trackedSeason === 0) && (trackedEpisode === 0)) {
|
||||||
wishlistStr = "Whole show tracked";
|
wishlistStr = "Whole show tracked";
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,45 +2,47 @@ 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,
|
||||||
deleteShowFromWishlist, getShowDetails } from '../../actions/shows'
|
deleteShowFromWishlist, getShowDetails, updateFilter } 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 { showsStore: state.showsStore };
|
return {
|
||||||
|
loading : state.showsStore.get('loading'),
|
||||||
|
shows : state.showsStore.get('shows'),
|
||||||
|
filter : state.showsStore.get('filter'),
|
||||||
|
selectedImdbId : state.showsStore.get('selectedImdbId'),
|
||||||
|
lastFetchUrl : state.showsStore.get('lastFetchUrl'),
|
||||||
|
exploreOptions : state.showsStore.get('exploreOptions'),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const mapDispatchToProps = (dispatch) =>
|
const mapDispatchToProps = (dispatch) =>
|
||||||
bindActionCreators({ selectShow, addShowToWishlist,
|
bindActionCreators({ selectShow, addShowToWishlist,
|
||||||
deleteShowFromWishlist, getShowDetails }, dispatch)
|
deleteShowFromWishlist, getShowDetails, updateFilter }, dispatch)
|
||||||
|
|
||||||
class ShowList extends React.Component {
|
class ShowList extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const shows = this.props.showsStore.shows;
|
let selectedShow;
|
||||||
const selectedShowId = this.props.showsStore.selectedImdbId;
|
if (this.props.selectedImdbId !== "") {
|
||||||
let index = shows.map((el) => el.imdb_id).indexOf(selectedShowId);
|
selectedShow = this.props.shows.get(this.props.selectedImdbId);
|
||||||
if (index === -1) {
|
|
||||||
index = 0;
|
|
||||||
}
|
}
|
||||||
const selectedShow = shows[index];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row" id="container">
|
<div className="row" id="container">
|
||||||
<ListPosters
|
<ListPosters
|
||||||
data={shows}
|
data={this.props.shows}
|
||||||
type="shows"
|
type="shows"
|
||||||
formModel="showsStore"
|
placeHolder="Filter shows..."
|
||||||
filterControlModel="showsStore.filter"
|
exploreOptions={this.props.exploreOptions}
|
||||||
filterControlPlaceHolder="Filter shows..."
|
updateFilter={this.props.updateFilter}
|
||||||
exploreOptions={this.props.showsStore.exploreOptions}
|
selectedImdbId={this.props.selectedImdbId}
|
||||||
selectedImdbId={selectedShowId}
|
filter={this.props.filter}
|
||||||
filter={this.props.showsStore.filter}
|
|
||||||
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.showsStore.loading}
|
loading={this.props.loading}
|
||||||
/>
|
/>
|
||||||
{selectedShow &&
|
{selectedShow &&
|
||||||
<ListDetails data={selectedShow} >
|
<ListDetails data={selectedShow} >
|
||||||
@ -49,7 +51,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.showsStore.getDetails}
|
updateFilter={this.props.updateFilter}
|
||||||
/>
|
/>
|
||||||
</ListDetails>
|
</ListDetails>
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { DropdownButton } from 'react-bootstrap'
|
|||||||
import { WishlistButton, RefreshButton } from '../buttons/actions'
|
import { WishlistButton, RefreshButton } from '../buttons/actions'
|
||||||
|
|
||||||
export default function ShowButtons(props) {
|
export default function ShowButtons(props) {
|
||||||
const imdbLink = `http://www.imdb.com/title/${props.show.imdb_id}`;
|
const imdbLink = `http://www.imdb.com/title/${props.show.get('imdb_id')}`;
|
||||||
return (
|
return (
|
||||||
<div className="list-details-buttons btn-toolbar">
|
<div className="list-details-buttons btn-toolbar">
|
||||||
<ActionsButton
|
<ActionsButton
|
||||||
@ -14,12 +14,11 @@ export default function ShowButtons(props) {
|
|||||||
addToWishlist={props.addToWishlist}
|
addToWishlist={props.addToWishlist}
|
||||||
deleteFromWishlist={props.deleteFromWishlist}
|
deleteFromWishlist={props.deleteFromWishlist}
|
||||||
getDetails={props.getDetails}
|
getDetails={props.getDetails}
|
||||||
fetching={props.fetching}
|
|
||||||
/>
|
/>
|
||||||
<a type="button" className="btn btn-warning btn-sm" href={imdbLink}>
|
<a type="button" className="btn btn-warning btn-sm" href={imdbLink}>
|
||||||
<i className="fa fa-external-link"></i> IMDB
|
<i className="fa fa-external-link"></i> IMDB
|
||||||
</a>
|
</a>
|
||||||
<Link type="button" className="btn btn-primary btn-sm" to={"/shows/details/" + props.show.imdb_id}>
|
<Link type="button" className="btn btn-primary btn-sm" to={"/shows/details/" + props.show.get('imdb_id')}>
|
||||||
<i className="fa fa-external-link"></i> Details
|
<i className="fa fa-external-link"></i> Details
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -27,16 +26,16 @@ export default function ShowButtons(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ActionsButton(props) {
|
function ActionsButton(props) {
|
||||||
let wishlisted = (props.show.tracked_season !== null && props.show.tracked_episode !== null);
|
let wishlisted = (props.show.get('tracked_season') !== null && props.show.get('tracked_episode') !== null);
|
||||||
return (
|
return (
|
||||||
<DropdownButton className="btn btn-default btn-sm" title="Actions" id="actions-button" dropup>
|
<DropdownButton className="btn btn-default btn-sm" title="Actions" id="actions-button" dropup>
|
||||||
<RefreshButton
|
<RefreshButton
|
||||||
fetching={props.fetching}
|
fetching={props.show.get('fetchingDetails')}
|
||||||
resourceId={props.show.imdb_id}
|
resourceId={props.show.get('imdb_id')}
|
||||||
getDetails={props.getDetails}
|
getDetails={props.getDetails}
|
||||||
/>
|
/>
|
||||||
<WishlistButton
|
<WishlistButton
|
||||||
resourceId={props.show.imdb_id}
|
resourceId={props.show.get('imdb_id')}
|
||||||
wishlisted={wishlisted}
|
wishlisted={wishlisted}
|
||||||
addToWishlist={props.addToWishlist}
|
addToWishlist={props.addToWishlist}
|
||||||
deleteFromWishlist={props.deleteFromWishlist}
|
deleteFromWishlist={props.deleteFromWishlist}
|
||||||
|
@ -1,87 +1,52 @@
|
|||||||
const defaultState = {
|
import { OrderedMap, Map, fromJS } from 'immutable'
|
||||||
|
|
||||||
|
const defaultState = Map({
|
||||||
loading: false,
|
loading: false,
|
||||||
shows: [],
|
shows: OrderedMap(),
|
||||||
filter: "",
|
filter: "",
|
||||||
perPage: 30,
|
|
||||||
selectedImdbId: "",
|
selectedImdbId: "",
|
||||||
getDetails: false,
|
lastFetchUrl: "",
|
||||||
lastShowsFetchUrl: "",
|
exploreOptions: Map(),
|
||||||
exploreOptions: {},
|
});
|
||||||
};
|
|
||||||
|
|
||||||
export default function showsStore(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 state.set('loading', true);
|
||||||
loading: true,
|
|
||||||
})
|
|
||||||
case 'SHOW_LIST_FETCH_FULFILLED':
|
case 'SHOW_LIST_FETCH_FULFILLED':
|
||||||
|
let shows = Map();
|
||||||
|
action.payload.response.data.map(function (show) {
|
||||||
|
show.fetchingDetails = false;
|
||||||
|
show.fetchingSubtitles = false;
|
||||||
|
shows = shows.set(show.imdb_id, fromJS(show));
|
||||||
|
})
|
||||||
|
|
||||||
let selectedImdbId = "";
|
let selectedImdbId = "";
|
||||||
// Select the first show
|
if (shows.size > 0) {
|
||||||
console.log("Hey", action.payload);
|
// Sort by year
|
||||||
if (action.payload.response.data.length > 0) {
|
shows = shows.sort((a,b) => b.get('year') - a.get('year'));
|
||||||
selectedImdbId = action.payload.response.data[0].imdb_id;
|
selectedImdbId = shows.first().get('imdb_id');
|
||||||
}
|
}
|
||||||
return Object.assign({}, state, {
|
|
||||||
shows: action.payload.response.data,
|
return state.delete('shows').merge(Map({
|
||||||
|
shows: shows,
|
||||||
|
filter: "",
|
||||||
|
loading: false,
|
||||||
selectedImdbId: selectedImdbId,
|
selectedImdbId: selectedImdbId,
|
||||||
filter: defaultState.filter,
|
}))
|
||||||
loading: false,
|
|
||||||
})
|
|
||||||
case 'SHOW_GET_DETAILS_PENDING':
|
case 'SHOW_GET_DETAILS_PENDING':
|
||||||
return Object.assign({}, state, {
|
return state.setIn(['shows', action.payload.main.imdbId, 'fetchingDetails'], true);
|
||||||
getDetails: true,
|
|
||||||
})
|
|
||||||
case 'SHOW_GET_DETAILS_FULFILLED':
|
case 'SHOW_GET_DETAILS_FULFILLED':
|
||||||
return Object.assign({}, state, {
|
let show = action.payload.response.data;
|
||||||
shows: updateShowDetails(state.shows.slice(), action.payload.response.data),
|
show.fetchingDetails = false;
|
||||||
getDetails: false,
|
show.fetchingSubtitles = false;
|
||||||
})
|
return state.setIn(['shows', show.imdb_id], fromJS(show));
|
||||||
case 'EXPLORE_SHOWS_PENDING':
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
loading: true,
|
|
||||||
})
|
|
||||||
case 'EXPLORE_SHOWS_FULFILLED':
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
shows: action.payload.response.data,
|
|
||||||
loading: false,
|
|
||||||
})
|
|
||||||
case 'SHOW_GET_EXPLORE_OPTIONS_FULFILLED':
|
case 'SHOW_GET_EXPLORE_OPTIONS_FULFILLED':
|
||||||
return Object.assign({}, state, {
|
return state.set('exploreOptions', fromJS(action.payload.response.data));
|
||||||
exploreOptions: action.payload.response.data,
|
|
||||||
})
|
|
||||||
case 'SHOW_UPDATE_STORE_WISHLIST':
|
case 'SHOW_UPDATE_STORE_WISHLIST':
|
||||||
return Object.assign({}, state, {
|
let season = action.payload.season;
|
||||||
shows: updateShowsStoreWishlist(state.shows.slice(), action.payload),
|
let episode = action.payload.episode;
|
||||||
})
|
if (action.payload.wishlisted) {
|
||||||
case 'UPDATE_LAST_SHOWS_FETCH_URL':
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
lastShowsFetchUrl: action.payload.url,
|
|
||||||
})
|
|
||||||
case 'SELECT_SHOW':
|
|
||||||
// Don't select the show if we're fetching another show's details
|
|
||||||
if (state.fetchingDetails) {
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
selectedImdbId: action.imdbId,
|
|
||||||
})
|
|
||||||
default:
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the store containing all the shows
|
|
||||||
function updateShowsStoreWishlist(shows, payload) {
|
|
||||||
if (shows.length === 0) {
|
|
||||||
return shows;
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = shows.map((el) => el.imdb_id).indexOf(payload.imdbId);
|
|
||||||
let season = payload.season;
|
|
||||||
let episode = payload.episode;
|
|
||||||
if (payload.wishlisted) {
|
|
||||||
if (season === null) {
|
if (season === null) {
|
||||||
season = 0;
|
season = 0;
|
||||||
}
|
}
|
||||||
@ -89,13 +54,18 @@ function updateShowsStoreWishlist(shows, payload) {
|
|||||||
episode = 0;
|
episode = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shows[index].tracked_season = season;
|
|
||||||
shows[index].tracked_episode = episode;
|
|
||||||
return shows
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateShowDetails(shows, data) {
|
return state.mergeIn(['shows', action.payload.imdbId], Map({
|
||||||
let index = shows.map((el) => el.imdb_id).indexOf(data.imdb_id);
|
tracked_season: season,
|
||||||
shows[index] = data;
|
tracked_episode: episode,
|
||||||
return shows
|
}));
|
||||||
|
case 'UPDATE_LAST_SHOWS_FETCH_URL':
|
||||||
|
return state.set('lastFetchUrl', action.payload.url);
|
||||||
|
case 'SELECT_SHOW':
|
||||||
|
return state.set('selectedImdbId', action.payload.imdbId);
|
||||||
|
case 'SHOWS_UPDATE_FILTER':
|
||||||
|
return state.set('filter', action.payload.filter);
|
||||||
|
default:
|
||||||
|
return state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ export default function getRoutes(App) {
|
|||||||
loginCheck(nextState, replace, next, function() {
|
loginCheck(nextState, replace, next, function() {
|
||||||
var state = store.getState();
|
var state = store.getState();
|
||||||
// Fetch the explore options
|
// Fetch the explore options
|
||||||
if (Object.keys(state.showsStore.exploreOptions).length === 0) {
|
if (state.showsStore.get('exploreOptions').size === 0) {
|
||||||
store.dispatch(getShowExploreOptions());
|
store.dispatch(getShowExploreOptions());
|
||||||
}
|
}
|
||||||
store.dispatch(fetchShows(
|
store.dispatch(fetchShows(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user