Move in the poster list with h,j,k,l

This commit is contained in:
Grégoire Delattre 2019-06-21 17:18:45 +02:00
parent 48a6dc9fef
commit 20ca2adefc

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react" import React, { useState, useEffect, useCallback } from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import { OrderedMap, Map } from "immutable" import { OrderedMap, Map } from "immutable"
import fuzzy from "fuzzy"; import fuzzy from "fuzzy";
@ -81,6 +81,99 @@ ListPosters.propTypes = {
export default ListPosters; export default ListPosters;
const Posters = (props) => { const Posters = (props) => {
const addMoreCount = 20;
const [size, setSize] = useState(0);
const [postersPerRow, setPostersPerRow] = useState(0);
const [posterHeight, setPosterHeight] = useState(0);
const loadMore = () => {
if ((size === props.elmts.size)) { return }
const newSize = (((size + addMoreCount) >= props.elmts.size)
? props.elmts.size
: size + addMoreCount);
setSize(newSize);
}
useEffect(() => {
loadMore()
}, [props.elmts.size]);
const move = (event) => {
// Only run the function if nothing else if actively focused
if (document.activeElement.tagName.toLowerCase() !== "body") { return }
let diff = 0;
let moveFocus = 0;
switch (event.key) {
case "Enter":
props.onKeyEnter(props.selectedImdbId);
return;
case "l":
diff = 1;
break;
case "h":
diff = -1;
break;
case "k":
diff = -1*postersPerRow;
moveFocus = -1*posterHeight;
break;
case "j":
diff = postersPerRow;
moveFocus = posterHeight;
break;
default:
return;
}
// Get the index of the currently selected item
const idx = props.elmts.keySeq().findIndex(k => k === props.selectedImdbId);
var newIdx = idx + diff;
// Handle edge cases
if (newIdx > props.elmts.size -1) {
newIdx = props.elmts.size -1;
} else if (newIdx < 0) {
newIdx = 0;
}
// Get the imdbID of the newly selected item
var selectedImdb = Object.keys(props.elmts.toJS())[newIdx];
// Select the movie
props.selectPoster(selectedImdb);
if (moveFocus !== 0) {
window.scrollBy(0, moveFocus);
}
}
const posterCount = useCallback(node => {
if (node === null) { return }
const parentWidth = node.getBoundingClientRect().width;
const childContainer = node.getElementsByClassName("img-thumbnail");
let childWidth = 0;
let posterHeight = 0;
if ((childContainer !== null) && (childContainer.item(0) !== null)) {
const child = childContainer.item(0);
childWidth = child.getBoundingClientRect().width + child.getBoundingClientRect().left;
posterHeight = child.getBoundingClientRect().height;
}
let numberPerRow = (childWidth >= parentWidth) ? 1 : Math.floor(parentWidth/childWidth);
setPostersPerRow(numberPerRow);
setPosterHeight(posterHeight);
})
useEffect(() => {
document.onkeypress = move;
return () => {
document.onkeypress = null;
}
}, [move])
if (props.loading) { if (props.loading) {
return (<Loader />); return (<Loader />);
} }
@ -93,46 +186,31 @@ const Posters = (props) => {
); );
} }
const addMoreCount = 20;
const [size, setSize] = useState(0);
useEffect(() => {
loadMore()
}, [props.elmts.size]);
const hasMore = () => (size !== props.elmts.size);
const loadMore = () => {
if (!hasMore()) { return }
const newSize = (((size + addMoreCount) >= props.elmts.size)
? props.elmts.size
: size + addMoreCount);
setSize(newSize);
}
return ( return (
<InfiniteScroll <div ref={posterCount}>
className="poster-list d-flex flex-column flex-sm-row flex-sm-wrap justify-content-around" <InfiniteScroll
dataLength={size} className="poster-list d-flex flex-column flex-sm-row flex-sm-wrap justify-content-around"
next={loadMore} dataLength={size}
hasMore={hasMore()} next={loadMore}
loader={<Loader />} hasMore={(size !== props.elmts.size)}
> loader={<Loader />}
{props.elmts.slice(0, size).toIndexedSeq().map(function(el, index) { >
const imdbId = el.get("imdb_id"); {props.elmts.slice(0, size).toIndexedSeq().map(function(el, index) {
const selected = (imdbId === props.selectedImdbId) ? true : false; const imdbId = el.get("imdb_id");
const selected = (imdbId === props.selectedImdbId) ? true : false;
return ( return (
<Poster <Poster
data={el} data={el}
key={`poster-${imdbId}-${index}`} key={`poster-${imdbId}-${index}`}
selected={selected} selected={selected}
onClick={() => props.selectPoster(imdbId)} onClick={() => props.selectPoster(imdbId)}
onDoubleClick={() => props.onDoubleClick(imdbId)} onDoubleClick={() => props.onDoubleClick(imdbId)}
/> />
) )
} ,this)} } ,this)}
</InfiniteScroll> </InfiniteScroll>
</div>
); );
} }
Posters.propTypes = { Posters.propTypes = {