@@ -37,18 +37,6 @@ interface ChatBubbleProps {
37
37
totalMessages ?: number ;
38
38
}
39
39
40
- const Pre = memo (
41
- ( { children } ) => (
42
- < pre className = "code-pre" >
43
- < CopyToClipboard key = { nanoid ( ) } textToCopy = { children . props . children } />
44
- { children }
45
- </ pre >
46
- ) ,
47
- [ ]
48
- ) ;
49
-
50
- Pre . displayName = 'Pre' ;
51
-
52
40
export const ChatBubble = memo (
53
41
( {
54
42
index,
@@ -60,10 +48,23 @@ export const ChatBubble = memo(
60
48
model,
61
49
reload,
62
50
stop,
63
- totalMessages,
51
+ totalMessages
64
52
} : ChatBubbleProps ) => {
65
53
const editorTheme = useAtomValue ( editorThemeAtom ) ;
66
- const copyToClipBoardKey = useMemo ( ( ) => nanoid ( ) , [ ] ) ;
54
+ const copyToClipBoardKey = nanoid ( ) ;
55
+ const preCopyToClipBoardKey = nanoid ( ) ;
56
+
57
+ const Pre = ( { children } ) => {
58
+ return (
59
+ < pre className = "code-pre" >
60
+ < CopyToClipboard
61
+ key = { preCopyToClipBoardKey }
62
+ textToCopy = { children . props . children }
63
+ />
64
+ { children }
65
+ </ pre >
66
+ ) ;
67
+ } ;
67
68
68
69
const rehypePlugins = useMemo (
69
70
( ) => [ rehypeKatex , rehypeSanitize , rehypeStringify ] ,
@@ -101,86 +102,29 @@ export const ChatBubble = memo(
101
102
) ;
102
103
} , [ index , isLoading , isUser , totalMessages ] ) ;
103
104
104
- const chatClass = useMemo (
105
- ( ) =>
106
- clsx ( 'chat mb-10' , {
105
+ return (
106
+ ( < div
107
+ className = { clsx ( 'chat mb-10' , {
107
108
'chat-start' : isUser ,
108
109
'chat-end' : ! isUser ,
109
- } ) ,
110
- [ isUser ]
111
- ) ;
112
-
113
- const avatarClass = useMemo (
114
- ( ) =>
115
- clsx ( 'w-12 pt-2 p-1 rounded' , {
116
- 'bg-primary text-primary-content' : isUser ,
117
- 'bg-secondary text-secondary-content' : ! isUser ,
118
- } ) ,
119
- [ isUser ]
120
- ) ;
121
-
122
- const chatBubbleClass = useMemo (
123
- ( ) =>
124
- clsx ( 'prose relative chat-bubble' , {
125
- 'chat-bubble-primary' : isUser ,
126
- 'chat-bubble-secondary bot' : ! isUser ,
127
- } ) ,
128
- [ isUser ]
129
- ) ;
130
-
131
- const chatFooterClass = useMemo (
132
- ( ) =>
133
- clsx ( 'chat-footer' , {
134
- bot : ! isUser ,
135
- } ) ,
136
- [ isUser ]
137
- ) ;
138
-
139
- const markdownComponents = useMemo (
140
- ( ) => ( {
141
- pre : Pre ,
142
- code ( props ) {
143
- const { children, className = 'code-pre' , node, ...rest } = props ;
144
- const match = / l a n g u a g e - ( \w + ) / . exec ( className || '' ) ;
145
- return match ? (
146
- < SyntaxHighlighter
147
- { ...rest }
148
- style = { editorTheme }
149
- language = { match [ 1 ] }
150
- PreTag = "div"
151
- showLineNumbers = { true }
152
- >
153
- { String ( children ) . replace ( / \n $ / , '' ) }
154
- </ SyntaxHighlighter >
155
- ) : (
156
- < code { ...rest } className = { className } >
157
- { children }
158
- </ code >
159
- ) ;
160
- } ,
161
- } ) ,
162
- [ editorTheme ]
163
- ) ;
164
-
165
- const renderedMarkdown = useMemo (
166
- ( ) => (
167
- < Markdown
168
- rehypePlugins = { rehypePlugins }
169
- remarkPlugins = { remarkPlugins }
170
- components = { markdownComponents }
171
- >
172
- { messageContent . replace ( / \n / g, ' \n' ) }
173
- </ Markdown >
174
- ) ,
175
- [ rehypePlugins , remarkPlugins , markdownComponents , messageContent ]
176
- ) ;
177
-
178
- return (
179
- < div className = { chatClass } >
110
+ } ) }
111
+ >
180
112
< div className = "chat-image avatar" >
181
- < div className = { avatarClass } > { chatBubbleUserIcon } </ div >
113
+ < div
114
+ className = { clsx ( 'w-12 pt-2 p-1 rounded' , {
115
+ 'bg-primary text-primary-content' : isUser ,
116
+ 'bg-secondary text-secondary-content' : ! isUser ,
117
+ } ) }
118
+ >
119
+ { chatBubbleUserIcon }
120
+ </ div >
182
121
</ div >
183
- < div className = { chatBubbleClass } >
122
+ < div
123
+ className = { clsx ( 'prose relative chat-bubble' , {
124
+ 'chat-bubble-primary' : isUser ,
125
+ 'chat-bubble-secondary bot' : ! isUser ,
126
+ } ) }
127
+ >
184
128
{ ( isUser || ! isLoading || index !== totalMessages ) && (
185
129
< >
186
130
< CopyToClipboard
@@ -198,9 +142,45 @@ export const ChatBubble = memo(
198
142
) : null }
199
143
</ >
200
144
) }
201
- { renderedMarkdown }
145
+ < Markdown
146
+ rehypePlugins = { rehypePlugins }
147
+ remarkPlugins = { remarkPlugins }
148
+ components = { {
149
+ pre : Pre ,
150
+ code ( props ) {
151
+ const {
152
+ children,
153
+ className = 'code-pre' ,
154
+ node,
155
+ ...rest
156
+ } = props ;
157
+ const match = / l a n g u a g e - ( \w + ) / . exec ( className || '' ) ;
158
+ return match ? (
159
+ < SyntaxHighlighter
160
+ { ...rest }
161
+ style = { editorTheme }
162
+ language = { match [ 1 ] }
163
+ PreTag = "div"
164
+ showLineNumbers = { true }
165
+ >
166
+ { String ( children ) . replace ( / \n $ / , '' ) }
167
+ </ SyntaxHighlighter >
168
+ ) : (
169
+ < code { ...rest } className = { className } >
170
+ { children }
171
+ </ code >
172
+ ) ;
173
+ } ,
174
+ } }
175
+ >
176
+ { messageContent . replace ( / \n / g, ' \n' ) }
177
+ </ Markdown >
202
178
</ div >
203
- < div className = { chatFooterClass } >
179
+ < div
180
+ className = { clsx ( 'chat-footer' , {
181
+ 'bot' : ! isUser ,
182
+ } ) }
183
+ >
204
184
< ChatMeta
205
185
index = { index }
206
186
isLoading = { isLoading }
@@ -211,7 +191,7 @@ export const ChatBubble = memo(
211
191
totalMessages = { totalMessages }
212
192
/>
213
193
</ div >
214
- </ div >
194
+ </ div > )
215
195
) ;
216
196
}
217
197
) ;
0 commit comments