Files
geocaching_js/static/js/supervise.js
2024-12-24 00:52:14 +01:00

214 lines
8.0 KiB
JavaScript

let map; // Carte unique
let baptisteMarker = null; // Marker de Baptiste
let julienMarker = null; // Marker de Julien
// -------------------------------------
// SECTION : Fonctions Utilitaires
// -------------------------------------
// Calcul du temps d'inactivité en secondes
function calculateDeltaInSeconds(lastUpdate) {
const lastUpdateTime = new Date(lastUpdate).getTime();
const currentTime = Date.now();
return Math.floor((currentTime - lastUpdateTime) / 1000);
}
// Ajout d'un pin personnalisé
function addCustomPin(coordinates, iconUrl, popupText, offsetX = 20, offsetY = 40) {
const customIcon = L.icon({
iconUrl: iconUrl,
iconSize: [40, 40],
iconAnchor: [offsetX, offsetY],
popupAnchor: [0, -40],
});
return L.marker(coordinates, { icon: customIcon }).bindPopup(popupText);
}
// Initialisation de la carte
function initializeMap(centerCoordinates = [ 45.142066, 4.076664]) {
// Initialiser la carte
map = L.map('map', {
center: centerCoordinates, // Coordonnées du centre
zoom: 20, // Niveau de zoom par défaut
minZoom: 15, // Zoom minimum autorisé
maxZoom: 20 // Zoom maximum autorisé
});
// Définir les différentes couches de la carte
const osmStandard = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
});
const cycleOSM = L.tileLayer('https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.cyclosm.org/">CycleOSM</a>',
});
const satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: '&copy; <a href="https://www.esri.com/">ESRI</a> World Imagery',
});
// Nouvelle couche de tuiles personnalisées
const customTiles = L.tileLayer('https://jeu.maison43.duckdns.org/tiles/messinhac/{z}/{x}/{y}.png', {
attribution: '&copy; Mes Tuiles Personnalisées',
maxZoom: 20, // Assure un zoom maximal compatible avec tes tuiles
});
// Ajouter OpenStreetMap comme layer par défaut
customTiles.addTo(map);
// Ajouter un contrôle pour basculer entre les couches
const baseLayers = {
"OpenStreetMap Standard": osmStandard,
"CycleOSM": cycleOSM,
"Satellite": satellite,
"Tuiles Personnalisées": customTiles, // Ajout de la nouvelle couche ici
};
L.control.layers(baseLayers).addTo(map);
}
// -------------------------------------
// SECTION : Gestion des Utilisateurs
// -------------------------------------
// Fonction générique pour mettre à jour un utilisateur
async function updateAvatarPosition(username, markerRefName) {
try {
const response = await fetch(`/data/${username}.yaml`);
const userData = await response.json();
const newCoordinates = [
userData.position_actuelle.latitude,
userData.position_actuelle.longitude,
];
// Référence globale au marker
let marker = markerRefName === 'baptiste' ? baptisteMarker : julienMarker;
if (marker) {
// Met à jour directement la position du marker
marker.setLatLng(newCoordinates);
} else {
// Créez le marker pour la première fois
const newMarker = addCustomPin(
newCoordinates,
userData.avatar || 'default-avatar.png',
`${username} : ${userData.progression}`
);
newMarker.addTo(map);
// Met à jour la variable globale
if (markerRefName === 'baptiste') {
baptisteMarker = newMarker;
} else if (markerRefName === 'julien') {
julienMarker = newMarker;
}
}
console.log(`Position de ${username} mise à jour :`, newCoordinates);
} catch (error) {
console.error(`Erreur lors de la mise à jour de la position de ${username} :`, error);
}
}
// Fonction générique pour charger les pins des défis
async function loadChallengePins(username) {
try {
const response = await fetch(`/data/${username}.yaml`);
const userData = await response.json();
const offsetX = userData.pin_offset?.x || 20;
const offsetY = userData.pin_offset?.y || 40;
for (let i = 1; i <= 6; i++) {
const defi = userData.defis[`defi_${i}`];
if (!defi) continue;
const defiMarker = addCustomPin(
[defi.geolocalisation.latitude, defi.geolocalisation.longitude],
defi.pin || 'default-pin.png',
`Défi ${i} - trouvé ${defi.resolu}`,
offsetX,
offsetY
);
defiMarker.addTo(map);
// Ajouter le label "option" si résolu est "oui"
if (defi.resolu === "oui") {
defiMarker.bindTooltip(`Défi ${i}`, {
permanent: true, // Affiche le label en permanence
direction: "bottom", // Positionne le label au-dessus du marqueur
offset: [0, -5] // Ajuste l'offset pour éviter que le label chevauche le marqueur
});
}
}
console.log(`Pins des défis pour ${username} chargés avec succès.`);
} catch (error) {
console.error(`Erreur lors du chargement des défis pour ${username} :`, error);
}
}
// Fonction générique pour récupérer et afficher les données utilisateur
async function fetchUserData(username, domElements) {
try {
const response = await fetch(`/data/${username}.yaml`);
const userData = await response.json();
const lastUpdate = userData.position_actuelle.last_update;
const inactivitySeconds = calculateDeltaInSeconds(lastUpdate);
// Mise à jour des éléments HTML
document.getElementById(domElements.name).textContent = `${userData.nom}`;
document.getElementById(domElements.progression).textContent = `Progression : ${userData.progression}`;
document.getElementById(domElements.avatar).src = userData.avatar;
document.getElementById(domElements.longitude).textContent = userData.position_actuelle.longitude;
document.getElementById(domElements.latitude).textContent = userData.position_actuelle.latitude;
document.getElementById(domElements.inactive).textContent = `Inactif depuis : ${inactivitySeconds} s`;
console.log(`Données de ${username} mises à jour.`);
} catch (error) {
console.error(`Erreur lors de la récupération des données de ${username} :`, error);
}
}
// -------------------------------------
// SECTION : Événements DOM
// -------------------------------------
document.addEventListener("DOMContentLoaded", async () => {
initializeMap();
// Charger les pins des défis
await loadChallengePins('baptiste');
await loadChallengePins('julien');
// Planifier les mises à jour des positions des utilisateurs
setInterval(() => updateAvatarPosition('baptiste', 'baptiste'), 3000);
setInterval(() => updateAvatarPosition('julien', 'julien'), 3000);
setInterval(() =>loadChallengePins('baptiste'), 3000);
setInterval(() =>loadChallengePins('julien'), 3000);
// Mettre à jour les avatars et les données utilisateur
setInterval(() => updateAvatarPosition('baptiste', { value: baptisteMarker }), 3000);
setInterval(() => updateAvatarPosition('julien', { value: julienMarker }), 3000);
setInterval(() => fetchUserData('baptiste', {
name: 'user-name',
progression: 'user-progression',
avatar: 'user-avatar',
longitude: 'user-longitude',
latitude: 'user-latitude',
inactive: 'user-inactive',
}), 3000);
setInterval(() => fetchUserData('julien', {
name: 'user-name-julien',
progression: 'user-progression-julien',
avatar: 'user-avatar-julien',
longitude: 'user-longitude-julien',
latitude: 'user-latitude-julien',
inactive: 'user-inactive-julien',
}), 3000);
});