diff --git a/app/Http/Controllers/ChatController.php b/app/Http/Controllers/ChatController.php index 867a001..35bc736 100644 --- a/app/Http/Controllers/ChatController.php +++ b/app/Http/Controllers/ChatController.php @@ -1,6 +1,7 @@ user()->chats() - ->with(['messages' => function ($query) { - $query->latest()->limit(1); - }, 'members']) // Assure-toi que la relation members est chargée - ->latest() - ->get() - ->map(function ($discussion) { - // Vérifie si la discussion est un chat individuel (2 membres) - if ($discussion->members->count() == 2) { - // Détermine l'image en fonction des membres - $otherMember = $discussion->members->first()->id == auth()->id() - ? $discussion->members->skip(1)->first() - : $discussion->members->first(); - - // Ajoute l'image sélectionnée comme propriété de la discussion - $discussion->discussionPicture = $otherMember->image - ? asset('storage/' . $otherMember->image) - : asset('source/assets/avatar/avatar.png'); - } else { - // Utilise une image par défaut pour les groupes - $discussion->discussionPicture = asset('source/assets/images/group.png'); - } - - return $discussion; - }); + ->with(['messages' => function ($query) { + $query->latest()->limit(1); + }, 'members']) // Assure-toi que la relation members est chargée + ->latest() + ->get() + ->map(function ($discussion) { + // Vérifie si la discussion est un chat individuel (2 membres) + if ($discussion->members->count() == 2) { + // Détermine l'image en fonction des membres + $otherMember = $discussion->members->first()->id == auth()->id() + ? $discussion->members->skip(1)->first() + : $discussion->members->first(); + + // Ajoute l'image sélectionnée comme propriété de la discussion + $discussion->discussionPicture = $otherMember->image + ? asset('storage/' . $otherMember->image) + : asset('source/assets/avatar/avatar.png'); + } else { + // Utilise une image par défaut pour les groupes + $discussion->discussionPicture = asset('source/assets/images/group.png'); + } + + return $discussion; + }); // Récupérer les amis acceptés $friends = Friendship::where(function ($query) { $query->where('user_id', auth()->id()) ->orWhere('friend_id', auth()->id()); - }) + }) ->where('status', 'accepted') ->with('user', 'friend') ->get() @@ -68,19 +69,60 @@ public function getMessages($chatId) } public function storeMessage(Request $request, $chatId) - { - $request->validate([ - 'message' => 'required|string', - ]); - $message = new Message(); - $message->user_id = auth()->id(); - $message->chat_id = $chatId; - $message->message = $request->message; - $message->save(); +{ + $request->validate([ + 'message' => 'required|string', + ]); - return response()->json(['message' => $message]); + $chat = Chat::with('members')->find($chatId); + + if (!$chat || !$chat->members->contains(auth()->id())) { + return response()->json(['error' => 'Chat not found or unauthorized.'], 404); } + if ($chat->members->count() > 2) { + $blockedByAnyone = $chat->members->filter(function ($member) { + return $member->id !== auth()->id(); + })->contains(function ($member) { + $friendship = Friendship::where(function ($query) use ($member) { + $query->where('user_id', auth()->id()) + ->where('friend_id', $member->id); + })->orWhere(function ($query) use ($member) { + $query->where('user_id', $member->id) + ->where('friend_id', auth()->id()); + })->first(); + + return $friendship && $friendship->isBlocked(); + }); + + if ($blockedByAnyone) { + return response()->json(['error' => 'You are blocked by one of the members of this group.']); + } + } else { + $otherMember = $chat->members->firstWhere('id', '!=', auth()->id()); + + $friendship = Friendship::where(function ($query) use ($otherMember) { + $query->where('user_id', auth()->id()) + ->where('friend_id', $otherMember->id); + })->orWhere(function ($query) use ($otherMember) { + $query->where('user_id', $otherMember->id) + ->where('friend_id', auth()->id()); + })->first(); + + if ($friendship && $friendship->isBlocked()) { + return response()->json(['error' => 'You are blocked by this user or you blocked this user.']); + } + } + + $message = new Message(); + $message->user_id = auth()->id(); + $message->chat_id = $chatId; + $message->message = $request->message; + $message->save(); + + return response()->json(['message' => $message]); +} + public function storeChat(Request $request) { // Valider les champs du formulaire @@ -104,5 +146,4 @@ public function storeChat(Request $request) // Rediriger avec un message de succès return redirect()->route('dashboard')->with('success', 'Discussion créée avec succès !'); } - } diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 592c4cd..d7956de 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -1,17 +1,16 @@
- - + -
-
@@ -21,126 +20,104 @@ let currentChatId = null; let interval = null; let allMessages = []; + const currentUserId = {{ auth()->id() }}; - // Fonction pour charger la discussion function loadChat(chatId, discussionName, discussionPicture, newOpening = true) { - const messagesContainer = document.getElementById('messages'); + const messagesContainer = document.getElementById('messages'); - // Masquer le placeholder et afficher la zone de chat - document.getElementById('chat-placeholder').style.display = 'none'; - document.getElementById('chat-area').style.display = 'flex'; + document.getElementById('chat-placeholder').style.display = 'none'; + document.getElementById('chat-area').style.display = 'flex'; - // Vérifier si la discussion est déjà chargée - if (currentChatId !== chatId) { - // Réinitialiser la liste de tout les messages - allMessages = []; - document.getElementById('messages').innerHTML = ''; - } + if (currentChatId !== chatId) { + allMessages = []; + messagesContainer.innerHTML = ''; + } - // Mettre à jour l'ID de la discussion actuelle - currentChatId = chatId; + currentChatId = chatId; - // Mettre à jour le titre du header si nécessaire - if (newOpening) { - const headerTitle = document.querySelector('.headerTitle'); - if (headerTitle) headerTitle.textContent = discussionName; + if (newOpening) { + const headerTitle = document.querySelector('.headerTitle'); + if (headerTitle) headerTitle.textContent = discussionName; - const headerImage = document.querySelector('.headerImage'); - if(headerImage) headerImage.src = discussionPicture; - } + const headerImage = document.querySelector('.headerImage'); + if (headerImage) headerImage.src = discussionPicture; + } - fetch(`/chat/${chatId}/messages`, { - method: 'GET', - headers: { - 'X-Requested-With': 'XMLHttpRequest', - 'X-CSRF-TOKEN': '{{ csrf_token() }}' - } - }) - .then(response => response.json()) - .then(data => { - let newMessages = []; - // Si la liste de tout les messages correspond à la liste actuelle - if (JSON.stringify(allMessages) === JSON.stringify(data.messages)) { - return; - } else if (allMessages.length === 0) { - // Si la liste de tout les messages est vide - newMessages = data.messages; - } else { - // Récupérer la liste des messages qui ne sont pas déjà affichés - newMessages = data.messages.filter(message => !allMessages.some(m => m.id === message.id)); + fetch(`/chat/${chatId}/messages`, { + method: 'GET', + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'X-CSRF-TOKEN': '{{ csrf_token() }}' + } + }) + .then(response => response.json()) + .then(data => { + let newMessages = []; + + if (JSON.stringify(allMessages) === JSON.stringify(data.messages)) { + return; + } else if (allMessages.length === 0) { + newMessages = data.messages; + } else { + newMessages = data.messages.filter(message => !allMessages.some(m => m.id === message.id)); + } + + const isAtBottom = messagesContainer.scrollHeight - messagesContainer.scrollTop === messagesContainer.clientHeight; + + newMessages.forEach(message => { + const isCurrentUser = message.user_id === currentUserId; + const messageElement = document.createElement('div'); + messageElement.className = `flex ${isCurrentUser ? 'justify-end' : 'justify-start'} mb-2`; + + let messageContent = ` +

+ ${message.user.name} + ${message.message} +

+ `; + + if (message.media_url) { + if (message.media_url.endsWith('.mp4')) { + messageContent = ` + `; + } else if (message.media_url.endsWith('.mp3')) { + messageContent = ` + `; + } else { + messageContent = ` + +

${message.message}

`; + } } - // Récupérer la position dans le scroll et vérifier si on est tout en bas - // Utile pour savoir si on doit défiler jusqu'en bas après l'ajout des nouveaux messages ou si l'utilisateur est entrain de consulter des anciens messages - const isAtBottom = messagesContainer.scrollHeight - messagesContainer.scrollTop === messagesContainer.clientHeight; - - // Parcourir les messages et les ajouter - newMessages.forEach(message => { - const isCurrentUser = message.user_id === {{ auth()->id() }}; - const messageElement = document.createElement('div'); - messageElement.className = `flex ${isCurrentUser ? 'justify-end' : 'justify-start'} mb-2`; - messageElement.innerHTML = ` - -

- - ${message.user.name} - ${message.message} -

`; - - // Gestion des médias - if (message.media_url) { - let mediaElement = - ` -
- ${message.user.name}`; - if (message.media_url.endsWith('.mp4')) { - mediaElement += ` - `; - } else if (message.media_url.endsWith('.mp3')) { - mediaElement += ` - `; - } else { - mediaElement += ` - `; - } - - mediaElement += ` -

- ${message.message} -

-
`; - messageElement.innerHTML = mediaElement; + messageElement.innerHTML = messageContent; + messagesContainer.appendChild(messageElement); + }); + + allMessages = data.messages; + + const mediaElements = document.querySelectorAll('img, video'); + mediaElements.forEach(mediaElement => { + mediaElement.addEventListener('load', () => { + if (isAtBottom) { + scrollToBottom(); } - messagesContainer.appendChild(messageElement); }); + }); - // Mettre à jour la liste de tout les messages - allMessages = data.messages; - - // Attendre que tout les médias soient chargés avant de faire défiler - const mediaElements = document.querySelectorAll('img, video'); - mediaElements.forEach(mediaElement => { - mediaElement.addEventListener('load', () => { - if (isAtBottom) { - scrollToBottom() - }; - }); - }); + if (isAtBottom) { + scrollToBottom(); + } + }) + .catch(error => console.error('Erreur:', error)); +} - // Faire défiler jusqu'en bas (utile si il y a pas de médias) - if (isAtBottom) { - scrollToBottom() - }; - }) - .catch(error => console.error('Erreur:', error)) - } - // Fonction pour démarrer la mise à jour automatique des messages function startAutoRefresh(intervalTime = 500) { if (interval) clearInterval(interval); interval = setInterval(() => { @@ -164,13 +141,29 @@ function sendMessage() { message: messageContent }) }) - .then(() => { - document.getElementById('message-content').value = ''; + .then(response => { + return response.json(); }) - .catch(error => console.error('Erreur:', error)); + .then(data => { + const errorMessage = document.getElementById('error-message'); + if (data.error) { + errorMessage.textContent = data.error; + errorMessage.style.display = 'block'; + } else { + + document.getElementById('message-content').value = ''; + errorMessage.style.display = 'none'; + } + }) + .catch(error => { + console.error('Erreur:', error); + const errorMessage = document.getElementById('error-message'); + errorMessage.textContent = 'Une erreur est survenue. Veuillez réessayer.'; + errorMessage.style.display = 'block'; + }); } - // Fonction pour faire défiler les messages jusqu'en bas + function scrollToBottom() { const messagesContainer = document.getElementById('messages'); if (messagesContainer) { @@ -178,5 +171,5 @@ function scrollToBottom() { } } - startAutoRefresh(); // Démarrer l'auto-rafraîchissement + startAutoRefresh(); \ No newline at end of file