Merge branch 'dev/fixWishlist' into 'master'

MoarStability

See merge request !55
This commit is contained in:
Lucas 2017-04-19 12:40:01 +00:00
commit 7d308927e1
5 changed files with 125 additions and 147 deletions

View File

@ -4,67 +4,57 @@ import { Form, FormGroup, FormControl, ControlLabel } from 'react-bootstrap'
export default class ExplorerOptions extends React.Component { export default class ExplorerOptions extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
let source = null;
let category = null;
let categories = [];
// Check if the options are present
if (Object.keys(this.props.options).length === 0) { if (Object.keys(this.props.options).length === 0) {
// Fetch options
this.props.fetchOptions(); this.props.fetchOptions();
// Explore
this.props.explore(this.props.params.source, this.props.params.category);
} else {
source = this.props.params.source;
category = this.props.params.category;
categories = this.props.options[this.props.params.source];
} }
this.state = { // Initial explore
selectedSource: source, if (this.propsValid(props)) {
selectedCategory: category, props.explore(props.params.source, props.params.category);
categories: categories, }
};
this.handleSourceChange = this.handleSourceChange.bind(this); this.handleSourceChange = this.handleSourceChange.bind(this);
this.handleCategoryChange = this.handleCategoryChange.bind(this); this.handleCategoryChange = this.handleCategoryChange.bind(this);
} }
handleSourceChange(event) { handleSourceChange(event) {
let source = event.target.value; let source = event.target.value;
let category = this.props.options[event.target.value][0]; let category = this.props.options[event.target.value][0];
this.setState({ this.props.explore(source, category);
selectedSource: source,
selectedCategory: category,
categories: this.props.options[source],
});
this.props.router.push(`/${this.props.type}/explore/${source}/${category}`); this.props.router.push(`/${this.props.type}/explore/${source}/${category}`);
} }
handleCategoryChange(event) { handleCategoryChange(event) {
this.setState({ selectedCategory: event.target.value }); let source = this.props.params.source;
this.props.router.push(`/${this.props.type}/explore/${this.state.selectedSource}/${event.target.value}`); let category = event.target.value;
this.props.explore(source, category);
this.props.router.push(`/${this.props.type}/explore/${source}/${category}`);
}
propsValid(props) {
if (!props.params
|| !props.params.source
|| !props.params.category
|| (props.params.source === "")
|| (props.params.category === "")) {
return false
}
return true;
} }
componentWillUpdate(nextProps, nextState) { componentWillUpdate(nextProps, nextState) {
// Check props // Check props
if (!nextProps.params.source if (!this.propsValid(nextProps)) {
|| !nextProps.params.category
|| (nextProps.params.source === "")
|| (nextProps.params.category === "")) {
return return
} }
// No previous params
if (!this.props.params.source && !this.props.params.category) {
this.props.explore(this.props.params.source, this.props.params.category);
return;
}
// Explore params changed // Explore params changed
if ((this.props.params.source !== nextProps.params.source) if ((this.props.params.source !== nextProps.params.source)
|| (this.props.params.category !== nextProps.params.category)) { || (this.props.params.category !== nextProps.params.category)) {
this.props.explore(nextProps.params.source, nextProps.params.category); this.props.explore(nextProps.params.source, nextProps.params.category);
} return;
// State must be updated
if ((this.state.selectedSource !== nextProps.params.source)
|| (this.state.selectedCategory !== nextProps.params.category)) {
this.setState({
selectedSource: nextProps.params.source,
selectedCategory: nextProps.params.category,
categories: nextProps.options[nextProps.params.source],
});
} }
} }
prettyName(name) { prettyName(name) {
@ -84,11 +74,15 @@ export default class ExplorerOptions extends React.Component {
return null; return null;
} }
// State is not yet set // Invalid props
if (!this.state.selectedSource && !this.state.selectedCategory) { if (!this.propsValid(this.props)) {
return null; return
} }
let source = this.props.params.source;
let category = this.props.params.category;
let categories = this.props.options[this.props.params.source];
return ( return (
<div className="row"> <div className="row">
<div className="col-xs-12 col-md-12"> <div className="col-xs-12 col-md-12">
@ -101,7 +95,7 @@ export default class ExplorerOptions extends React.Component {
bsClass="form-control input-sm" bsClass="form-control input-sm"
componentClass="select" componentClass="select"
onChange={this.handleSourceChange} onChange={this.handleSourceChange}
value={this.state.selectedSource} value={source}
> >
{Object.keys(this.props.options).map(function(source) { {Object.keys(this.props.options).map(function(source) {
return (<option key={source} value={source}>{this.prettyName(source)}</option>) return (<option key={source} value={source}>{this.prettyName(source)}</option>)
@ -116,9 +110,9 @@ export default class ExplorerOptions extends React.Component {
bsClass="form-control input-sm" bsClass="form-control input-sm"
componentClass="select" componentClass="select"
onChange={this.handleCategoryChange} onChange={this.handleCategoryChange}
value={this.state.selectedCategory} value={category}
> >
{this.state.categories.map(function(category) { {categories.map(function(category) {
return (<option key={category} value={category}>{this.prettyName(category)}</option>) return (<option key={category} value={category}>{this.prettyName(category)}</option>)
}, this)} }, this)}
</FormControl> </FormControl>

View File

@ -7,6 +7,8 @@ import ListFilter from './filter'
import ExplorerOptions from './explorerOptions' import ExplorerOptions from './explorerOptions'
import ListPoster from './poster' import ListPoster from './poster'
import Loader from '../loader/loader'
export default class ListPosters extends React.Component { export default class ListPosters extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -78,30 +80,52 @@ export default class ListPosters extends React.Component {
options={this.props.exploreOptions} options={this.props.exploreOptions}
explore={this.props.explore} explore={this.props.explore}
/> />
{elmts.length === 0 && <Posters
<div className="jumbotron"> elmts={elmts}
<h2>No result</h2> loading={this.props.loading}
</div>
}
<InfiniteScroll
hasMore={this.state.hasMore} hasMore={this.state.hasMore}
loadMore={this.loadMore} loadMore={this.loadMore}
className="row" selectedImdbId={this.props.selectedImdbId}
> onClick={this.props.onClick}
{elmts.map(function(el, index) { />
const selected = (el.imdb_id === this.props.selectedImdbId) ? true : false;
return (
<ListPoster
index={index}
data={el}
key={el.imdb_id}
selected={selected}
onClick={() => this.props.onClick(el.imdb_id)}
/>
)}
, this)}
</InfiniteScroll>
</div> </div>
); );
} }
} }
function Posters(props) {
if (props.loading) {
return (<Loader />);
}
if (props.elmts.length === 0) {
return (
<div className="jumbotron">
<h2>No result</h2>
</div>
);
}
return (
<div>
<InfiniteScroll
hasMore={props.hasMore}
loadMore={props.loadMore}
className="row"
>
{props.elmts.map(function(el, index) {
const selected = (el.imdb_id === props.selectedImdbId) ? true : false;
return (
<ListPoster
index={index}
data={el}
key={el.imdb_id}
selected={selected}
onClick={() => props.onClick(el.imdb_id)}
/>
)}
)}
</InfiniteScroll>
</div>
);
}

View File

@ -5,7 +5,6 @@ import TorrentsButton from './torrents'
import ActionsButton from './actions' import ActionsButton from './actions'
import ListPosters from '../list/posters' import ListPosters from '../list/posters'
import ListDetails from '../list/details' import ListDetails from '../list/details'
import Loader from '../loader/loader'
function MovieButtons(props) { function MovieButtons(props) {
const imdb_link = `http://www.imdb.com/title/${props.movie.imdb_id}`; const imdb_link = `http://www.imdb.com/title/${props.movie.imdb_id}`;
@ -41,41 +40,12 @@ function MovieButtons(props) {
} }
export default class MovieList extends React.Component { export default class MovieList extends React.Component {
handleParams(props = this.props) { constructor(props) {
// Check if the URL to fetch is in the props super(props);
if (props.moviesUrl) {
this.props.fetchMovies(props.moviesUrl);
return
}
// Check for URL parameters
if (!props.params) {
return
}
// Search param
if (props.params.search && props.params.search !== "") {
props.searchMovies({
key: props.params.search
});
return
}
} }
componentWillMount() { componentWillMount() {
this.handleParams(); if (this.props.moviesUrl) {
} this.props.fetchMovies(this.props.moviesUrl);
componentWillUpdate(nextProps, nextState) {
// No params
if (!nextProps.params) {
return
}
// Search field changed
if (this.props.params.search
&& (this.props.params.search !== nextProps.params.search)
&& (nextProps.params.search !== "")) {
this.handleParams(nextProps);
return
} }
} }
render() { render() {
@ -87,11 +57,6 @@ export default class MovieList extends React.Component {
} }
const selectedMovie = movies[index]; const selectedMovie = movies[index];
// Loading
if (this.props.movieStore.loading) {
return (<Loader />);
}
return ( return (
<div className="row" id="container"> <div className="row" id="container">
<ListPosters <ListPosters
@ -109,6 +74,7 @@ export default class MovieList extends React.Component {
onClick={this.props.selectMovie} onClick={this.props.selectMovie}
params={this.props.params} params={this.props.params}
router={this.props.router} router={this.props.router}
loading={this.props.movieStore.loading}
/> />
{selectedMovie && {selectedMovie &&
<ListDetails data={selectedMovie}> <ListDetails data={selectedMovie}>

View File

@ -30,8 +30,10 @@ export default function NavBar(props) {
placeholder="Search movies" placeholder="Search movies"
router={props.router} router={props.router}
search={props.movieStore.search} search={props.movieStore.search}
searchFunc={props.searchMovies}
path='/movies/search' path='/movies/search'
pathMatch='movies' pathMatch='movies'
params={props.params}
/> />
<Search <Search
model="showStore" model="showStore"
@ -39,8 +41,10 @@ export default function NavBar(props) {
placeholder="Search shows" placeholder="Search shows"
router={props.router} router={props.router}
search={props.showStore.search} search={props.showStore.search}
searchFunc={props.searchShows}
path='/shows/search' path='/shows/search'
pathMatch='shows' pathMatch='shows'
params={props.params}
/> />
</Navbar.Collapse> </Navbar.Collapse>
</Navbar> </Navbar>
@ -52,14 +56,40 @@ class Search extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleSearch = this.handleSearch.bind(this); this.handleSearch = this.handleSearch.bind(this);
this.search(this.props);
} }
handleSearch() { handleSearch() {
this.props.router.push(`${this.props.path}/${encodeURI(this.props.search)}`) if (this.props.search === "") {
return;
}
this.search(this.props);
this.props.router.push(`${this.props.path}/${encodeURI(this.props.search)}`);
}
isActive() {
const location = this.props.router.getCurrentLocation().pathname;
return (location.indexOf(this.props.pathMatch) !== -1)
}
search(props) {
if (!this.isActive()) {
return;
}
// Search from the props if defined
if (props.search !== "") {
props.searchFunc({ key: props.search });
return;
}
// Search from the url params
if (props.params
&& props.params.search
&& props.params.search !== "") {
props.searchFunc({ key: props.params.search });
return;
}
} }
render() { render() {
const location = this.props.router.getCurrentLocation().pathname; if (!this.isActive()) {
if (location.indexOf(this.props.pathMatch) === -1)
{
return null; return null;
} }

View File

@ -2,44 +2,12 @@ import React from 'react'
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 ShowButtons from './listButtons' import ShowButtons from './listButtons'
export default class ShowList extends React.Component { export default class ShowList extends React.Component {
handleParams(props = this.props) {
// Check if the URL to fetch is in the props
if (props.showsUrl) {
this.props.fetchShows(props.showsUrl);
return
}
// Check for URL parameters
if (!props.params) {
return
}
// Search param
if (props.params.search && props.params.search !== "") {
this.props.searchShows({
key: this.props.params.search
});
return
}
}
componentWillMount() { componentWillMount() {
this.handleParams(); if (this.props.showsUrl) {
} this.props.fetchShows(this.props.showsUrl);
componentWillUpdate(nextProps, nextState) {
// No params
if (!nextProps.params) {
return
}
// Search field changed
if (this.props.params.search
&& (this.props.params.search !== nextProps.params.search)
&& (nextProps.params.search !== "")) {
this.handleParams(nextProps);
return return
} }
} }
@ -52,11 +20,6 @@ export default class ShowList extends React.Component {
} }
const selectedShow = shows[index]; const selectedShow = shows[index];
// Loading
if (this.props.showStore.loading) {
return (<Loader />);
}
return ( return (
<div className="row" id="container"> <div className="row" id="container">
<ListPosters <ListPosters
@ -74,6 +37,7 @@ export default class ShowList extends React.Component {
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}
/> />
{selectedShow && {selectedShow &&
<ListDetails data={selectedShow} > <ListDetails data={selectedShow} >