DeepCodeGeniusWeb-vscode/src/views/CurrentMessage.tsx
Rankin Zheng 2d12c8978d Enhance CurrentMessage component with dynamic width and improved styling
- Passed dynamic width from ChatPanel to CurrentMessage component.
- Imported Container from "@mantine/core" for better layout control in CurrentMessage.
- Added styling to the CurrentMessage component to handle dynamic width and improve text display.
- Added 'whiteSpace: 'break-spaces'' to preserve white spaces and line breaks in the preformatted text.
2023-07-06 05:56:36 +08:00

106 lines
2.9 KiB
TypeScript

import React, { useEffect } from "react";
import { keyframes } from "@emotion/react";
import { Container, Text } from "@mantine/core";
import {
selectResponsed,
} from './chatSlice';
import { useAppDispatch, useAppSelector } from '@/views/hooks';
import CodeBlock from "@/views/CodeBlock";
import {
newMessage,
updateLastMessage,
selectGenerating,
selectCurrentMessage,
selecLastMessage,
selecHasDone,
} from './chatSlice';
const MessageBlink = () => {
const responsed = useAppSelector(selectResponsed);
const blink = keyframes({
'50%': { opacity: 0 },
});
return <Text sx={{
animation: `${blink} 0.5s infinite;`,
width: 5,
marginTop: responsed ? 0 : '1em',
backgroundColor: 'black',
display: 'block'
}}>|</Text>;
};
const getBlocks = (message) => {
const messageText = message || '';
const regex = /```([\s\S]+?)```/g;
let match;
let lastIndex = 0;
const blocks: string[] = [];
while ((match = regex.exec(messageText))) {
const unmatchedText = messageText.substring(lastIndex, match.index);
const matchedText = match[0];
blocks.push(unmatchedText, matchedText);
lastIndex = regex.lastIndex;
}
const unmatchedText = messageText.substring(lastIndex);
blocks.push(unmatchedText);
return blocks;
}
const CurrentMessage = (props: any) => {
const { width } = props;
const dispatch = useAppDispatch();
const currentMessage = useAppSelector(selectCurrentMessage);
const lastMessage = useAppSelector(selecLastMessage);
const generating = useAppSelector(selectGenerating);
const hasDone = useAppSelector(selecHasDone);
// split blocks
const messageBlocks = getBlocks(currentMessage);
const lastMessageBlocks = getBlocks(lastMessage?.message);
const fixedCount = lastMessageBlocks.length;
const receivedCount = messageBlocks.length;
const renderBlocks = messageBlocks.splice(-1);
useEffect(() => {
if (generating) {
// new a bot message
dispatch(newMessage({ type: 'bot', message: currentMessage }));
}
if (hasDone) {
// update the last one bot message
dispatch(updateLastMessage({ type: 'bot', message: currentMessage }));
}
}, [generating, hasDone]);
useEffect(() => {
if (receivedCount - fixedCount >= 1) {
dispatch(updateLastMessage({ type: 'bot', message: currentMessage }));
}
}, [currentMessage]);
return generating
? <Container
sx={{
margin: 0,
padding: 0,
width: width,
pre: {
whiteSpace: 'break-spaces'
},
}}>
<CodeBlock messageText={renderBlocks.join('\n\n')} messageType="bot" />
<MessageBlink />
</Container>
: <></>;
};
export default CurrentMessage;