Fix des bugs de scroll dans la page de message
Fix des bugs de l'api dans le cache pour les messages
This commit is contained in:
parent
caf6e771f8
commit
15b0c91992
4 changed files with 59 additions and 25 deletions
|
@ -1,18 +1,4 @@
|
|||
services:
|
||||
app:
|
||||
build: .
|
||||
hostname: chat-app
|
||||
restart: always
|
||||
environment:
|
||||
- DATABASE_URL=mongodb://temp-root-username:temp-password@mongodb:27017/chat_projetweb
|
||||
- JWT_SECRET=1f49ba5426afebd6e27eed416d0c31925ca5c4dc39ab4fdea514c8a858312608
|
||||
ports:
|
||||
- "3000:3000"
|
||||
networks:
|
||||
- app_network
|
||||
depends_on:
|
||||
- mongodb
|
||||
- redis
|
||||
|
||||
mongodb:
|
||||
build: ./mongodb_rs
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { createClient } from 'redis';
|
||||
|
||||
const client = await createClient({
|
||||
url: process.env.REDIS_URL || 'redis://redis-server:6379'
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379'
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -14,13 +14,28 @@ export async function GET({ params, url }) {
|
|||
|
||||
try {
|
||||
logger.debug(`Tentative de récupération des messages du cache pour le channel : ${channelId}`);
|
||||
const redisMessageKeys = await redisClient.zRangeWithScores(
|
||||
let redisMessageKeys = await redisClient.zRangeWithScores(
|
||||
`channel:${channelId}:messages`,
|
||||
offset,
|
||||
offset + limit - 1,
|
||||
{ REV: true }
|
||||
);
|
||||
|
||||
const redisPipelineRemove = redisClient.multi();
|
||||
|
||||
|
||||
for (const messageKey of redisMessageKeys) {
|
||||
// Vérifie si la clé existe dans Redis
|
||||
const messageKeyValue = messageKey.value;
|
||||
const exists = await redisClient.exists(messageKeyValue);
|
||||
if (!exists) {
|
||||
// Supprime la référence expirée dans le zSet
|
||||
redisPipelineRemove.zRem(`channel:${channelId}:messages`, messageKeyValue);
|
||||
redisMessageKeys = redisMessageKeys.filter((key) => key.value !== messageKeyValue);
|
||||
}
|
||||
}
|
||||
await redisPipelineRemove.exec();
|
||||
|
||||
if (redisMessageKeys.length > 0) {
|
||||
const messages = await Promise.all(
|
||||
redisMessageKeys.map(async (key) => {
|
||||
|
@ -114,7 +129,7 @@ export async function POST({ params, request }) {
|
|||
});
|
||||
|
||||
// Ajouter le message dans Redis
|
||||
await redisClient.set(`message:${newMessage.id}`, JSON.stringify(newMessage));
|
||||
await redisClient.set(`message:${newMessage.id}`, JSON.stringify(newMessage), {EX: 1800});
|
||||
await redisClient.zAdd(`channel:${channelId}:messages`, {
|
||||
score: new Date(newMessage.createdAt).getTime(),
|
||||
value: `message:${newMessage.id}`,
|
||||
|
@ -125,6 +140,7 @@ export async function POST({ params, request }) {
|
|||
let channels = cachedChannels ? JSON.parse(cachedChannels) : [];
|
||||
let channel = channels.find((c) => c.id === channelId);
|
||||
if(channel){
|
||||
console.log('channel found')
|
||||
channel.lastMessage = {
|
||||
id: newMessage.id,
|
||||
text: newMessage.text,
|
||||
|
@ -141,8 +157,8 @@ export async function POST({ params, request }) {
|
|||
user: newMessage.user,
|
||||
createdAt: newMessage.createdAt,
|
||||
}, lastUpdate: newMessage.createdAt, messages: undefined};
|
||||
channels = [channel, ...channels];
|
||||
}
|
||||
channels = [channel, ...channels];
|
||||
await redisClient.set('channels', JSON.stringify(channels), { EX: 600 });
|
||||
|
||||
newMessage.channel = {
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
}
|
||||
isLoading = true;
|
||||
|
||||
const previousMessages = $messagesStore;
|
||||
|
||||
let newMessages = [];
|
||||
|
||||
try {
|
||||
// Calculer la page à charger en fonction du nombre total de messages existants
|
||||
const totalMessages = $messagesStore.length;
|
||||
|
@ -90,7 +94,7 @@
|
|||
});
|
||||
|
||||
if (response.ok) {
|
||||
const newMessages = await response.json();
|
||||
newMessages = await response.json();
|
||||
|
||||
if (newMessages.messages.length <= 0) {
|
||||
console.log("Pas d'autres anciens messages");
|
||||
|
@ -116,6 +120,23 @@
|
|||
console.error("Erreur réseau lors du chargement des messages:", error);
|
||||
} finally {
|
||||
isLoading = false;
|
||||
await tick();
|
||||
const filteredNewMessages = newMessages.messages.filter((msg) => {
|
||||
return !previousMessages.some((m) => m.id === msg.id);
|
||||
});
|
||||
scrollContainer.scrollTo({
|
||||
top: filteredNewMessages.length*300,
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function handleScroll() {
|
||||
if (scrollContainer) {
|
||||
// Détection quand on est en haut du scroll
|
||||
if (scrollContainer.scrollTop <= 0 && !isLoading) {
|
||||
loadMoreMessages();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +160,7 @@
|
|||
socket.emit('stop-writing', { userId: data.userId, channelId: data.channelId });
|
||||
}
|
||||
|
||||
async function scrollToBottom(retries = 3) {
|
||||
async function scrollToBottom(retries = 20) {
|
||||
await tick();
|
||||
|
||||
const attemptScroll = () => {
|
||||
|
@ -151,16 +172,22 @@
|
|||
}
|
||||
};
|
||||
|
||||
attemptScroll();
|
||||
// Protéger l'utilisation de requestAnimationFrame
|
||||
if (typeof window !== 'undefined' && typeof requestAnimationFrame === 'function') {
|
||||
attemptScroll();
|
||||
|
||||
if (retries > 0) {
|
||||
requestAnimationFrame(() => scrollToBottom(retries - 1));
|
||||
if (retries > 0) {
|
||||
requestAnimationFrame(() => scrollToBottom(retries - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
socket.emit('leave-channel', { userId: data.userId, channelId: data.channelId });
|
||||
socket.disconnect(); // Déconnexion propre du socket
|
||||
if (scrollContainer) {
|
||||
scrollContainer.removeEventListener('scroll', handleScroll);
|
||||
}
|
||||
});
|
||||
|
||||
// Ecoute des événements socket
|
||||
|
@ -221,12 +248,16 @@
|
|||
|
||||
messagesStore.subscribe(async () => {
|
||||
await tick();
|
||||
await scrollToBottom(); // Scroll to the bottom after the message is added
|
||||
});
|
||||
|
||||
let firstPageLoad = true;
|
||||
|
||||
onMount(async () => {
|
||||
await tick();
|
||||
await scrollToBottom();
|
||||
if(firstPageLoad){
|
||||
firstPageLoad = false;
|
||||
await scrollToBottom();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -254,6 +285,7 @@
|
|||
<div
|
||||
class="m-10 flex flex-col gap-5 overflow-auto flex-grow"
|
||||
bind:this={scrollContainer}
|
||||
on:scroll={handleScroll}
|
||||
>
|
||||
{#if isLoading}
|
||||
<div class="loading-indicator">Chargement...</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue