From 828df4b35194a015ec91d414f8ff3f59c5bfd479 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taneli=20Riihim=C3=A4ki?= <m3034@student.jamk.fi>
Date: Tue, 9 Jul 2019 13:42:13 +0300
Subject: [PATCH] Background timer location working!

---
 components/GameList.js                        | 61 +++++++++----------
 components/Login.js                           | 18 ++++--
 components/LoginForm.js                       |  2 +-
 components/RegisterForm.js                    |  2 +-
 ios/ReactNativeTest.xcodeproj/project.pbxproj | 38 ++++++++++++
 package.json                                  |  3 +-
 6 files changed, 84 insertions(+), 40 deletions(-)

diff --git a/components/GameList.js b/components/GameList.js
index ecb869c..db8a79d 100644
--- a/components/GameList.js
+++ b/components/GameList.js
@@ -1,10 +1,13 @@
 import React, { Component, Fragment } from "react";
 import { Picker, Text, StyleSheet } from "react-native";
+import BackgroundTimer from "react-native-background-timer";
 
 import LocationTracker from "./LocationTracker";
 import PasswordPopup from "./PasswordPopup";
 import MessagePopup from "./MessagePopup";
 
+let intervalId;
+
 class GameList extends Component {
   constructor(props) {
     super(props);
@@ -27,8 +30,6 @@ class GameList extends Component {
         longitudeDelta: null
       }
     };
-
-    intervalID = 0; // Used for starting and stopping the tracking ticks
   }
 
   componentDidMount() {
@@ -41,7 +42,7 @@ class GameList extends Component {
 
   // Get all the games from the server and set the state to the first game
   async getGames() {
-    await fetch("https://tacs-testing.cf:8443/game/listgames", {
+    await fetch("http://10.0.2.2:5000/game/listgames", {
       method: "GET",
       headers: {
         Accept: "application/json",
@@ -63,7 +64,7 @@ class GameList extends Component {
   }
 
   getFactionMembers() {
-    fetch(`https://tacs-testing.cf:8443/game/${this.state.selectedGame.id}`, {
+    fetch(`http://10.0.2.2:5000/game/${this.state.selectedGame.id}`, {
       method: "GET",
       headers: {
         Accept: "application/json",
@@ -85,7 +86,7 @@ class GameList extends Component {
 
   // Get all the factions from the server
   getFactions() {
-    fetch(`https://tacs-testing.cf:8443/game/${this.state.selectedGame.id}`, {
+    fetch(`http://10.0.2.2:5000/game/${this.state.selectedGame.id}`, {
       method: "GET",
       headers: {
         Accept: "application/json",
@@ -120,7 +121,7 @@ class GameList extends Component {
   };
   // There's lots of bad solutions here beware! (at least it should work)
   joinFaction() {
-    fetch("https://tacs-testing.cf:8443/faction/join-faction", {
+    fetch("http://10.0.2.2:5000/faction/join-faction", {
       method: "PUT",
       headers: {
         Authorization: "Bearer " + this.props.token,
@@ -170,25 +171,14 @@ class GameList extends Component {
   }
 
   // Start the player tracking with the wanted interval (ms)
-  startTracking() {
-    console.log("Pelaajan token : " + this.props.token);
+  startTracking = () => {
     this.getCurrentLocation();
-    let interval = 10000;
-    this.intervalID = setInterval(() => {
-      console.log(
-        "Nyt träkätää nim birusti peliä: " + this.state.selectedGame.name
-      );
-
-      console.log(
-        "Pelaajan latitude: " +
-          this.state.userLocation.latitude +
-          "Pelaajan longitude: " +
-          this.state.userLocation.longitude
-      );
+    this.intervalId = BackgroundTimer.setInterval(() => {
+      // this will be executed every <interval> ms
+      // even when app is the the background
+      this.getCurrentLocation();
       fetch(
-        `https:/tacs-testing.cf:8443/tracking/location/${
-          this.state.selectedGame.id
-        }`,
+        `http://10.0.2.2:5000/tracking/location/${this.state.selectedGame.id}`,
         {
           method: "POST",
           headers: {
@@ -222,18 +212,27 @@ class GameList extends Component {
             console.log(error);
           }
         );
-      console.log("Tracking: " + this.state.tracking);
-    }, interval);
-  }
+      console.log(
+        "Pelaajan lokaatio: Latitude " +
+          this.state.userLocation.latitude +
+          " Longitude " +
+          this.state.userLocation.longitude
+      );
+    }, 1000);
+  };
 
   // Stop tracking the player
   stopTracking() {
-    clearInterval(this.intervalID);
+    BackgroundTimer.clearInterval(this.intervalId);
     console.log("Nyt lopetetaa seuranta.");
   }
 
   // Start & stop tracking depending on the boolean 'tracking' in state
   componentDidUpdate() {
+    console.log("LOGGED: " + this.props.logged);
+    if (!this.props.logged) {
+      this.stopTracking();
+    }
     // if (this.state.tracking) {
     //   this.startTracking();
     // } else if (!this.state.tracking) {
@@ -244,13 +243,13 @@ class GameList extends Component {
   selectGame = async (selectedGame, itemIndex) => {
     await this.setState({ selectedGame, tracking: false });
     await this.getFactions();
-    await clearInterval(this.intervalID);
+    //await clearInterval(this.intervalID);
   };
   // When you select a faction, it asks you for a password, which is then sent to the server
   selectFaction = async (selectedFaction, itemIndex) => {
     await this.setState({ selectedFaction, tracking: false });
     await this.joinFactionPopup(this.state.selectedFaction.factionId);
-    await clearInterval(this.intervalID);
+    //await clearInterval(this.intervalID);
   };
   //Getting the user location and storing it in the state
   getCurrentLocation = () => {
@@ -259,7 +258,7 @@ class GameList extends Component {
       timeout: 30000,
       maximumAge: 0
     };
-    navigator.geolocation.watchPosition(
+    navigator.geolocation.getCurrentPosition(
       position => {
         console.log(
           "Positio päivittyi: " +
@@ -282,7 +281,7 @@ class GameList extends Component {
 
   // Stop tracking on Unmount
   componentWillUnmount() {
-    clearInterval(this.intervalID);
+    BackgroundTimer.clearInterval(intervalId);
   }
   render() {
     if (this.state.games.length > 0) {
diff --git a/components/Login.js b/components/Login.js
index 6cc775f..ae3d996 100644
--- a/components/Login.js
+++ b/components/Login.js
@@ -9,7 +9,8 @@ class Login extends Component {
   state = {
     form: "login", // Used for forms (login, register etc.)
     username: null,
-    token: null
+    token: null,
+    logged: false
   };
   // Toggling the register and login forms visibility
   toggleView = view => {
@@ -22,12 +23,16 @@ class Login extends Component {
   handleState = async data => {
     await AsyncStorage.setItem("name", data.name);
     await AsyncStorage.setItem("token", data.token);
-    await this.setState({ username: data.name, token: data.token });
+    await this.setState({
+      username: data.name,
+      token: data.token,
+      logged: true
+    });
   };
 
   // When logging out, removing the token from the storage
   handleLogout = async () => {
-    await this.setState({ username: null, token: null });
+    await this.setState({ username: null, token: null, logged: false });
     await AsyncStorage.removeItem("token");
     this.toggleView("login");
   };
@@ -41,7 +46,7 @@ class Login extends Component {
   componentDidMount() {
     let token = this.loadToken();
     if (token) {
-      fetch("https:/tacs-testing.cf:8443/user/verify", {
+      fetch("http://10.0.2.2:5000/user/verify", {
         headers: {
           Authorization: "Bearer " + token
         }
@@ -53,7 +58,8 @@ class Login extends Component {
             if (result === true) {
               this.setState({
                 username: AsyncStorage.getItem("name"),
-                token: token
+                token: token,
+                logged: true
               });
               // logout user if token has expired / is invalid
             } else {
@@ -116,7 +122,7 @@ class Login extends Component {
                   title="Logout"
                 />
               </View>
-              <GameList token={this.state.token} />
+              <GameList logged={this.state.logged} token={this.state.token} />
             </Fragment>
           )}
         </View>
diff --git a/components/LoginForm.js b/components/LoginForm.js
index ddae257..292dbf7 100644
--- a/components/LoginForm.js
+++ b/components/LoginForm.js
@@ -27,7 +27,7 @@ export class LoginForm extends React.Component {
     e.preventDefault();
 
     // Send login info to the server
-    fetch("https:/tacs-testing.cf:8443/user/login", {
+    fetch("http://10.0.2.2:5000/user/login", {
       method: "POST",
       headers: {
         Accept: "application/json",
diff --git a/components/RegisterForm.js b/components/RegisterForm.js
index 1a1ca9e..3632c15 100644
--- a/components/RegisterForm.js
+++ b/components/RegisterForm.js
@@ -39,7 +39,7 @@ export class RegisterForm extends React.Component {
       this.handleError("Passwords do not match");
     } else {
       // Send register info to the server
-      fetch("https:/tacs-testing.cf:8443/user/register", {
+      fetch("http://10.0.2.2:5000/user/register", {
         method: "POST",
         headers: {
           Accept: "application/json",
diff --git a/ios/ReactNativeTest.xcodeproj/project.pbxproj b/ios/ReactNativeTest.xcodeproj/project.pbxproj
index 53b9504..81990dd 100755
--- a/ios/ReactNativeTest.xcodeproj/project.pbxproj
+++ b/ios/ReactNativeTest.xcodeproj/project.pbxproj
@@ -41,6 +41,8 @@
 		ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; };
 		07B392F2A5F34BA28E45CF6C /* libAirMaps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 708314BCF1A445EDB1E8AE1B /* libAirMaps.a */; };
 		791E1999531A434FAD73E2B2 /* libRNSketchCanvas.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A42F8E574A046F0B81F36F5 /* libRNSketchCanvas.a */; };
+		905753E2B7EE4A6596E12629 /* libRNCAsyncStorage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F7741BA7E7F411A910AED01 /* libRNCAsyncStorage.a */; };
+		BA114190326344048A109AA2 /* libRNBackgroundTimer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FC7750798F646B896A0F5CA /* libRNBackgroundTimer.a */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -352,6 +354,10 @@
 		708314BCF1A445EDB1E8AE1B /* libAirMaps.a */ = {isa = PBXFileReference; name = "libAirMaps.a"; path = "libAirMaps.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
 		0F6AB3E50BE345F6A5FC8278 /* RNSketchCanvas.xcodeproj */ = {isa = PBXFileReference; name = "RNSketchCanvas.xcodeproj"; path = "../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/RNSketchCanvas.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
 		1A42F8E574A046F0B81F36F5 /* libRNSketchCanvas.a */ = {isa = PBXFileReference; name = "libRNSketchCanvas.a"; path = "libRNSketchCanvas.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
+		C0F302C2186D4885B55873D4 /* RNCAsyncStorage.xcodeproj */ = {isa = PBXFileReference; name = "RNCAsyncStorage.xcodeproj"; path = "../node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+		1F7741BA7E7F411A910AED01 /* libRNCAsyncStorage.a */ = {isa = PBXFileReference; name = "libRNCAsyncStorage.a"; path = "libRNCAsyncStorage.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
+		09CFD408F6674624A9BD50E8 /* RNBackgroundTimer.xcodeproj */ = {isa = PBXFileReference; name = "RNBackgroundTimer.xcodeproj"; path = "../node_modules/react-native-background-timer/ios/RNBackgroundTimer.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+		5FC7750798F646B896A0F5CA /* libRNBackgroundTimer.a */ = {isa = PBXFileReference; name = "libRNBackgroundTimer.a"; path = "libRNBackgroundTimer.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -382,6 +388,8 @@
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
 				07B392F2A5F34BA28E45CF6C /* libAirMaps.a in Frameworks */,
 				791E1999531A434FAD73E2B2 /* libRNSketchCanvas.a in Frameworks */,
+				905753E2B7EE4A6596E12629 /* libRNCAsyncStorage.a in Frameworks */,
+				BA114190326344048A109AA2 /* libRNBackgroundTimer.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -573,6 +581,8 @@
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
 				7345D2BF6C834E73AEEDB1B6 /* AirMaps.xcodeproj */,
 				0F6AB3E50BE345F6A5FC8278 /* RNSketchCanvas.xcodeproj */,
+				C0F302C2186D4885B55873D4 /* RNCAsyncStorage.xcodeproj */,
+				09CFD408F6674624A9BD50E8 /* RNBackgroundTimer.xcodeproj */,
 			);
 			name = Libraries;
 			sourceTree = "<group>";
@@ -1202,11 +1212,15 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Debug;
@@ -1230,11 +1244,15 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Release;
@@ -1259,6 +1277,8 @@
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Debug;
@@ -1282,6 +1302,8 @@
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Release;
@@ -1313,11 +1335,15 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Debug;
@@ -1349,11 +1375,15 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Release;
@@ -1384,11 +1414,15 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Debug;
@@ -1419,11 +1453,15 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(SRCROOT)/../node_modules/react-native-maps/lib/ios/**",
 					"$(SRCROOT)/../node_modules/@terrylinla/react-native-sketch-canvas/ios/RNSketchCanvas/**",
+					"$(SRCROOT)/../node_modules/@react-native-community/async-storage/ios",
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
 				);
 			};
 			name = Release;
diff --git a/package.json b/package.json
index 10cbd09..5daa34d 100755
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
   "dependencies": {
     "@react-native-community/async-storage": "^1.5.0",
     "react": "16.8.6",
-    "react-native": "0.59.9"
+    "react-native": "0.59.9",
+    "react-native-background-timer": "^2.1.1"
   },
   "devDependencies": {
     "@babel/core": "7.4.5",
-- 
GitLab