Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Bilal Dieumegard 2024-12-16 12:12:39 +01:00
commit b1d3cbd786
2 changed files with 42 additions and 61 deletions

View file

@ -0,0 +1,4 @@
import { writable } from 'svelte/store';
export const messagesStore = writable<string[]>([]);

View file

@ -4,20 +4,20 @@
import PaperPlane from "svelte-radix/PaperPlane.svelte"; import PaperPlane from "svelte-radix/PaperPlane.svelte";
import Message from "$lib/components/Message.svelte"; import Message from "$lib/components/Message.svelte";
import UserChat from '$lib/components/ui/UserChat.svelte'; import UserChat from '$lib/components/ui/UserChat.svelte';
import { onMount, tick, onDestroy } from 'svelte'; import { tick, onDestroy, onMount } from 'svelte';
import { initSocket } from '$lib/stores/socket'; import { initSocket } from '$lib/stores/socket';
import { ArrowLeft } from 'lucide-svelte'; import { ArrowLeft } from 'lucide-svelte';
import { messagesStore } from '$lib/stores/messagesStore';
export let data; export let data;
export let messages = data.messages.messages;
messagesStore.set(data.messages.messages);
let user = data.user; let user = data.user;
const socket = initSocket(); // Initialiser le socket const socket = initSocket(); // Initialiser le socket
let users= []; let users= [];
let isAtBottom = true;
let previousHeight = 0;
let scrollContainer: HTMLElement; let scrollContainer: HTMLElement;
let messageText = ''; let messageText = '';
@ -43,8 +43,6 @@
socket.emit('new-message', newMessage); socket.emit('new-message', newMessage);
console.log('Message envoyé avec succès'); console.log('Message envoyé avec succès');
messageText = ''; messageText = '';
isAtBottom = true;
await scrollToBottom();
}else{ }else{
console.log('Erreur lors de l\'envoi du message'); console.log('Erreur lors de l\'envoi du message');
} }
@ -61,7 +59,7 @@
try { try {
// Calculer la page à charger en fonction du nombre total de messages existants // Calculer la page à charger en fonction du nombre total de messages existants
const totalMessages = messages.length; const totalMessages = $messagesStore.length;
const pageToLoad = Math.floor(totalMessages / limit) + 1; const pageToLoad = Math.floor(totalMessages / limit) + 1;
const response = await fetch(`/api/channels/${data.channelId}/messages?page=${pageToLoad}&limit=${limit}`, { const response = await fetch(`/api/channels/${data.channelId}/messages?page=${pageToLoad}&limit=${limit}`, {
@ -80,13 +78,13 @@
} }
// Éviter les doublons en filtrant les messages déjà présents // Éviter les doublons en filtrant les messages déjà présents
const existingMessageIds = new Set(messages.map((msg) => msg.id)); const existingMessageIds = new Set($messagesStore.map((msg) => msg.id));
const filteredMessages = newMessages.messages.filter( const filteredMessages = newMessages.messages.filter(
(msg) => !existingMessageIds.has(msg.id) (msg) => !existingMessageIds.has(msg.id)
); );
if (filteredMessages.length > 0) { if (filteredMessages.length > 0) {
messages = [...filteredMessages, ...messages]; // Ajouter les nouveaux messages en haut $messagesStore = [...filteredMessages, ...$messagesStore]; // Ajouter les nouveaux messages en haut
console.log(`${filteredMessages.length} nouveaux messages ajoutés`); console.log(`${filteredMessages.length} nouveaux messages ajoutés`);
} else { } else {
console.log("Aucun nouveau message à ajouter (tous déjà chargés)"); console.log("Aucun nouveau message à ajouter (tous déjà chargés)");
@ -101,19 +99,6 @@
} }
} }
function handleScroll(event: Event) {
const container = event.target as HTMLElement;
// Vérifiez si l'utilisateur est proche du bas du conteneur
const threshold = 50; // Pixels avant d'atteindre le bas
const position = container.scrollHeight - container.scrollTop - container.clientHeight;
isAtBottom = position <= threshold;
if(container.scrollTop <= 0){
loadMoreMessages();
}
}
async function handleEnter(event: KeyboardEvent) { async function handleEnter(event: KeyboardEvent) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
await sendMessage(); await sendMessage();
@ -134,38 +119,24 @@
socket.emit('stop-writing', { userId: data.userId, channelId: data.channelId }); socket.emit('stop-writing', { userId: data.userId, channelId: data.channelId });
} }
async function scrollToBottom() { async function scrollToBottom(retries = 3) {
if (scrollContainer && isAtBottom) {
await tick(); await tick();
scrollContainer.scrollTop = scrollContainer.scrollHeight;
}
}
let isFirstLoad = 0; const attemptScroll = () => {
onMount(async () => {
if (scrollContainer) { if (scrollContainer) {
const observer = new MutationObserver(async () => { scrollContainer.scrollTo({
if (isFirstLoad <= messages.length) { top: scrollContainer.scrollHeight,
await scrollToBottom(); // Appel à scrollToBottom() seulement lors du premier chargement behavior: 'smooth',
isFirstLoad++; // Une fois les messages chargés pour la première fois, on empêche les appels suivants
}
if(scrollContainer.scrollTop <= 5){
const newHeight = scrollContainer.scrollHeight;
if (newHeight !== previousHeight) {
scrollContainer.scrollTop = scrollContainer.scrollHeight - previousHeight;
previousHeight = newHeight;
}
}
}); });
observer.observe(scrollContainer, { childList: true, subtree: true });
isAtBottom = true;
return () => observer.disconnect();
} }
}); };
attemptScroll();
if (retries > 0) {
requestAnimationFrame(() => scrollToBottom(retries - 1));
}
}
onDestroy(() => { onDestroy(() => {
socket.emit('leave-channel', { userId: data.userId, channelId: data.channelId }); socket.emit('leave-channel', { userId: data.userId, channelId: data.channelId });
@ -174,10 +145,12 @@
// Ecoute des événements socket // Ecoute des événements socket
socket.on("new-message", async (message) => { socket.on("new-message", async (message) => {
messages = [...messages, message]; // Ajouter le message à l'historique $messagesStore = [...$messagesStore, message]; // Add the new message to the store
await tick(); await tick();
await scrollToBottom(); // Scroll to the bottom after the message is added
}); });
socket.on("load-users-channel", async (us) => { socket.on("load-users-channel", async (us) => {
users = us; users = us;
await tick(); await tick();
@ -211,7 +184,6 @@
socket.on('user-stop-writing', async (userId) => { socket.on('user-stop-writing', async (userId) => {
console.log('user-stop-writing reçu pour userId:', userId); console.log('user-stop-writing reçu pour userId:', userId);
// On met à jour l'état de l'utilisateur
users = users.map((u) => { users = users.map((u) => {
if (u.id === userId) { if (u.id === userId) {
// Mettre à jour le state // Mettre à jour le state
@ -220,16 +192,22 @@
return u; return u;
}); });
// On recrée une nouvelle référence du tableau `users`
users = [...users]; // Cela force Svelte à détecter le changement dans la liste users = [...users]; // Cela force Svelte à détecter le changement dans la liste
console.log('Utilisateurs après mise à jour de l\'état:', users); console.log('Utilisateurs après mise à jour de l\'état:', users);
// Forcer une mise à jour avec tick
await tick(); await tick();
}); });
messagesStore.subscribe(async () => {
await tick();
await scrollToBottom();
});
onMount(async () => {
await tick();
await scrollToBottom();
});
</script> </script>
@ -253,15 +231,14 @@
<div class="flex-1 flex flex-col h-full"> <div class="flex-1 flex flex-col h-full">
<!-- Messages --> <!-- Messages -->
<div <div
class="m-10 flex flex-col gap-5 overflow-y-auto flex-grow " class="m-10 flex flex-col gap-5 overflow-auto flex-grow"
bind:this={scrollContainer} bind:this={scrollContainer}
on:scroll={handleScroll}
> >
{#if isLoading} {#if isLoading}
<div class="loading-indicator">Chargement...</div> <div class="loading-indicator">Chargement...</div>
{/if} {/if}
{#if messages !== undefined && messages.length > 0} {#if $messagesStore !== undefined && $messagesStore.length > 0}
{#each messages as message} {#each $messagesStore as message}
<Message <Message
userId={data.userId} userId={data.userId}
message={message} message={message}