129 lines
2.6 KiB
JavaScript
129 lines
2.6 KiB
JavaScript
import { useEffect, useState, useCallback } from "react";
|
|
import PropTypes from "prop-types";
|
|
import { connect } from "react-redux";
|
|
import { setFetchedTorrents } from "../actions/torrents";
|
|
import { newMovieEvent } from "../actions/movies";
|
|
import { newEpisodeEvent } from "../actions/shows";
|
|
|
|
const mapStateToProps = state => ({
|
|
isLogged: state.userStore.get("isLogged")
|
|
});
|
|
const mapDispatchToProps = {
|
|
setFetchedTorrents,
|
|
newMovieEvent,
|
|
newEpisodeEvent
|
|
};
|
|
|
|
const WsHandler = ({
|
|
isLogged,
|
|
setFetchedTorrents,
|
|
newMovieEvent,
|
|
newEpisodeEvent
|
|
}) => {
|
|
const [ws, setWs] = useState(null);
|
|
|
|
const stop = useCallback(() => {
|
|
if (!ws) {
|
|
return;
|
|
}
|
|
ws.close();
|
|
setWs(null);
|
|
}, [ws]);
|
|
|
|
const connect = useCallback(() => {
|
|
if (ws) {
|
|
return;
|
|
}
|
|
|
|
if (!isLogged) {
|
|
stop();
|
|
}
|
|
|
|
const type = location.protocol === "https:" ? "wss" : "ws";
|
|
const socket = new WebSocket(type + ":" + location.host + "/events");
|
|
socket.onopen = () => {
|
|
socket.send(
|
|
JSON.stringify({
|
|
type: "subscribe",
|
|
message: "torrents"
|
|
})
|
|
);
|
|
socket.send(
|
|
JSON.stringify({
|
|
type: "subscribe",
|
|
message: "newVideo"
|
|
})
|
|
);
|
|
};
|
|
|
|
socket.onmessage = event => {
|
|
if (!event.data) {
|
|
return;
|
|
}
|
|
|
|
const data = JSON.parse(event.data);
|
|
if (!data.type) {
|
|
return;
|
|
}
|
|
|
|
if (data.status !== "ok") {
|
|
// TODO: handle this somehow
|
|
return;
|
|
}
|
|
|
|
switch (data.type) {
|
|
case "torrents":
|
|
setFetchedTorrents(data.message);
|
|
break;
|
|
case "newVideo":
|
|
if (data.message.type === "movie") {
|
|
newMovieEvent(data.message.data);
|
|
} else if (data.message.type === "episode") {
|
|
newEpisodeEvent(data.message.data);
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
|
|
socket.onerror = () => {
|
|
stop();
|
|
};
|
|
|
|
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);
|