canape/frontend/js/components/websocket.js
Grégoire Delattre 4b26080193
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Update redux state management
Use immer with native javascript objects instead of immutablejs.
2020-04-07 18:22:26 +02:00

110 lines
2.2 KiB
JavaScript

import { useEffect, useState, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setFetchedTorrents } from "../actions/torrents";
import { newMovieEvent } from "../actions/movies";
import { newEpisodeEvent } from "../actions/shows";
export const WsHandler = () => {
const dispatch = useDispatch();
const isLogged = useSelector((state) => state.user.isLogged);
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":
dispatch(setFetchedTorrents(data.message));
break;
case "newVideo":
if (data.message.type === "movie") {
dispatch(newMovieEvent(data.message.data));
} else if (data.message.type === "episode") {
dispatch(newEpisodeEvent(data.message.data));
}
break;
}
};
socket.onerror = () => {
stop();
};
setWs(socket);
}, [ws, isLogged, dispatch, 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;
};