diff --git a/client/src/App.css b/client/src/App.css index 22150fb..97c6b52 100755 --- a/client/src/App.css +++ b/client/src/App.css @@ -15,10 +15,26 @@ body { width: 100%; bottom: 0; flex-direction: row; - justify-content: space-between; /* left-justify 'board', right-justify 'game' */ background-image: url("./assets/tabletop.png"); } +.Table .ErrorDialog { + display: flex; + justify-content: space-around; + align-items: center; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-color: #00000060; +} + +.Table .ErrorDialog .Error { + display: flex; + padding: 1rem; +} + .Table .Game { display: flex; flex-direction: column; @@ -34,8 +50,6 @@ body { .Table .Hand { display: flex; position: relative; - border: 1px solid orange; - margin: 1rem; height: 11rem; } @@ -51,8 +65,6 @@ body { .Table .Board { display: flex; flex-grow: 1; - margin: 1rem; - border: 1px solid purple; } .Table .Sidebar .Chat { diff --git a/client/src/App.js b/client/src/App.js index b20a8d5..7973bc6 100755 --- a/client/src/App.js +++ b/client/src/App.js @@ -7,8 +7,8 @@ import { Routes, useParams } from "react-router-dom"; -import { base, gamesPath } from './Common.js'; -import history from "./history.js"; + +import Paper from '@material-ui/core/Paper'; import { GlobalContext } from "./GlobalContext.js"; import { PingPong } from "./PingPong.js"; @@ -17,7 +17,8 @@ import { Chat } from "./Chat.js"; import { MediaAgent } from "./MediaControl.js"; import { Board } from "./Board.js"; import { Actions } from "./Actions.js"; - +import { base, gamesPath, debounce } from './Common.js'; +import history from "./history.js"; import "./App.css"; const Table = () => { @@ -29,6 +30,7 @@ const Table = () => { const [ error, setError ] = useState(undefined); const [ peers, setPeers ] = useState({}); const [loaded, setLoaded] = useState(false); + const [connecting, setConnecting] = useState(false); useEffect(() => { console.log(peers); @@ -41,7 +43,8 @@ const Table = () => { /* We do not set the socket as bound until the 'open' message * comes through */ setWs(event.target); - + setConnecting(false); + /* Request a game-update */ event.target.send(JSON.stringify({ type: 'get', @@ -75,18 +78,32 @@ const Table = () => { } }; + const resetConnection = (function () { + let timer = 0; + function reset() { + timer = 0; + setConnecting(false); + }; + return _ => { + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(reset, 5000); + }; + })(); + const onWsError = (event) => { console.log(`ws: error`, event); const error = `Connection to Ketr Ketran game server failed! ` + - `Try refreshing in a few seconds.`; + `Connection attempt will be retried every 5 seconds.`; console.error(error); + resetConnection(); setError(error); }; const onWsClose = (event) => { console.log(`ws: close`); - setWs(undefined); - global.ws = undefined; + resetConnection(); }; /* callback refs are used to provide correct state reference @@ -125,8 +142,8 @@ const Table = () => { }, }).then((res) => { if (res.status >= 400) { - const error = `Unable to connect to Ketr Ketran game server!` + - `Try refreshing in a few seconds.`; + const error = `Unable to connect to Ketr Ketran game server! ` + + `Try refreshing your browser in a few seconds.`; console.error(error); setError(error); throw error; @@ -163,6 +180,7 @@ const Table = () => { new_uri = `${new_uri}://${loc.host}${base}/api/v1/games/ws/${gameId}`; console.log(`Attempting WebSocket connection to ${new_uri}`); socket = new WebSocket(new_uri); + setConnecting(true); } console.log('table - bind'); @@ -185,11 +203,7 @@ const Table = () => { socket.removeEventListener('message', cbMessage); } } - }, [ setWs, gameId, ws, refWsOpen, refWsMessage, refWsClose, refWsError ]); - - if (error) { - return