diff options
Diffstat (limited to 'WebInterface/NodeJSServer/src/modules/ui')
4 files changed, 155 insertions, 16 deletions
diff --git a/WebInterface/NodeJSServer/src/modules/ui/backdrop.js b/WebInterface/NodeJSServer/src/modules/ui/backdrop.js index 1a24bd2..f89a3c9 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/backdrop.js +++ b/WebInterface/NodeJSServer/src/modules/ui/backdrop.js @@ -11,6 +11,7 @@ export default class Backdrop { * @param {string} menuButton ID of Show / Hide Menu Button */ constructor(backdropMenu, frontLayer, menuButton) { + this.ids = {backdropMenu, frontLayer, menuButton}; this.backdrop = document.getElementById(backdropMenu); this.frontLayer = document.getElementById(frontLayer); this.menuButton = document.getElementById(menuButton); @@ -25,6 +26,16 @@ export default class Backdrop { } /** + * Reloads the object + */ + refresh() { + this.backdrop = document.getElementById(this.ids.backdropMenu); + this.frontLayer = document.getElementById(this.ids.frontLayer); + this.menuButton = document.getElementById(this.ids.menuButton); + this.register(); + } + + /** * Registers showing / hiding through menu button */ registerButtonEvent() { diff --git a/WebInterface/NodeJSServer/src/modules/ui/login-modal.js b/WebInterface/NodeJSServer/src/modules/ui/login-modal.js index 4c7b872..0bfd70d 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/login-modal.js +++ b/WebInterface/NodeJSServer/src/modules/ui/login-modal.js @@ -11,11 +11,16 @@ export default class LoginModal extends Modal { * in title * @param {ServerClient} serverClient Server client object used to send the * login + * @param {BannerController} notificationManager Object controlling the main + * notification banners + * @param {array} ui UI elements to call refresh method on after login */ - constructor(serverName, serverClient) { + constructor(serverName, serverClient, notificationManager, ui) { super(serverName); this.serverName = serverName; this.serverClient = serverClient; + this.notificationManager = notificationManager; + this.pageUI = ui; let passBox = document.createElement('div'); let nameBox = document.createElement('div'); @@ -23,15 +28,20 @@ export default class LoginModal extends Modal { let passwordLabel = document.createElement('label'); let passwordInput = document.createElement('input'); + let passwordInvalid = document.createElement('span'); passwordLabel.setAttribute('for', 'password-input'); passwordLabel.textContent = 'Passwort:'; passwordLabel.title = 'Das Passwort des Spiels'; passwordInput.id = 'password-input'; passwordInput.type = 'password'; passwordInput.placeholder = 'Passwort'; + passwordInput.title = 'Das Passwort des Spiels'; + passwordInvalid.className = 'invalid hidden'; + passwordInvalid.textContent = 'Das eingegebene Passwort ist falsch.'; let nameLabel = document.createElement('label'); let nameInput = document.createElement('input'); + let nameInvalid = document.createElement('span'); nameLabel.setAttribute('for', 'name-input'); nameLabel.textContent = 'Benutzername:'; nameLabel.title = 'Dein Anzeigename'; @@ -39,17 +49,22 @@ export default class LoginModal extends Modal { nameInput.type = 'text'; nameInput.autocomplete = 'on'; nameInput.placeholder = 'Name'; + nameInput.title = 'Dein Anzeigename'; + nameInvalid.className = 'invalid hidden'; + nameInvalid.textContent = + 'Der eingegebene Nutzername ist bereits vergeben.'; let sendButton = document.createElement('button'); sendButton.className = 'btn'; sendButton.textContent = 'Login'; sendButton.id = 'login-button'; - passBox.appendChild(passwordLabel); passBox.appendChild(passwordInput); + passBox.appendChild(passwordInvalid); nameBox.appendChild(nameLabel); nameBox.appendChild(nameInput); + nameBox.appendChild(nameInvalid); sendBox.appendChild(sendButton); this.body.appendChild(passBox); @@ -60,6 +75,9 @@ export default class LoginModal extends Modal { this.passwordInput = passwordInput; this.loginButton = sendButton; + this.passwordInvalid = passwordInvalid; + this.nameInvalid = nameInvalid; + this.registerLoginBtn(); } @@ -67,18 +85,92 @@ export default class LoginModal extends Modal { * Registers event to send login, on button press */ registerLoginBtn() { - let eventListener = () => { + let eventListener; + let loginCallBack = (result, connection) => { + console.log(result); + if (result == 0) { + this.redirectToPlay(connection); + this.close(); + } else if (result == 1) { + this.invalid('Name'); + this.loginButton.addEventListener('click', eventListener); + } else if (result == 2) { + this.invalid('Pass'); + this.loginButton.addEventListener('click', eventListener); + } else { + this.notificationManager.show('unknownLoginErr', + 'Ein unbekannter Fehler ist aufgetreten'); + this.close(); + } + }; + + eventListener = () => { + this.invalid(); // Remove 'invalid' messages this.loginButton.removeEventListener('click', eventListener); - let userName = this.nameInput.value; + this.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.serverClient.sendLogin(this.serverName, result, + this.userName, loginCallBack); }); }; this.loginButton.addEventListener('click', eventListener); } + + /** + * Displays text under invalid password / username + * @param {string} inv Which field to display under (Pass / Name) + * Blank inv will hide both + */ + invalid(inv) { + this.body.classList.remove('frst-warning'); + this.body.classList.remove('scnd-warning'); + + this.passwordInvalid.classList.add('hidden'); + this.nameInvalid.classList.add('hidden'); + + this.passwordInput.style.borderColor = 'none'; + this.nameInput.style.borderColor = 'none'; + + if (inv == 'Pass') { + this.body.classList.add('frst-warning'); + this.passwordInvalid.classList.remove('hidden'); + this.passwordInput.style.borderColor = '#ef5350'; + } else if (inv == 'Name') { + this.body.classList.add('scnd-warning'); + this.nameInvalid.classList.remove('hidden'); + this.nameInput.style.borderColor = '#ef5350'; + } + } + + /** + * Loads play site + * @param {HubConnection} connection Connection to the server + */ + redirectToPlay(connection) { + window.history.pushState('object or string', 'Game Page', + 'play#game=' + this.serverName); + fetch('play').then((response) => { + response.text().then((htmlString) => { + htmlString = htmlString.replace(/\.\.\//g, './'); + htmlString = htmlString.replace(/<script src=".*"><\/script>/, ''); + console.log(htmlString); + htmlString = htmlString.replace( + /<remove_if_redirected>((.)|\n)*?<\/remove_if_redirected>/g, ''); + document.open(); + document.write(htmlString); + document.close(); + + for (let ui of this.pageUI) { + ui.refresh(); + } + + import(/* webpackChunkName: "/playModule" */ '../playModule') + .then(({default: GameClient}) => { + let gameClient = new GameClient(this.userName, connection); + gameClient.registerChat('chat'); + }); + }); + }); + } } diff --git a/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js b/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js index 395db94..7e6b8cb 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js +++ b/WebInterface/NodeJSServer/src/modules/ui/notification-banner.js @@ -7,11 +7,14 @@ export default class BannerController { * @param {string} bannerId ID of Notification Banner * @param {string} textP ID of Notification Banner text field * @param {string} dismissBtn ID of dismiss button + * @param {string} notificationBadge ID of badge (# of notifications) */ - constructor(bannerId, textP, dismissBtn) { + constructor(bannerId, textP, dismissBtn, notificationBadge) { + this.ids = {bannerId, textP, dismissBtn, notificationBadge}; this.banner = document.getElementById(bannerId); this.bannerText = document.getElementById(textP); this.dismissBtn = document.getElementById(dismissBtn); + this.notificationBadge = document.getElementById(notificationBadge); this.bannerMsgs = []; // Hide Banner after JS loading finished @@ -28,6 +31,21 @@ export default class BannerController { } /** + * Reloads the object + */ + refresh() { + this.banner = document.getElementById(this.ids.bannerId); + this.bannerText = document.getElementById(this.ids.textP); + this.dismissBtn = document.getElementById(this.ids.dismissBtn); + this.notificationBadge = document.getElementById( + this.ids.notificationBadge); + this.bannerMsgs = []; + + // Hide Banner after JS loading finished + this.banner.classList.add('hidden'); + } + + /** * 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 @@ -69,7 +87,6 @@ export default class BannerController { * 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; @@ -85,5 +102,16 @@ export default class BannerController { else this.bannerText.innerText = text; this.current = name; + + // Update notification badge + if (this.bannerMsgs.length < 2) { + this.notificationBadge.classList.add('hidden'); + } else if (this.bannerMsgs.length > 9) { + this.notificationBadge.classList.remove('hidden'); + this.notificationBadge.textContent = '∞'; + } else { + this.notificationBadge.classList.remove('hidden'); + this.notificationBadge.textContent = this.bannerMsgs.length.toString(); + } } } diff --git a/WebInterface/NodeJSServer/src/modules/ui/server-listing.js b/WebInterface/NodeJSServer/src/modules/ui/server-listing.js index 0069ac6..78ca323 100644 --- a/WebInterface/NodeJSServer/src/modules/ui/server-listing.js +++ b/WebInterface/NodeJSServer/src/modules/ui/server-listing.js @@ -1,3 +1,5 @@ +import LoginModal from './login-modal.js'; + /** * Class for handling the server list */ @@ -5,9 +7,11 @@ export default class ServerListing { /** * Creates reference to container * @param {string} serverListId ID of the server list div + * @param {BannerController} notifications Notification Manager */ - constructor(serverListId) { + constructor(serverListId, notifications) { this.serverListing = document.getElementById(serverListId); + this.notifications = notifications; } /** @@ -20,12 +24,13 @@ export default class ServerListing { /** * Populates servers from a given array of games * @param {array} array Array of available games + * @param {ServerClient} serverClient Server Client to handle login + * @param {array} ui UI Elements to reload after login */ - addElements(array) { + addElements(array, serverClient, ui) { for (let server of array) { const name = server['name']; - const playerList = server['users']; - const playerAmount = playerList.length; + const playerAmount = server['userCount']; let serverDiv = document.createElement('div'); let nameSpan = document.createElement('span'); @@ -46,13 +51,16 @@ export default class ServerListing { playerCountSpan.textContent = playerAmount; playerCountStaticSpan.textContent = 'Spieler online'; joinButton.textContent = 'Beitreten'; + joinButton.addEventListener('click', () => { + new LoginModal(name, serverClient, this.notifications, ui); + }); rightAlignDiv.appendChild(onlineDot); rightAlignDiv.appendChild(playerCountSpan); rightAlignDiv.appendChild(playerCountStaticSpan); rightAlignDiv.appendChild(joinButton); serverDiv.appendChild(nameSpan); - serverDiv.appendChild(rightAlignDiv) + serverDiv.appendChild(rightAlignDiv); this.serverListing.appendChild(serverDiv); } } |