mirror of
https://git.rezel.net/LudoTech/traque.git
synced 2026-04-11 00:30:19 +02:00
Modify folder structure
This commit is contained in:
27
mobile/traque-app/src/hook/useGame.jsx
Normal file
27
mobile/traque-app/src/hook/useGame.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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 };
|
||||
};
|
||||
43
mobile/traque-app/src/hook/useLocalStorage.jsx
Normal file
43
mobile/traque-app/src/hook/useLocalStorage.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
// React
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
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));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error loading key "${key}":`, error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
return () => { isMounted = false; };
|
||||
}, [key]);
|
||||
|
||||
const setValue = useCallback(async (value) => {
|
||||
try {
|
||||
setStoredValue((prevValue) => {
|
||||
const valueToStore = value instanceof Function ? value(prevValue) : value;
|
||||
|
||||
AsyncStorage.setItem(key, JSON.stringify(valueToStore)).catch(err =>
|
||||
console.error(`Error saving key "${key}":`, err)
|
||||
);
|
||||
|
||||
return valueToStore;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}, [key]);
|
||||
|
||||
return [storedValue, setValue];
|
||||
};
|
||||
33
mobile/traque-app/src/hook/useLocation.jsx
Normal file
33
mobile/traque-app/src/hook/useLocation.jsx
Normal file
@@ -0,0 +1,33 @@
|
||||
// React
|
||||
import { useState, useEffect } from 'react';
|
||||
// Expo
|
||||
import * as Location from 'expo-location';
|
||||
// Constants
|
||||
import { LOCATION_PARAMETERS } from '../constants';
|
||||
|
||||
export const useLocation = () => {
|
||||
const [location, setLocation] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
let subscription;
|
||||
|
||||
const startWatching = async () => {
|
||||
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||
|
||||
if (status !== 'granted') return;
|
||||
|
||||
subscription = await Location.watchPositionAsync(
|
||||
LOCATION_PARAMETERS,
|
||||
(location) => setLocation(location.coords)
|
||||
);
|
||||
};
|
||||
|
||||
startWatching();
|
||||
|
||||
return () => {
|
||||
if (subscription) subscription.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { location };
|
||||
};
|
||||
39
mobile/traque-app/src/hook/usePickImage.jsx
Normal file
39
mobile/traque-app/src/hook/usePickImage.jsx
Normal file
@@ -0,0 +1,39 @@
|
||||
// React
|
||||
import { useState, useCallback } from 'react';
|
||||
import { Alert } from 'react-native';
|
||||
// Expo
|
||||
import { launchImageLibraryAsync, requestMediaLibraryPermissionsAsync } from 'expo-image-picker';
|
||||
|
||||
export const usePickImage = () => {
|
||||
const [image, setImage] = useState(null);
|
||||
|
||||
const pickImage = useCallback(async () => {
|
||||
try {
|
||||
const permissionResult = await requestMediaLibraryPermissionsAsync();
|
||||
|
||||
if (permissionResult.granted === false) {
|
||||
Alert.alert("Permission refusée", "Activez l'accès au stockage ou à la gallerie dans les paramètres.");
|
||||
return;
|
||||
}
|
||||
let result = await launchImageLibraryAsync({
|
||||
mediaTypes: ['images'],
|
||||
allowsMultipleSelection: false,
|
||||
allowsEditing: true,
|
||||
aspect: [4, 3],
|
||||
quality: 1,
|
||||
});
|
||||
|
||||
if (!result.canceled && result) {
|
||||
setImage(result.assets[0]);
|
||||
}
|
||||
else {
|
||||
console.log('Image picker cancelled.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error picking image;', error);
|
||||
Alert.alert('Erreur', "Une erreur est survenue lors de la sélection d'une image.");
|
||||
}
|
||||
}, []);
|
||||
|
||||
return {image, pickImage};
|
||||
};
|
||||
46
mobile/traque-app/src/hook/useSendDeviceInfo.jsx
Normal file
46
mobile/traque-app/src/hook/useSendDeviceInfo.jsx
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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;
|
||||
};
|
||||
60
mobile/traque-app/src/hook/useSocketAuth.jsx
Normal file
60
mobile/traque-app/src/hook/useSocketAuth.jsx
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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};
|
||||
};
|
||||
22
mobile/traque-app/src/hook/useTimeDifference.jsx
Normal file
22
mobile/traque-app/src/hook/useTimeDifference.jsx
Normal file
@@ -0,0 +1,22 @@
|
||||
// React
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
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(() => {
|
||||
const updateTime = () => {
|
||||
setTime(Math.floor((Date.now() - refTime) / 1000));
|
||||
};
|
||||
|
||||
updateTime();
|
||||
const interval = setInterval(updateTime, timeout);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [refTime, timeout]);
|
||||
|
||||
return [time];
|
||||
};
|
||||
Reference in New Issue
Block a user