From 237e4d43229847bb69aadcfa6e6aca517128913b Mon Sep 17 00:00:00 2001 From: TrueKuehli Date: Mon, 1 Oct 2018 14:15:05 +0200 Subject: Documented the code better and made some minor fixes --- WebInterface/NodeJSServer/src/index.js | 6 +- WebInterface/NodeJSServer/src/modules/hash.js | 5 +- .../NodeJSServer/src/modules/server-client.js | 82 +++++++++++++++------- .../NodeJSServer/src/modules/ui/backdrop.js | 19 ++++- .../NodeJSServer/src/modules/ui/login-modal.js | 27 +++++-- WebInterface/NodeJSServer/src/modules/ui/modal.js | 21 +++++- .../src/modules/ui/notification-banner.js | 42 +++++++---- .../NodeJSServer/src/modules/ui/server-listing.js | 14 ++++ 8 files changed, 165 insertions(+), 51 deletions(-) (limited to 'WebInterface') diff --git a/WebInterface/NodeJSServer/src/index.js b/WebInterface/NodeJSServer/src/index.js index a37ae5f..3ca0e39 100644 --- a/WebInterface/NodeJSServer/src/index.js +++ b/WebInterface/NodeJSServer/src/index.js @@ -1,7 +1,7 @@ import Backdrop from './modules/ui/backdrop.js'; import BannerController from './modules/ui/notification-banner.js'; -import ServerClient from './modules/server-client.js' -import LoginModal from './modules/ui/login-modal.js'; // TODO: JUST FOR DEBUGGING +import ServerClient from './modules/server-client.js'; +import LoginModal from './modules/ui/login-modal.js'; // TODO: JUST DEBUG let backdrop = new Backdrop('menu', 'front-layer', 'show-menu'); backdrop.register(); @@ -16,4 +16,4 @@ document.getElementById('refresh-button') new LoginModal('The Crew', client); -window.client = client; //TODO: REMOVE, JUST FOR DEBUGGING +window.client = client; // TODO: REMOVE, JUST FOR DEBUGGING diff --git a/WebInterface/NodeJSServer/src/modules/hash.js b/WebInterface/NodeJSServer/src/modules/hash.js index 826c8ee..3abcc21 100644 --- a/WebInterface/NodeJSServer/src/modules/hash.js +++ b/WebInterface/NodeJSServer/src/modules/hash.js @@ -1,3 +1,6 @@ +/** + * Creates Base64 String with SHA-256 Hash of given string + */ String.prototype.getHash = async function() { let data = new ArrayBuffer(this.length * 2); let bufferView = new Uint16Array(data); @@ -14,4 +17,4 @@ String.prototype.getHash = async function() { } return btoa(base64String); -} +}; diff --git a/WebInterface/NodeJSServer/src/modules/server-client.js b/WebInterface/NodeJSServer/src/modules/server-client.js index 0a257ba..ea37e1e 100644 --- a/WebInterface/NodeJSServer/src/modules/server-client.js +++ b/WebInterface/NodeJSServer/src/modules/server-client.js @@ -1,10 +1,20 @@ import * as signalR from '@aspnet/signalr'; import ServerListing from './ui/server-listing.js'; +/** + * Class for communication to server + */ export default class ServerClient { + /** + * Creates new connection + * @param {string} url URL of server running signalR + * @param {string} serverListingId HTML ID of server-listing element, + * to populate with available games + * @param {boolean} [debug=false] Enable debug output? + */ constructor(url, serverListingId, debug = false) { const connectionBuilder = new signalR.HubConnectionBuilder() - .withUrl(url) + .withUrl(url); if (debug) { connectionBuilder.configureLogging(signalR.LogLevel.Debug); @@ -14,20 +24,25 @@ export default class ServerClient { this.connection = connectionBuilder.build(); this.connection.start() - .then(() => this.loadServers()) - .catch(() => err => console.error(err.toString())); + .then(() => this.loadServers()) // Load games list, once connected + .catch((err) => console.error(err.toString())); + // Initialize refreshing (blocks new refreshes if true) this.refreshing = false; this.serverListing = new ServerListing(serverListingId); - this.messageHandling(); //TODO: REMOVE, JUST FOR DEBUGGING + this.messageHandling(); } + /** + * Requests list of avalable games on the server + */ loadServers() { - if (this.refreshing) return; + if (this.refreshing) return; // If already refreshing, no new request + this.connection.on('ListGroups', (groups) => { - console.log(groups) + // Populate server listing this.serverListing.flushElements(); this.serverListing.addElements(groups); this.connection.off('ListGroups'); @@ -36,39 +51,54 @@ export default class ServerClient { }); this.connection.invoke('GetGroups') - .catch(err => { + .catch((err) => { this.refreshing = false; - console.error(err.toString()) + console.error(err.toString()); }); this.refreshing = true; } - createServer(){ + /** + * Sends a game creating request to the server + * @param {string} name Name of the new game + * @param {string} password Password + */ + createServer(name, password) { // TODO: Create } - sendLogin(group, password, username){ + /** + * Sends a login request + * @param {string} group Group name to join + * @param {string} password Password to send as SHA-256 Base64 String + * @param {string} username Display name to use + * @param {ServerClient~loginCallback} callback Callback function to use + */ + sendLogin(group, password, username, callback) { + this.connection.on('LoginResponse', (result) => { + callback(result); + this.connection.off('LoginResponse'); + }); this.connection.invoke('Login', group, username, password); } - messageHandling(){ + /** + * Registers message handling + */ + messageHandling() { this.connection.on('ReceiveMessage', (user, message) => { - let msg = message.replace(/&/g, "&") - .replace(//g, ">"); - let encodedMsg = user + " sagt: " + msg; - console.log(encodedMsg); //TODO: REMOVE, JUST FOR DEBUGGING + let msg = message.replace(/&/g, '&') + .replace(//g, '>'); + let encodedMsg = user + ' sagt: ' + msg; + console.log(encodedMsg); // TODO: REMOVE, JUST FOR DEBUGGING }); } } - - -// connection.on('ReceiveMessage', (user, message) => { -// let msg = message.replace(/&/g, "&").replace(//g, ">"); -// let encodedMsg = user + " says " + msg; -// let li = document.createElement("div"); -// li.classList.add('server'); -// li.textContent = encodedMsg; -// document.getElementById('server-list').appendChild(li); -// }); +/** + * Callback to call with response to login request + * @callback ServerClient~loginCallback + * @param {number} result 0: Success, 1: PasswordError, 2:UsernameTaken + * , 3:Unknown Error + */ diff --git a/WebInterface/NodeJSServer/src/modules/ui/backdrop.js b/WebInterface/NodeJSServer/src/modules/ui/backdrop.js index 243bbb3..1a24bd2 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/backdrop.js +++ b/WebInterface/NodeJSServer/src/modules/ui/backdrop.js @@ -1,18 +1,32 @@ // Showing / Hiding the backdrop menu +/** + * Class for adding functionality to backdrop elements + */ export default class Backdrop { + /** + * Registers all important elements in the backdrop + * @param {string} backdropMenu ID of Backdrop Menu + * @param {string} frontLayer ID of Front Layer + * @param {string} menuButton ID of Show / Hide Menu Button + */ constructor(backdropMenu, frontLayer, menuButton) { this.backdrop = document.getElementById(backdropMenu); this.frontLayer = document.getElementById(frontLayer); this.menuButton = document.getElementById(menuButton); } - + /** + * Registers all neccessary events + */ register() { this.registerButtonEvent(); this.registerFrontLayerEvent(); } + /** + * Registers showing / hiding through menu button + */ registerButtonEvent() { this.menuButton.addEventListener('click', () => { // Hide / Unhide Backdrop Menu @@ -31,6 +45,9 @@ export default class Backdrop { }); } + /** + * Registers hiding, when clicking on the front layer + */ registerFrontLayerEvent() { // Hide menu when interacting with front layer this.frontLayer.addEventListener('click', () => { diff --git a/WebInterface/NodeJSServer/src/modules/ui/login-modal.js b/WebInterface/NodeJSServer/src/modules/ui/login-modal.js index cb1f2ac..4c7b872 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/login-modal.js +++ b/WebInterface/NodeJSServer/src/modules/ui/login-modal.js @@ -1,7 +1,17 @@ import Modal from './modal.js'; import '../hash.js'; +/** + * Class to implement a login modal from the parent modal class + */ export default class LoginModal extends Modal { + /** + * Creates necessary elements for login modal + * @param {string} serverName Name of the server, used for login and displayed + * in title + * @param {ServerClient} serverClient Server client object used to send the + * login + */ constructor(serverName, serverClient) { super(serverName); this.serverName = serverName; @@ -15,7 +25,7 @@ export default class LoginModal extends Modal { let passwordInput = document.createElement('input'); passwordLabel.setAttribute('for', 'password-input'); passwordLabel.textContent = 'Passwort:'; - passwordLabel.title = 'Das Passwort des Spiels' + passwordLabel.title = 'Das Passwort des Spiels'; passwordInput.id = 'password-input'; passwordInput.type = 'password'; passwordInput.placeholder = 'Passwort'; @@ -24,7 +34,7 @@ export default class LoginModal extends Modal { let nameInput = document.createElement('input'); nameLabel.setAttribute('for', 'name-input'); nameLabel.textContent = 'Benutzername:'; - nameLabel.title = 'Dein Anzeigename' + nameLabel.title = 'Dein Anzeigename'; nameInput.id = 'name-input'; nameInput.type = 'text'; nameInput.autocomplete = 'on'; @@ -53,15 +63,22 @@ export default class LoginModal extends Modal { this.registerLoginBtn(); } + /** + * Registers event to send login, on button press + */ registerLoginBtn() { - this.loginButton.addEventListener('click', () => { - console.log('button pressed') + let eventListener = () => { + this.loginButton.removeEventListener('click', eventListener); let userName = this.nameInput.value; this.passwordInput.value.getHash() .then((result) => { this.serverClient.sendLogin(this.serverName, result, userName); + + // TODO: Wait for response, if error keep window intact, + // and reenable event listener this.close(); }); - }); + }; + this.loginButton.addEventListener('click', eventListener); } } diff --git a/WebInterface/NodeJSServer/src/modules/ui/modal.js b/WebInterface/NodeJSServer/src/modules/ui/modal.js index 55e38bd..10a1be5 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/modal.js +++ b/WebInterface/NodeJSServer/src/modules/ui/modal.js @@ -1,4 +1,12 @@ +/** + * Parent class to create Modals on the screen + * Contains no content, as that is implemented by child classes + */ export default class Modal { + /** + * Creates a new modal with a title and empty content + * @param {string} titleString Title to show at the top of the modal + */ constructor(titleString) { let modalBackground = document.createElement('div'); let modal = document.createElement('div'); @@ -8,7 +16,7 @@ export default class Modal { modalBackground.className = 'modal-container'; modal.className = 'modal'; title.className = 'modal-title'; - body.className = 'modal-body' + body.className = 'modal-body'; title.textContent = titleString; @@ -25,6 +33,10 @@ export default class Modal { this.registerEvents(); } + /** + * Register event to close if clicked outside of modal + * Clicking on the modal itself should not close it though + */ registerEvents() { this.modal.addEventListener('click', (e) => { e.stopPropagation(); @@ -35,6 +47,9 @@ export default class Modal { }); } + /** + * Fades modal out and removes it from the flow of the document + */ close() { this.bg.classList.add('hidden'); this.bg.addEventListener('transitionend', () => { @@ -42,6 +57,10 @@ export default class Modal { }); } + /** + * Puts text in the body + * @param {string} text Text to put into the body + */ setBodyText(text) { this.body.textContent = text; } diff --git a/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js b/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js index d14845e..395db94 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js +++ b/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js @@ -1,4 +1,13 @@ +/** + * Class for controlling the Notification banner + */ export default class BannerController { + /** + * Creates references to objects and hides notification banner + * @param {string} bannerId ID of Notification Banner + * @param {string} textP ID of Notification Banner text field + * @param {string} dismissBtn ID of dismiss button + */ constructor(bannerId, textP, dismissBtn) { this.banner = document.getElementById(bannerId); this.bannerText = document.getElementById(textP); @@ -9,12 +18,20 @@ export default class BannerController { this.banner.classList.add('hidden'); } + /** + * Registers dismissing via the dismiss button + */ register() { this.dismissBtn.addEventListener('click', () => { this.dismissCurrent(); }); } + /** + * Pushes a new message to the notification banner and shows it + * @param {string} name Name to register notification (referenced in hide) + * @param {string} text Notification text + */ show(name, text) { let bannerItem = {name, text, 'html': false}; this.bannerMsgs.push(bannerItem); @@ -22,6 +39,10 @@ export default class BannerController { this.update(); } + /** + * Removes notification from banner + * @param {string} name Name, that the notification was registered under + */ hide(name) { if (!name) { this.bannerMsgs = []; @@ -37,11 +58,18 @@ export default class BannerController { } } + /** + * Dismisses the currently shown message + */ dismissCurrent() { this.hide(this.current); } + /** + * Updates the notification banner with the most recent message + */ update() { + // TODO: Show if multiple messages are there if (this.bannerMsgs.length === 0) { this.banner.classList.add('hidden'); return; @@ -58,18 +86,4 @@ export default class BannerController { this.current = name; } - - showPersistence() { - let text = `Storage persistence is disabled, so in-browser storage of created Wikis might not work.\n` + - `Click here to enable storage persistence.`; - let bannerItem = {'name': 'persistence', text, 'html': true}; - this.bannerMsgs.push(bannerItem); - this.update(); - } } diff --git a/WebInterface/NodeJSServer/src/modules/ui/server-listing.js b/WebInterface/NodeJSServer/src/modules/ui/server-listing.js index 2c501fd..0069ac6 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/server-listing.js +++ b/WebInterface/NodeJSServer/src/modules/ui/server-listing.js @@ -1,12 +1,26 @@ +/** + * Class for handling the server list + */ export default class ServerListing { + /** + * Creates reference to container + * @param {string} serverListId ID of the server list div + */ constructor(serverListId) { this.serverListing = document.getElementById(serverListId); } + /** + * Removes all elements currently in the server listing + */ flushElements() { this.serverListing.innerHTML = ''; } + /** + * Populates servers from a given array of games + * @param {array} array Array of available games + */ addElements(array) { for (let server of array) { const name = server['name']; -- cgit v1.2.3-54-g00ecf