This reverts commit c206336c7b54f0855526991d13443b1b79c469f4. It breaks the fuzzy search while in the poster list. We need to find a better solution to get the keyboard focus.
219 lines
5.8 KiB
JavaScript
219 lines
5.8 KiB
JavaScript
import React from "react"
|
|
|
|
import { Map } from "immutable"
|
|
import fuzzy from "fuzzy";
|
|
import InfiniteScroll from "react-infinite-scroller";
|
|
|
|
import ListFilter from "./filter"
|
|
import ExplorerOptions from "./explorerOptions"
|
|
import Poster from "./poster"
|
|
|
|
import Loader from "../loader/loader"
|
|
|
|
const DEFAULT_ADD_EXTRA_ITEMS = 30;
|
|
|
|
export default class ListPosters extends React.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.loadMore = this.loadMore.bind(this);
|
|
this.state = this.getNextState(props);
|
|
}
|
|
loadMore() {
|
|
// Nothing to do if the app is loading
|
|
if (this.props.loading) {
|
|
return;
|
|
}
|
|
|
|
if (this.props.data === undefined) {
|
|
return;
|
|
}
|
|
|
|
this.setState(this.getNextState(this.props));
|
|
}
|
|
getNextState(props) {
|
|
let totalListSize = props.data !== undefined ? props.data.size : 0;
|
|
let currentListSize = (this.state && this.state.items) ? this.state.items : 0;
|
|
let nextListSize = currentListSize + DEFAULT_ADD_EXTRA_ITEMS;
|
|
let hasMore = true;
|
|
|
|
if (nextListSize >= totalListSize) {
|
|
nextListSize = totalListSize;
|
|
hasMore = false;
|
|
}
|
|
|
|
return {
|
|
items: nextListSize,
|
|
hasMore: hasMore,
|
|
};
|
|
}
|
|
componentWillReceiveProps(nextProps) {
|
|
if (this.props.data === undefined) { return }
|
|
if (nextProps.data === undefined) { return }
|
|
|
|
if (this.props.data.size !== nextProps.data.size) {
|
|
this.setState(this.getNextState(nextProps));
|
|
}
|
|
}
|
|
render() {
|
|
let elmts = this.props.data;
|
|
const listSize = elmts !== undefined ? elmts.size : 0;
|
|
const colSize = (listSize !== 0) ? "col-xs-5 col-md-8" : "col-xs-12";
|
|
|
|
// Filter the list of elements
|
|
if (this.props.filter !== "") {
|
|
elmts = elmts.filter((v) => fuzzy.test(this.props.filter, v.get("title")), this);
|
|
} else {
|
|
elmts = elmts.slice(0, this.state.items);
|
|
}
|
|
|
|
// Chose when to display filter / explore options
|
|
let displayFilter = true;
|
|
if ((this.props.params
|
|
&& this.props.params.category
|
|
&& this.props.params.category !== ""
|
|
&& this.props.params.source
|
|
&& this.props.params.source !== "")
|
|
|| (listSize === 0)) {
|
|
displayFilter = false;
|
|
}
|
|
|
|
|
|
let displayExplorerOptions = false;
|
|
if (listSize !== 0) {
|
|
displayExplorerOptions = !displayFilter;
|
|
}
|
|
|
|
return (
|
|
<div className={colSize}>
|
|
{displayFilter &&
|
|
<ListFilter
|
|
updateFilter={this.props.updateFilter}
|
|
placeHolder={this.props.placeHolder}
|
|
/>
|
|
}
|
|
<ExplorerOptions
|
|
type={this.props.type}
|
|
display={displayExplorerOptions}
|
|
params={this.props.params}
|
|
router={this.props.router}
|
|
options={this.props.exploreOptions}
|
|
/>
|
|
<Posters
|
|
elmts={elmts}
|
|
loading={this.props.loading}
|
|
hasMore={this.state.hasMore}
|
|
loadMore={this.loadMore}
|
|
selectedImdbId={this.props.selectedImdbId}
|
|
selectPoster={this.props.onClick}
|
|
onDoubleClick={this.props.onDoubleClick}
|
|
onKeyEnter={this.props.onKeyEnter}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
class Posters extends React.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
}
|
|
|
|
move(event) {
|
|
// Detect which direction to go
|
|
const keyToDiff = Map({
|
|
"ArrowRight": 1,
|
|
"l": 1,
|
|
"ArrowLeft": -1,
|
|
"h": -1,
|
|
"ArrowUp": -6,
|
|
"k": -6,
|
|
"ArrowDown": 6,
|
|
"j": 6,
|
|
});
|
|
|
|
if (event.key === "Enter") {
|
|
this.props.onKeyEnter(this.props.selectedImdbId);
|
|
}
|
|
|
|
if (! keyToDiff.has(event.key) ) {
|
|
return;
|
|
}
|
|
var diff = keyToDiff.get(event.key);
|
|
|
|
// Don't scroll when changing poster
|
|
event.preventDefault();
|
|
|
|
// Get the index of the currently selected item
|
|
const idx = this.props.elmts.keySeq().findIndex(k => k === this.props.selectedImdbId);
|
|
|
|
var newIdx = idx + diff;
|
|
|
|
// Handle edge cases
|
|
if (newIdx > this.props.elmts.size -1) {
|
|
newIdx = this.props.elmts.size -1;
|
|
} else if (newIdx < 0) {
|
|
newIdx = 0;
|
|
}
|
|
|
|
// Get the imdbID of the newly selected item
|
|
var selectedImdb = Object.keys(this.props.elmts.toJS())[newIdx];
|
|
|
|
// Select the movie
|
|
this.props.selectPoster(selectedImdb);
|
|
}
|
|
|
|
render() {
|
|
if (this.props.loading) {
|
|
return (<Loader />);
|
|
}
|
|
|
|
if (this.props.elmts.size === 0) {
|
|
return (
|
|
<div className="jumbotron">
|
|
<h2>No result</h2>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div tabIndex="0"
|
|
onKeyDown={(event) => this.move(event)}
|
|
className="poster-list"
|
|
>
|
|
<InfiniteScroll
|
|
hasMore={this.props.hasMore}
|
|
loadMore={this.props.loadMore}
|
|
className="row"
|
|
>
|
|
{this.props.elmts.toIndexedSeq().map(function(movie, index) {
|
|
const imdbId = movie.get("imdb_id");
|
|
const selected = (imdbId === this.props.selectedImdbId) ? true : false;
|
|
|
|
let clearFixes = [];
|
|
if ((index % 6) === 0) { clearFixes.push("clearfix visible-lg") };
|
|
if ((index % 4) === 0) { clearFixes.push("clearfix visible-md") };
|
|
if ((index % 2) === 0) { clearFixes.push("clearfix visible-sm") };
|
|
|
|
return (
|
|
<div key={imdbId}>
|
|
{clearFixes.length > 0 && clearFixes.map(function(el, i) {
|
|
return (
|
|
<div key={`clearfix-${imdbId}-${i}`} className={el}></div>
|
|
);
|
|
})}
|
|
<Poster
|
|
data={movie}
|
|
key={`poster-${imdbId}`}
|
|
selected={selected}
|
|
onClick={() => this.props.selectPoster(imdbId)}
|
|
onDoubleClick={() => this.props.onDoubleClick(imdbId)}
|
|
/>
|
|
</div>
|
|
)
|
|
} ,this)}
|
|
</InfiniteScroll>
|
|
</div>
|
|
);
|
|
}
|
|
}
|