From 42ce7ec7c9f930a480a7a2f71fa810268b3890e8 Mon Sep 17 00:00:00 2001
From: Jussi Surma-Aho <L4929@student.jamk.fi>
Date: Mon, 15 Jul 2019 11:18:20 +0300
Subject: [PATCH] Get players on socket initialisation. Fixed drawing doubles.
 Fixed some warnings. Get players every minute

---
 src/App.js                  |  1 +
 src/components/DrawTools.js | 20 +++++----
 src/components/Player.js    | 51 +++++++++++++----------
 src/components/Socket.js    |  7 +++-
 src/components/UserMap.js   | 81 ++++++++++++++++---------------------
 5 files changed, 82 insertions(+), 78 deletions(-)

diff --git a/src/App.js b/src/App.js
index b01a832..013fe42 100644
--- a/src/App.js
+++ b/src/App.js
@@ -44,6 +44,7 @@ class App extends Component {
   // setting the socket signal automatically fires shouldComponentUpdate function where socketSignal prop is present
   // setting socketSignal to null immediately after to avoid multiple database fetches
   getSocketSignal = type => {
+    console.log(type);
     this.setState(
       {
         socketSignal: type
diff --git a/src/components/DrawTools.js b/src/components/DrawTools.js
index 3de6edd..be1b7b3 100644
--- a/src/components/DrawTools.js
+++ b/src/components/DrawTools.js
@@ -152,6 +152,7 @@ class DrawTools extends Component {
     } // end if (e.layerType === "textbox")
 
     this.makeGeoJSON(e.layerType, e.layer);
+    e.layer.remove();
   }; // end _onCreated
 
   // turn layer to GeoJSON data
@@ -159,7 +160,8 @@ class DrawTools extends Component {
     // setting the format in which the data will be sent
     let geoJSON = {
       data: layer.toGeoJSON(),
-      mapDrawingId: layer.options.id
+      mapDrawingId: layer.options.id,
+      drawingIsActive: true
     };
 
     // setting properties
@@ -179,7 +181,7 @@ class DrawTools extends Component {
     geoJSON.data.properties.color = layer.options.color;
 
     // send item to database, and receive an ID for the layer
-    this.props.sendGeoJSON(geoJSON, false);
+    this.props.sendGeoJSON(geoJSON);
   };
 
   _onEditDeleteStart = () => {
@@ -209,6 +211,7 @@ class DrawTools extends Component {
       } else {
         this.makeGeoJSON(null, layer);
       }
+      return true;
     });
   };
 
@@ -223,14 +226,16 @@ class DrawTools extends Component {
     idsToDelete.map(layer => {
       let geoJSON = {
         data: layer.toGeoJSON(),
-        mapDrawingId: layer.options.id
+        mapDrawingId: layer.options.id,
+        drawingIsActive: false
       };
 
-      this.props.sendGeoJSON(geoJSON, true);
+      this.props.sendGeoJSON(geoJSON);
+      return true;
     });
   };
 
-  shouldComponentUpdate() {
+  shouldComponentUpdate(nextProps, nextState) {
     // disable re-rendering when edit mode is active
     return !this.state.editModeActive;
   }
@@ -326,9 +331,9 @@ class DrawTools extends Component {
                     className="editable"
                     interactive={true}
                   >
-                    <div class="editable">
+                    <div className="editable">
                       <div
-                        contenteditable="true"
+                        contentEditable="true"
                         placeholder="Click out to save"
                       >
                         {text}
@@ -388,6 +393,7 @@ class DrawTools extends Component {
               />
             );
           }
+          return null;
         })}
       </FeatureGroup>
     );
diff --git a/src/components/Player.js b/src/components/Player.js
index 195cc40..0786142 100644
--- a/src/components/Player.js
+++ b/src/components/Player.js
@@ -5,11 +5,12 @@ class Player extends Component {
   constructor(props) {
     super(props);
     this.state = {
-      players: null
+      players: null,
+      timer: null
     };
   }
 
-  getPlayers() {
+  getPlayers = () => {
     fetch(
       `${process.env.REACT_APP_API_URL}/tracking/players/${
         this.props.currentGameId
@@ -26,45 +27,51 @@ class Player extends Component {
         // don't do anything if data is not an array, as it breaks the map function at render
         if (Array.isArray(data)) {
           this.setState({
-            players: data
+            players: data,
+            timer: null // state for updating player positions every minute
           });
         }
       })
       .catch(error => {
         console.log(error);
       });
-  }
-
-  componentDidMount() {
-    // update components every 10 seconds
-    this.interval = setInterval(() => this.setState(this.getPlayers()), 5000);
-  }
+  };
 
   shouldComponentUpdate(nextProps, nextState) {
     // do not update component until players have been fetched and game ID is available
-    if (this.state.players === null) {
-      this.getPlayers();
+    if (this.props.currentGameId === null) {
       return false;
-    } else if (this.props.currentGameId === null) {
+    }
+    /*
+    if (this.props.socketSignal !== "tracking-update") {
+      return false;
+    }
+    */
+    return true;
+    /*
+    if (nextProps.currentGameId === null) {
+      return false;
+    } else if (this.state.players === null) {
+      this.getPlayers();
       return false;
     } else {
       return true;
     }
+    */
   }
 
-  componentDidUpdate() {
-    // check if game ID has changed
-    if (this.state.currentGameId !== this.props.currentGameId) {
-      this.setState({
-        currentGameId: this.props.currentGameId
-      });
+  componentDidUpdate(prevProps, prevState) {
+    if (prevProps.socketSignal === "tracking-update") {
+      // start updating interval
+      if (prevState.timer === null) {
+        this.getPlayers();
+        this.setState({
+          timer: setInterval(this.getPlayers, 60000)
+        });
+      }
     }
   }
 
-  componentWillUnmount() {
-    clearInterval(this.interval);
-  }
-
   render() {
     return (
       <div>
diff --git a/src/components/Socket.js b/src/components/Socket.js
index 34f3158..06cc2fd 100644
--- a/src/components/Socket.js
+++ b/src/components/Socket.js
@@ -16,10 +16,12 @@ export default class ClientSocket extends React.Component {
   }
 
   // initiate the socket on component mount
-  componentWillMount() {
+  async componentWillMount() {
     console.log("hi socket");
+    // need to explicitly update drawings and trackings when gameID first becomes available
     if (this.props.gameId !== null) {
-      this.props.getSocketSignal("drawing-update");
+      await this.props.getSocketSignal("drawing-update");
+      await this.props.getSocketSignal("tracking-update");
     }
     this.initSocket();
   }
@@ -45,6 +47,7 @@ export default class ClientSocket extends React.Component {
 
     // set the socket to listen gameId-thread
     socket.on(this.props.gameId, data => {
+      console.log(data);
       this.props.getSocketSignal(data.type);
       // check socket update type
       this.setState({ update: data.type });
diff --git a/src/components/UserMap.js b/src/components/UserMap.js
index 19ab74b..c5347fa 100644
--- a/src/components/UserMap.js
+++ b/src/components/UserMap.js
@@ -31,59 +31,42 @@ class UserMap extends Component {
   }
 
   shouldComponentUpdate(nextProps, nextState) {
-    if (nextProps.socketSignal === "drawing-update") {
-      this.fetchGeoJSON();
+    if (nextProps.currentGameId === null) {
+      return false;
     }
+
     return true;
   }
 
-  // Sends the players drawings to the backend (and database)
-  sendGeoJSON(layerToDatabase, isDeleted) {
-    // isDeleted is used to determine the drawing's drawingIsActive status
-    // otherwise the fetch functions are the same in both if and else. any smarter way to do this?
-    if (isDeleted === true) {
-      fetch(
-        `${process.env.REACT_APP_API_URL}/draw/mapdrawing/${
-          this.props.currentGameId
-        }`,
-        {
-          method: "PUT",
-          headers: {
-            Authorization: "Bearer " + sessionStorage.getItem("token"),
-            Accept: "application/json",
-            "Content-Type": "application/json"
-          },
-          body: JSON.stringify({
-            type: "FeatureCollection",
-            drawingIsActive: false,
-            mapDrawingId: layerToDatabase.mapDrawingId,
-            data: layerToDatabase.data
-          })
-        }
-      );
-    } else {
-      fetch(
-        `${process.env.REACT_APP_API_URL}/draw/mapdrawing/${
-          this.props.currentGameId
-        }`,
-        {
-          method: "PUT",
-          headers: {
-            Authorization: "Bearer " + sessionStorage.getItem("token"),
-            Accept: "application/json",
-            "Content-Type": "application/json"
-          },
-          body: JSON.stringify({
-            type: "FeatureCollection",
-            drawingIsActive: true,
-            mapDrawingId: layerToDatabase.mapDrawingId,
-            data: layerToDatabase.data
-          })
-        }
-      );
+  componentDidUpdate(prevProps, prevState) {
+    if (prevProps.socketSignal === "drawing-update") {
+      this.fetchGeoJSON();
     }
   }
 
+  // Sends the players drawings to the backend (and database)
+  sendGeoJSON(layerToDatabase) {
+    fetch(
+      `${process.env.REACT_APP_API_URL}/draw/mapdrawing/${
+        this.props.currentGameId
+      }`,
+      {
+        method: "PUT",
+        headers: {
+          Authorization: "Bearer " + sessionStorage.getItem("token"),
+          Accept: "application/json",
+          "Content-Type": "application/json"
+        },
+        body: JSON.stringify({
+          type: "FeatureCollection",
+          drawingIsActive: layerToDatabase.drawingIsActive,
+          mapDrawingId: layerToDatabase.mapDrawingId,
+          data: layerToDatabase.data
+        })
+      }
+    );
+  }
+
   // Get the drawings from the backend and add them to the state, so they can be drawn
   fetchGeoJSON() {
     fetch(
@@ -102,6 +85,7 @@ class UserMap extends Component {
         let newFeatures = [];
         data.map(item => {
           newFeatures.push(item);
+          return true;
         });
 
         this.setState({
@@ -192,7 +176,10 @@ class UserMap extends Component {
             </Popup>
           </Marker>
         )}
-        <Player currentGameId={this.state.currentGameId} />
+        <Player
+          currentGameId={this.props.currentGameId}
+          socketSignal={this.props.socketSignal}
+        />
       </Map>
     );
   }
-- 
GitLab