Browse Source

add connection to server + online room games

jojo 5 years ago
parent
commit
1071b2aa79

+ 6 - 0
.vscode/settings.json

@@ -0,0 +1,6 @@
+{
+    "git.ignoreLimitWarning": true,
+    "typescript.validate.enable": false,
+    "tslint.enable": false,
+    "javascript.validate.enable": false
+}

+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "cor-build": "CORDOVA=true cordova build -- --webpackConfig webpack.config.js",
     "cordova": "CORDOVA=true cordova run -- -w webpack.config.js",
     "start": "npm-run-all --parallel server dev lint:watch",
+    "start-client": "npm-run-all --parallel dev lint:watch",
     "lint": "esw webpack.config.* src --color",
     "lint:watch": "npm run lint -- --watch",
     "localtunnel": "lt --port 3000",

+ 58 - 15
server/main.js

@@ -7,17 +7,17 @@ const server = io.listen(4000);
 
 let players = [];
 
-const authorizedPlayersNames = [ "jojo", "mart", "lily" ];
+const authorizedPlayersNames = ["jojo", "mart", "lily"];
 let authorizedPlayers = new Map();
+let connectedPlayers = new Map();
 
 authorizedPlayersNames.forEach(name => {
-  authorizedPlayers.set(name,new PlayerId(name));
+  authorizedPlayers.set(name, new PlayerId(name));
 });
-
 let addNewPlayer = function (playerSocket, playerName) {
   console.log('players length : ' + players.length + ' : ' + players);
   if (players.length < 2) {
-    let newPlayer = new PlayerId(playerSocket,playerName);
+    let newPlayer = new PlayerId(playerSocket, playerName);
     console.log('push player : ' + newPlayer);
     players.push(newPlayer);
   }
@@ -28,35 +28,78 @@ let addNewPlayer = function (playerSocket, playerName) {
 
 server.on('connection', function (socket) {
   console.log("A player connected with id : " + socket.id);
-  socket.on ('disconnect', () => {
-    console.log("A player disconnected with id : " + socket.id);
+
+  socket.on('disconnect', (reason) => {
+    if (reason === 'client namespace disconnect') {
+      console.log("A player disconnected with id : " + socket.id);
+      let playerName = connectedPlayers.get(socket.id);
+      if (playerName) {
+        connectedPlayers.delete(socket.id);
+        authorizedPlayers.get(playerName).setConnected(false);
+        authorizedPlayers.get(playerName).setSocket(null);
+        console.log(playerName + " disconnected");
+      }
+    } else {
+      console.log("disconnected unexpectidly with reason : " + reason);
+    }
   });
+  socket.on('connect', () => {
+    console.log("Connected to server");
 
+  });
   socket.on('auth', (playerName, callback) => {
     console.log(' Received auth message, player name : ' + playerName);
     let response = {};
-    if (! authorizedPlayersNames.includes(playerName)) {
+    let kickout = false;
+    if (!authorizedPlayersNames.includes(playerName)) {
       response = {
-        res:"ko",
-        message:playerName + " Not found"
+        res: "ko",
+        message: playerName + " Not found"
       };
+      kickout = true;
     }
-    else if (authorizedPlayers.get(playerName).isConnected()) {
+    // If the player is already connected and active
+    else if (authorizedPlayers.get(playerName).isConnected()
+      && authorizedPlayers.get(playerName).getSocket().connected) {
       response = {
-        res:"ko",
-        message:playerName + " already connected"
+        res: "ko",
+        message: playerName + " already connected"
       };
+      kickout = true;
     }
     else {
+      // Player marked as connected but socket is down
+      if (authorizedPlayers.get(playerName).isConnected()) {
+        authorizedPlayers.get(playerName).getSocket().disconnect(true);
+      }
       response = {
-        res:"ok",
-        message:playerName + " connected"
+        res: "ok",
+        message: playerName + " connected"
       };
       authorizedPlayers.get(playerName).setConnected(true);
       authorizedPlayers.get(playerName).setSocket(socket);
-
+      connectedPlayers.set(socket.id, playerName);
     }
+
     callback(response);
+    if (kickout === true) {
+      setTimeout(() => {
+        socket.disconnect(true);
+      }, 600);
+    }
   });
 
+  socket.on('games-list', (playerName, callback) => {
+    console.log(' Received games-list message, player name : ' + playerName);
+    let games= {
+      game1: {p1:"jojo", p2:'lily',mode:'faction', rules:[]},
+      game2: {p1:"mart", p2:'',mode:'tournament', rules:['popularity', 'discard']},
+      game3: {p1:"jojo", p2:'mart',mode:'draft', rules:['discard']}
+    };
+    let response = {
+      res: "ok",
+      message: games
+    };
+    callback(response);
+  });
 });

+ 5 - 2
server/players/player-id.js

@@ -8,6 +8,9 @@ export default class PlayerId {
     this.connected=false;
   }
 
+  getSocket() {
+    return this.playerSocket;
+  }
   setSocket(socket) {
     this.playerSocket = socket;
   }
@@ -18,9 +21,9 @@ export default class PlayerId {
     this.playerColor = playerColor;
   }
   setConnected(connected) {
-    this.isConnected = connected;
+    this.connected = connected;
   }
   isConnected() {
-    return this.isConnected;
+    return this.connected;
   }
 }

+ 0 - 3
settings.json

@@ -1,3 +0,0 @@
-{
-    "git.ignoreLimitWarning": true
-}

+ 96 - 30
src/assets/html/main-menu.html

@@ -1,10 +1,10 @@
 <style type="text/css">
 .main-div {
-  background: #C7CC2D;
-  border: 1px solid #972620;
+  background: #03c11b;
+  border: 1px solid #013007;
   border-radius: 6px;
   height: 300px;
-  margin-top: 250px;
+  margin-top: 0px;
   margin-left: auto;
   width: 300px;
 }
@@ -15,10 +15,10 @@
 }
 
 input[type="password"], input[type="text"] {
-  background: linear-gradient(top, #C7CC2D, #e6e6e6);
-  border: 1px solid #C7CC2D;
+  background: linear-gradient(top, #03c11b, #e6e6e6);
+  border: 1px solid #03c11b;
   border-radius: 4px;
-  box-shadow: 0 1px #C7CC2D;
+  box-shadow: 0 1px #03c11b;
   box-sizing: border-box;
   color: #567199;
   height: 39px;
@@ -78,7 +78,7 @@ input[type="button"] {
   border-top-right-radius: 5px;
   border-bottom-right-radius: 5px;
   border-bottom-left-radius:5px;
-  box-shadow: inset 0px 1px 0px #567199, 0px 5px 0px 0px #324F70, 0px 10px 5px #C7CC2D;
+  box-shadow: inset 0px 1px 0px #567199, 0px 5px 0px 0px #324F70, 0px 10px 5px #03c11b;
 }
 
 input[type="button"]:hover:enabled, input[type="text"]:hover:enabled {
@@ -107,7 +107,7 @@ input[type="button"]:disabled {
   border-top-right-radius: 5px;
   border-bottom-right-radius: 5px;
   border-bottom-left-radius:5px;
-  box-shadow: inset 0px 1px 0px #7e7e7e, 0px 5px 0px 0px #808586, 0px 7px 5px #C7CC2D;
+  box-shadow: inset 0px 1px 0px #7e7e7e, 0px 5px 0px 0px #808586, 0px 7px 5px #03c11b;
 }
 .shadow {
   background: #000;
@@ -121,20 +121,26 @@ input[type="button"]:disabled {
 
 input[type="button"]:enabled:active {
   top:3px;
-  box-shadow: inset 0px 1px 0px #567199, 0px 2px 0px 0px #324F70, 0px 5px 3px #C7CC2D;
+  box-shadow: inset 0px 1px 0px #567199, 0px 2px 0px 0px #324F70, 0px 5px 3px #03c11b;
 }
 .connection {
   font-family:Arial, "Helvetica", sans-serif;
   font-size:14px;
-  color: #972620;
+  color: #660c07;
   text-align:center;
 }
 
 #online-room-buttons {
   position: absolute;
-  top:50px;
+  top:20px;
   left:205px;
 }
+#online-room-buttons p {
+margin-left: 20px;
+}
+#online-room-buttons div {
+  margin-top: 50px;
+}
 
 #online-games {
   background: #567199;
@@ -156,25 +162,75 @@ input[type="button"]:enabled:active {
   padding-top: 8px;
 }
 #list-games {
+  display: none;
   padding: 0;
   list-style:none;
+  margin-top: 1px;
 }
 
 #list-games li {
+  margin: 7px 5px 0px 5px;
+
+  width:170px;
+  height:35px;
+  background-color:#191817;
+  padding-left:5px;
+  font-weight:normal;
+  text-transform: none;
+  text-shadow:none;
+  text-align: left;
+
+}
+
+.el-selected {
+border: 2px solid #f10505;
+  margin-left: 3px;
+}
+
+#list-games li div {
+  margin-bottom: -3px;
+}
+#list-games li span {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.game-entry-title {
   font-family:Arial, "Helvetica", sans-serif;
   font-size:14px;
-  margin: 7px 10px 0px 10px;
+  color:#F8E15E;
+  padding-left: 10px;
 }
-
-#list-games span {
-  width:155px;
-  height:35px;
-  background-color:#333;
-  padding-left:10px;
+.game-entry-desc {
   text-decoration:none;
-  color:#bfe1f1;
-  display: table-cell;
-  vertical-align: middle;
+  font-size:11px;
+  color:#F8E15E;
+}
+#loader-online-games {
+  display: block;
+  margin-top: 50px;
+  margin-left: 62px;
+  border: 8px solid #f3f3f3;
+  border-radius: 50%;
+  border-top: 8px solid #F8E15E;
+  width: 40px;
+  height: 40px;
+  -webkit-animation: spin 1.5s linear infinite; /* Safari */
+  animation: spin 1.5s linear infinite;
+}
+
+/* Safari */
+@-webkit-keyframes spin {
+  0% { -webkit-transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(360deg); }
+}
+
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
 }
 
 #game-creation {
@@ -277,7 +333,7 @@ input[type="button"]:enabled:active {
 </head>
 
 <body class="body">
-  <div id="login" class="main-div" style="display:block">
+  <div id="login" class="main-div" style="display:none">
     <input type="text" placeholder="Username" id="username" name="username" autocomplete="off">
     <input type="button" value="Connect" name="loginButton">
     <p class="connection" id="connectionStatus">Not Connected</p>
@@ -287,20 +343,30 @@ input[type="button"]:enabled:active {
 
   <div id="online-room" class="main-div" style="display:none">
     <div id="online-games">
-      Created Games
+      Existing Games
       <hr>
+      <div id="loader-online-games"></div>
       <ul id="list-games">
-        <!-- <li>
-          <span></span>
-        </li> -->
+        <li>
+          <span class="game-entry-title">Resume jojo VS lily</span>
+          <div></div>
+          <span class="game-entry-desc">Factions + no adv. rules</span>
+        </li>
+        <li>
+          <span class="game-entry-title">mart waiting...</span>
+          <div></div>
+          <span class="game-entry-desc">Tournament + popularity + discard</span>
+        </li>
       </ul>
     </div>
 
     <div id="online-room-buttons">
-      <input type="button" value="Create new game" name="createOnlineGame">
-      <input type="button" value="Join open game" name="joinOnlineGame" disabled>
-      <input type="button" value="Back to Menu" name="backToMain">
-
+      <p class="connection" id="connectionStatusOnline"></p>
+      <div>
+        <input type="button" value="Create new game" name="createOnlineGame">
+        <input type="button" value="Join / Resume game" name="joinOnlineGame" disabled>
+        <input type="button" value="Back to Menu" name="backToMain">
+      </div>
     </div>
   </div>
 

+ 69 - 20
src/common/socket-service.js

@@ -1,6 +1,6 @@
 'use strict';
 import io from 'socket.io-client';
-
+// import promiseTimeout from './utils/promise-timeout';
 /*
   Messages :
     - disconnect
@@ -12,35 +12,84 @@ import io from 'socket.io-client';
 const SERVER_URL = process.env.SERVER_URL || 'http://localhost';
 const SERVER_PORT = process.env.SERVER_PORT || 4000;
 
+
+
 export default class SocketService {
   constructor() {
-
     //this.ioClient = io.connect(SERVER_URL + ":" + SERVER_PORT + '/');
+    this.lostConnectionListeners = new Set();
+    // this.ioClient = {};
   }
 
-  connect(serverUrl, serverPort) {
-    this.disconnected=false;
-    this.ioClient = io.connect(serverUrl + ":" + serverPort);
-
-    console.log("is connected : " + this.ioClient.connected);
-    this.ioClient.on('disconnect', () => {
-      console.log("Connection with server lost");
+  addlostConnectionListener(listener) {
+    this.lostConnectionListeners.add(listener);
+  }
 
-    });
-    this.ioClient.on('connect', () => {
-      console.log("Connected to server");
 
-    });
+  removelostConnectionListener(listener) {
+    this.lostConnectionListeners.delete(listener);
   }
-  auth(name) {
-    return new Promise(function (resolve, reject) {
-      this.ioClient.emit('auth', name, function (response) {
-        if (response.res === "ok") {
-          resolve(response.message);
-        } else {
-          reject(response.message);
+
+  connect(name) {
+    let promise = new Promise((resolve, reject) => {
+      this.ioClient = io('http://localhost:4000',
+        { reconnectionAttempts: 2 });
+
+      this.ioClient.on('disconnect', (reason) => {
+        if (reason !== 'io client disconnect') {
+          console.log("Connection with server lost unexpectidly : " + reason);
+          //this.ioClient.close();
         }
       });
+
+      this.ioClient.on('connect', () => {
+        console.log("Connected to server");
+          this.ioClient.emit('auth', name, function (response) {
+            if (response.res === "ok") {
+              resolve(response.message);
+            } else {
+              reject(response.message);
+            }
+          });
+      });
+
+      this.ioClient.on('connect_error', () => {
+        console.log("connect_error to server");
+      });
+
+      this.ioClient.on('reconnect_failed', () => {
+        console.log("reconnect_failed to server");
+        reject('Cannot reach server');
+      });
+
     });
+    return promise;
+  }
+
+  checkConnection(playername) {
+    if (this.ioClient.connected === false) {
+      return this.connect(playername);
+    } else {
+      return Promise.resolve('Still connected');
+    }
+  }
+
+  disconnect() {
+    console.log('Manual client disconnect');
+    this.ioClient.close();
+  }
+  getGamesList(playername) {
+    return this.checkConnection(playername).then( () => {
+      return new Promise( (resolve, reject) => {
+        this.ioClient.emit('games-list', playername, function (response) {
+          if (response.res === "ok") {
+            resolve(response.message);
+          } else {
+            reject(response.message);
+          }
+        });
+      });
+    },
+    (error) => Promise.reject(error));
   }
 }

+ 17 - 4
src/menu/control/menu-controller.js

@@ -14,9 +14,7 @@ export default class MenuController {
 
     this.mainMenuScene = new MainMenuScene(this.menuEventListener());
 
-    //this.socketService = new SocketService();
-    //this.socketService.connect('http://localhost', 4000);
-    //this.socketService.auth('jojo');
+    this.socketService = new SocketService();
   }
 
   displayMainMenu() {
@@ -25,9 +23,21 @@ export default class MenuController {
     this.phaserEngine.scene.start(PhaserScene.MAIN_MENU);
   }
 
+
+  tryConnect(username) {
+    return this.socketService.connect(username);
+  }
+
+  onRequestDisconnection() {
+    this.socketService.disconnect();
+  }
+
   menuEventListener() {
     return {
-      onNewPnpGame: this.onNewPnpGame.bind(this)
+      onNewPnpGame: this.onNewPnpGame.bind(this),
+      onOnlineGamesListRequested: this.onOnlineGamesListRequested.bind(this),
+      onTryConnect: this.tryConnect.bind(this),
+      onRequestDisconnection: this.onRequestDisconnection.bind(this),
     };
   }
 
@@ -38,4 +48,7 @@ export default class MenuController {
       gameControllerPnp.displayDeckBuilding();
   }
 
+  onOnlineGamesListRequested(playername) {
+    return this.socketService.getGamesList(playername);
+  }
 }

+ 90 - 126
src/menu/views/main-menu-scene.js

@@ -3,6 +3,10 @@ import { GameDeckMode } from '../../common/utils/const/game-deck-mode-enum';
 import { PhaserScene } from '../../common/utils/const/phaser-scene-enum';
 import Phaser from 'phaser';
 
+import LoginDivPage from './menu-pages/login-div-page';
+import OnlineRoomDivPage from './menu-pages/online-room-div-page';
+import GameCreationDivPage from './menu-pages/game-creation-div-page';
+
 export default class MainMenuScene extends Phaser.Scene {
 
   constructor(menuEventListener) {
@@ -10,7 +14,7 @@ export default class MainMenuScene extends Phaser.Scene {
     this.menuEventListener = menuEventListener;
 
     this.username = '';
-    this.previousMenu = null;
+    this.previousPages = new Array();
   }
 
   preload() {
@@ -19,150 +23,110 @@ export default class MainMenuScene extends Phaser.Scene {
     this.load.html('main-menu', '../../assets/html/main-menu.html');
   }
 
+
+  // create is call automatically by Phaser engine
   create() {
     console.log('create');
     let background = this.add.image(0, 0, 'game-cover');
     background.setOrigin(0, 0);
 
     // Add main-menu HTML
-    let element = this.add.dom(400, 100).createFromCache('main-menu');
-
-    // Menu blocks
-    let loginHtmlDiv = element.getChildByID('login');
-    let onlineRoomHtmlDiv = element.getChildByID('online-room');
-    let gameCreationHtmlDiv = element.getChildByID('game-creation');
-
-    // Login block buttons
-    let connectButton = element.getChildByName('loginButton');
-    let username = element.getChildByName('username');
-    let connectionStatus = element.getChildByID('connectionStatus');
-    let onlineGame = element.getChildByName('onlineGame');
-
-    // Online room buttons
-    let createOnlineGameButton = element.getChildByName('createOnlineGame');
-    let joinOnlineGameButton = element.getChildByName('joinOnlineGame');
-    let backToMainButton = element.getChildByName('backToMain');
-    let createdOnlineGamesList = element.getChildByID('list-games');
-
-    // Game creation buttons
-
-
-
-    element.setPerspective(800);
-
-    element.addListener('click');
-
-    username.addEventListener("keyup", event => {
-      if (connectButton.value === 'Connect') {
-        if (event.key !== "Enter") return;
-        connectButton.click();
-        event.preventDefault();
-      }
-    });
-
-    console.log(connectButton);
-    connectButton.focus();
-    element.on('click', function (event) {
-      console.log(event);
-      let eventName = event.target.name;
-      switch (eventName) {
-        case "loginButton":
-          if (connectButton.value === 'Connect') {
-            if (username.value !== '') {
-              connectButton.disabled = true;
-              connectionStatus.innerText = 'Connecting...';
-              username.disabled = true;
-              console.log(username.value);
-              console.log(' log  :' + onlineGame.disabled);
-              setTimeout(() => {
-                connectionStatus.innerText = 'Connected as ' + username.value;
-                this.username = username.value;
-                onlineGame.disabled = false;
-                connectButton.value = "Disconnect";
-
-                connectButton.disabled = false;
-              }, 1000);
-            } else {
-              connectionStatus.innerText = 'Not Connected : Enter Username';
-            }
-          } else {
-            connectButton.disabled = true;
-            connectionStatus.innerText = `Disconnecting ${this.username}...`;
-            onlineGame.disabled = true;
-            setTimeout(() => {
-              connectionStatus.innerText = 'Not Connected';
-              connectButton.value = "Connect";
-              connectButton.disabled = false;
-              username.value = '';
-              this.username = username.value;
-
-              username.disabled = false;
-            }, 500);
-          }
-          break;
-        case "onlineGame":
-          loginHtmlDiv.style.display = 'none';
-          onlineRoomHtmlDiv.style.display = 'block';
-
-          break;
-        case "backToMain":
-          onlineRoomHtmlDiv.style.display = 'none';
-          loginHtmlDiv.style.display = 'block';
-
-          break;
-        case "createOnlineGame":
-          this.previousMenu = onlineRoomHtmlDiv;
-          onlineRoomHtmlDiv.style.display = 'none';
-          gameCreationHtmlDiv.style.display = 'block';
-          break;
-        case "backToPrev":
-          this.previousMenu = null;
-          gameCreationHtmlDiv.style.display = 'none';
-          onlineRoomHtmlDiv.style.display = 'block';
-          break;
-        case "localGame":
-          alert('Feature not implemented yet');
-          break;
-
-        default:
-          break;
-      }
-    });
-
-    this.tweens.add({
-      targets: element,
-      y: 215,
-      duration: 2300,
-      ease: 'Power3'
-    });
-    //this.add.dom
+    let element = this.add.dom(250, 0).createFromCache('main-menu');
+    // Menu div pages
+    this.loginDivPage = new LoginDivPage(element,this.loginPageListener());
+    this.onlineRoomDivPage = new OnlineRoomDivPage(element, this.onlineRoomPageListener());
+    this.gameCreationDivPage = new GameCreationDivPage(element, this.gameCreationPageListener());
+
+    setTimeout(() => {
 
+      this.loginDivPage.show();
+      element.setPerspective(800);
+      this.tweens.add({
+        targets: element,
+        y: 190,
+        duration: 2300,
+        ease: 'Power3'
 
+      });
+
+     }, 1000);
 
     // TODO : Display main menu
     // Create new scenes : Local player room / Multi player room
     // Pass to them the event listener
     // On local player room, user can enter player names, selected color, game deck mode & rules
 
-    // FOR TESTING
-    //this.fakeNewPnpGameSelected();
   }
 
   update() {
+  }
+
 
+  // Listener for login page events
+  loginPageListener() {
+    return {
+      onRequestConnection: this.onRequestConnection.bind(this),
+      onRequestDisconnection: this.onRequestDisconnection.bind(this),
+      onGoOnlineRoom: this.onGoOnlineRoom.bind(this)
+    };
   }
 
-  fakeNewPnpGameSelected() {
-    setTimeout(() => {
-      let pBlueName = prompt("Player blue name : ");
-      let pRedName = prompt("Player red name : ");
-
-      //let gameDeckModeOptions = Object.values(GameDeckMode);
-      //let gameDeckMode = Utils.promptSelectAmongOptions("Select Deck Mode", gameDeckModeOptions);
-      let gameDeckMode = "factions";
-      let advancedRules = [];
-      console.log("Calling listener");
-      this.menuEventListener.onNewPnpGame(pBlueName, pRedName, gameDeckMode, advancedRules);
-    }, 1000);
+  // Listener for online room page events
+  onlineRoomPageListener() {
+    return {
+      onRequestOnlineGamesList: this.onRequestOnlineGamesList.bind(this),
+      onGoGameCreation: this.onGoGameCreation.bind(this),
+      onGoPreviousPage: this.onGoPreviousPage.bind(this)
+    };
+  }
+
+  // Listener for game creation page events
+  gameCreationPageListener() {
+    return {
+      onGoPreviousPage: this.onGoPreviousPage.bind(this)
+    };
   }
+
+  // Callbacks implementation
+  onGoPreviousPage(fromPage) {
+    fromPage.hide();
+    this.previousPages.pop().show();
+  }
+
+  // Login page specific
+  onGoOnlineRoom() {
+
+    this.loginDivPage.hide();
+    this.previousPages.push(this.loginDivPage);
+    this.onlineRoomDivPage.setConnectionStatus(this.loginDivPage.getConnectionStatus());
+    this.onlineRoomDivPage.show();
+  }
+  onRequestConnection(username) {
+    this.username=username;
+    return this.menuEventListener.onTryConnect(username);
+  }
+  onRequestDisconnection() {
+    this.menuEventListener.onRequestDisconnection();
+  }
+
+  // Online room specific
+  onRequestOnlineGamesList() {
+    return this.menuEventListener.onOnlineGamesListRequested(this.username);
+  }
+
+  onGoGameCreation() {
+    this.onlineRoomDivPage.hide();
+    this.previousPages.push(this.onlineRoomDivPage);
+    this.gameCreationDivPage.show();
+  }
+
+  // Game cration specific
+  onGameCreated() {
+
+    // let gameDeckMode = "factions";
+    // let advancedRules = [];
+    // console.log("Calling listener");
+    // this.menuEventListener.onNewPnpGame(pBlueName, pRedName, gameDeckMode, advancedRules)
+  }
+
 }

+ 32 - 0
src/menu/views/menu-pages/div-page-common.js

@@ -0,0 +1,32 @@
+
+export const canShow = (page) => ({
+  show() {
+    page.div.style.display = 'block';
+    if (typeof page.onShow === 'function') {
+      page.onShow();
+    } else {
+      console.log('Warning : class ' + page.className + ' needs to implement onShow()');
+    }
+  }
+});
+
+export const canHide = (page) => ({
+  hide() {
+    page.div.style.display = 'none';
+    if (typeof page.onHide === 'function') {
+      page.onHide();
+    } else {
+      console.log('Warning : class ' + page.className + ' needs to implement onHide()');
+    }
+  }
+});
+
+export const hasConnectionState = (page) => ({
+  getConnectionStatus() {
+    return page.connectionStatus.innerText;
+  },
+
+  setConnectionStatus(connectionStatus) {
+    page.connectionStatus.innerText=connectionStatus;
+  }
+});

+ 51 - 0
src/menu/views/menu-pages/game-creation-div-page.js

@@ -0,0 +1,51 @@
+import * as DivCommon from './div-page-common';
+
+export default function GameCreationDivPage(element, listener) {
+
+  const id='game-creation';
+  const className=GameCreationDivPage.name;
+
+  let div = element.getChildByID(id);
+  let connectButton = element.getChildByName('loginButton');
+  let username = element.getChildByName('username');
+  let connectionStatus = element.getChildByID('connectionStatus');
+  let onlineGame = element.getChildByName('onlineGame');
+
+  let eventListener = function(event) {
+    let eventName = event.target.name;
+    switch (eventName) {
+        case "backToPrev":
+          listener.onGoPreviousPage(gameCreationDivPage);
+          break;
+
+      default:
+        break;
+    }
+  };
+
+  div.addEventListener('click',eventListener);
+
+  let onShow = function() {
+
+  };
+
+  let onHide = function() {
+
+  };
+
+  let gameCreationDivPage = {
+    className,
+    div,
+    onShow,
+    onHide
+  };
+  return Object.assign(
+    gameCreationDivPage,
+    DivCommon.canShow(gameCreationDivPage),
+    DivCommon.canHide(gameCreationDivPage)
+  );
+
+}
+
+
+

+ 104 - 0
src/menu/views/menu-pages/login-div-page.js

@@ -0,0 +1,104 @@
+import * as DivCommon from './div-page-common';
+
+export default function LoginDivPage(element, listener) {
+
+  const id = 'login';
+  const className = LoginDivPage.name;
+
+  let div = element.getChildByID(id);
+  let connectButton = element.getChildByName('loginButton');
+  let username = element.getChildByName('username');
+  let connectionStatus = element.getChildByID('connectionStatus');
+  let onlineGame = element.getChildByName('onlineGame');
+
+
+  username.addEventListener("keyup", event => {
+    if (connectButton.value === 'Connect') {
+      if (event.key !== "Enter") return;
+      connectButton.click();
+      event.preventDefault();
+    }
+  });
+
+  let eventListener = function (event) {
+    let eventName = event.target.name;
+    switch (eventName) {
+      case "loginButton":
+        if (connectButton.value === 'Connect') {
+          if (username.value !== '') {
+            connectButton.disabled = true;
+            connectionStatus.innerText = 'Connecting...';
+            username.disabled = true;
+            listener.onRequestConnection(username.value).then(
+              () => {
+                connectionStatus.innerText = 'Connected as ' + username.value;
+                this.username = username.value;
+                onlineGame.disabled = false;
+                connectButton.value = "Disconnect";
+                connectButton.disabled = false;
+              },
+              (error) => {
+                console.log(`Could not connect as ${username.value} : ${error}`);
+                connectButton.disabled = false;
+                connectionStatus.innerText = error;
+                username.disabled = false;
+              }
+            );
+          } else {
+            connectionStatus.innerText = 'Not Connected : Enter Username';
+          }
+        } else {
+          connectButton.disabled = true;
+          connectionStatus.innerText = `Disconnecting ${this.username}...`;
+          onlineGame.disabled = true;
+          listener.onRequestDisconnection();
+          connectionStatus.innerText = 'Not Connected';
+          connectButton.value = "Connect";
+          connectButton.disabled = false;
+          username.value = '';
+          this.username = username.value;
+          username.disabled = false;
+        }
+        break;
+      case "onlineGame":
+        listener.onGoOnlineRoom();
+        break;
+
+      default:
+        break;
+    }
+  };
+
+  div.addEventListener('click', eventListener);
+
+  let onShow = function() {
+
+    connectionStatus.focus();
+  };
+
+  let onHide = function() {
+
+  };
+
+  let loginDivPage = {
+    className,
+    div,
+    connectButton,
+    username,
+    connectionStatus,
+    onlineGame,
+    onShow,
+    onHide
+  };
+
+  return Object.assign(
+    loginDivPage,
+    DivCommon.canShow(loginDivPage),
+    DivCommon.canHide(loginDivPage),
+    DivCommon.hasConnectionState(loginDivPage)
+  );
+
+}
+
+
+

+ 111 - 0
src/menu/views/menu-pages/online-room-div-page.js

@@ -0,0 +1,111 @@
+import * as DivCommon from './div-page-common';
+
+export default function OnlineRoomDivPage(element, listener) {
+
+  const id='online-room';
+  const className=OnlineRoomDivPage.name;
+  let div = element.getChildByID(id);
+
+  let createOnlineGameButton = element.getChildByName('createOnlineGame');
+  let joinOnlineGameButton = element.getChildByName('joinOnlineGame');
+  let backToMainButton = element.getChildByName('backToMain');
+  let listOnlineGames = element.getChildByID('list-games');
+  let connectionStatus = element.getChildByID('connectionStatusOnline');
+  let loaderOnlineGames = element.getChildByID('loader-online-games');
+
+  let eventListener = function(event) {
+    let eventName = event.target.name;
+    switch (eventName) {
+      case "backToMain":
+        console.log('in online room div page, backToMain clicked');
+        listener.onGoPreviousPage(onlineRoomDivPage);
+        break;
+      case "createOnlineGame":
+        listener.onGoGameCreation();
+        break;
+
+      default:
+        break;
+    }
+
+  };
+
+  div.addEventListener('click',eventListener);
+
+  let onShow = function() {
+    listener.onRequestOnlineGamesList()
+      .then( (games) => {
+        console.log('received games : ', games);
+        while(listOnlineGames.firstChild) listOnlineGames.removeChild(listOnlineGames.firstChild);
+        console.log('removed ex list');
+        Object.values(games).forEach(game => {
+          console.log(game);
+          let title='';
+          let desc='';
+          let rules= '';
+          if (game.rules.length !== 0) {
+            game.rules.forEach(rule => {
+              rules += ' + ' + rule;
+            });
+          } else {
+            rules= ' + no adv. rules';
+          }
+          desc=`${game.mode}${rules}`;
+          if (game.p2 !== '') {
+            title=`Resume ${game.p1} VS ${game.p2}`;
+          } else {
+            title=`${game.p1} waiting...`;
+          }
+          let li = document.createElement("li");
+          let spanTitle = document.createElement("span");
+          let spanDesc = document.createElement("span");
+          let div = document.createElement("div");
+          spanTitle.setAttribute("class", "game-entry-title");
+          spanDesc.setAttribute("class", "game-entry-desc");
+          spanTitle.appendChild(document.createTextNode(title));
+          spanDesc.appendChild(document.createTextNode(desc));
+          li.appendChild(spanTitle);
+          li.appendChild(div);
+          li.appendChild(spanDesc);
+          listOnlineGames.appendChild(li);
+        });
+        loaderOnlineGames.style.display= 'none';
+        listOnlineGames.style.display= 'block';
+      })
+      .catch( (error) => {
+        loaderOnlineGames.style.display= 'none';
+        listOnlineGames.style.display= 'block';
+        listOnlineGames.innerText=error;
+        connectionStatus.innerText=error;
+        createOnlineGameButton.disabled=true;
+        console.log('error to receive games : ' + error);
+      });
+  };
+
+  let onHide = function() {
+
+    listOnlineGames.style.display= 'none';
+    loaderOnlineGames.style.display= 'block';
+    createOnlineGameButton.disabled=false;
+    listOnlineGames.innerText='';
+  };
+
+  let onlineRoomDivPage = {
+    className,
+    div,
+    connectionStatus,
+    onShow,
+    onHide
+  };
+
+  return Object.assign(
+    onlineRoomDivPage,
+    DivCommon.canShow(onlineRoomDivPage),
+    DivCommon.canHide(onlineRoomDivPage),
+    DivCommon.hasConnectionState(onlineRoomDivPage)
+  );
+
+}
+
+
+