178 lines
4.1 KiB
JavaScript
178 lines
4.1 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import PropTypes from "prop-types";
|
|
import fuzzy from "fuzzy";
|
|
import InfiniteScroll from "react-infinite-scroll-component";
|
|
|
|
import ListFilter from "./filter";
|
|
import ExplorerOptions from "./explorerOptions";
|
|
import Poster from "./poster";
|
|
import { KeyboardNavigation } from "./keyboard";
|
|
|
|
import Loader from "../loader/loader";
|
|
|
|
const ListPosters = ({
|
|
data,
|
|
exploreFetchOptions,
|
|
exploreOptions,
|
|
loading,
|
|
onClick,
|
|
onDoubleClick,
|
|
onKeyEnter,
|
|
params,
|
|
placeHolder,
|
|
selectedImdbId,
|
|
type,
|
|
}) => {
|
|
const [list, setList] = useState([]);
|
|
const [filteredList, setFilteredList] = useState([]);
|
|
const [filter, setFilter] = useState("");
|
|
|
|
useEffect(() => {
|
|
let l = [];
|
|
data.forEach((e) => {
|
|
l.push({
|
|
imdbId: e.imdb_id,
|
|
posterUrl: e.poster_url,
|
|
title: e.title,
|
|
});
|
|
});
|
|
setList(l);
|
|
}, [data]);
|
|
|
|
useEffect(() => {
|
|
if (filter !== "" && filter.length >= 3) {
|
|
setFilteredList(list.filter((e) => fuzzy.test(filter, e.title)));
|
|
} else {
|
|
setFilteredList(list);
|
|
}
|
|
}, [filter, list]);
|
|
|
|
if (loading) {
|
|
return <Loader />;
|
|
}
|
|
|
|
// Chose when to display filter / explore options
|
|
let displayFilter = true;
|
|
if (
|
|
(params &&
|
|
params.category &&
|
|
params.category !== "" &&
|
|
params.source &&
|
|
params.source !== "") ||
|
|
list.length === 0
|
|
) {
|
|
displayFilter = false;
|
|
}
|
|
|
|
let displayExplorerOptions = false;
|
|
if (list.length !== 0) {
|
|
displayExplorerOptions = !displayFilter;
|
|
}
|
|
|
|
return (
|
|
<div className="col-4 col-md-8 px-1">
|
|
{displayFilter && (
|
|
<ListFilter updateFilter={setFilter} placeHolder={placeHolder} />
|
|
)}
|
|
<ExplorerOptions
|
|
type={type}
|
|
display={displayExplorerOptions}
|
|
params={params}
|
|
fetch={exploreFetchOptions}
|
|
options={exploreOptions}
|
|
/>
|
|
<Posters
|
|
list={filteredList}
|
|
loading={loading}
|
|
selectedImdbId={selectedImdbId}
|
|
selectPoster={onClick}
|
|
onDoubleClick={onDoubleClick}
|
|
onKeyEnter={onKeyEnter}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
ListPosters.propTypes = {
|
|
data: PropTypes.object,
|
|
onClick: PropTypes.func,
|
|
onDoubleClick: PropTypes.func,
|
|
onKeyEnter: PropTypes.func,
|
|
selectedImdbId: PropTypes.string,
|
|
loading: PropTypes.bool.isRequired,
|
|
params: PropTypes.object.isRequired,
|
|
exploreOptions: PropTypes.object,
|
|
type: PropTypes.string.isRequired,
|
|
placeHolder: PropTypes.string.isRequired,
|
|
exploreFetchOptions: PropTypes.func,
|
|
};
|
|
|
|
export default ListPosters;
|
|
|
|
const Posters = ({
|
|
list,
|
|
onKeyEnter,
|
|
selectedImdbId,
|
|
selectPoster,
|
|
onDoubleClick,
|
|
}) => {
|
|
const addMoreCount = 20;
|
|
const [size, setSize] = useState(0);
|
|
|
|
const updateSize = (newSize, maxSize) => {
|
|
setSize(Math.min(newSize, maxSize));
|
|
};
|
|
|
|
useEffect(() => {
|
|
updateSize(size + addMoreCount, list.length);
|
|
}, [list]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
const loadMore = () => {
|
|
updateSize(size + addMoreCount, list.length);
|
|
};
|
|
|
|
if (list.length === 0) {
|
|
return (
|
|
<div className="jumbotron">
|
|
<h2>No result</h2>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<KeyboardNavigation
|
|
onKeyEnter={onKeyEnter}
|
|
selectPoster={selectPoster}
|
|
list={list}
|
|
selected={selectedImdbId}
|
|
>
|
|
<InfiniteScroll
|
|
className="poster-list d-flex flex-column flex-sm-row flex-sm-wrap justify-content-around"
|
|
dataLength={size}
|
|
next={loadMore}
|
|
hasMore={size !== list.length}
|
|
loader={<Loader />}
|
|
>
|
|
{list.slice(0, size).map((el, index) => {
|
|
const imdbId = el.imdbId;
|
|
return (
|
|
<Poster
|
|
url={el.posterUrl}
|
|
key={index}
|
|
selected={imdbId === selectedImdbId}
|
|
onClick={() => selectPoster(imdbId)}
|
|
onDoubleClick={() => onDoubleClick(imdbId)}
|
|
/>
|
|
);
|
|
}, this)}
|
|
</InfiniteScroll>
|
|
</KeyboardNavigation>
|
|
);
|
|
};
|
|
Posters.propTypes = {
|
|
list: PropTypes.array.isRequired,
|
|
selectedImdbId: PropTypes.string,
|
|
onDoubleClick: PropTypes.func,
|
|
onKeyEnter: PropTypes.func,
|
|
selectPoster: PropTypes.func,
|
|
};
|