750 lines
28 KiB
JavaScript
750 lines
28 KiB
JavaScript
// Fonctionnalités sociales pour OEDB
|
|
|
|
class OEDBSocial {
|
|
constructor() {
|
|
this.socket = null;
|
|
this.position = null;
|
|
this.username = '';
|
|
this.friends = [];
|
|
this.markers = {};
|
|
this.map = null;
|
|
this.lastPouetTime = 0;
|
|
this.showOnlyFriends = false;
|
|
|
|
// Charger les amis depuis le localStorage
|
|
this.loadFriends();
|
|
|
|
// Boutons pour l'interface sociale
|
|
this.createSocialUI();
|
|
}
|
|
|
|
// Initialiser la connexion WebSocket
|
|
init(map, username) {
|
|
this.map = map;
|
|
this.username = username || localStorage.getItem('oedb_social_username') || '';
|
|
|
|
if (!this.username) {
|
|
this.promptForUsername();
|
|
} else {
|
|
localStorage.setItem('oedb_social_username', this.username);
|
|
}
|
|
|
|
// Créer la connexion WebSocket
|
|
// Utiliser l'URL relative au serveur actuel
|
|
const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
|
const wsUrl = `${wsProtocol}${window.location.host}/ws`;
|
|
this.socket = new WebSocket(wsUrl);
|
|
|
|
this.socket.onopen = () => {
|
|
console.log('Connexion WebSocket établie');
|
|
this.startSendingPosition();
|
|
};
|
|
|
|
this.socket.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
this.handleSocketMessage(data);
|
|
};
|
|
|
|
this.socket.onclose = () => {
|
|
console.log('Connexion WebSocket fermée');
|
|
// Tentative de reconnexion après 5 secondes
|
|
setTimeout(() => this.init(this.map, this.username), 5000);
|
|
};
|
|
|
|
this.socket.onerror = (error) => {
|
|
console.error('Erreur WebSocket:', error);
|
|
this.showToast(`Erreur de connexion au serveur WebSocket. Vérifiez que le serveur est en cours d'exécution sur le port 8765.`, 'error');
|
|
};
|
|
}
|
|
|
|
// Demander le pseudo à l'utilisateur
|
|
promptForUsername() {
|
|
// Créer une boîte de dialogue modale pour demander le pseudo
|
|
const modalOverlay = document.createElement('div');
|
|
modalOverlay.className = 'modal-overlay';
|
|
modalOverlay.style.position = 'fixed';
|
|
modalOverlay.style.top = '0';
|
|
modalOverlay.style.left = '0';
|
|
modalOverlay.style.width = '100%';
|
|
modalOverlay.style.height = '100%';
|
|
modalOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
|
modalOverlay.style.zIndex = '1000';
|
|
modalOverlay.style.display = 'flex';
|
|
modalOverlay.style.justifyContent = 'center';
|
|
modalOverlay.style.alignItems = 'center';
|
|
|
|
const modalContent = document.createElement('div');
|
|
modalContent.className = 'modal-content';
|
|
modalContent.style.backgroundColor = '#fff';
|
|
modalContent.style.padding = '20px';
|
|
modalContent.style.borderRadius = '5px';
|
|
modalContent.style.maxWidth = '400px';
|
|
modalContent.style.width = '80%';
|
|
|
|
const title = document.createElement('h3');
|
|
title.textContent = 'Choisissez un pseudo';
|
|
title.style.marginBottom = '15px';
|
|
|
|
const form = document.createElement('form');
|
|
form.onsubmit = (e) => {
|
|
e.preventDefault();
|
|
const input = document.getElementById('username-input');
|
|
const username = input.value.trim();
|
|
if (username) {
|
|
this.username = username;
|
|
localStorage.setItem('oedb_social_username', username);
|
|
document.body.removeChild(modalOverlay);
|
|
this.startSendingPosition();
|
|
}
|
|
};
|
|
|
|
const input = document.createElement('input');
|
|
input.type = 'text';
|
|
input.id = 'username-input';
|
|
input.placeholder = 'Votre pseudo';
|
|
input.style.width = '100%';
|
|
input.style.padding = '8px';
|
|
input.style.marginBottom = '15px';
|
|
input.style.borderRadius = '4px';
|
|
input.style.border = '1px solid #ddd';
|
|
|
|
const button = document.createElement('button');
|
|
button.type = 'submit';
|
|
button.textContent = 'Valider';
|
|
button.style.padding = '8px 15px';
|
|
button.style.backgroundColor = '#0078ff';
|
|
button.style.color = 'white';
|
|
button.style.border = 'none';
|
|
button.style.borderRadius = '4px';
|
|
button.style.cursor = 'pointer';
|
|
|
|
form.appendChild(input);
|
|
form.appendChild(button);
|
|
|
|
modalContent.appendChild(title);
|
|
modalContent.appendChild(form);
|
|
modalOverlay.appendChild(modalContent);
|
|
|
|
document.body.appendChild(modalOverlay);
|
|
|
|
input.focus();
|
|
}
|
|
|
|
// Commencer à envoyer sa position
|
|
startSendingPosition() {
|
|
if (!this.username || !this.socket) return;
|
|
|
|
// Obtenir la position actuelle
|
|
this.getCurrentPosition();
|
|
|
|
// Mettre à jour la position toutes les 5 secondes
|
|
setInterval(() => {
|
|
this.getCurrentPosition();
|
|
}, 5000);
|
|
}
|
|
|
|
// Obtenir la position GPS actuelle
|
|
getCurrentPosition() {
|
|
if (navigator.geolocation && this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
navigator.geolocation.getCurrentPosition(
|
|
(position) => {
|
|
this.position = {
|
|
lat: position.coords.latitude,
|
|
lng: position.coords.longitude
|
|
};
|
|
|
|
// Envoyer la position au serveur WebSocket
|
|
this.socket.send(JSON.stringify({
|
|
type: 'position',
|
|
username: this.username,
|
|
position: this.position,
|
|
timestamp: new Date().toISOString(),
|
|
showOnlyToFriends: this.showOnlyFriends
|
|
}));
|
|
},
|
|
(error) => {
|
|
console.error('Erreur lors de la récupération de la position:', error);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
// Traiter les messages reçus par WebSocket
|
|
handleSocketMessage(data) {
|
|
switch (data.type) {
|
|
case 'position':
|
|
this.updateUserPosition(data);
|
|
break;
|
|
case 'pouet':
|
|
this.receivePouet(data);
|
|
break;
|
|
case 'friendRequest':
|
|
this.receiveFriendRequest(data);
|
|
break;
|
|
case 'users':
|
|
this.updateAllUsers(data.users);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Mettre à jour la position d'un utilisateur sur la carte
|
|
updateUserPosition(data) {
|
|
// Ignorer les mises à jour de notre propre position
|
|
if (data.username === this.username) return;
|
|
|
|
// Vérifier si l'utilisateur est visible uniquement pour ses amis
|
|
if (data.showOnlyToFriends && !this.friends.includes(data.username)) return;
|
|
|
|
// Supprimer l'ancien marqueur s'il existe
|
|
if (this.markers[data.username]) {
|
|
this.markers[data.username].remove();
|
|
}
|
|
|
|
// Créer un élément HTML personnalisé pour le marqueur
|
|
const el = document.createElement('div');
|
|
el.className = 'user-marker';
|
|
|
|
// Styles de base pour le marqueur
|
|
el.style.width = '40px';
|
|
el.style.height = '40px';
|
|
el.style.borderRadius = '50%';
|
|
el.style.backgroundColor = this.friends.includes(data.username) ? '#4CAF50' : '#0078ff';
|
|
el.style.border = '2px solid white';
|
|
el.style.boxShadow = '0 0 5px rgba(0,0,0,0.3)';
|
|
el.style.display = 'flex';
|
|
el.style.justifyContent = 'center';
|
|
el.style.alignItems = 'center';
|
|
el.style.color = 'white';
|
|
el.style.fontWeight = 'bold';
|
|
el.style.fontSize = '12px';
|
|
el.style.cursor = 'pointer';
|
|
|
|
// Ajouter les initiales de l'utilisateur
|
|
const initials = data.username.substring(0, 2).toUpperCase();
|
|
el.textContent = initials;
|
|
|
|
// Ajouter un tooltip avec le nom complet
|
|
el.title = data.username;
|
|
|
|
// Créer le popup
|
|
const popupContent = `
|
|
<div class="user-popup" style="padding: 10px; max-width: 200px;">
|
|
<h3 style="margin-top: 0;">${data.username}</h3>
|
|
<p style="margin-bottom: 10px;">Position mise à jour: ${this.formatTimestamp(data.timestamp)}</p>
|
|
<div style="display: flex; justify-content: space-between;">
|
|
<button class="pouet-btn" style="padding: 5px 10px; background-color: #FFC107; border: none; border-radius: 3px; cursor: pointer;">Pouet Pouet!</button>
|
|
${!this.friends.includes(data.username) ? `
|
|
<button class="add-friend-btn" style="padding: 5px 10px; background-color: #4CAF50; color: white; border: none; border-radius: 3px; cursor: pointer;">Ajouter ami</button>
|
|
` : ''}
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
const popup = new maplibregl.Popup({
|
|
closeButton: true,
|
|
closeOnClick: true
|
|
}).setHTML(popupContent);
|
|
|
|
// Ajouter des gestionnaires d'événements au popup
|
|
popup.on('open', () => {
|
|
// Gérer le clic sur le bouton Pouet Pouet
|
|
setTimeout(() => {
|
|
const pouetBtn = document.querySelector('.pouet-btn');
|
|
if (pouetBtn) {
|
|
pouetBtn.addEventListener('click', () => {
|
|
this.sendPouet(data.username);
|
|
});
|
|
}
|
|
|
|
// Gérer le clic sur le bouton Ajouter ami
|
|
const addFriendBtn = document.querySelector('.add-friend-btn');
|
|
if (addFriendBtn) {
|
|
addFriendBtn.addEventListener('click', () => {
|
|
this.sendFriendRequest(data.username);
|
|
});
|
|
}
|
|
}, 100);
|
|
});
|
|
|
|
// Créer le marqueur et l'ajouter à la carte
|
|
const marker = new maplibregl.Marker(el)
|
|
.setLngLat([data.position.lng, data.position.lat])
|
|
.setPopup(popup)
|
|
.addTo(this.map);
|
|
|
|
// Stocker le marqueur pour pouvoir le supprimer plus tard
|
|
this.markers[data.username] = marker;
|
|
}
|
|
|
|
// Mettre à jour tous les utilisateurs actifs
|
|
updateAllUsers(users) {
|
|
// Supprimer les marqueurs des utilisateurs qui ne sont plus actifs
|
|
Object.keys(this.markers).forEach(username => {
|
|
if (!users.find(user => user.username === username)) {
|
|
this.markers[username].remove();
|
|
delete this.markers[username];
|
|
}
|
|
});
|
|
}
|
|
|
|
// Envoyer un pouet à un utilisateur
|
|
sendPouet(username) {
|
|
const now = Date.now();
|
|
|
|
// Vérifier si on peut envoyer un pouet (limité à 1 toutes les 10 secondes)
|
|
if (now - this.lastPouetTime < 10000) {
|
|
const remainingTime = Math.ceil((10000 - (now - this.lastPouetTime)) / 1000);
|
|
this.showToast(`Merci d'attendre encore ${remainingTime} secondes avant d'envoyer un autre pouet!`, 'warning');
|
|
return;
|
|
}
|
|
|
|
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
this.socket.send(JSON.stringify({
|
|
type: 'pouet',
|
|
from: this.username,
|
|
to: username,
|
|
timestamp: new Date().toISOString()
|
|
}));
|
|
|
|
this.lastPouetTime = now;
|
|
this.showToast(`Pouet pouet envoyé à ${username}!`, 'success');
|
|
}
|
|
}
|
|
|
|
// Recevoir un pouet
|
|
receivePouet(data) {
|
|
this.showToast(`${data.from} vous a envoyé un pouet pouet!`, 'info');
|
|
|
|
// Jouer un son
|
|
const audio = new Audio('/static/pouet.mp3');
|
|
audio.play().catch(e => console.log('Erreur lors de la lecture du son:', e));
|
|
}
|
|
|
|
// Envoyer une demande d'ami
|
|
sendFriendRequest(username) {
|
|
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
this.socket.send(JSON.stringify({
|
|
type: 'friendRequest',
|
|
from: this.username,
|
|
to: username,
|
|
timestamp: new Date().toISOString()
|
|
}));
|
|
|
|
this.showToast(`Demande d'ami envoyée à ${username}!`, 'success');
|
|
}
|
|
}
|
|
|
|
// Recevoir une demande d'ami
|
|
receiveFriendRequest(data) {
|
|
// Créer une boîte de dialogue modale pour la demande d'ami
|
|
const modalOverlay = document.createElement('div');
|
|
modalOverlay.className = 'modal-overlay';
|
|
modalOverlay.style.position = 'fixed';
|
|
modalOverlay.style.top = '0';
|
|
modalOverlay.style.left = '0';
|
|
modalOverlay.style.width = '100%';
|
|
modalOverlay.style.height = '100%';
|
|
modalOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
|
modalOverlay.style.zIndex = '1000';
|
|
modalOverlay.style.display = 'flex';
|
|
modalOverlay.style.justifyContent = 'center';
|
|
modalOverlay.style.alignItems = 'center';
|
|
|
|
const modalContent = document.createElement('div');
|
|
modalContent.className = 'modal-content';
|
|
modalContent.style.backgroundColor = '#fff';
|
|
modalContent.style.padding = '20px';
|
|
modalContent.style.borderRadius = '5px';
|
|
modalContent.style.maxWidth = '400px';
|
|
modalContent.style.width = '80%';
|
|
|
|
const title = document.createElement('h3');
|
|
title.textContent = 'Demande d\'ami';
|
|
title.style.marginBottom = '15px';
|
|
|
|
const message = document.createElement('p');
|
|
message.textContent = `${data.from} souhaite vous ajouter à sa liste d'amis.`;
|
|
message.style.marginBottom = '20px';
|
|
|
|
const buttonsContainer = document.createElement('div');
|
|
buttonsContainer.style.display = 'flex';
|
|
buttonsContainer.style.justifyContent = 'space-between';
|
|
|
|
const acceptButton = document.createElement('button');
|
|
acceptButton.textContent = 'Accepter';
|
|
acceptButton.style.padding = '8px 15px';
|
|
acceptButton.style.backgroundColor = '#4CAF50';
|
|
acceptButton.style.color = 'white';
|
|
acceptButton.style.border = 'none';
|
|
acceptButton.style.borderRadius = '4px';
|
|
acceptButton.style.cursor = 'pointer';
|
|
acceptButton.onclick = () => {
|
|
this.addFriend(data.from);
|
|
document.body.removeChild(modalOverlay);
|
|
};
|
|
|
|
const rejectButton = document.createElement('button');
|
|
rejectButton.textContent = 'Refuser';
|
|
rejectButton.style.padding = '8px 15px';
|
|
rejectButton.style.backgroundColor = '#f44336';
|
|
rejectButton.style.color = 'white';
|
|
rejectButton.style.border = 'none';
|
|
rejectButton.style.borderRadius = '4px';
|
|
rejectButton.style.cursor = 'pointer';
|
|
rejectButton.onclick = () => {
|
|
document.body.removeChild(modalOverlay);
|
|
};
|
|
|
|
buttonsContainer.appendChild(acceptButton);
|
|
buttonsContainer.appendChild(rejectButton);
|
|
|
|
modalContent.appendChild(title);
|
|
modalContent.appendChild(message);
|
|
modalContent.appendChild(buttonsContainer);
|
|
modalOverlay.appendChild(modalContent);
|
|
|
|
document.body.appendChild(modalOverlay);
|
|
}
|
|
|
|
// Ajouter un ami à la liste d'amis
|
|
addFriend(username) {
|
|
if (!this.friends.includes(username)) {
|
|
this.friends.push(username);
|
|
this.saveFriends();
|
|
this.showToast(`${username} a été ajouté à votre liste d'amis!`, 'success');
|
|
|
|
// Mettre à jour le marqueur de cet ami s'il est visible
|
|
if (this.markers[username]) {
|
|
const position = this.markers[username].getLngLat();
|
|
this.markers[username].remove();
|
|
delete this.markers[username];
|
|
|
|
// Simuler une mise à jour de position pour recréer le marqueur
|
|
this.updateUserPosition({
|
|
username: username,
|
|
position: {
|
|
lng: position.lng,
|
|
lat: position.lat
|
|
},
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sauvegarder la liste d'amis dans le localStorage
|
|
saveFriends() {
|
|
localStorage.setItem('oedb_social_friends', JSON.stringify(this.friends));
|
|
}
|
|
|
|
// Charger la liste d'amis depuis le localStorage
|
|
loadFriends() {
|
|
try {
|
|
const friendsJson = localStorage.getItem('oedb_social_friends');
|
|
if (friendsJson) {
|
|
this.friends = JSON.parse(friendsJson);
|
|
}
|
|
} catch (e) {
|
|
console.error('Erreur lors du chargement des amis:', e);
|
|
this.friends = [];
|
|
}
|
|
}
|
|
|
|
// Créer l'interface utilisateur pour les fonctionnalités sociales
|
|
createSocialUI() {
|
|
// Conteneur principal pour les contrôles sociaux
|
|
const socialContainer = document.createElement('div');
|
|
socialContainer.className = 'social-controls';
|
|
socialContainer.style.position = 'absolute';
|
|
socialContainer.style.top = '10px';
|
|
socialContainer.style.right = '10px';
|
|
socialContainer.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
|
|
socialContainer.style.padding = '10px';
|
|
socialContainer.style.borderRadius = '5px';
|
|
socialContainer.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.1)';
|
|
socialContainer.style.zIndex = '10';
|
|
socialContainer.style.display = 'flex';
|
|
socialContainer.style.flexDirection = 'column';
|
|
socialContainer.style.gap = '10px';
|
|
|
|
// Titre
|
|
const title = document.createElement('h3');
|
|
title.textContent = 'Mode Social';
|
|
title.style.margin = '0 0 10px 0';
|
|
title.style.textAlign = 'center';
|
|
|
|
// Bouton pour activer/désactiver le mode social
|
|
const toggleButton = document.createElement('button');
|
|
toggleButton.className = 'toggle-social-btn';
|
|
toggleButton.textContent = 'Activer le mode social';
|
|
toggleButton.style.padding = '8px';
|
|
toggleButton.style.backgroundColor = '#0078ff';
|
|
toggleButton.style.color = 'white';
|
|
toggleButton.style.border = 'none';
|
|
toggleButton.style.borderRadius = '4px';
|
|
toggleButton.style.cursor = 'pointer';
|
|
toggleButton.style.fontWeight = 'bold';
|
|
|
|
let socialActive = false;
|
|
|
|
toggleButton.addEventListener('click', () => {
|
|
socialActive = !socialActive;
|
|
|
|
if (socialActive) {
|
|
toggleButton.textContent = 'Désactiver le mode social';
|
|
toggleButton.style.backgroundColor = '#f44336';
|
|
this.init(this.map);
|
|
} else {
|
|
toggleButton.textContent = 'Activer le mode social';
|
|
toggleButton.style.backgroundColor = '#0078ff';
|
|
|
|
// Fermer la connexion WebSocket
|
|
if (this.socket) {
|
|
this.socket.close();
|
|
this.socket = null;
|
|
}
|
|
|
|
// Supprimer tous les marqueurs
|
|
Object.values(this.markers).forEach(marker => marker.remove());
|
|
this.markers = {};
|
|
}
|
|
|
|
// Afficher/masquer les options supplémentaires
|
|
optionsContainer.style.display = socialActive ? 'block' : 'none';
|
|
});
|
|
|
|
// Conteneur pour les options supplémentaires
|
|
const optionsContainer = document.createElement('div');
|
|
optionsContainer.className = 'social-options';
|
|
optionsContainer.style.display = 'none';
|
|
|
|
// Bouton pour changer de pseudo
|
|
const changeUsernameBtn = document.createElement('button');
|
|
changeUsernameBtn.textContent = 'Changer de pseudo';
|
|
changeUsernameBtn.style.width = '100%';
|
|
changeUsernameBtn.style.padding = '8px';
|
|
changeUsernameBtn.style.backgroundColor = '#FFC107';
|
|
changeUsernameBtn.style.border = 'none';
|
|
changeUsernameBtn.style.borderRadius = '4px';
|
|
changeUsernameBtn.style.marginBottom = '10px';
|
|
changeUsernameBtn.style.cursor = 'pointer';
|
|
|
|
changeUsernameBtn.addEventListener('click', () => {
|
|
this.promptForUsername();
|
|
});
|
|
|
|
// Case à cocher pour la visibilité uniquement aux amis
|
|
const visibilityContainer = document.createElement('div');
|
|
visibilityContainer.style.display = 'flex';
|
|
visibilityContainer.style.alignItems = 'center';
|
|
visibilityContainer.style.marginBottom = '10px';
|
|
|
|
const visibilityCheckbox = document.createElement('input');
|
|
visibilityCheckbox.type = 'checkbox';
|
|
visibilityCheckbox.id = 'visibility-checkbox';
|
|
visibilityCheckbox.checked = this.showOnlyFriends;
|
|
|
|
const visibilityLabel = document.createElement('label');
|
|
visibilityLabel.htmlFor = 'visibility-checkbox';
|
|
visibilityLabel.textContent = 'Visible uniquement par mes amis';
|
|
visibilityLabel.style.marginLeft = '5px';
|
|
|
|
visibilityContainer.appendChild(visibilityCheckbox);
|
|
visibilityContainer.appendChild(visibilityLabel);
|
|
|
|
visibilityCheckbox.addEventListener('change', () => {
|
|
this.showOnlyFriends = visibilityCheckbox.checked;
|
|
this.getCurrentPosition(); // Mettre à jour immédiatement avec le nouveau paramètre
|
|
});
|
|
|
|
// Gestionnaire d'amis
|
|
const friendsManager = document.createElement('div');
|
|
friendsManager.style.marginTop = '10px';
|
|
|
|
const friendsTitle = document.createElement('h4');
|
|
friendsTitle.textContent = 'Mes amis';
|
|
friendsTitle.style.margin = '0 0 5px 0';
|
|
|
|
const friendsList = document.createElement('ul');
|
|
friendsList.style.listStyle = 'none';
|
|
friendsList.style.padding = '0';
|
|
friendsList.style.margin = '0';
|
|
friendsList.style.maxHeight = '150px';
|
|
friendsList.style.overflowY = 'auto';
|
|
friendsList.style.border = '1px solid #ddd';
|
|
friendsList.style.borderRadius = '4px';
|
|
friendsList.style.padding = '5px';
|
|
|
|
// Fonction pour mettre à jour la liste d'amis
|
|
const updateFriendsList = () => {
|
|
friendsList.innerHTML = '';
|
|
|
|
if (this.friends.length === 0) {
|
|
const emptyItem = document.createElement('li');
|
|
emptyItem.textContent = 'Aucun ami pour l\'instant';
|
|
emptyItem.style.fontStyle = 'italic';
|
|
emptyItem.style.padding = '5px';
|
|
friendsList.appendChild(emptyItem);
|
|
} else {
|
|
this.friends.forEach(friend => {
|
|
const listItem = document.createElement('li');
|
|
listItem.style.display = 'flex';
|
|
listItem.style.justifyContent = 'space-between';
|
|
listItem.style.alignItems = 'center';
|
|
listItem.style.padding = '5px';
|
|
listItem.style.borderBottom = '1px solid #eee';
|
|
|
|
const friendName = document.createElement('span');
|
|
friendName.textContent = friend;
|
|
|
|
const removeBtn = document.createElement('button');
|
|
removeBtn.textContent = 'X';
|
|
removeBtn.style.backgroundColor = '#f44336';
|
|
removeBtn.style.color = 'white';
|
|
removeBtn.style.border = 'none';
|
|
removeBtn.style.borderRadius = '50%';
|
|
removeBtn.style.width = '20px';
|
|
removeBtn.style.height = '20px';
|
|
removeBtn.style.fontSize = '10px';
|
|
removeBtn.style.cursor = 'pointer';
|
|
removeBtn.style.display = 'flex';
|
|
removeBtn.style.justifyContent = 'center';
|
|
removeBtn.style.alignItems = 'center';
|
|
|
|
removeBtn.addEventListener('click', () => {
|
|
this.friends = this.friends.filter(f => f !== friend);
|
|
this.saveFriends();
|
|
updateFriendsList();
|
|
});
|
|
|
|
listItem.appendChild(friendName);
|
|
listItem.appendChild(removeBtn);
|
|
friendsList.appendChild(listItem);
|
|
});
|
|
}
|
|
};
|
|
|
|
// Initialiser la liste d'amis
|
|
updateFriendsList();
|
|
|
|
friendsManager.appendChild(friendsTitle);
|
|
friendsManager.appendChild(friendsList);
|
|
|
|
// Ajouter tous les éléments au conteneur d'options
|
|
optionsContainer.appendChild(changeUsernameBtn);
|
|
optionsContainer.appendChild(visibilityContainer);
|
|
optionsContainer.appendChild(friendsManager);
|
|
|
|
// Ajouter tous les éléments au conteneur principal
|
|
socialContainer.appendChild(title);
|
|
socialContainer.appendChild(toggleButton);
|
|
socialContainer.appendChild(optionsContainer);
|
|
|
|
// Ajouter le conteneur au document après le chargement du DOM
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
document.body.appendChild(socialContainer);
|
|
});
|
|
}
|
|
|
|
// Afficher un toast (message flottant)
|
|
showToast(message, type = 'info') {
|
|
// Créer le conteneur de toast s'il n'existe pas
|
|
let toastContainer = document.getElementById('toast-container');
|
|
|
|
if (!toastContainer) {
|
|
toastContainer = document.createElement('div');
|
|
toastContainer.id = 'toast-container';
|
|
toastContainer.style.position = 'fixed';
|
|
toastContainer.style.top = '20px';
|
|
toastContainer.style.left = '50%';
|
|
toastContainer.style.transform = 'translateX(-50%)';
|
|
toastContainer.style.zIndex = '1000';
|
|
toastContainer.style.display = 'flex';
|
|
toastContainer.style.flexDirection = 'column';
|
|
toastContainer.style.alignItems = 'center';
|
|
toastContainer.style.gap = '10px';
|
|
document.body.appendChild(toastContainer);
|
|
}
|
|
|
|
// Créer le toast
|
|
const toast = document.createElement('div');
|
|
toast.className = `toast toast-${type}`;
|
|
toast.style.padding = '10px 15px';
|
|
toast.style.borderRadius = '5px';
|
|
toast.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.2)';
|
|
toast.style.minWidth = '250px';
|
|
toast.style.textAlign = 'center';
|
|
toast.style.animation = 'fadeIn 0.3s, fadeOut 0.3s 2.7s';
|
|
toast.style.opacity = '0';
|
|
toast.style.maxWidth = '80vw';
|
|
|
|
// Définir la couleur en fonction du type
|
|
switch (type) {
|
|
case 'success':
|
|
toast.style.backgroundColor = '#4CAF50';
|
|
toast.style.color = 'white';
|
|
break;
|
|
case 'warning':
|
|
toast.style.backgroundColor = '#FFC107';
|
|
toast.style.color = 'black';
|
|
break;
|
|
case 'error':
|
|
toast.style.backgroundColor = '#f44336';
|
|
toast.style.color = 'white';
|
|
break;
|
|
default: // info
|
|
toast.style.backgroundColor = '#0078ff';
|
|
toast.style.color = 'white';
|
|
}
|
|
|
|
toast.textContent = message;
|
|
|
|
// Ajouter le style d'animation s'il n'existe pas
|
|
if (!document.getElementById('toast-style')) {
|
|
const style = document.createElement('style');
|
|
style.id = 'toast-style';
|
|
style.textContent = `
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(-20px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
@keyframes fadeOut {
|
|
from { opacity: 1; transform: translateY(0); }
|
|
to { opacity: 0; transform: translateY(-20px); }
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
}
|
|
|
|
// Ajouter le toast au conteneur
|
|
toastContainer.appendChild(toast);
|
|
|
|
// Animer l'entrée
|
|
setTimeout(() => {
|
|
toast.style.opacity = '1';
|
|
toast.style.transform = 'translateY(0)';
|
|
}, 10);
|
|
|
|
// Supprimer le toast après 3 secondes
|
|
setTimeout(() => {
|
|
toast.style.opacity = '0';
|
|
toast.style.transform = 'translateY(-20px)';
|
|
|
|
setTimeout(() => {
|
|
toastContainer.removeChild(toast);
|
|
}, 300);
|
|
}, 3000);
|
|
}
|
|
|
|
// Formatter un timestamp en heure locale
|
|
formatTimestamp(timestamp) {
|
|
const date = new Date(timestamp);
|
|
return date.toLocaleTimeString();
|
|
}
|
|
}
|
|
|
|
// Initialiser l'objet social lorsque le DOM est chargé
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Créer l'instance sociale
|
|
window.oedbSocial = new OEDBSocial();
|
|
});
|