Skip to content

Commit

Permalink
Reset useChat messages when room disconnects (#866)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasIO authored May 13, 2024
1 parent e262650 commit 3b257b1
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 15 deletions.
6 changes: 6 additions & 0 deletions .changeset/popular-roses-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@livekit/components-core": patch
"@livekit/components-react": minor
---

Reset useChat messages when room disconnects
2 changes: 1 addition & 1 deletion packages/core/src/components/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions packages/react/etc/components-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,8 @@ export function useAudioPlayback(room?: Room): {

// @public
export function useChat(options?: ChatOptions): {
send: ((message: string) => Promise<ChatMessage>) | undefined;
update: ((message: string, messageId: string) => Promise<ChatMessage>) | undefined;
send: (message: string) => Promise<ChatMessage>;
update: (message: string, messageId: string) => Promise<ChatMessage>;
chatMessages: ReceivedChatMessage[];
isSending: boolean;
};
Expand Down
11 changes: 9 additions & 2 deletions packages/react/src/hooks/internal/useObservableState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ import type { Observable } from 'rxjs';
/**
* @internal
*/
export function useObservableState<T>(observable: Observable<T> | undefined, startWith: T) {
export function useObservableState<T>(
observable: Observable<T> | undefined,
startWith: T,
resetWhenObservableChanges = true,
) {
const [state, setState] = React.useState<T>(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;
}
25 changes: 15 additions & 10 deletions packages/react/src/hooks/useChat.ts
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -14,14 +16,17 @@ import { useObservableState } from './internal/useObservableState';
*/
export function useChat(options?: ChatOptions) {
const room = useRoomContext();
const [setup, setSetup] = React.useState<ReturnType<typeof setupChat>>();
const isSending = useObservableState(setup?.isSendingObservable, false);
const chatMessages = useObservableState<ReceivedChatMessage[]>(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<ReturnType<typeof setupChat>>(
() => setupChat(room, options),
[room, options, isDisconnected],
);
const isSending = useObservableState(setup.isSendingObservable, false);
const chatMessages = useObservableState<ReceivedChatMessage[]>(setup.messageObservable, []);

return { send: setup?.send, update: setup?.update, chatMessages, isSending };
return { send: setup.send, update: setup.update, chatMessages, isSending };
}

0 comments on commit 3b257b1

Please sign in to comment.