From 5126325915c0671870fd52cb7446029162ea464f Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 8 May 2024 16:57:09 +0200 Subject: [PATCH 1/4] Reset useChat messages when room disconnects --- packages/core/src/components/chat.ts | 2 +- .../src/hooks/internal/useObservableState.ts | 11 ++++++-- packages/react/src/hooks/useChat.ts | 27 ++++++++++++------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/packages/core/src/components/chat.ts b/packages/core/src/components/chat.ts index 0f91ae897..088b6e932 100644 --- a/packages/core/src/components/chat.ts +++ b/packages/core/src/components/chat.ts @@ -150,7 +150,7 @@ export function setupChat(room: Room, options?: ChatOptions) { function destroy() { onDestroyObservable.next(); onDestroyObservable.complete(); - topicSubjectMap.clear(); + topicSubjectMap.delete(room); } room.once(RoomEvent.Disconnected, destroy); diff --git a/packages/react/src/hooks/internal/useObservableState.ts b/packages/react/src/hooks/internal/useObservableState.ts index 9b892f11d..e81da9572 100644 --- a/packages/react/src/hooks/internal/useObservableState.ts +++ b/packages/react/src/hooks/internal/useObservableState.ts @@ -5,13 +5,20 @@ import type { Observable } from 'rxjs'; /** * @internal */ -export function useObservableState(observable: Observable | undefined, startWith: T) { +export function useObservableState( + observable: Observable | undefined, + startWith: T, + resetWhenObservableChanges = true, +) { const [state, setState] = React.useState(startWith); React.useEffect(() => { + if (resetWhenObservableChanges) { + setState(startWith); + } // observable state doesn't run in SSR if (typeof window === 'undefined' || !observable) return; const subscription = observable.subscribe(setState); return () => subscription.unsubscribe(); - }, [observable]); + }, [observable, resetWhenObservableChanges]); return state; } diff --git a/packages/react/src/hooks/useChat.ts b/packages/react/src/hooks/useChat.ts index 2c0d34a94..f2fd0ca6a 100644 --- a/packages/react/src/hooks/useChat.ts +++ b/packages/react/src/hooks/useChat.ts @@ -1,8 +1,10 @@ +import * as React from 'react'; import type { ChatOptions, ReceivedChatMessage } from '@livekit/components-core'; import { setupChat } from '@livekit/components-core'; -import * as React from 'react'; +import { ConnectionState } from 'livekit-client'; import { useRoomContext } from '../context'; import { useObservableState } from './internal/useObservableState'; +import { useConnectionState } from './useConnectionStatus'; /** * The `useChat` hook provides chat functionality for a LiveKit room. @@ -14,14 +16,19 @@ import { useObservableState } from './internal/useObservableState'; */ export function useChat(options?: ChatOptions) { const room = useRoomContext(); - const [setup, setSetup] = React.useState>(); - const isSending = useObservableState(setup?.isSendingObservable, false); - const chatMessages = useObservableState(setup?.messageObservable, []); - - React.useEffect(() => { - const setupChatReturn = setupChat(room, options); - setSetup(setupChatReturn); - }, [room, options]); + const connectionState = useConnectionState(room); + const isDisconnected = React.useMemo( + () => connectionState === ConnectionState.Disconnected, + [connectionState], + ); // used to reset the messages on room disconnect + const setup = React.useMemo>(() => { + if (isDisconnected) { + console.log('clear due to disconnect'); + } + return setupChat(room, options); + }, [room, options, isDisconnected]); + const isSending = useObservableState(setup.isSendingObservable, false); + const chatMessages = useObservableState(setup.messageObservable, []); - return { send: setup?.send, update: setup?.update, chatMessages, isSending }; + return { send: setup.send, update: setup.update, chatMessages, isSending }; } From f3bd7ab7697f07498a203d0fd5bad7cda5e5c5f0 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 8 May 2024 16:58:36 +0200 Subject: [PATCH 2/4] remove debug logs --- packages/react/src/hooks/useChat.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/react/src/hooks/useChat.ts b/packages/react/src/hooks/useChat.ts index f2fd0ca6a..52f251ad8 100644 --- a/packages/react/src/hooks/useChat.ts +++ b/packages/react/src/hooks/useChat.ts @@ -21,12 +21,10 @@ export function useChat(options?: ChatOptions) { () => connectionState === ConnectionState.Disconnected, [connectionState], ); // used to reset the messages on room disconnect - const setup = React.useMemo>(() => { - if (isDisconnected) { - console.log('clear due to disconnect'); - } - return setupChat(room, options); - }, [room, options, isDisconnected]); + const setup = React.useMemo>( + () => setupChat(room, options), + [room, options, isDisconnected], + ); const isSending = useObservableState(setup.isSendingObservable, false); const chatMessages = useObservableState(setup.messageObservable, []); From 1f00982866ec1ee1ac00fa237f82b830c3255971 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 8 May 2024 16:59:41 +0200 Subject: [PATCH 3/4] Create popular-roses-breathe.md --- .changeset/popular-roses-breathe.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/popular-roses-breathe.md diff --git a/.changeset/popular-roses-breathe.md b/.changeset/popular-roses-breathe.md new file mode 100644 index 000000000..69f64af69 --- /dev/null +++ b/.changeset/popular-roses-breathe.md @@ -0,0 +1,6 @@ +--- +"@livekit/components-core": patch +"@livekit/components-react": minor +--- + +Reset useChat messages when room disconnects From 0ae06d0ecec7be528a600d277e11ebbebb9c4508 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 8 May 2024 17:03:36 +0200 Subject: [PATCH 4/4] update api docs --- packages/react/etc/components-react.api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react/etc/components-react.api.md b/packages/react/etc/components-react.api.md index 1dfb63afd..03a716172 100644 --- a/packages/react/etc/components-react.api.md +++ b/packages/react/etc/components-react.api.md @@ -659,8 +659,8 @@ export function useAudioPlayback(room?: Room): { // @public export function useChat(options?: ChatOptions): { - send: ((message: string) => Promise) | undefined; - update: ((message: string, messageId: string) => Promise) | undefined; + send: (message: string) => Promise; + update: (message: string, messageId: string) => Promise; chatMessages: ReceivedChatMessage[]; isSending: boolean; };