Skip to content

Commit be4f05a

Browse files
committed
chore: extract logic in hook
1 parent 8cd54f0 commit be4f05a

File tree

2 files changed

+55
-30
lines changed

2 files changed

+55
-30
lines changed

package/src/components/Message/MessageSimple/StreamingMessageView.tsx

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import React, { useEffect, useRef, useState } from 'react';
1+
import React from 'react';
22

33
import { MessageTextContainer, MessageTextContainerProps } from './MessageTextContainer';
44

55
import { useMessageContext } from '../../../contexts';
66
import type { DefaultStreamChatGenerics } from '../../../types/types';
7-
8-
const DEFAULT_LETTER_INTERVAL = 0;
9-
const DEFAULT_RENDERING_LETTER_COUNT = 2;
7+
import { useStreamingMessage } from '../hooks/useStreamingMessage';
108

119
export type StreamingMessageViewProps<
1210
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -20,33 +18,16 @@ export const StreamingMessageView = <
2018
>(
2119
props: StreamingMessageViewProps<StreamChatGenerics>,
2220
) => {
23-
const {
24-
letterInterval = DEFAULT_LETTER_INTERVAL,
25-
renderingLetterCount = DEFAULT_RENDERING_LETTER_COUNT,
26-
...restProps
27-
} = props;
28-
const { message } = useMessageContext<StreamChatGenerics>();
21+
const { letterInterval, renderingLetterCount, ...restProps } = props;
22+
const { message: messageFromProps } = restProps;
23+
const { message: messageFromContext } = useMessageContext<StreamChatGenerics>();
24+
const message = messageFromProps || messageFromContext;
2925
const { text = '' } = message;
30-
const [streamedMessageText, setStreamedMessageText] = useState<string>(text);
31-
const textCursor = useRef<number>(text.length);
32-
33-
useEffect(() => {
34-
const textLength = text.length;
35-
const interval = setInterval(() => {
36-
if (!text || textCursor.current >= textLength) {
37-
clearInterval(interval);
38-
}
39-
// TODO: make this configurable maybe
40-
const newCursorValue = textCursor.current + renderingLetterCount;
41-
const newText = text.substring(0, newCursorValue);
42-
textCursor.current += newText.length - textCursor.current;
43-
setStreamedMessageText(newText);
44-
}, letterInterval);
45-
46-
return () => {
47-
clearInterval(interval);
48-
};
49-
}, [letterInterval, renderingLetterCount, text]);
26+
const { streamedMessageText } = useStreamingMessage({
27+
letterInterval,
28+
renderingLetterCount,
29+
text,
30+
});
5031

5132
return (
5233
<MessageTextContainer message={{ ...message, text: streamedMessageText }} {...restProps} />
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useEffect, useRef, useState } from 'react';
2+
3+
import type { DefaultStreamChatGenerics } from '../../../types/types';
4+
import { StreamingMessageViewProps } from '../MessageSimple/StreamingMessageView';
5+
6+
export type UseStreamingMessageProps<
7+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
8+
> = Pick<
9+
StreamingMessageViewProps<StreamChatGenerics>,
10+
'letterInterval' | 'renderingLetterCount'
11+
> & { text: string };
12+
13+
const DEFAULT_LETTER_INTERVAL = 0;
14+
const DEFAULT_RENDERING_LETTER_COUNT = 2;
15+
16+
export const useStreamingMessage = <
17+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
18+
>({
19+
letterInterval = DEFAULT_LETTER_INTERVAL,
20+
renderingLetterCount = DEFAULT_RENDERING_LETTER_COUNT,
21+
text,
22+
}: UseStreamingMessageProps<StreamChatGenerics>) => {
23+
const [streamedMessageText, setStreamedMessageText] = useState<string>(text);
24+
const textCursor = useRef<number>(text.length);
25+
26+
useEffect(() => {
27+
const textLength = text.length;
28+
const interval = setInterval(() => {
29+
if (!text || textCursor.current >= textLength) {
30+
clearInterval(interval);
31+
}
32+
const newCursorValue = textCursor.current + renderingLetterCount;
33+
const newText = text.substring(0, newCursorValue);
34+
textCursor.current += newText.length - textCursor.current;
35+
setStreamedMessageText(newText);
36+
}, letterInterval);
37+
38+
return () => {
39+
clearInterval(interval);
40+
};
41+
}, [letterInterval, renderingLetterCount, text]);
42+
43+
return { streamedMessageText };
44+
};

0 commit comments

Comments
 (0)