stream-chat-react
Version:
React components to create chat conversations or livestream style chat
81 lines (80 loc) • 3.11 kB
JavaScript
import { useEffect, useMemo } from 'react';
import { FixedSizeQueueCache, MessageComposer } from 'stream-chat';
import { useThreadContext } from '../../Threads';
import { useChannelStateContext, useChatContext, useMessageContext, } from '../../../context';
import { useLegacyThreadContext } from '../../Thread';
const queueCache = new FixedSizeQueueCache(64);
export const useMessageComposer = () => {
const { client } = useChatContext();
const { channel } = useChannelStateContext();
const { editing, message: editedMessage } = useMessageContext();
// legacy thread will receive new composer
const { legacyThread: parentMessage } = useLegacyThreadContext();
const threadInstance = useThreadContext();
const cachedEditedMessage = useMemo(() => {
if (!editedMessage)
return undefined;
return editedMessage;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [editedMessage?.id]);
const cachedParentMessage = useMemo(() => {
if (!parentMessage)
return undefined;
return parentMessage;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [parentMessage?.id]);
// composer hierarchy
// edited message (always new) -> thread instance (own) -> thread message (always new) -> channel (own)
// editedMessage ?? thread ?? parentMessage ?? channel;
const messageComposer = useMemo(() => {
if (editing && cachedEditedMessage) {
const tag = MessageComposer.constructTag(cachedEditedMessage);
const cachedComposer = queueCache.get(tag);
if (cachedComposer)
return cachedComposer;
return new MessageComposer({
client,
composition: cachedEditedMessage,
compositionContext: cachedEditedMessage,
});
}
else if (threadInstance) {
return threadInstance.messageComposer;
}
else if (cachedParentMessage) {
const compositionContext = {
...cachedParentMessage,
legacyThreadId: cachedParentMessage.id,
};
const tag = MessageComposer.constructTag(compositionContext);
const cachedComposer = queueCache.get(tag);
if (cachedComposer)
return cachedComposer;
return new MessageComposer({
client,
compositionContext,
});
}
else {
return channel.messageComposer;
}
}, [
cachedEditedMessage,
cachedParentMessage,
channel,
client,
editing,
threadInstance,
]);
if (['legacy_thread', 'message'].includes(messageComposer.contextType) &&
!queueCache.peek(messageComposer.tag)) {
queueCache.add(messageComposer.tag, messageComposer);
}
useEffect(() => {
const unsubscribe = messageComposer.registerSubscriptions();
return () => {
unsubscribe();
};
}, [messageComposer]);
return messageComposer;
};