Compare commits

..

No commits in common. "a14776611849d2e2f1ef0142e5e08df436470432" and "69115c731854c886579a1c7303e241062e54c19b" have entirely different histories.

8 changed files with 117 additions and 149 deletions

View File

@ -5,10 +5,10 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="Description" content="Canapé">
<link rel="icon" type="image/png" href="<%= require("./img/favicon-16x16.png").default %>" sizes="16x16">
<link rel="icon" type="image/png" href="<%= require("./img/favicon-32x32.png").default %>" sizes="32x32">
<link rel="icon" type="image/png" href="<%= require("./img/favicon-32x32.png") %>" sizes="32x32">
<link rel="icon" type="image/png" href="<%= require("./img/favicon-16x16.png") %>" sizes="16x16">
<meta name="msapplication-navbutton-color" content="#4E5D6C">
<link rel="mask-icon" href="<%= require("./img/safari-pinned-tab.svg").default %>" color="#5bbad5">
<link rel="mask-icon" href="<%= require("./img/safari-pinned-tab.svg") %>" color="#5bbad5">
<title>Canapé</title>
</head>
<body>

View File

@ -27,7 +27,7 @@ export const ShowMore = ({ children, id, inLibrary }) => {
ShowMore.propTypes = {
id: PropTypes.string,
inLibrary: PropTypes.bool.isRequired,
children: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
children: PropTypes.oneOf(PropTypes.object, PropTypes.array)
};
ShowMore.defaultProps = {
id: "",

View File

@ -48,5 +48,5 @@ FormModal.propTypes = {
icon: PropTypes.string,
title: PropTypes.string,
handleSubmit: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
children: PropTypes.oneOf(PropTypes.object, PropTypes.array)
};

View File

@ -85,35 +85,30 @@ ListPosters.propTypes = {
export default ListPosters;
const Posters = ({
elmts,
onKeyEnter,
selectedImdbId,
selectPoster,
onDoubleClick
}) => {
const Posters = props => {
const addMoreCount = 20;
const [size, setSize] = useState(0);
const [postersPerRow, setPostersPerRow] = useState(0);
const [posterHeight, setPosterHeight] = useState(0);
const loadMore = useCallback(() => {
if (size === elmts.size) {
const loadMore = () => {
if (size === props.elmts.size) {
return;
}
const newSize =
size + addMoreCount >= elmts.size ? elmts.size : size + addMoreCount;
size + addMoreCount >= props.elmts.size
? props.elmts.size
: size + addMoreCount;
setSize(newSize);
}, [size, elmts.size]);
};
useEffect(() => {
loadMore();
}, [elmts.size, loadMore]);
}, [props.elmts.size]);
const move = useCallback(
event => {
const move = event => {
// Only run the function if nothing else if actively focused
if (document.activeElement.tagName.toLowerCase() !== "body") {
return;
@ -123,7 +118,7 @@ const Posters = ({
let moveFocus = 0;
switch (event.key) {
case "Enter":
onKeyEnter(selectedImdbId);
props.onKeyEnter(props.selectedImdbId);
return;
case "l":
diff = 1;
@ -144,37 +139,28 @@ const Posters = ({
}
// Get the index of the currently selected item
const idx = elmts.keySeq().findIndex(k => k === selectedImdbId);
const idx = props.elmts.keySeq().findIndex(k => k === props.selectedImdbId);
var newIdx = idx + diff;
// Handle edge cases
if (newIdx > elmts.size - 1) {
newIdx = elmts.size - 1;
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(elmts.toJS())[newIdx];
var selectedImdb = Object.keys(props.elmts.toJS())[newIdx];
// Select the movie
selectPoster(selectedImdb);
props.selectPoster(selectedImdb);
if (moveFocus !== 0) {
window.scrollBy(0, moveFocus);
}
},
[
elmts,
onKeyEnter,
posterHeight,
postersPerRow,
selectPoster,
selectedImdbId
]
);
};
const posterCount = node => {
const posterCount = useCallback(node => {
if (node === null) {
return;
}
@ -194,7 +180,7 @@ const Posters = ({
childWidth >= parentWidth ? 1 : Math.floor(parentWidth / childWidth);
setPostersPerRow(numberPerRow);
setPosterHeight(posterHeight);
};
});
useEffect(() => {
document.onkeypress = move;
@ -203,7 +189,7 @@ const Posters = ({
};
}, [move]);
if (elmts.size === 0) {
if (props.elmts.size === 0) {
return (
<div className="jumbotron">
<h2>No result</h2>
@ -217,23 +203,23 @@ const Posters = ({
className="poster-list d-flex flex-column flex-sm-row flex-sm-wrap justify-content-around"
dataLength={size}
next={loadMore}
hasMore={size !== elmts.size}
hasMore={size !== props.elmts.size}
loader={<Loader />}
>
{elmts
{props.elmts
.slice(0, size)
.toIndexedSeq()
.map(function(el, index) {
const imdbId = el.get("imdb_id");
const selected = imdbId === selectedImdbId ? true : false;
const selected = imdbId === props.selectedImdbId ? true : false;
return (
<Poster
url={el.get("poster_url")}
key={index}
selected={selected}
onClick={() => selectPoster(imdbId)}
onDoubleClick={() => onDoubleClick(imdbId)}
onClick={() => props.selectPoster(imdbId)}
onDoubleClick={() => props.onDoubleClick(imdbId)}
/>
);
}, this)}

View File

@ -55,7 +55,7 @@ const MoviesRoute = ({
);
};
MoviesRoute.propTypes = {
component: PropTypes.object,
component: PropTypes.func,
match: PropTypes.object,
isExplorerFetched: PropTypes.bool.isRequired,
fetchMovies: PropTypes.func.isRequired,

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from "react";
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { addTorrent, searchTorrents } from "../../actions/torrents";
@ -15,21 +15,12 @@ const mapStateToProps = state => ({
});
const mapDispatchToProps = { addTorrent, searchTorrents };
const TorrentSearch = ({
searching,
searchTorrents,
results,
addTorrent,
history,
match
}) => {
const [search, setSearch] = useState(match.params.search || "");
const [type, setType] = useState(match.params.type || "");
const TorrentSearch = props => {
const [search, setSearch] = useState(props.match.params.search || "");
const [type, setType] = useState(props.match.params.type || "");
const [url, setUrl] = useState("");
const getUrl = useCallback(() => {
return `/torrents/search/${type}/${encodeURI(search)}`;
}, [type, search]);
const getUrl = () => `/torrents/search/${type}/${encodeURI(search)}`;
useEffect(() => {
if (search === "") {
@ -40,9 +31,9 @@ const TorrentSearch = ({
}
const url = getUrl();
searchTorrents(url);
history.push(url);
}, [url, getUrl, searchTorrents, history, search, type]);
props.searchTorrents(url);
props.history.push(url);
}, [url]);
return (
<div className="row">
@ -77,9 +68,9 @@ const TorrentSearch = ({
</div>
<div className="col-12">
<TorrentList
searching={searching}
results={results}
addTorrent={addTorrent}
searching={props.searching}
results={props.results}
addTorrent={props.addTorrent}
searchFromURL={search}
/>
</div>

View File

@ -1,5 +1,4 @@
import { useEffect, useState, useCallback } from "react";
import PropTypes from "prop-types";
import { useEffect, useState } from "react";
import { connect } from "react-redux";
import { setFetchedTorrents } from "../actions/torrents";
import { newMovieEvent } from "../actions/movies";
@ -14,28 +13,47 @@ const mapDispatchToProps = {
newEpisodeEvent
};
const WsHandler = ({
isLogged,
setFetchedTorrents,
newMovieEvent,
newEpisodeEvent
}) => {
const WsHandler = props => {
const [ws, setWs] = useState(null);
const stop = useCallback(() => {
useEffect(() => {
const intervalID = setInterval(() => {
if (!ws) {
connect();
return;
}
if (ws.readyState === WebSocket.CLOSED) {
stop();
}
}, 10000);
if (!ws) {
connect();
}
return () => {
if (ws) {
stop();
}
clearInterval(intervalID);
};
}, [ws]);
const stop = () => {
if (!ws) {
return;
}
ws.close();
setWs(null);
}, [ws]);
};
const connect = useCallback(() => {
const connect = () => {
if (ws) {
return;
}
if (!isLogged) {
if (!props.isLogged) {
stop();
}
@ -73,13 +91,13 @@ const WsHandler = ({
switch (data.type) {
case "torrents":
setFetchedTorrents(data.message);
props.setFetchedTorrents(data.message);
break;
case "newVideo":
if (data.message.type === "movie") {
newMovieEvent(data.message.data);
props.newMovieEvent(data.message.data);
} else if (data.message.type === "episode") {
newEpisodeEvent(data.message.data);
props.newEpisodeEvent(data.message.data);
}
break;
}
@ -90,39 +108,9 @@ const WsHandler = ({
};
setWs(socket);
}, [ws, isLogged, newMovieEvent, setFetchedTorrents, newEpisodeEvent, stop]);
useEffect(() => {
const intervalID = setInterval(() => {
if (!ws) {
connect();
return;
}
if (ws.readyState === WebSocket.CLOSED) {
stop();
}
}, 10000);
if (!ws) {
connect();
}
return () => {
if (ws) {
stop();
}
clearInterval(intervalID);
};
}, [ws, connect, stop]);
return null;
};
WsHandler.propTypes = {
isLogged: PropTypes.bool.isRequired,
setFetchedTorrents: PropTypes.func,
newMovieEvent: PropTypes.func,
newEpisodeEvent: PropTypes.func
};
export default connect(mapStateToProps, mapDispatchToProps)(WsHandler);

View File

@ -104,8 +104,11 @@ const config = {
],
resolve: {
extensions: [".js"]
},
devtool: mode === "production" ? "source-map" : "inline-source-map"
}
};
if (process.env.NODE_ENV !== "production") {
config.devtool = "#cheap-module-source-map";
}
module.exports = config;