commit
f62413d5dc
@ -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) {
|
export function fetchMovies(url) {
|
||||||
return request(
|
return request(
|
||||||
'MOVIE_LIST_FETCH',
|
'MOVIE_LIST_FETCH',
|
||||||
@ -156,6 +188,43 @@ export function fetchShowDetails(imdbId) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addShowToWishlist(imdbId, season = null, episode = null) {
|
||||||
|
return request(
|
||||||
|
'SHOW_ADD_TO_WISHLIST',
|
||||||
|
configureAxios().post(`/wishlist/shows/${imdbId}`, {
|
||||||
|
season: season,
|
||||||
|
episode: episode,
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
addAlertOk("Show added to the wishlist"),
|
||||||
|
updateShowWishlistStore(imdbId, true, season, episode),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteShowFromWishlist(imdbId) {
|
||||||
|
return request(
|
||||||
|
'SHOW_DELETE_FROM_WISHLIST',
|
||||||
|
configureAxios().delete(`/wishlist/shows/${imdbId}`),
|
||||||
|
[
|
||||||
|
addAlertOk("Show deleted from the wishlist"),
|
||||||
|
updateShowWishlistStore(imdbId, false),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateShowWishlistStore(imdbId, wishlisted, season = null, episode = null) {
|
||||||
|
return {
|
||||||
|
type: 'SHOW_UPDATE_STORE_WISHLIST',
|
||||||
|
payload: {
|
||||||
|
wishlisted: wishlisted,
|
||||||
|
imdbId,
|
||||||
|
season,
|
||||||
|
episode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function selectShow(imdbId) {
|
export function selectShow(imdbId) {
|
||||||
return {
|
return {
|
||||||
type: 'SELECT_SHOW',
|
type: 'SELECT_SHOW',
|
||||||
|
87
src/public/js/components/buttons/actions.js
Normal file
87
src/public/js/components/buttons/actions.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { MenuItem } from 'react-bootstrap'
|
||||||
|
|
||||||
|
export 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.resourceId);
|
||||||
|
} else {
|
||||||
|
this.props.addToWishlist(this.props.resourceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
if (this.props.wishlisted) {
|
||||||
|
return (
|
||||||
|
<MenuItem onClick={this.handleClick}>
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-bookmark"></i> Delete from wishlist
|
||||||
|
</span>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<MenuItem onClick={this.handleClick}>
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-bookmark-o"></i> Add to wishlist
|
||||||
|
</span>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DeleteButton extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.handleClick = this.handleClick.bind(this);
|
||||||
|
}
|
||||||
|
handleClick(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.deleteFunc(this.props.resourceId);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<MenuItem onClick={this.handleClick}>
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-trash"></i> Delete
|
||||||
|
</span>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RefreshButton extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.handleClick = this.handleClick.bind(this);
|
||||||
|
}
|
||||||
|
handleClick(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (this.props.fetching) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.props.getDetails(this.props.resourceId);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<MenuItem onClick={this.handleClick}>
|
||||||
|
{this.props.fetching ||
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-refresh"></i> Refresh
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
{this.props.fetching &&
|
||||||
|
<span>
|
||||||
|
<i className="fa fa-spin fa-refresh"></i> Refreshing
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,72 +1,29 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import { DropdownButton, MenuItem } from 'react-bootstrap'
|
import { WishlistButton, DeleteButton, RefreshButton } from '../buttons/actions'
|
||||||
|
import { DropdownButton } from 'react-bootstrap'
|
||||||
|
|
||||||
export default function ActionsButton(props) {
|
export default function ActionsButton(props) {
|
||||||
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.fetching}
|
||||||
movieId={props.movieId}
|
resourceId={props.movieId}
|
||||||
getDetails={props.getDetails}
|
getDetails={props.getDetails}
|
||||||
/>
|
/>
|
||||||
{(props.isUserAdmin && props.hasMovie) &&
|
{(props.isUserAdmin && props.hasMovie) &&
|
||||||
<DeleteButton
|
<DeleteButton
|
||||||
movieId={props.movieId}
|
resourceId={props.movieId}
|
||||||
deleteMovie={props.deleteMovie}
|
deleteFunc={props.deleteMovie}
|
||||||
isUserAdmin={props.isUserAdmin}
|
isUserAdmin={props.isUserAdmin}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
<WishlistButton
|
||||||
|
resourceId={props.movieId}
|
||||||
|
wishlisted={props.wishlisted}
|
||||||
|
addToWishlist={props.addToWishlist}
|
||||||
|
deleteFromWishlist={props.deleteFromWishlist}
|
||||||
|
/>
|
||||||
</DropdownButton>
|
</DropdownButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RefreshButton extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.handleClick = this.handleClick.bind(this);
|
|
||||||
}
|
|
||||||
handleClick(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (this.props.fetching) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.props.getDetails(this.props.movieId);
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<MenuItem onClick={this.handleClick}>
|
|
||||||
{this.props.fetching ||
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-refresh"></i> Refresh
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
{this.props.fetching &&
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-spin fa-refresh"></i> Refreshing
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeleteButton extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.handleClick = this.handleClick.bind(this);
|
|
||||||
}
|
|
||||||
handleClick(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.deleteMovie(this.props.movieId);
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<MenuItem onClick={this.handleClick}>
|
|
||||||
<span>
|
|
||||||
<i className="fa fa-trash"></i> Delete
|
|
||||||
</span>
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -31,6 +31,9 @@ function MovieButtons(props) {
|
|||||||
deleteMovie={props.deleteMovie}
|
deleteMovie={props.deleteMovie}
|
||||||
isUserAdmin={props.isUserAdmin}
|
isUserAdmin={props.isUserAdmin}
|
||||||
hasMovie={hasMovie}
|
hasMovie={hasMovie}
|
||||||
|
wishlisted={props.movie.wishlisted}
|
||||||
|
addToWishlist={props.addToWishlist}
|
||||||
|
deleteFromWishlist={props.deleteFromWishlist}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<a type="button" className="btn btn-warning btn-sm" href={imdb_link}>
|
<a type="button" className="btn btn-warning btn-sm" href={imdb_link}>
|
||||||
@ -97,6 +100,8 @@ export default class MovieList extends React.Component {
|
|||||||
addTorrent={this.props.addTorrent}
|
addTorrent={this.props.addTorrent}
|
||||||
deleteMovie={this.props.deleteMovie}
|
deleteMovie={this.props.deleteMovie}
|
||||||
isUserAdmin={this.props.userStore.isAdmin}
|
isUserAdmin={this.props.userStore.isAdmin}
|
||||||
|
addToWishlist={this.props.addMovieToWishlist}
|
||||||
|
deleteFromWishlist={this.props.deleteMovieFromWishlist}
|
||||||
/>
|
/>
|
||||||
</ListDetails>
|
</ListDetails>
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Link } from 'react-router'
|
|
||||||
|
|
||||||
import ListDetails from '../list/details'
|
import ListDetails from '../list/details'
|
||||||
import ListPosters from '../list/posters'
|
import ListPosters from '../list/posters'
|
||||||
import Loader from '../loader/loader'
|
import Loader from '../loader/loader'
|
||||||
|
import ShowButtons from './listButtons'
|
||||||
function ShowButtons(props) {
|
|
||||||
const imdbLink = `http://www.imdb.com/title/${props.show.imdb_id}`;
|
|
||||||
return (
|
|
||||||
<div className="list-details-buttons btn-toolbar">
|
|
||||||
<a type="button" className="btn btn-warning btn-sm" href={imdbLink}>
|
|
||||||
<i className="fa fa-external-link"></i> IMDB
|
|
||||||
</a>
|
|
||||||
<Link type="button" className="btn btn-primary btn-sm" to={"/shows/details/" + props.show.imdb_id}>
|
|
||||||
<i className="fa fa-external-link"></i> Details
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class ShowList extends React.Component {
|
export default class ShowList extends React.Component {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -68,7 +54,11 @@ export default class ShowList extends React.Component {
|
|||||||
/>
|
/>
|
||||||
{selectedShow &&
|
{selectedShow &&
|
||||||
<ListDetails data={selectedShow} >
|
<ListDetails data={selectedShow} >
|
||||||
<ShowButtons show={selectedShow} />
|
<ShowButtons
|
||||||
|
show={selectedShow}
|
||||||
|
deleteFromWishlist={this.props.deleteShowFromWishlist}
|
||||||
|
addToWishlist={this.props.addShowToWishlist}
|
||||||
|
/>
|
||||||
</ListDetails>
|
</ListDetails>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
39
src/public/js/components/shows/listButtons.js
Normal file
39
src/public/js/components/shows/listButtons.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Link } from 'react-router'
|
||||||
|
import { DropdownButton } from 'react-bootstrap'
|
||||||
|
|
||||||
|
import { WishlistButton } from '../buttons/actions'
|
||||||
|
|
||||||
|
export default function ShowButtons(props) {
|
||||||
|
const imdbLink = `http://www.imdb.com/title/${props.show.imdb_id}`;
|
||||||
|
return (
|
||||||
|
<div className="list-details-buttons btn-toolbar">
|
||||||
|
<ActionsButton
|
||||||
|
show={props.show}
|
||||||
|
addToWishlist={props.addToWishlist}
|
||||||
|
deleteFromWishlist={props.deleteFromWishlist}
|
||||||
|
/>
|
||||||
|
<a type="button" className="btn btn-warning btn-sm" href={imdbLink}>
|
||||||
|
<i className="fa fa-external-link"></i> IMDB
|
||||||
|
</a>
|
||||||
|
<Link type="button" className="btn btn-primary btn-sm" to={"/shows/details/" + props.show.imdb_id}>
|
||||||
|
<i className="fa fa-external-link"></i> Details
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ActionsButton(props) {
|
||||||
|
let wishlisted = (props.show.tracked_season !== null && props.show.tracked_episode !== null);
|
||||||
|
return (
|
||||||
|
<DropdownButton className="btn btn-default btn-sm" title="Actions" id="actions-button" dropup>
|
||||||
|
<WishlistButton
|
||||||
|
resourceId={props.show.imdb_id}
|
||||||
|
wishlisted={wishlisted}
|
||||||
|
addToWishlist={props.addToWishlist}
|
||||||
|
deleteFromWishlist={props.deleteFromWishlist}
|
||||||
|
/>
|
||||||
|
</DropdownButton>
|
||||||
|
);
|
||||||
|
}
|
@ -39,17 +39,17 @@ export default function movieStore(state = defaultState, action) {
|
|||||||
fetchingDetails: true,
|
fetchingDetails: true,
|
||||||
})
|
})
|
||||||
case 'MOVIE_GET_DETAILS_FULFILLED':
|
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, {
|
return Object.assign({}, state, {
|
||||||
movies: movies,
|
movies: updateMovieDetails(state.movies.slice(), action.payload.data.imdb_id, action.payload.data),
|
||||||
fetchingDetails: false,
|
fetchingDetails: false,
|
||||||
})
|
})
|
||||||
|
case 'MOVIE_UPDATE_STORE_WISHLIST':
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
movies: updateStoreWishlist(state.movies.slice(), action.payload.imdbId, action.payload.wishlisted),
|
||||||
|
})
|
||||||
case 'DELETE_MOVIE':
|
case 'DELETE_MOVIE':
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
movies: state.movies.filter((e) => (e.imdb_id !== action.imdbId)),
|
movies: state.movies.filter((e) => (e.imdb_id !== action.imdbId)),
|
||||||
fetchingDetails: false,
|
|
||||||
})
|
})
|
||||||
case 'SELECT_MOVIE':
|
case 'SELECT_MOVIE':
|
||||||
// Don't select the movie if we're fetching another movie's details
|
// Don't select the movie if we're fetching another movie's details
|
||||||
@ -64,3 +64,15 @@ export default function movieStore(state = defaultState, action) {
|
|||||||
return state
|
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
|
||||||
|
}
|
||||||
|
@ -45,6 +45,10 @@ export default function showStore(state = defaultState, action) {
|
|||||||
shows: action.payload.data,
|
shows: action.payload.data,
|
||||||
loading: false,
|
loading: false,
|
||||||
})
|
})
|
||||||
|
case 'SHOW_UPDATE_STORE_WISHLIST':
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
shows: updateStoreWishlist(state.shows.slice(), action.payload),
|
||||||
|
})
|
||||||
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) {
|
||||||
@ -102,3 +106,20 @@ function sortEpisodes(show) {
|
|||||||
|
|
||||||
return show;
|
return show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateStoreWishlist(shows, payload) {
|
||||||
|
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) {
|
||||||
|
season = 0;
|
||||||
|
}
|
||||||
|
if (episode === null) {
|
||||||
|
episode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shows[index].tracked_season = season;
|
||||||
|
shows[index].tracked_episode = episode;
|
||||||
|
return shows
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user