Change the DB to store torrents in database Add Torrenters to the party Add raw links to movie Torrents in the web interface Change the way explore works with multiple source and categories with external_medias Delete StringSlice and use pq StringArray type to avoid problems
180 lines
5.1 KiB
JavaScript
180 lines
5.1 KiB
JavaScript
import React from 'react'
|
|
import axios from 'axios'
|
|
import { Control, Form } from 'react-redux-form';
|
|
import fuzzy from 'fuzzy';
|
|
|
|
function MoviePosters(props) {
|
|
let movies = props.movies.slice();
|
|
|
|
// Filter the movies
|
|
if (props.filter !== "") {
|
|
const filtered = fuzzy.filter(props.filter, movies, {
|
|
extract: (el) => el.title
|
|
});
|
|
movies = filtered.map((el) => el.original);
|
|
}
|
|
|
|
// Limit the number of results
|
|
if (movies.length > props.perPage) {
|
|
movies = movies.slice(0, props.perPage);
|
|
}
|
|
|
|
return (
|
|
<div className="col-xs-5 col-md-8">
|
|
<MovieListFilter />
|
|
<div className="row">
|
|
{movies.map(function(movie, index) {
|
|
const selected = (movie.imdb_id === props.selectedMovieId) ? true : false;
|
|
return (
|
|
<MoviePoster
|
|
data={movie}
|
|
key={movie.imdb_id}
|
|
selected={selected}
|
|
onClick={() => props.onClick(movie.imdb_id)}
|
|
/>
|
|
)}
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
class MovieListFilter extends React.Component {
|
|
render() {
|
|
return (
|
|
<div className="col-xs-12 col-md-12 movie-list-filter">
|
|
<div className="row">
|
|
<Form model="movieStore" className="input-group" >
|
|
<Control.text
|
|
model="movieStore.filter"
|
|
className="form-control input-sm"
|
|
placeholder="Filter movies..."
|
|
updateOn="change"
|
|
/>
|
|
<span className="input-group-btn">
|
|
<button className="btn btn-default btn-sm" type="button">Filter</button>
|
|
</span>
|
|
</Form>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
function MoviePoster(props) {
|
|
const selected = props.selected ? ' thumbnail-selected' : '';
|
|
const imgClass = 'thumbnail' + selected;
|
|
return (
|
|
<div className="col-xs-12 col-sm-6 col-md-3 col-lg-2">
|
|
<a className={imgClass}>
|
|
<img
|
|
src={props.data.poster_url}
|
|
onClick={props.onClick}
|
|
/>
|
|
</a>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function MovieDetails(props) {
|
|
return (
|
|
<div className="col-xs-7 col-md-4">
|
|
<div className="movie-detail affix">
|
|
<h1 className="hidden-xs">{props.movie.title}</h1>
|
|
<h3 className="visible-xs">{props.movie.title}</h3>
|
|
<p>
|
|
<i className="fa fa-clock-o"></i>
|
|
{props.movie.runtime} min
|
|
</p>
|
|
<p>
|
|
<i className="fa fa-star-o"></i>
|
|
{props.movie.rating} <small>({props.movie.votes} counts)</small>
|
|
</p>
|
|
<p className="movie-plot">{props.movie.plot}</p>
|
|
</div>
|
|
<MovieButtons {...props} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
class MovieButtons extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.handleClick = this.handleClick.bind(this);
|
|
}
|
|
handleClick(e) {
|
|
e.preventDefault();
|
|
if (this.props.fetching) {
|
|
return
|
|
}
|
|
this.props.getMovieDetails(this.props.movie.imdb_id);
|
|
}
|
|
render() {
|
|
const imdb_link = `http://www.imdb.com/title/${this.props.movie.imdb_id}`;
|
|
return (
|
|
<div className="movie-details-buttons btn-toolbar">
|
|
<a type="button" className="btn btn-default btn-sm" 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>
|
|
}
|
|
</a>
|
|
{this.props.movie.polochon_url !== "" &&
|
|
<a type="button" className="btn btn-primary btn-sm" href={this.props.movie.polochon_url}>
|
|
<i className="fa fa-download"></i> Download
|
|
</a>
|
|
}
|
|
{this.props.movie.torrents && this.props.movie.torrents.map(function(torrent, index) {
|
|
return (
|
|
<a key={torrent.url} type="button" className="btn btn-primary btn-sm" href={torrent.url}>
|
|
<i className="fa fa-download"></i> {torrent.quality} Torrent
|
|
</a>
|
|
)}
|
|
)}
|
|
<a type="button" className="btn btn-warning btn-sm" href={imdb_link}>
|
|
<i className="fa fa-external-link"></i> IMDB
|
|
</a>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default class MovieList extends React.Component {
|
|
componentWillMount() {
|
|
this.props.fetchMovies(this.props.moviesUrl);
|
|
}
|
|
render() {
|
|
const movies = this.props.movieStore.movies;
|
|
const selectedMovieId = this.props.movieStore.selectedImdbId;
|
|
let index = movies.map((el) => el.imdb_id).indexOf(selectedMovieId);
|
|
if (index === -1) {
|
|
index = 0;
|
|
}
|
|
const selectedMovie = movies[index];
|
|
return (
|
|
<div className="row" id="container">
|
|
<MoviePosters
|
|
movies={movies}
|
|
selectedMovieId={selectedMovieId}
|
|
filter={this.props.movieStore.filter}
|
|
perPage={this.props.movieStore.perPage}
|
|
onClick={this.props.selectMovie}
|
|
/>
|
|
{selectedMovie &&
|
|
<MovieDetails
|
|
movie={selectedMovie}
|
|
fetching={this.props.movieStore.fetchingDetails}
|
|
getMovieDetails={this.props.getMovieDetails}
|
|
/>
|
|
}
|
|
</div>
|
|
);
|
|
}
|
|
}
|