From 981cbd339d4a6f5c071ff6b0b08909719f584e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Delattre?= Date: Mon, 23 Jan 2017 14:20:53 +0100 Subject: [PATCH] Add a wishlist button for the movies --- src/public/js/actions/actionCreators.js | 32 +++++++++++++++++ src/public/js/components/movies/actions.js | 40 ++++++++++++++++++++++ src/public/js/components/movies/list.js | 5 +++ src/public/js/reducers/movies.js | 23 ++++++++++--- 4 files changed, 95 insertions(+), 5 deletions(-) diff --git a/src/public/js/actions/actionCreators.js b/src/public/js/actions/actionCreators.js index c630e2a..67e63ad 100644 --- a/src/public/js/actions/actionCreators.js +++ b/src/public/js/actions/actionCreators.js @@ -124,6 +124,38 @@ export function deleteMovie(imdbId) { ) } +export function addMovieToWishlist(imdbId) { + return request( + 'MOVIE_ADD_TO_WISHLIST', + configureAxios().post(`/wishlist/movies/${imdbId}`), + [ + addAlertOk("Movie added to the wishlist"), + updateMovieWishlistStore(imdbId, true), + ], + ) +} + +export function deleteMovieFromWishlist(imdbId) { + return request( + 'MOVIE_DELETE_FROM_WISHLIST', + configureAxios().delete(`/wishlist/movies/${imdbId}`), + [ + addAlertOk("Movie deleted from the wishlist"), + updateMovieWishlistStore(imdbId, false), + ], + ) +} + +export function updateMovieWishlistStore(imdbId, wishlisted) { + return { + type: 'MOVIE_UPDATE_STORE_WISHLIST', + payload: { + imdbId, + wishlisted, + } + } +} + export function fetchMovies(url) { return request( 'MOVIE_LIST_FETCH', diff --git a/src/public/js/components/movies/actions.js b/src/public/js/components/movies/actions.js index e78e634..0754a8f 100644 --- a/src/public/js/components/movies/actions.js +++ b/src/public/js/components/movies/actions.js @@ -17,6 +17,12 @@ export default function ActionsButton(props) { isUserAdmin={props.isUserAdmin} /> } + ); } @@ -70,3 +76,37 @@ class DeleteButton extends React.Component { ); } } + +class WishlistButton extends React.Component { + constructor(props) { + super(props); + this.handleClick = this.handleClick.bind(this); + } + handleClick(e) { + e.preventDefault(); + if (this.props.wishlisted) { + this.props.deleteFromWishlist(this.props.movieId); + } else { + this.props.addToWishlist(this.props.movieId); + } + } + render() { + if (this.props.wishlisted) { + return ( + + + Delete from wishlist + + + ); + } else { + return ( + + + Add to wishlist + + + ); + } + } +} diff --git a/src/public/js/components/movies/list.js b/src/public/js/components/movies/list.js index 37866b7..ece9a55 100644 --- a/src/public/js/components/movies/list.js +++ b/src/public/js/components/movies/list.js @@ -31,6 +31,9 @@ function MovieButtons(props) { deleteMovie={props.deleteMovie} isUserAdmin={props.isUserAdmin} hasMovie={hasMovie} + wishlisted={props.movie.wishlisted} + addToWishlist={props.addToWishlist} + deleteFromWishlist={props.deleteFromWishlist} /> @@ -97,6 +100,8 @@ export default class MovieList extends React.Component { addTorrent={this.props.addTorrent} deleteMovie={this.props.deleteMovie} isUserAdmin={this.props.userStore.isAdmin} + addToWishlist={this.props.addMovieToWishlist} + deleteFromWishlist={this.props.deleteMovieFromWishlist} /> } diff --git a/src/public/js/reducers/movies.js b/src/public/js/reducers/movies.js index 83f9bd1..44aa015 100644 --- a/src/public/js/reducers/movies.js +++ b/src/public/js/reducers/movies.js @@ -39,17 +39,18 @@ export default function movieStore(state = defaultState, action) { fetchingDetails: true, }) case 'MOVIE_GET_DETAILS_FULFILLED': - let movies = state.movies.slice(); - let index = movies.map((el) => el.imdb_id).indexOf(action.payload.data.imdb_id); - movies[index] = action.payload.data; return Object.assign({}, state, { - movies: movies, + movies: updateMovieDetails(state.movies.slice(), action.payload.data.imdb_id, action.payload.data), + fetchingDetails: false, + }) + case 'MOVIE_UPDATE_STORE_WISHLIST': + return Object.assign({}, state, { + movies: updateStoreWishlist(state.movies.slice(), action.payload.imdbId, action.payload.wishlisted), fetchingDetails: false, }) case 'DELETE_MOVIE': return Object.assign({}, state, { movies: state.movies.filter((e) => (e.imdb_id !== action.imdbId)), - fetchingDetails: false, }) case 'SELECT_MOVIE': // Don't select the movie if we're fetching another movie's details @@ -64,3 +65,15 @@ export default function movieStore(state = defaultState, action) { return state } } + +function updateMovieDetails(movies, imdbId, data) { + let index = movies.map((el) => el.imdb_id).indexOf(imdbId); + movies[index] = data; + return movies +} + +function updateStoreWishlist(movies, imdbId, wishlisted) { + let index = movies.map((el) => el.imdb_id).indexOf(imdbId); + movies[index].wishlisted = wishlisted; + return movies +}