1
0

Routing works between webpack and app, game loading works, new game creation works

Signed-off-by: James Ketrenos <james.p.ketrenos@intel.com>
This commit is contained in:
James Ketrenos 2020-04-22 09:57:28 -07:00
parent 15b2c67fa6
commit 41e7ef9aa0
11 changed files with 85 additions and 28 deletions

View File

@ -5,6 +5,7 @@
name="viewport" name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width" content="minimum-scale=1, initial-scale=1, width=device-width"
/> />
<script>'<base href="BASEPATH">';</script>
<link rel="icon" href="../assets/favicon-32.png" sizes="32x32"> <link rel="icon" href="../assets/favicon-32.png" sizes="32x32">
<link rel="icon" href="../assets/favicon-57.png" sizes="57x57"> <link rel="icon" href="../assets/favicon-57.png" sizes="57x57">
<link rel="icon" href="../assets/favicon-76.png" sizes="76x76"> <link rel="icon" href="../assets/favicon-76.png" sizes="76x76">

View File

@ -10,19 +10,14 @@ const express = require("express"),
config = require("config"), config = require("config"),
session = require('express-session'), session = require('express-session'),
hb = require("handlebars"), hb = require("handlebars"),
SQLiteStore = require('connect-sqlite3')(session); SQLiteStore = require('connect-sqlite3')(session),
basePath = require("./basepath");
require("./console-line.js"); /* Monkey-patch console.log with line numbers */ require("./console-line.js"); /* Monkey-patch console.log with line numbers */
const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/", const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/",
serverConfig = config.get("server"); serverConfig = config.get("server");
let basePath = config.get("basePath");
basePath = "/" + basePath.replace(/^\/+/, "").replace(/\/+$/, "") + "/";
if (basePath == "//") {
basePath = "/";
}
console.log("Hosting server from: " + basePath); console.log("Hosting server from: " + basePath);
let userDB, gameDB; let userDB, gameDB;
@ -231,6 +226,8 @@ app.use(basePath, function(req, res, next) {
/* Allow loading of the app w/out being logged in */ /* Allow loading of the app w/out being logged in */
app.use(basePath, index); app.use(basePath, index);
/* /games loads the default index */
app.use(basePath + "games", index);
/* Allow access to the 'users' API w/out being logged in */ /* Allow access to the 'users' API w/out being logged in */
const users = require("./routes/users"); const users = require("./routes/users");

9
server/basepath.js Executable file
View File

@ -0,0 +1,9 @@
const config = require("config");
let basePath = config.get("basePath");
basePath = "/" + basePath.replace(/^\/+/, "").replace(/\/+$/, "") + "/";
if (basePath == "//") {
basePath = "/";
}
module.exports = basePath;

2
server/console-line.js Normal file → Executable file
View File

@ -15,7 +15,7 @@ if (process.env.LOG_LINE) {
} }
let err = getErrorObject(), let err = getErrorObject(),
caller_line = err.stack.split("\n")[4], caller_line = err.stack.split("\n")[3],
args = [caller_line.replace(cwdRe, "$1 -")]; args = [caller_line.replace(cwdRe, "$1 -")];
/* arguments.unshift() doesn't exist... */ /* arguments.unshift() doesn't exist... */

0
server/mail.js Normal file → Executable file
View File

View File

@ -100,7 +100,7 @@ for (let i = 0; i < 5; i++) {
const games = {}; const games = {};
router.get("/:id", (req, res/*, next*/) => { router.get("/:id", (req, res/*, next*/) => {
console.log("GET /" + req.params.id); console.log("GET games/" + req.params.id);
if (req.params.id in games) { if (req.params.id in games) {
return res.status(200).send(games[req.params.id]); return res.status(200).send(games[req.params.id]);
} else { } else {
@ -110,7 +110,7 @@ router.get("/:id", (req, res/*, next*/) => {
}); });
router.post("/", (req, res/*, next*/) => { router.post("/", (req, res/*, next*/) => {
console.log("POST /"); console.log("POST games/");
const game = { const game = {
startTime: Date.now(), startTime: Date.now(),
tiles: [], tiles: [],
@ -150,6 +150,7 @@ router.post("/", (req, res/*, next*/) => {
games[game.id] = game; games[game.id] = game;
console.log(`New game created: ${game.id}`);
return res.status(200).send(game); return res.status(200).send(game);
}); });

View File

@ -3,7 +3,8 @@
const express = require("express"), const express = require("express"),
fs = require("fs"), fs = require("fs"),
url = require("url"), url = require("url"),
config = require("config"); config = require("config"),
basePath = require("../basepath");
const router = express.Router(); const router = express.Router();
@ -31,24 +32,24 @@ const extensionMatch = new RegExp("^.*?(" + extensions.join("|") + ")$", "i");
* dynamic client side route and *then* return index.html. * dynamic client side route and *then* return index.html.
*/ */
router.get("/*", function(req, res, next) { router.get("/*", function(req, res, next) {
const parts = url.parse(req.url), const parts = url.parse(req.url);
basePath = req.app.get("basePath");
/* If req.user isn't set yet (authentication hasn't happened) then /* If req.user isn't set yet (authentication hasn't happened) then
* only allow / to be loaded--everything else chains to the next * only allow / to be loaded--everything else chains to the next
* handler */ * handler */
if (!req.user && req.url != "/") { if (!req.user &&
req.url != "/" &&
req.url.indexOf("/games") != 0) {
return next(); return next();
} }
if (req.url == "/" || !extensionMatch.exec(parts.pathname)) { if (req.url == "/" || req.url.indexOf("/games") == 0 || !extensionMatch.exec(parts.pathname)) {
console.log("Returning index for " + req.url); console.log("Returning index for " + req.url);
/* Replace <script>'<base href="/BASEPATH/">';</script> in index.html with /* Replace <script>'<base href="BASEPATH">';</script> in index.html with
* the basePath */ * the basePath */
const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/", const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/",
index = fs.readFileSync(frontendPath + "/index.html", "utf8"); index = fs.readFileSync(frontendPath + "index.html", "utf8");
res.send(index.replace( res.send(index.replace(
/<script>'<base href="BASEPATH">';<\/script>/, /<script>'<base href="BASEPATH">';<\/script>/,
"<base href='" + basePath + "'>")); "<base href='" + basePath + "'>"));

View File

@ -11,13 +11,20 @@ import AppBar from '@material-ui/core/AppBar';
import Box from '@material-ui/core/Box'; import Box from '@material-ui/core/Box';
import Toolbar from '@material-ui/core/Toolbar'; import Toolbar from '@material-ui/core/Toolbar';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { Router, Route } from "react-router-dom";
//import 'typeface-roboto'; //import 'typeface-roboto';
import history from "./history.js";
import Board from "./Board.js"; import Board from "./Board.js";
import "./App.css"; import "./App.css";
function App() { function App() {
let base = document.querySelector("base") ? document.querySelector("base").href : "";
if (base) {
base = new URL(base).pathname;
}
console.log(`Base: ${base}`);
return ( return (
<React.Fragment> <React.Fragment>
<AppBar position="fixed"> <AppBar position="fixed">
@ -25,7 +32,10 @@ function App() {
<Button color="inherit">Login</Button> <Button color="inherit">Login</Button>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
<Board/> <Router history={history}>
<Route exact path={base + 'games/:id?'} component={Board}/>
<Route exact path={base} component={Board}/>
</Router>
</React.Fragment> </React.Fragment>
); );
} }

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import "./Board.css"; import "./Board.css";
import history from "./history.js";
const hexagonRatio = 1.1547005, const hexagonRatio = 1.1547005,
tileHeight = 0.16, tileHeight = 0.16,
@ -195,8 +196,20 @@ class Board extends React.Component {
this.mouse = { x: 0, y: 0 }; this.mouse = { x: 0, y: 0 };
this.radius = 0.317; this.radius = 0.317;
window.fetch("api/v1/games", { const params = {}
method: 'POST',
if (props.match.params.id) {
console.log(`Loading game: ${props.match.params.id}`);
params.url = `api/v1/games/${props.match.params.id}`;
params.method = "GET"
} else {
console.log("Requesting new game.");
params.url = "api/v1/games";
params.method = "POST";
}
window.fetch(params.url, {
method: params.method,
cache: 'no-cache', cache: 'no-cache',
credentials: 'same-origin', credentials: 'same-origin',
headers: { headers: {
@ -204,9 +217,17 @@ class Board extends React.Component {
}, },
// body: JSON.stringify(data) // body data type must match "Content-Type" header // body: JSON.stringify(data) // body data type must match "Content-Type" header
}).then((res) => { }).then((res) => {
if (res.status > 400) {
throw `Unable to load game ${props.match.params.id}`;
}
return res.json(); return res.json();
}).then((game) => { }).then((game) => {
console.log(JSON.stringify(game, null, 2)); console.log (`Game ${game.id} loaded.`);
if (!props.match.params.id) {
history.push(`games/${game.id}`);
}
this.game = game; this.game = game;
this.pips = Pips(this); this.pips = Pips(this);
this.tiles = Tiles(this); this.tiles = Tiles(this);
@ -225,6 +246,7 @@ class Board extends React.Component {
}); });
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
alert(error);
}); });
} }
@ -395,7 +417,7 @@ class Board extends React.Component {
} }
drawFrame() { drawFrame() {
if (!this.canvas) { if (!this.canvas || !this.table) {
return; return;
} }

11
src/history.js Executable file
View File

@ -0,0 +1,11 @@
import { createBrowserHistory } from 'history';
// Run our app under the /base URL.
const history = createBrowserHistory(),
push = history.push;
history.push = (path) => {
const base = new URL(document.querySelector("base") ? document.querySelector("base").href : "");
push(base.pathname + path);
};
export default history;

15
webpack.dev.js Normal file → Executable file
View File

@ -9,18 +9,23 @@ const proxy = {
// "/photos/api/*": "http://localhost:8123/", // "/photos/api/*": "http://localhost:8123/",
} }
console.log(`Using base: ${base}`);
proxy[`${base}/`] = { proxy[`${base}/`] = {
target: "http://localhost:8911", target: "http://localhost:8911",
bypass: function(req, res, proxyOptions) { bypass: function(req, res, proxyOptions) {
console.log(req.url); console.log(`Proxy test: ${req.url}`);
if (req.url.match(new RegExp(base.replace(/\//g, "\\/") + "\/identities[/?]?"))) { if ((req.url.indexOf(`${base}/assets`) == 0) ||
return 'index.html'; (req.url.indexOf(`${base}/dist`) == 0)) {
} else { return req.url.replace(base, "");
return null;
} }
console.log(`Proxying to backend server: ${req.url}`);
return null;
} }
}; };
/* https://webpack.js.org/configuration/dev-server/ */
module.exports = merge(common, { module.exports = merge(common, {
mode: "development", mode: "development",
devServer: { devServer: {