import { useEffect, useState } from "react"; 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 = props => { const [ws, setWs] = useState(null); 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); }; const connect = () => { if (ws) { return; } if (!props.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": props.setFetchedTorrents(data.message); break; case "newVideo": if (data.message.type === "movie") { props.newMovieEvent(data.message.data); } else if (data.message.type === "episode") { props.newEpisodeEvent(data.message.data); } break; } }; socket.onerror = () => { stop(); }; setWs(socket); }; return null; }; export default connect(mapStateToProps, mapDispatchToProps)(WsHandler);