mirror of
https://github.com/AndrioCelos/TableturfBattleApp.git
synced 2026-07-12 22:21:15 -05:00
Use history.pushState where possible
This commit is contained in:
parent
fe9d3c3d64
commit
e3fd48b45e
Binary file not shown.
|
|
@ -402,7 +402,7 @@ document.addEventListener('keydown', e => {
|
|||
|
||||
document.getElementById('resultLeaveButton')!.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
clearPreGameForm();
|
||||
clearPreGameForm(true);
|
||||
showSection('preGame');
|
||||
newGameButton.focus();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ maxPlayersBox.addEventListener('change', () => {
|
|||
let response = JSON.parse(request.responseText);
|
||||
if (!clientToken)
|
||||
setClientToken(response.clientToken);
|
||||
|
||||
setGameUrl(response.gameID);
|
||||
|
||||
getGameInfo(response.gameID, 0);
|
||||
}
|
||||
});
|
||||
|
|
@ -44,18 +47,34 @@ maxPlayersBox.addEventListener('change', () => {
|
|||
}
|
||||
});
|
||||
|
||||
function setGameUrl(gameID: string | null) {
|
||||
if (canPushState) {
|
||||
try {
|
||||
history.pushState(null, '', `game/${gameID}`);
|
||||
} catch {
|
||||
canPushState = false;
|
||||
location.hash = `#game/${gameID}`;
|
||||
}
|
||||
} else
|
||||
location.hash = `#game/${gameID}`;
|
||||
}
|
||||
|
||||
function tryJoinGame(name: string, idOrUrl: string, fromInitialLoad: boolean) {
|
||||
const gameID = idOrUrl.substring(idOrUrl.lastIndexOf('#') + 1);
|
||||
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(gameID)) {
|
||||
const m = /(?:^|[#/])([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i.exec(idOrUrl);
|
||||
if (!m) {
|
||||
alert("Invalid game ID or link");
|
||||
if (fromInitialLoad)
|
||||
clearPreGameForm();
|
||||
clearPreGameForm(true);
|
||||
else {
|
||||
gameIDBox.focus();
|
||||
gameIDBox.setSelectionRange(0, gameIDBox.value.length);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const gameID = m[1];
|
||||
|
||||
if (!fromInitialLoad)
|
||||
setGameUrl(gameID);
|
||||
|
||||
let request = new XMLHttpRequest();
|
||||
request.open('POST', `${config.apiBaseUrl}/games/${gameID}/join`);
|
||||
|
|
@ -73,7 +92,7 @@ function tryJoinGame(name: string, idOrUrl: string, fromInitialLoad: boolean) {
|
|||
else
|
||||
alert('Unable to join the room.');
|
||||
if (fromInitialLoad)
|
||||
clearPreGameForm();
|
||||
clearPreGameForm(true);
|
||||
else {
|
||||
gameIDBox.focus();
|
||||
gameIDBox.setSelectionRange(0, gameIDBox.value.length);
|
||||
|
|
@ -88,34 +107,63 @@ function tryJoinGame(name: string, idOrUrl: string, fromInitialLoad: boolean) {
|
|||
|
||||
function getGameInfo(gameID: string, myPlayerIndex: number | null) {
|
||||
board.playerIndex = myPlayerIndex;
|
||||
window.location.hash = `#${gameID}`;
|
||||
initLobbyPage(window.location.toString());
|
||||
|
||||
myPlayerIndex = setupWebSocket(gameID, myPlayerIndex);
|
||||
}
|
||||
|
||||
function backPreGameForm() {
|
||||
function backPreGameForm(updateUrl: boolean) {
|
||||
document.getElementById('preGameDefaultSection')!.hidden = false;
|
||||
document.getElementById('preGameJoinSection')!.hidden = true;
|
||||
window.location.hash = '';
|
||||
|
||||
if (updateUrl) {
|
||||
if (canPushState) {
|
||||
try {
|
||||
history.pushState(null, '', '../..');
|
||||
} catch {
|
||||
canPushState = false;
|
||||
}
|
||||
}
|
||||
if (location.hash)
|
||||
location.hash = '';
|
||||
}
|
||||
}
|
||||
function clearPreGameForm() {
|
||||
backPreGameForm();
|
||||
function clearPreGameForm(updateUrl: boolean) {
|
||||
backPreGameForm(updateUrl);
|
||||
currentGame = null;
|
||||
gameIDBox.value = '';
|
||||
}
|
||||
|
||||
document.getElementById('preGameBackButton')!.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
backPreGameForm();
|
||||
backPreGameForm(true);
|
||||
})
|
||||
|
||||
const playerName = window.localStorage.getItem('name');
|
||||
(document.getElementById('nameBox') as HTMLInputElement).value = playerName || '';
|
||||
if (window.location.hash != '') {
|
||||
function presetGameID(url: string) {
|
||||
document.getElementById('preGameDefaultSection')!.hidden = true;
|
||||
document.getElementById('preGameJoinSection')!.hidden = false;
|
||||
(document.getElementById('gameIDBox') as HTMLInputElement).value = window.location.hash;
|
||||
(document.getElementById('gameIDBox') as HTMLInputElement).value = url;
|
||||
if (playerName)
|
||||
tryJoinGame(playerName, window.location.hash, true);
|
||||
tryJoinGame(playerName, url, true);
|
||||
}
|
||||
|
||||
const playerName = localStorage.getItem('name');
|
||||
(document.getElementById('nameBox') as HTMLInputElement).value = playerName || '';
|
||||
|
||||
function processUrl() {
|
||||
const m = /^(.*)\/game\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/.exec(location.toString());
|
||||
if (m)
|
||||
presetGameID(m[2]);
|
||||
else if (location.hash) {
|
||||
canPushState = false;
|
||||
presetGameID(location.hash);
|
||||
} else {
|
||||
clearPreGameForm(false);
|
||||
showSection('preGame');
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', () => {
|
||||
processUrl();
|
||||
});
|
||||
processUrl();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
let canPushState = isSecureContext && location.protocol != 'file:';
|
||||
|
||||
function delay(ms: number) { return new Promise(resolve => setTimeout(() => resolve(null), ms)); }
|
||||
|
||||
// Sections
|
||||
|
|
@ -90,7 +92,7 @@ function setupWebSocket(gameID: string, myPlayerIndex: number | null) {
|
|||
const webSocket = new WebSocket(`${config.apiBaseUrl.replace(/(http)(s)?\:\/\//, 'ws$2://')}/websocket?gameID=${gameID}&clientToken=${clientToken}`);
|
||||
webSocket.addEventListener('open', e => {
|
||||
const request2 = new XMLHttpRequest();
|
||||
request2.open('GET', `${config.apiBaseUrl}/games/${gameID}/playerData/${clientToken}`);
|
||||
request2.open('GET', `${config.apiBaseUrl}/games/${gameID}/playerData?clientToken=${clientToken}`);
|
||||
request2.addEventListener('load', e => {
|
||||
if (request2.status == 200) {
|
||||
const response = JSON.parse(request2.responseText);
|
||||
|
|
@ -230,8 +232,6 @@ function setupWebSocket(gameID: string, myPlayerIndex: number | null) {
|
|||
return myPlayerIndex;
|
||||
}
|
||||
|
||||
showSection('preGame');
|
||||
|
||||
function isInternetExplorer() {
|
||||
return !!(window.document as any).documentMode; // This is a non-standard property implemented only by Internet Explorer.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ using Timer = System.Timers.Timer;
|
|||
namespace TableturfBattleServer;
|
||||
|
||||
internal class Program {
|
||||
internal static HttpServer httpServer = new(IPAddress.Loopback, 3333);
|
||||
internal static HttpServer httpServer = new(IPAddress.Loopback, 3333) { DocumentRootPath = Path.Combine("..", "..", "..", "..", "TableturfBattleClient") };
|
||||
internal static Dictionary<Guid, Game> games = new();
|
||||
internal static readonly Timer timer = new(500);
|
||||
private static readonly List<Guid> gameIdsToRemove = new();
|
||||
|
|
@ -45,7 +45,22 @@ internal class Program {
|
|||
|
||||
private static void HttpServer_OnRequest(object? sender, HttpRequestEventArgs e) {
|
||||
e.Response.AppendHeader("Access-Control-Allow-Origin", "*");
|
||||
if (e.Request.RawUrl == "/api/games/new") {
|
||||
if (!e.Request.RawUrl.StartsWith("/api/")) {
|
||||
var path = e.Request.RawUrl == "/" || e.Request.RawUrl.StartsWith("/game/") ? "index.html" : e.Request.RawUrl[1..];
|
||||
if (e.TryReadFile(path, out var bytes))
|
||||
SetResponse(e.Response, 200,
|
||||
Path.GetExtension(path) switch {
|
||||
".html" or ".htm" => "text/html",
|
||||
".css" => "text/css",
|
||||
".js" => "text/javascript",
|
||||
".png" => "image/png",
|
||||
".woff" or ".woff2" => "font/woff",
|
||||
_ => "application/octet-stream"
|
||||
}, bytes);
|
||||
else
|
||||
SetErrorResponse(e.Response, 404, new("FileNotFound", "File not found."));
|
||||
return;
|
||||
} else if (e.Request.RawUrl == "/api/games/new") {
|
||||
if (e.Request.HttpMethod != "POST") {
|
||||
e.Response.StatusCode = (int) HttpStatusCode.MethodNotAllowed;
|
||||
e.Response.AddHeader("Allow", "POST");
|
||||
|
|
@ -87,7 +102,7 @@ internal class Program {
|
|||
} else if (e.Request.RawUrl == "/api/stages") {
|
||||
SetStaticResponse(e.Request, e.Response, StageDatabase.JSON, StageDatabase.Version.ToString(), StageDatabase.LastModified);
|
||||
} else {
|
||||
var m = Regex.Match(e.Request.RawUrl, @"^/api/games/([\w-]+)(?:/(\w+)(?:/([\w-]+))?)?$", RegexOptions.Compiled);
|
||||
var m = Regex.Match(e.Request.RawUrl, @"^/api/games/([\w-]+)(?:/(\w+)(?:\?clientToken=([\w-]+))?)?$", RegexOptions.Compiled);
|
||||
if (m.Success) {
|
||||
if (!Guid.TryParse(m.Groups[1].Value, out var gameID)) {
|
||||
SetResponse(e.Response, 400, "text/plain", "Invalid game ID");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user