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:
parent
15b2c67fa6
commit
41e7ef9aa0
@ -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">
|
||||||
|
@ -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
9
server/basepath.js
Executable 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
2
server/console-line.js
Normal file → Executable 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
0
server/mail.js
Normal file → Executable 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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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 + "'>"));
|
||||||
|
12
src/App.js
12
src/App.js
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
30
src/Board.js
30
src/Board.js
@ -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
11
src/history.js
Executable 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
15
webpack.dev.js
Normal file → Executable 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, "");
|
||||||
|
}
|
||||||
|
console.log(`Proxying to backend server: ${req.url}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* https://webpack.js.org/configuration/dev-server/ */
|
||||||
|
|
||||||
module.exports = merge(common, {
|
module.exports = merge(common, {
|
||||||
mode: "development",
|
mode: "development",
|
||||||
devServer: {
|
devServer: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user