From 67e9bf2fef9cc15dd92f342f454815720b4e101f Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Fri, 24 Jul 2026 18:04:52 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(frontend)=20reset=20chat=20state?= =?UTF-8?q?=20when=20the=20ChatProvider=20mounts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reset the chat state on the first render of the ChatProvider, to make sure no chat messages from a previous room leak into the new one. This covers SPA navigations where the user switches from one room to another without a full page reload. --- .../src/features/chat/components/ChatProvider.tsx | 6 +++++- .../layout/hooks/useSpeakerPromotionTrigger.ts | 2 +- src/frontend/src/stores/chat.ts | 15 +++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/features/chat/components/ChatProvider.tsx b/src/frontend/src/features/chat/components/ChatProvider.tsx index a6328fb0..8a76578e 100644 --- a/src/frontend/src/features/chat/components/ChatProvider.tsx +++ b/src/frontend/src/features/chat/components/ChatProvider.tsx @@ -3,7 +3,7 @@ import { ref } from 'valtio' import { useSidePanel } from '@/features/rooms/livekit/hooks/useSidePanel' import React, { useEffect } from 'react' import { useChat, useRoomContext } from '@livekit/components-react' -import { appendRow, chatStore } from '@/stores/chat' +import { appendRow, chatStore, resetChatStore } from '@/stores/chat' import type { ChatMessage } from '@livekit/components-core' import { LocalParticipant, @@ -19,6 +19,10 @@ export const ChatProvider = () => { const room = useRoomContext() + useEffect(() => { + resetChatStore() + }, []) + // Tigger the message notification (temporary) useEffect(() => { // TEMPORARY: This is a brittle workaround that relies on message count tracking diff --git a/src/frontend/src/features/layout/hooks/useSpeakerPromotionTrigger.ts b/src/frontend/src/features/layout/hooks/useSpeakerPromotionTrigger.ts index 53c01db3..d0030ebd 100644 --- a/src/frontend/src/features/layout/hooks/useSpeakerPromotionTrigger.ts +++ b/src/frontend/src/features/layout/hooks/useSpeakerPromotionTrigger.ts @@ -19,7 +19,7 @@ import { useEffect, useReducer, useRef } from 'react' * `useTracks(..., { updateOnlyOn: [] })` upstream. */ export function useSpeakerPromotionTrigger( - sortedTiles: TrackReferenceOrPlaceholder[], + sortedTiles: TrackReferenceOrPlaceholder[] ) { const room = useRoomContext() const [, forceRender] = useReducer((n: number) => n + 1, 0) diff --git a/src/frontend/src/stores/chat.ts b/src/frontend/src/stores/chat.ts index 74c2fb11..a48fb024 100644 --- a/src/frontend/src/stores/chat.ts +++ b/src/frontend/src/stores/chat.ts @@ -22,14 +22,16 @@ type State = { textAreaValue: string } -export const chatStore = proxy({ +const initialState: State = { unreadMessages: 0, isSending: false, rows: [], names: {}, send: undefined, textAreaValue: '', -}) +} + +export const chatStore = proxy({ ...initialState }) const GROUPING_WINDOW_MS = 60_000 @@ -60,3 +62,12 @@ export const persistTextAreaValue = (value: string) => { export const clearTextAreaValue = () => { chatStore.textAreaValue = '' } + +export function resetChatStore() { + console.count('resetChatStore') + Object.assign(chatStore, { + ...initialState, + rows: [], + names: {}, + }) +}