Merge pull request #21 from runjinz/message-handler

Message handler
This commit is contained in:
Rankin Zheng 2023-05-07 00:54:09 +08:00 committed by GitHub
commit 67bdf57d2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 188 additions and 137 deletions

126
package-lock.json generated
View File

@ -1969,21 +1969,21 @@
}
},
"node_modules/@emotion/babel-plugin": {
"version": "11.10.8",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz",
"integrity": "sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ==",
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
"@emotion/hash": "^0.9.0",
"@emotion/memoize": "^0.8.0",
"@emotion/serialize": "^1.1.1",
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/serialize": "^1.1.2",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
"find-root": "^1.1.0",
"source-map": "^0.5.7",
"stylis": "4.1.4"
"stylis": "4.2.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
@ -1999,6 +1999,11 @@
"node": ">=0.10.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
},
"node_modules/@emotion/cache": {
"version": "11.10.8",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.8.tgz",
@ -2012,14 +2017,14 @@
}
},
"node_modules/@emotion/hash": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
"integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
},
"node_modules/@emotion/memoize": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
},
"node_modules/@emotion/react": {
"version": "11.10.8",
@ -2045,14 +2050,14 @@
}
},
"node_modules/@emotion/serialize": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz",
"integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==",
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz",
"integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==",
"dependencies": {
"@emotion/hash": "^0.9.0",
"@emotion/memoize": "^0.8.0",
"@emotion/unitless": "^0.8.0",
"@emotion/utils": "^1.2.0",
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/unitless": "^0.8.1",
"@emotion/utils": "^1.2.1",
"csstype": "^3.0.2"
}
},
@ -2062,22 +2067,22 @@
"integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA=="
},
"node_modules/@emotion/unitless": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
"integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
},
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
"integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@emotion/utils": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
"integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
},
"node_modules/@emotion/weak-memoize": {
"version": "0.3.0",
@ -13811,21 +13816,21 @@
"dev": true
},
"@emotion/babel-plugin": {
"version": "11.10.8",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz",
"integrity": "sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ==",
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
"requires": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
"@emotion/hash": "^0.9.0",
"@emotion/memoize": "^0.8.0",
"@emotion/serialize": "^1.1.1",
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/serialize": "^1.1.2",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
"find-root": "^1.1.0",
"source-map": "^0.5.7",
"stylis": "4.1.4"
"stylis": "4.2.0"
},
"dependencies": {
"convert-source-map": {
@ -13837,6 +13842,11 @@
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
},
"stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
}
}
},
@ -13853,14 +13863,14 @@
}
},
"@emotion/hash": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
"integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
},
"@emotion/memoize": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
},
"@emotion/react": {
"version": "11.10.8",
@ -13878,14 +13888,14 @@
}
},
"@emotion/serialize": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz",
"integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==",
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz",
"integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==",
"requires": {
"@emotion/hash": "^0.9.0",
"@emotion/memoize": "^0.8.0",
"@emotion/unitless": "^0.8.0",
"@emotion/utils": "^1.2.0",
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/unitless": "^0.8.1",
"@emotion/utils": "^1.2.1",
"csstype": "^3.0.2"
}
},
@ -13895,20 +13905,20 @@
"integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA=="
},
"@emotion/unitless": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
"integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
},
"@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
"integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
"requires": {}
},
"@emotion/utils": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
"integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
},
"@emotion/weak-memoize": {
"version": "0.3.0",

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import App from './App';
import App from './views/App';
const container = document.getElementById('app')!;
const root = createRoot(container); // createRoot(container!) if you use TypeScript

View File

@ -25,7 +25,8 @@ export default class WebviewManager {
}
private _getHtmlContent(): string {
const htmlPath = vscode.Uri.joinPath(this._extensionUri, 'dist', 'assets', 'chatPanel.html');
// const htmlPath = vscode.Uri.joinPath(this._extensionUri, 'dist', 'assets', 'chatPanel.html');
const htmlPath = vscode.Uri.joinPath(this._extensionUri, 'dist', 'index.html');
const htmlContent = fs.readFileSync(htmlPath.fsPath, 'utf8');
return htmlContent.replace(/<vscode-resource:(\/.+?)>/g, (_, resourcePath) => {

View File

@ -3,9 +3,32 @@
const vscodeApi = window.acquireVsCodeApi();
class MessageUtil {
private static instance: MessageUtil;
handlers: { [x: string]: any; };
messageListener: any;
constructor() {
this.handlers = {};
this.messageListener = null;
if (!this.messageListener) {
this.messageListener = (event: { data: any; }) => {
const message = event.data;
this.handleMessage(message);
};
window.addEventListener('message', this.messageListener);
} else {
console.log('Message listener has already been bound.');
}
}
public static getInstance(): MessageUtil {
if (!MessageUtil.instance) {
MessageUtil.instance = new MessageUtil();
}
return MessageUtil.instance;
}
// Register a message handler for a specific message type
@ -42,4 +65,4 @@ class MessageUtil {
}
// Export the MessageUtil class as a module
export default MessageUtil;
export default MessageUtil.getInstance();

View File

@ -1,18 +1,23 @@
import * as React from 'react';
import { useState } from 'react';
import { Avatar, Container, Divider, Flex, Grid, Stack, TypographyStylesProvider } from '@mantine/core';
import { useState, useEffect } from 'react';
import { Avatar, Center, Container, Divider, Flex, Grid, Stack, TypographyStylesProvider } from '@mantine/core';
import { Input, Tooltip } from '@mantine/core';
import { List } from '@mantine/core';
import { ScrollArea } from '@mantine/core';
import { createStyles } from '@mantine/core';
import { createStyles, keyframes } from '@mantine/core';
import { ActionIcon } from '@mantine/core';
import { Menu, Button, Text } from '@mantine/core';
import { useViewportSize } from '@mantine/hooks';
import { useListState, useViewportSize } from '@mantine/hooks';
import { IconEdit, IconRobot, IconSend, IconSquareRoundedPlus, IconUser } from '@tabler/icons-react';
import { IconSettings, IconSearch, IconPhoto, IconMessageCircle, IconTrash, IconArrowsLeftRight } from '@tabler/icons-react';
import { Prism } from '@mantine/prism';
import { useRemark } from 'react-remark';
import MessageUtil from '../utils/MessageUtil';
import { useRemark, Remark } from 'react-remark';
import messageUtil from '../util/MessageUtil';
const blink = keyframes({
'50%': { opacity: 0 },
});
const useStyles = createStyles((theme, _params, classNames) => ({
panel: {
@ -38,9 +43,12 @@ const useStyles = createStyles((theme, _params, classNames) => ({
color: theme.colors.gray[6],
},
responseContent: {
marginTop: 8,
marginTop: 0,
marginLeft: 0,
marginRight: 0,
paddingLeft: 0,
paddingRight: 0,
width: 'calc(100% - 62px)',
},
icon: {
pointerEvents: 'all',
@ -51,28 +59,25 @@ const useStyles = createStyles((theme, _params, classNames) => ({
},
messageBody: {
},
cursor: {
animation: `${blink} 0.5s infinite;`
}
}));
const chatPanel = () => {
const [reactContent, setMarkdownSource] = useRemark();
const [messages, handlers] = useListState<{ type: string; message: string; }>([]);
const [showCursor, setShowCursor] = useState(false);
const [registed, setRegisted] = useState(false);
const [opened, setOpened] = useState(false);
// const [markdown, setMarkdown] = useRemark();
// const [message, setMessage] = useState('');
const [input, setInput] = useState('');
const [commandOpened, setCommandOpened] = useState(false);
const { classes } = useStyles();
const { height, width } = useViewportSize();
const messageUtil = new MessageUtil();
const demoCode = `import { Button } from '@mantine/core';
function Demo() {
return <Button>Hello</Button>
}`;
setMarkdownSource(`# code block
print '3 backticks or'
print 'indent 4 spaces'`);
const handlePlusBottonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
const handlePlusClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setOpened(!opened);
event.stopPropagation();
};
@ -80,35 +85,45 @@ const chatPanel = () => {
if (opened) { setOpened(false); }
};
const handleSendClick = (event: React.MouseEvent<HTMLButtonElement>) => {
const message = input;
if (message) {
if (input) {
// Add the user's message to the chat UI
// addMessageToUI('user', message);
handlers.append({ type: 'user', message: input });
// Clear the input field
event.currentTarget.value = '';
setInput('');
setShowCursor(true);
// Process and send the message to the extension
messageUtil.sendMessage({
command: 'sendMessage',
text: message
text: input
});
}
};
// Register message handlers for receiving messages from the extension
messageUtil.registerHandler('receiveMessage', (message: { text: string; }) => {
console.log(`receiveMessage: ${message.text}`);
useEffect(() => {
if (registed) return;
// Add the received message to the chat UI as a bot message
setMarkdownSource(message.text);
});
messageUtil.registerHandler('receiveMessagePartial', (message: { text: string; }) => {
console.log(`receiveMessagePartial: ${message.text}`);
// Add the received message to the chat UI as a bot message
setMarkdownSource(message.text);
});
messageUtil.registerHandler('receiveMessage', (message: { text: string; }) => {
console.log(`receiveMessage: ${message.text}`);
handlers.append({ type: 'bot', message: message.text });
setRegisted(true);
});
}, [registed]);
// useEffect(() => {
// let current = 0;
// const interval = setInterval(() => {
// if (current >= message.length) {
// clearInterval(interval);
// setShowCursor(false);
// return;
// }
// setMarkdown(message.slice(0, current + 1));
// current++;
// }, 25);
// return () => clearInterval(interval);
// }, [message]);
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
@ -121,47 +136,47 @@ const chatPanel = () => {
setInput(value);
};
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
handleSendClick(event as any);
}
};
const defaultMessages = (<Center>
<Text size="lg" color="gray" weight={500}>No messages yet</Text>
</Center>);
const messageList = messages.map(({ message: messageText, type: messageType }, index) => {
// setMessage(messageText);
return (<>
<Flex
mih={50}
gap="md"
justify="flex-start"
align="flex-start"
direction="row"
wrap="wrap"
className={classes.messageBody}
>
{
messageType === 'bot'
? <Avatar color="indigo" size='md' radius="xl" className={classes.avatar}><IconRobot size="1.5rem" /></Avatar>
: <Avatar color="cyan" size='md' radius="xl" className={classes.avatar}><IconUser size="1.5rem" /></Avatar>
}
<Container className={classes.responseContent}>
<Remark>{messageText}</Remark>
{/* {markdown}{showCursor && <span className={classes.cursor}>|</span>} */}
</Container>
</Flex>
{index !== messages.length - 1 && <Divider my="sm" />}
</>);
});
return (
<Container className={classes.panel} onClick={handleContainerClick}>
<ScrollArea h={height - 70} type="never">
<Flex
mih={50}
gap="md"
justify="flex-start"
align="flex-start"
direction="row"
wrap="wrap"
className={classes.messageBody}
>
<Avatar color="indigo" size='md' radius="xl" className={classes.avatar}>
<IconUser size="1.5rem" />
</Avatar>
<Container className={classes.responseContent}>
<Text>
Write a hello world, and explain it.
</Text>
</Container>
{/* <ActionIcon>
<IconEdit size="1.5rem" />
</ActionIcon> */}
</Flex>
<Divider my="sm" label="Mar 4, 2023" labelPosition="center" />
<Flex
mih={50}
gap="md"
justify="flex-start"
align="flex-start"
direction="row"
wrap="wrap"
className={classes.messageBody}
>
<Avatar color="blue" size='md' radius="xl" className={classes.avatar}>
<IconRobot size="1.5rem" />
</Avatar>
<Container className={classes.responseContent}>
{reactContent}
</Container>
</Flex>
{messageList.length > 0 ? messageList : defaultMessages}
</ScrollArea>
<Menu id='plusMenu' shadow="md" width={200} opened={opened} onChange={setOpened} >
<Menu.Dropdown className={classes.plusMenu}>
@ -238,7 +253,7 @@ const chatPanel = () => {
radius="md"
placeholder="Send a message."
icon={
<ActionIcon className={classes.icon} onClick={handlePlusBottonClick}>
<ActionIcon className={classes.icon} onClick={handlePlusClick}>
<IconSquareRoundedPlus size="1rem" />
</ActionIcon>
}
@ -247,6 +262,8 @@ const chatPanel = () => {
<IconSend size="1rem" />
</ActionIcon>
}
value={input}
onKeyDown={handleKeyDown}
onChange={handleInputChange}
/>
</Container>

View File

@ -69,7 +69,7 @@ const webviewConfig = {
target: 'web',
mode: 'development',
entry: './src/views/index.tsx',
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
@ -155,7 +155,7 @@ const webviewConfig = {
plugins: [
// generate an HTML file that includes the extension's JavaScript file
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src', 'views', 'index.html'),
template: path.resolve(__dirname, 'src', 'index.html'),
filename: 'index.html',
chunks: ['index']
}),