canape/frontend/js/components/websocket.js
Grégoire Delattre bcadc48d5a Launch prettier with the --fix option
They've changed their default settings, this changes a lot of stuff in
our code base.
2020-04-01 17:55:34 +02:00

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);