Skip to content

Commit 8c81e09

Browse files
committed
feat: add StreamingMessageView to kick off ai feature
1 parent a52b38b commit 8c81e09

File tree

8 files changed

+64
-6
lines changed

8 files changed

+64
-6
lines changed

package/src/components/Channel/Channel.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,15 @@ const ChannelWithContext = <
566566
MessageAvatar = MessageAvatarDefault,
567567
MessageBounce = MessageBounceDefault,
568568
MessageContent = MessageContentDefault,
569-
messageContentOrder = ['quoted_reply', 'gallery', 'files', 'poll', 'text', 'attachments'],
569+
messageContentOrder = [
570+
'quoted_reply',
571+
'gallery',
572+
'files',
573+
'poll',
574+
'ai_text',
575+
'text',
576+
'attachments',
577+
],
570578
MessageDeleted = MessageDeletedDefault,
571579
MessageEditedTimestamp = MessageEditedTimestampDefault,
572580
MessageError = MessageErrorDefault,

package/src/components/Message/Message.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
765765
prevMessage.text === nextMessage.text &&
766766
prevMessage.pinned === nextMessage.pinned &&
767767
`${prevMessage?.updated_at}` === `${nextMessage?.updated_at}` &&
768-
prevMessage.i18n === nextMessage.i18n;
768+
prevMessage.i18n === nextMessage.i18n &&
769+
prevMessage.ai_generated === nextMessage.ai_generated;
769770

770771
if (!messageEqual) return false;
771772

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010

1111
import { MessageTextContainer } from './MessageTextContainer';
1212

13+
import { StreamingMessageView } from './StreamingMessageView';
14+
1315
import { useChatContext } from '../../../contexts';
1416
import {
1517
MessageContextValue,
@@ -215,6 +217,8 @@ const MessageContentWithContext = <
215217
return bordersFromTheme;
216218
};
217219

220+
console.log('ISE: NEW: ', message.ai_generated, message.id);
221+
218222
return (
219223
<Pressable
220224
disabled={preventPress}
@@ -312,9 +316,16 @@ const MessageContentWithContext = <
312316
/>
313317
) : null;
314318
}
319+
case 'ai_text':
320+
return message.ai_generated ? (
321+
<StreamingMessageView
322+
key={`ai_message_text_container_${messageContentOrderIndex}`}
323+
/>
324+
) : null;
315325
case 'text':
316326
default:
317-
return otherAttachments.length && otherAttachments[0].actions ? null : (
327+
return (otherAttachments.length && otherAttachments[0].actions) ||
328+
message.ai_generated ? null : (
318329
<MessageTextContainer<StreamChatGenerics>
319330
key={`message_text_container_${messageContentOrderIndex}`}
320331
/>
@@ -381,7 +392,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
381392
prevMessage.type === nextMessage.type &&
382393
prevMessage.text === nextMessage.text &&
383394
prevMessage.pinned === nextMessage.pinned &&
384-
prevMessage.i18n === nextMessage.i18n;
395+
prevMessage.i18n === nextMessage.i18n &&
396+
prevMessage.ai_generated === nextMessage.ai_generated;
385397
if (!messageEqual) return false;
386398

387399
const isPrevQuotedMessageTypeDeleted = prevMessage.quoted_message?.type === 'deleted';

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
306306
prevMessage.type === nextMessage.type &&
307307
prevMessage.text === nextMessage.text &&
308308
prevMessage.i18n === nextMessage.i18n &&
309-
prevMessage.pinned === nextMessage.pinned;
309+
prevMessage.pinned === nextMessage.pinned &&
310+
prevMessage.ai_generated === nextMessage.ai_generated;
310311
if (!messageEqual) return false;
311312

312313
const isPrevQuotedMessageTypeDeleted = prevMessage.quoted_message?.type === 'deleted';

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ const MessageTextContainerWithContext = <
8383
message,
8484
) as MessageType<StreamChatGenerics>;
8585

86-
if (!message.text) return null;
86+
if (!message.text && !message.ai_generated) return null;
8787

8888
const markdownStyles = { ...markdown, ...markdownStylesProp };
8989

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React, { useEffect, useRef, useState } from 'react';
2+
3+
import { MessageTextContainer, MessageTextContainerProps } from './MessageTextContainer';
4+
5+
import { useMessageContext } from '../../../contexts';
6+
import type { DefaultStreamChatGenerics } from '../../../types/types';
7+
8+
export const StreamingMessageView = <
9+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
10+
>(
11+
props: MessageTextContainerProps<StreamChatGenerics>,
12+
) => {
13+
const { message } = useMessageContext<StreamChatGenerics>();
14+
const { text } = message;
15+
const [streamedMessageText, setStreamedMessageText] = useState<string>(text || '');
16+
const textCursor = useRef<number>(text?.length || 0);
17+
18+
useEffect(() => {
19+
if (!text || textCursor.current >= text.length) {
20+
return;
21+
}
22+
// TODO: make this configurable maybe
23+
const newCursorValue = textCursor.current + 1;
24+
const newBatch = text?.substring(textCursor.current, newCursorValue);
25+
setTimeout(() => {
26+
setStreamedMessageText((prevStreamedMessageText) => prevStreamedMessageText.concat(newBatch));
27+
}, 0);
28+
textCursor.current = newCursorValue;
29+
}, [streamedMessageText, text]);
30+
31+
return <MessageTextContainer message={{ ...message, text: streamedMessageText }} {...props} />;
32+
};
33+
34+
StreamingMessageView.displayName = 'MessageTextContainer{messageSimple{content}}';

package/src/components/Message/MessageSimple/utils/generateMarkdownText.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const generateMarkdownText = (text?: string) => {
3333
resultText = resultText.replace(mentionsRegex, `@${displayLink}`);
3434
}
3535

36+
// FIXME: Should not happen within codeblocks.
3637
resultText = resultText.replace(/[<"'>]/g, '\\$&');
3738

3839
// Remove whitespaces that come directly after newlines except in code blocks where we deem this allowed.

package/src/contexts/messagesContext/MessagesContext.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export type MessageContentType =
7575
| 'gallery'
7676
| 'quoted_reply'
7777
| 'poll'
78+
| 'ai_text'
7879
| 'text';
7980
export type DeletedMessagesVisibilityType = 'always' | 'never' | 'receiver' | 'sender';
8081

0 commit comments

Comments
 (0)