Modification des scroll dans les messages
This commit is contained in:
parent
33e4bc87d9
commit
1a97f720a7
2 changed files with 71 additions and 49 deletions
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from "$lib/components/ui/card";
|
import * as Card from "$lib/components/ui/card";
|
||||||
import { formatDistanceToNow } from "$lib/utils/date.js";
|
import { formatDistanceToNow } from '$lib/utils/date.js';
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import ProfileInfo from "$lib/components/ui/ProfileInfo.svelte"; // Importer le composant ProfileInfo
|
import ProfileInfo from "$lib/components/ui/ProfileInfo.svelte"; // Importer le composant ProfileInfo
|
||||||
|
|
||||||
|
@ -11,14 +11,6 @@
|
||||||
export let setActiveProfile;
|
export let setActiveProfile;
|
||||||
export let activeProfileId = null;
|
export let activeProfileId = null;
|
||||||
|
|
||||||
// Temps écoulé (calculé périodiquement)
|
|
||||||
let timeElapsed: string;
|
|
||||||
|
|
||||||
// Fonction pour mettre à jour le temps écoulé
|
|
||||||
const updateElapsed = () => {
|
|
||||||
timeElapsed = formatDistanceToNow(message.createdAt);
|
|
||||||
};
|
|
||||||
|
|
||||||
let user = null;
|
let user = null;
|
||||||
|
|
||||||
async function fetchUser() {
|
async function fetchUser() {
|
||||||
|
@ -30,22 +22,9 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
console.log(data)
|
|
||||||
user = data;
|
user = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialisation de l'intervalle
|
|
||||||
onMount(async () => {
|
|
||||||
updateElapsed(); // Calcul initial
|
|
||||||
const interval = setInterval(updateElapsed, 1000); // Mise à jour toutes les secondes
|
|
||||||
|
|
||||||
await fetchUser();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearInterval(interval); // Nettoyage lors du démontage
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
function toggleProfileInfo() {
|
function toggleProfileInfo() {
|
||||||
if (activeProfileId === message.id) {
|
if (activeProfileId === message.id) {
|
||||||
// Si le profil cliqué est déjà actif, le fermer
|
// Si le profil cliqué est déjà actif, le fermer
|
||||||
|
@ -56,7 +35,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let timeElapsed: string;
|
||||||
|
|
||||||
|
// Fonction pour mettre à jour le temps écoulé
|
||||||
|
const updateElapsed = () => {
|
||||||
|
timeElapsed = formatDistanceToNow(message.createdAt);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialisation de l'intervalle
|
||||||
|
onMount(() => {
|
||||||
|
fetchUser();
|
||||||
|
updateElapsed(); // Calcul initial
|
||||||
|
const interval = setInterval(updateElapsed, 1000); // Mise à jour toutes les secondes
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval); // Nettoyage lors du démontage
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
export let users = data.users;
|
export let users = data.users;
|
||||||
|
|
||||||
|
|
||||||
|
let isAtBottom = true;
|
||||||
|
let previousHeight = 0;
|
||||||
let scrollContainer: HTMLElement;
|
let scrollContainer: HTMLElement;
|
||||||
let messageText = '';
|
let messageText = '';
|
||||||
|
|
||||||
|
@ -36,11 +38,12 @@
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
let newMessage =await response.json();
|
let newMessage =await response.json();
|
||||||
|
|
||||||
// Envoyer le message avec les sockets (à implémenter)
|
// Envoyer le message avec les sockets (à implémenter)
|
||||||
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');
|
||||||
}
|
}
|
||||||
|
@ -50,11 +53,11 @@
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
async function loadMoreMessages() {
|
async function loadMoreMessages() {
|
||||||
if (isLoading) return;
|
|
||||||
isLoading = true;
|
|
||||||
|
|
||||||
// Sauvegarder la hauteur actuelle
|
if (isLoading) {
|
||||||
const previousHeight = scrollContainer.scrollHeight;
|
return;
|
||||||
|
}
|
||||||
|
isLoading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/channels/${data.channelId}/messages?page=${currentPage + 1}&limit=10`, {
|
const response = await fetch(`/api/channels/${data.channelId}/messages?page=${currentPage + 1}&limit=10`, {
|
||||||
|
@ -81,42 +84,65 @@
|
||||||
} finally {
|
} finally {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
// Réajuster la position de défilement
|
|
||||||
await tick(); // Attendre la mise à jour du DOM
|
|
||||||
const newHeight = scrollContainer.scrollHeight;
|
|
||||||
scrollContainer.scrollTop = newHeight - previousHeight;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleScroll(event: Event) {
|
function handleScroll(event: Event) {
|
||||||
const container = event.target as HTMLElement;
|
const container = event.target as HTMLElement;
|
||||||
if (container.scrollTop === 0 && !isLoading) {
|
|
||||||
|
// 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 <= threshold){
|
||||||
loadMoreMessages();
|
loadMoreMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
socket.on("new-message", (message) => {
|
|
||||||
messages = [...messages , message ];
|
|
||||||
});
|
|
||||||
scrollToBottom(scrollContainer);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function handleEnter(event: KeyboardEvent) {
|
async function handleEnter(event: KeyboardEvent) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
await sendMessage();
|
await sendMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollToBottom = node => {
|
async function scrollToBottom() {
|
||||||
const scroll = () => node.scroll({
|
if (scrollContainer && isAtBottom) {
|
||||||
top: node.scrollHeight,
|
await tick();
|
||||||
behavior: 'smooth',
|
scrollContainer.scrollTop = scrollContainer.scrollHeight;
|
||||||
});
|
}
|
||||||
scroll();
|
}
|
||||||
|
|
||||||
return { update: scroll }
|
|
||||||
};
|
|
||||||
|
onMount(() => {
|
||||||
|
if (scrollContainer) {
|
||||||
|
const observer = new MutationObserver(async () => {
|
||||||
|
await scrollToBottom();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on("new-message", async (message) => {
|
||||||
|
messages = [...messages , message ];
|
||||||
|
await tick();
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -144,13 +170,11 @@
|
||||||
<div
|
<div
|
||||||
class="m-10 flex flex-col gap-5 overflow-y-auto flex-grow "
|
class="m-10 flex flex-col gap-5 overflow-y-auto flex-grow "
|
||||||
bind:this={scrollContainer}
|
bind:this={scrollContainer}
|
||||||
use:scrollToBottom={messages}
|
|
||||||
on:scroll={handleScroll}
|
on:scroll={handleScroll}
|
||||||
>
|
>
|
||||||
{#if isLoading}
|
{#if isLoading}
|
||||||
<div class="loading-indicator">Chargement...</div>
|
<div class="loading-indicator">Chargement...</div>
|
||||||
{/if}
|
{/if}
|
||||||
<!-- Afficher les messages (mock d'un utilisateur sélectionné ou aucun message par défaut) -->
|
|
||||||
{#if messages !== undefined && messages.length > 0}
|
{#if messages !== undefined && messages.length > 0}
|
||||||
{#each messages as message}
|
{#each messages as message}
|
||||||
<Message
|
<Message
|
||||||
|
@ -184,4 +208,7 @@
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
color: gray;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
.overflow-y-auto {
|
||||||
|
scroll-behavior: smooth; /* Défilement fluide */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Add table
Reference in a new issue