diff --git a/mobile/traque-app/app/_layout.jsx b/mobile/traque-app/app/_layout.jsx
index d9c319c..1b9a1f8 100644
--- a/mobile/traque-app/app/_layout.jsx
+++ b/mobile/traque-app/app/_layout.jsx
@@ -1,16 +1,16 @@
// Expo
import { Slot } from 'expo-router';
// Contexts
-import { TeamConnexionProvider } from "../src/context/teamConnexionContext";
-import { TeamProvider } from "../src/context/teamContext";
+import { AuthProvider } from "../src/contexts/authContext";
+import { TeamProvider } from "../src/contexts/teamContext";
const Layout = () => {
return (
-
+
-
+
);
};
diff --git a/mobile/traque-app/app/index.jsx b/mobile/traque-app/app/index.jsx
index 1b3bfef..da9bced 100644
--- a/mobile/traque-app/app/index.jsx
+++ b/mobile/traque-app/app/index.jsx
@@ -8,19 +8,19 @@ import { CustomButton } from '../src/components/button';
import { CustomImage } from '../src/components/image';
import { CustomTextInput } from '../src/components/input';
// Contexts
-import { useTeamConnexion } from "../src/context/teamConnexionContext";
+import { useAuth } from "../src/contexts/authContext";
// Hooks
-import { usePickImage } from '../src/hook/usePickImage';
+import { usePickImage } from '../src/hooks/usePickImage';
// Services
-import { uploadTeamImage } from '../src/services/imageService';
-import { getLocationAuthorization, stopLocationTracking } from '../src/services/backgroundLocationTask';
+import { uploadTeamImage } from '../src/services/api/image';
+import { getLocationAuthorization, stopLocationTracking } from '../src/services/tasks/backgroundLocation';
// Constants
import { COLORS } from '../src/constants';
const Index = () => {
const router = useRouter();
- const { login, loggedIn } = useTeamConnexion();
- const {image, pickImage} = usePickImage();
+ const { loggedIn, login } = useAuth();
+ const { image, pickImage } = usePickImage();
const [teamId, setTeamId] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
diff --git a/mobile/traque-app/app/interface.jsx b/mobile/traque-app/app/interface.jsx
index b98e4ee..c619dbe 100644
--- a/mobile/traque-app/app/interface.jsx
+++ b/mobile/traque-app/app/interface.jsx
@@ -8,24 +8,23 @@ import { CustomMap } from '../src/components/map';
import { Drawer } from '../src/components/drawer';
import { TimerMMSS } from '../src/components/timer';
// Contexts
-import { useTeamConnexion } from '../src/context/teamConnexionContext';
-import { useTeamContext } from '../src/context/teamContext';
+import { useAuth } from '../src/contexts/authContext';
+import { useTeam } from '../src/contexts/teamContext';
// Hooks
-import { useGame } from '../src/hook/useGame';
-import { useTimeDifference } from '../src/hook/useTimeDifference';
+import { useTimeDifference } from '../src/hooks/useTimeDifference';
// Services
-import { startLocationTracking } from '../src/services/backgroundLocationTask';
+import { emitSendPosition } from '../src/services/socket/emitters';
+import { startLocationTracking } from '../src/services/tasks/backgroundLocation';
// Util
-import { secondsToMMSS } from '../src/util/functions';
+import { secondsToMMSS } from '../src/utils/functions';
// Constants
import { GAME_STATE, COLORS } from '../src/constants';
const Interface = () => {
const router = useRouter();
- const {teamInfos, messages, nextZoneDate, isShrinking, gameState} = useTeamContext();
+ const {teamInfos, messages, nextZoneDate, gameState} = useTeam();
const {name, ready, captured, locationSendDeadline, outOfZone, outOfZoneDeadline, hasHandicap, enemyHasHandicap} = teamInfos;
- const {loggedIn, logout} = useTeamConnexion();
- const {sendCurrentPosition} = useGame();
+ const { loggedIn, logout } = useAuth();
const [timeLeftSendLocation] = useTimeDifference(locationSendDeadline, 1000);
const [timeLeftNextZone] = useTimeDifference(nextZoneDate, 1000);
const [timeLeftOutOfZone] = useTimeDifference(outOfZoneDeadline, 1000);
@@ -87,7 +86,7 @@ const Interface = () => {
}
{ gameState == GAME_STATE.PLAYING && !captured &&
-
+
}
@@ -98,7 +97,7 @@ const Interface = () => {
setBottomContainerHeight(event.nativeEvent.layout.height)}>
{ gameState == GAME_STATE.PLAYING && !captured && !hasHandicap &&
-
+
}
diff --git a/mobile/traque-app/src/components/drawer.jsx b/mobile/traque-app/src/components/drawer.jsx
index 96cd974..de5b3f0 100644
--- a/mobile/traque-app/src/components/drawer.jsx
+++ b/mobile/traque-app/src/components/drawer.jsx
@@ -8,25 +8,24 @@ import { CustomImage } from './image';
import { CustomTextInput } from './input';
import { Stat } from './stat';
// Contexts
-import { useTeamConnexion } from '../context/teamConnexionContext';
-import { useTeamContext } from '../context/teamContext';
+import { useAuth } from '../contexts/authContext';
+import { useTeam } from '../contexts/teamContext';
// Hooks
-import { useTimeDifference } from '../hook/useTimeDifference';
-import { useGame } from '../hook/useGame';
+import { useTimeDifference } from '../hooks/useTimeDifference';
// Services
-import { enemyImage } from '../services/imageService';
+import { emitCapture } from '../services/socket/emitters';
+import { enemyImage } from '../services/api/image';
// Util
-import { secondsToHHMMSS } from '../util/functions';
+import { secondsToHHMMSS } from '../utils/functions';
// Constants
import { GAME_STATE, COLORS } from '../constants';
export const Drawer = ({ height }) => {
- const { teamId } = useTeamConnexion();
+ const { teamId } = useAuth();
const [collapsibleState, setCollapsibleState] = useState(true);
const [enemyCaptureCode, setEnemyCaptureCode] = useState("");
- const {teamInfos, gameState, startDate} = useTeamContext();
+ const {teamInfos, gameState, startDate} = useTeam();
const {enemyName, captureCode, name, distance, finishDate, nCaptures, nSentLocation, hasHandicap} = teamInfos;
- const {capture} = useGame();
const [timeSinceStart] = useTimeDifference(startDate, 1000);
const [captureStatus, setCaptureStatus] = useState(0); // 0 : no capture | 1 : waiting for response from server | 2 : capture failed | 3 : capture succesful
const captureStatusColor = {0: "#777", 1: "#FFA500", 2: "#FF6B6B", 3: "#81C784"};
@@ -53,7 +52,7 @@ export const Drawer = ({ height }) => {
const handleCapture = () => {
if (captureStatus != 1) {
setCaptureStatus(1);
- capture(enemyCaptureCode)
+ emitCapture(enemyCaptureCode)
.then((response) => {
if (response.hasCaptured) {
setCaptureStatus(3);
diff --git a/mobile/traque-app/src/components/layer.jsx b/mobile/traque-app/src/components/layer.jsx
index de659fe..4a80931 100644
--- a/mobile/traque-app/src/components/layer.jsx
+++ b/mobile/traque-app/src/components/layer.jsx
@@ -1,7 +1,7 @@
// React
import { Fragment } from 'react';
import { Polygon } from 'react-native-maps';
-import { circleToPolygon } from '../util/functions';
+import { circleToPolygon } from '../utils/functions';
export const InvertedPolygon = ({id, coordinates, fillColor}) => {
// We create 3 rectangles covering earth, with the first rectangle centered on the hole
diff --git a/mobile/traque-app/src/components/map.jsx b/mobile/traque-app/src/components/map.jsx
index 4711223..b810e40 100644
--- a/mobile/traque-app/src/components/map.jsx
+++ b/mobile/traque-app/src/components/map.jsx
@@ -6,15 +6,15 @@ import LinearGradient from 'react-native-linear-gradient';
// Components
import { DashedCircle, InvertedCircle, InvertedPolygon } from './layer';
// Contexts
-import { useTeamContext } from '../context/teamContext';
+import { useTeam } from '../contexts/teamContext';
// Hook
-import { useLocation } from '../hook/useLocation';
+import { useLocation } from '../hooks/useLocation';
// Util
import { ZONE_TYPES, INITIAL_REGIONS, GAME_STATE } from '../constants';
export const CustomMap = () => {
const { location } = useLocation();
- const {teamInfos, zoneType, zoneExtremities, gameState} = useTeamContext();
+ const {teamInfos, zoneType, zoneExtremities, gameState} = useTeam();
const {enemyLocation, startingArea, lastSentLocation, hasHandicap} = teamInfos;
const [centerMap, setCenterMap] = useState(true);
const mapRef = useRef(null);
diff --git a/mobile/traque-app/src/components/timer.jsx b/mobile/traque-app/src/components/timer.jsx
index 98a8920..f8eb36d 100644
--- a/mobile/traque-app/src/components/timer.jsx
+++ b/mobile/traque-app/src/components/timer.jsx
@@ -1,7 +1,7 @@
// React
import { View, Text, StyleSheet } from 'react-native';
// Util
-import { secondsToMMSS } from '../util/functions';
+import { secondsToMMSS } from '../utils/functions';
export const TimerMMSS = ({ title, seconds, style }) => {
return (
diff --git a/mobile/traque-app/src/context/teamConnexionContext.jsx b/mobile/traque-app/src/context/teamConnexionContext.jsx
deleted file mode 100644
index abc84eb..0000000
--- a/mobile/traque-app/src/context/teamConnexionContext.jsx
+++ /dev/null
@@ -1,22 +0,0 @@
-// React
-import { createContext, useContext, useMemo } from "react";
-// Hook
-import { useSocketAuth } from "../hook/useSocketAuth";
-
-const TeamConnexionContext = createContext();
-
-export const TeamConnexionProvider = ({ children }) => {
- const { login, password: teamId, loggedIn, logout } = useSocketAuth();
-
- const value = useMemo(() => ({ teamId, login, logout, loggedIn}), [teamId, login, logout, loggedIn]);
-
- return (
-
- {children}
-
- );
-};
-
-export const useTeamConnexion = () => {
- return useContext(TeamConnexionContext);
-};
diff --git a/mobile/traque-app/src/contexts/authContext.jsx b/mobile/traque-app/src/contexts/authContext.jsx
new file mode 100644
index 0000000..e85aad3
--- /dev/null
+++ b/mobile/traque-app/src/contexts/authContext.jsx
@@ -0,0 +1,80 @@
+// React
+import { createContext, useContext, useState, useEffect, useCallback, useMemo } from "react";
+import DeviceInfo from 'react-native-device-info';
+// Hook
+import { useLocalStorage } from '../hooks/useLocalStorage';
+// Services
+import { emitLogin, emitLogout, emitBattery, emitDeviceInfo } from "../services/socket/emitters";
+
+const AuthContext = createContext();
+
+export const AuthProvider = ({ children }) => {
+ const [loggedIn, setLoggedIn] = useState(false);
+ const [teamId, setTeamId] = useLocalStorage("team_id", null);
+
+ const login = useCallback(async (password) => {
+ if (loggedIn != false) return;
+
+ try {
+ const response = await emitLogin(password);
+ setLoggedIn(response.isLoggedIn);
+ if (response.isLoggedIn) setTeamId(password);
+ return response.isLoggedIn;
+ } catch (error) {
+ setLoggedIn(false);
+ throw error;
+ }
+ }, [loggedIn, setTeamId]);
+
+ const logout = useCallback(() => {
+ if (loggedIn != true) return;
+
+ setLoggedIn(false);
+ setTeamId(null);
+ emitLogout();
+ }, [loggedIn, setTeamId]);
+
+ // Try to log in with saved teamId
+ useEffect(() => {
+ if (!loggedIn && teamId) {
+ login(teamId);
+ }
+ }, [loggedIn, teamId, login]);
+
+ // Emit battery level and phone model at log in
+ useEffect(() => {
+ if (!loggedIn) return;
+
+ const sendInfo = async () => {
+ const [brand, model, name] = await Promise.all([
+ DeviceInfo.getBrand(),
+ DeviceInfo.getModel(),
+ DeviceInfo.getDeviceName()
+ ]);
+ emitDeviceInfo({model: brand + " " + model, name: name});
+ };
+
+ const sendBattery = async () => {
+ const level = await DeviceInfo.getBatteryLevel();
+ emitBattery(Math.round(level * 100));
+ };
+
+ sendInfo();
+ sendBattery();
+ const batteryCheckInterval = setInterval(() => sendBattery(), 5*60*1000); // 5 minutes
+
+ return () => clearInterval(batteryCheckInterval);
+ }, [loggedIn]);
+
+ const value = useMemo(() => ({ teamId, loggedIn, login, logout}), [teamId, loggedIn, login, logout]);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useAuth = () => {
+ return useContext(AuthContext);
+};
diff --git a/mobile/traque-app/src/context/teamContext.jsx b/mobile/traque-app/src/contexts/teamContext.jsx
similarity index 73%
rename from mobile/traque-app/src/context/teamContext.jsx
rename to mobile/traque-app/src/contexts/teamContext.jsx
index d0cab3b..7859163 100644
--- a/mobile/traque-app/src/context/teamContext.jsx
+++ b/mobile/traque-app/src/contexts/teamContext.jsx
@@ -1,26 +1,25 @@
// React
import { createContext, useContext, useMemo, useState, useEffect } from "react";
// Context
-import { useTeamConnexion } from "./teamConnexionContext";
-// Hook
-import { useSendDeviceInfo } from "../hook/useSendDeviceInfo";
+import { useAuth } from "./authContext";
// Services
-import { socket } from "../services/socket";
+import { socket } from "../services/socket/connection";
// Constants
import { GAME_STATE } from "../constants";
const TeamContext = createContext();
-const useSocketListener = (event, callback) => {
+const useOnEvent = (event, callback) => {
useEffect(() => {
socket.on(event, callback);
return () => {
socket.off(event, callback);
};
- }, [callback, event]);
+ }, [event, callback]);
};
export const TeamProvider = ({children}) => {
+ const { logout } = useAuth();
// update_team
const [teamInfos, setTeamInfos] = useState({});
// game_state
@@ -32,21 +31,17 @@ export const TeamProvider = ({children}) => {
// settings
const [messages, setMessages] = useState(null);
const [zoneType, setZoneType] = useState(null);
- // logout
- const { logout } = useTeamConnexion();
-
- useSendDeviceInfo();
- useSocketListener("update_team", (data) => {
+ useOnEvent("update_team", (data) => {
setTeamInfos(teamInfos => ({...teamInfos, ...data}));
});
- useSocketListener("game_state", (data) => {
+ useOnEvent("game_state", (data) => {
setGAME_STATE(data.state);
setStartDate(data.date);
});
- useSocketListener("settings", (data) => {
+ useOnEvent("settings", (data) => {
setMessages(data.messages);
setZoneType(data.zone.type);
//TODO
@@ -54,12 +49,12 @@ export const TeamProvider = ({children}) => {
//setOutOfZoneDelay(data.outOfZoneDelay);
});
- useSocketListener("current_zone", (data) => {
+ useOnEvent("current_zone", (data) => {
setZoneExtremities({begin: data.begin, end: data.end});
setNextZoneDate(data.endDate);
});
- useSocketListener("logout", logout);
+ useOnEvent("logout", logout);
const value = useMemo(() => (
{teamInfos, gameState, startDate, zoneType, zoneExtremities, nextZoneDate, messages}
@@ -72,6 +67,6 @@ export const TeamProvider = ({children}) => {
);
};
-export const useTeamContext = () => {
+export const useTeam = () => {
return useContext(TeamContext);
};
diff --git a/mobile/traque-app/src/hook/useGame.jsx b/mobile/traque-app/src/hook/useGame.jsx
deleted file mode 100644
index 91624d4..0000000
--- a/mobile/traque-app/src/hook/useGame.jsx
+++ /dev/null
@@ -1,27 +0,0 @@
-// React
-import { useCallback } from "react";
-// Services
-import { emitSendPosition, emitCapture } from "../services/socketEmitter";
-
-export const useGame = () => {
-
- const sendCurrentPosition = useCallback(() => {
- emitSendPosition();
- }, []);
-
- const capture = useCallback((captureCode) => {
- return new Promise((resolve, reject) => {
- const timeout = setTimeout(() => {
- console.warn("Server timeout: capture", captureCode);
- reject(new Error("Timeout"));
- }, 3000);
-
- emitCapture(captureCode, (response) => {
- clearTimeout(timeout);
- resolve(response);
- });
- });
- }, []);
-
- return { sendCurrentPosition, capture };
-};
diff --git a/mobile/traque-app/src/hook/useSendDeviceInfo.jsx b/mobile/traque-app/src/hook/useSendDeviceInfo.jsx
deleted file mode 100644
index 6d560a3..0000000
--- a/mobile/traque-app/src/hook/useSendDeviceInfo.jsx
+++ /dev/null
@@ -1,46 +0,0 @@
-// React
-import { useEffect, useRef } from 'react';
-import DeviceInfo from 'react-native-device-info';
-// Context
-import { useTeamConnexion } from "../context/teamConnexionContext";
-// Services
-import { emitBattery, emitDeviceInfo } from "../services/socketEmitter";
-
-export const useSendDeviceInfo = () => {
- const { loggedIn } = useTeamConnexion();
- const isMounted = useRef(true);
-
- useEffect(() => {
- isMounted.current = true;
-
- if (!loggedIn) return;
-
- const sendInfo = async () => {
- const [brand, model, name] = await Promise.all([
- DeviceInfo.getBrand(),
- DeviceInfo.getModel(),
- DeviceInfo.getDeviceName()
- ]);
- if (!isMounted) return;
- emitDeviceInfo({model: brand + " " + model, name: name});
- };
-
- const sendBattery = async () => {
- const level = await DeviceInfo.getBatteryLevel();
- if (!isMounted) return;
- emitBattery(Math.round(level * 100));
- };
-
- sendInfo();
- sendBattery();
-
- const batteryCheckInterval = setInterval(() => sendBattery(), 5*60*1000); // 5 minutes
-
- return () => {
- isMounted.current = false;
- clearInterval(batteryCheckInterval);
- };
- }, [loggedIn]);
-
- return null;
-};
diff --git a/mobile/traque-app/src/hook/useSocketAuth.jsx b/mobile/traque-app/src/hook/useSocketAuth.jsx
deleted file mode 100644
index 0b4fdfe..0000000
--- a/mobile/traque-app/src/hook/useSocketAuth.jsx
+++ /dev/null
@@ -1,60 +0,0 @@
-// React
-import { useState, useEffect, useCallback, useRef } from 'react';
-// Hook
-import { useLocalStorage } from './useLocalStorage';
-// Services
-import { emitLogin, emitLogout } from "../services/socketEmitter";
-
-export const useSocketAuth = () => {
- const [loggedIn, setLoggedIn] = useState(false);
- const [savedPassword, setSavedPassword] = useLocalStorage("team_password", null);
- const isMounted = useRef(true);
-
- useEffect(() => {
- isMounted.current = true;
- return () => {
- isMounted.current = false;
- };
- }, []);
-
- const login = useCallback((password) => {
- return new Promise((resolve, reject) => {
- const timeout = setTimeout(() => {
- if (!isMounted.current) return;
- console.warn("Server did not respond to login emit.");
- reject();
- }, 2000);
-
- emitLogin(password, (response) => {
- clearTimeout(timeout);
-
- if (!isMounted.current) return;
-
- if (response.isLoggedIn) {
- console.log("Log in accepted.");
- setLoggedIn(true);
- setSavedPassword(password);
- resolve(response);
- } else {
- console.log("Log in refused.");
- setLoggedIn(false);
- reject();
- }
- });
- });
- }, [setSavedPassword]);
-
- useEffect(() => {
- if (!loggedIn && savedPassword) {
- login(savedPassword);
- }
- }, [loggedIn, login, savedPassword]);
-
- const logout = useCallback(() => {
- setLoggedIn(false);
- setSavedPassword(null);
- emitLogout();
- }, [setSavedPassword]);
-
- return {login, logout, password: savedPassword, loggedIn};
-};
diff --git a/mobile/traque-app/src/hook/useLocalStorage.jsx b/mobile/traque-app/src/hooks/useLocalStorage.jsx
similarity index 85%
rename from mobile/traque-app/src/hook/useLocalStorage.jsx
rename to mobile/traque-app/src/hooks/useLocalStorage.jsx
index 64bb163..46a2cc3 100644
--- a/mobile/traque-app/src/hook/useLocalStorage.jsx
+++ b/mobile/traque-app/src/hooks/useLocalStorage.jsx
@@ -6,21 +6,16 @@ export const useLocalStorage = (key, initialValue) => {
const [storedValue, setStoredValue] = useState(initialValue);
useEffect(() => {
- let isMounted = true;
-
const fetchData = async () => {
try {
const item = await AsyncStorage.getItem(key);
- if (isMounted && item !== null) {
- setStoredValue(JSON.parse(item));
- }
+ if (item !== null) setStoredValue(JSON.parse(item));
} catch (error) {
console.error(`Error loading key "${key}":`, error);
}
};
fetchData();
- return () => { isMounted = false; };
}, [key]);
const setValue = useCallback(async (value) => {
diff --git a/mobile/traque-app/src/hook/useLocation.jsx b/mobile/traque-app/src/hooks/useLocation.jsx
similarity index 100%
rename from mobile/traque-app/src/hook/useLocation.jsx
rename to mobile/traque-app/src/hooks/useLocation.jsx
diff --git a/mobile/traque-app/src/hook/usePickImage.jsx b/mobile/traque-app/src/hooks/usePickImage.jsx
similarity index 97%
rename from mobile/traque-app/src/hook/usePickImage.jsx
rename to mobile/traque-app/src/hooks/usePickImage.jsx
index 4135f3d..d75396b 100644
--- a/mobile/traque-app/src/hook/usePickImage.jsx
+++ b/mobile/traque-app/src/hooks/usePickImage.jsx
@@ -35,5 +35,5 @@ export const usePickImage = () => {
}
}, []);
- return {image, pickImage};
+ return { image, pickImage };
};
diff --git a/mobile/traque-app/src/hook/useTimeDifference.jsx b/mobile/traque-app/src/hooks/useTimeDifference.jsx
similarity index 73%
rename from mobile/traque-app/src/hook/useTimeDifference.jsx
rename to mobile/traque-app/src/hooks/useTimeDifference.jsx
index c42d2fe..c1cea5d 100644
--- a/mobile/traque-app/src/hook/useTimeDifference.jsx
+++ b/mobile/traque-app/src/hooks/useTimeDifference.jsx
@@ -1,10 +1,12 @@
// React
import { useEffect, useState } from "react";
+/**
+ * If refTime is in the past, time will be positive
+ * If refTime is in the future, time will be negative
+ * The time is updated every timeout milliseconds
+ */
export const useTimeDifference = (refTime, timeout) => {
- // If refTime is in the past, time will be positive
- // If refTime is in the future, time will be negative
- // The time is updated every timeout milliseconds
const [time, setTime] = useState(0);
useEffect(() => {
diff --git a/mobile/traque-app/src/services/imageService.js b/mobile/traque-app/src/services/api/image.js
similarity index 94%
rename from mobile/traque-app/src/services/imageService.js
rename to mobile/traque-app/src/services/api/image.js
index 0711fdb..f14fb1f 100644
--- a/mobile/traque-app/src/services/imageService.js
+++ b/mobile/traque-app/src/services/api/image.js
@@ -1,5 +1,5 @@
// Constants
-import { SERVER_URL } from "../constants";
+import { SERVER_URL } from "../../constants";
export const uploadTeamImage = async (id, imageUri) => {
if (!imageUri || !id) return;
diff --git a/mobile/traque-app/src/services/socket.js b/mobile/traque-app/src/services/socket/connection.js
similarity index 74%
rename from mobile/traque-app/src/services/socket.js
rename to mobile/traque-app/src/services/socket/connection.js
index aa629fb..429d5ec 100644
--- a/mobile/traque-app/src/services/socket.js
+++ b/mobile/traque-app/src/services/socket/connection.js
@@ -1,7 +1,7 @@
// Socket
import { io } from "socket.io-client";
// Constants
-import { SOCKET_URL } from "../constants";
+import { SOCKET_URL } from "../../constants";
export const socket = io(SOCKET_URL, {
path: "/back/socket.io"
diff --git a/mobile/traque-app/src/services/socket/emitters.js b/mobile/traque-app/src/services/socket/emitters.js
new file mode 100644
index 0000000..b29a1a3
--- /dev/null
+++ b/mobile/traque-app/src/services/socket/emitters.js
@@ -0,0 +1,55 @@
+// Services
+import { socket } from "./connection";
+
+const customEmit = (event, ...args) => {
+ if (!socket?.connected) return false;
+ console.log("Emit", event);
+ socket.emit(event, ...args);
+ return true;
+};
+
+const customEmitCallback = (event, ...args) => {
+ return new Promise((resolve, reject) => {
+ if (!socket?.connected) return reject(new Error("Socket not connected"));
+
+ console.log("Emit", event);
+
+ const timeout = setTimeout(() => {
+ console.warn("Server timeout");
+ reject(new Error("Timeout"));
+ }, 3000);
+
+ socket.emit(event, ...args, (response) => {
+ clearTimeout(timeout);
+ resolve(response.length > 1 ? response : response[0]);
+ });
+ });
+};
+
+export const emitLogin = (password) => {
+ return customEmitCallback("login", password);
+};
+
+export const emitLogout = () => {
+ return customEmit("logout");
+};
+
+export const emitSendPosition = () => {
+ return customEmit("send_position");
+};
+
+export const emitUpdatePosition = (location) => {
+ return customEmit("update_position", location);
+};
+
+export const emitCapture = (captureCode) => {
+ return customEmitCallback("capture", captureCode);
+};
+
+export const emitBattery = (level) => {
+ return customEmit("battery_update", level);
+};
+
+export const emitDeviceInfo = (infos) => {
+ return customEmit("device_info", infos);
+};
diff --git a/mobile/traque-app/src/services/socketEmitter.js b/mobile/traque-app/src/services/socketEmitter.js
deleted file mode 100644
index e788747..0000000
--- a/mobile/traque-app/src/services/socketEmitter.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Services
-import { socket } from "./socket";
-
-export const emitLogin = (password, callback) => {
- if (!socket?.connected) return;
- console.log("Try to log in with :", password);
- socket.emit("login", password, callback);
-};
-
-export const emitLogout = () => {
- if (!socket?.connected) return;
- console.log("Logout.");
- socket.emit("logout");
-};
-
-export const emitSendPosition = () => {
- if (!socket?.connected) return;
- console.log("Reveal position.");
- socket.emit("send_position");
-};
-
-export const emitUpdatePosition = (location) => {
- if (!socket?.connected) return;
- console.log("Update position :", location);
- socket.emit("update_position", location);
-};
-
-export const emitCapture = (captureCode, callback) => {
- if (!socket?.connected) return;
- console.log("Try to capture :", captureCode);
- socket.emit("capture", captureCode, callback);
-};
-
-export const emitBattery = (level) => {
- if (!socket?.connected) return;
- console.log("Send battery level.");
- socket.emit('battery_update', level);
-};
-
-export const emitDeviceInfo = (infos) => {
- if (!socket?.connected) return;
- console.log("Send device infos.");
- socket.emit('device_info', infos);
-};
diff --git a/mobile/traque-app/src/services/backgroundLocationTask.js b/mobile/traque-app/src/services/tasks/backgroundLocation.js
similarity index 92%
rename from mobile/traque-app/src/services/backgroundLocationTask.js
rename to mobile/traque-app/src/services/tasks/backgroundLocation.js
index 23b7bd2..5112ceb 100644
--- a/mobile/traque-app/src/services/backgroundLocationTask.js
+++ b/mobile/traque-app/src/services/tasks/backgroundLocation.js
@@ -2,9 +2,9 @@
import { defineTask, isTaskRegisteredAsync } from "expo-task-manager";
import * as Location from 'expo-location';
// Services
-import { emitUpdatePosition } from "./socketEmitter";
+import { emitUpdatePosition } from "../socket/emitters";
// Constants
-import { TASKS, LOCATION_PARAMETERS } from "../constants";
+import { TASKS, LOCATION_PARAMETERS } from "../../constants";
// Task
diff --git a/mobile/traque-app/src/util/functions.js b/mobile/traque-app/src/utils/functions.js
similarity index 100%
rename from mobile/traque-app/src/util/functions.js
rename to mobile/traque-app/src/utils/functions.js