feat: update platform

This commit is contained in:
smallstone 2023-11-09 18:02:57 +08:00
parent 3ab349c6c4
commit 700cfff6ba
7 changed files with 9054 additions and 174 deletions

19
src/main.html Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DevChat</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="app"></div>
<script></script>
</body>
</html>

6
src/types/globle.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
declare global {
interface Window {
[key: string]: any;
}
}
export {};

View File

@ -1,12 +1,12 @@
// @ts-ignore
const vscodeApi = window.acquireVsCodeApi();
// const vscodeApi = window.acquireVsCodeApi();
const vscodeApi = {
postMessage: (message: any) => {},
};
class MessageUtil {
private static instance: MessageUtil;
handlers: { [x: string]: any; };
handlers: { [x: string]: any };
messageListener: any;
constructor() {
@ -14,13 +14,13 @@ class MessageUtil {
this.messageListener = null;
if (!this.messageListener) {
this.messageListener = (event: { data: any; }) => {
this.messageListener = (event: { data: any }) => {
const message = event.data;
this.handleMessage(message);
};
window.addEventListener('message', this.messageListener);
window.addEventListener("message", this.messageListener);
} else {
console.log('Message listener has already been bound.');
console.log("Message listener has already been bound.");
}
}
@ -49,17 +49,22 @@ class MessageUtil {
}
// Handle a received message
handleMessage(message: { command: string | number; }) {
handleMessage(message: { command: string | number }) {
const handlers = this.handlers[message.command];
if (handlers) {
handlers.forEach((handler: (arg0: { command: string | number; }) => any) => handler(message));
handlers.forEach((handler: (arg0: { command: string | number }) => any) =>
handler(message)
);
}
}
// Send a message to the VSCode API
sendMessage(message: any) {
// console.log(`${JSON.stringify(message)}`);
vscodeApi.postMessage(message);
if (process.env.platform === "idea") {
window.callJAVA();
} else {
window.acquireVsCodeApi().postMessage(message);
}
}
}

View File

@ -1,5 +1,13 @@
import { Stack, Container, Divider, Box, Group,Text, Button, createStyles } from "@mantine/core";
import {
Stack,
Container,
Divider,
Box,
Group,
Text,
Button,
createStyles,
} from "@mantine/core";
import React, { useEffect } from "react";
import MessageBody from "@/views/components/MessageBody";
import MessageAvatar from "@/views/components/MessageAvatar";
@ -8,69 +16,87 @@ import { useMst } from "@/views/stores/RootStore";
import { Message } from "@/views/stores/ChatStore";
import MessageContext from "@/views/components/MessageContext";
import CurrentMessage from "@/views/components/CurrentMessage";
import { Card } from '@mantine/core';
import { Card } from "@mantine/core";
import { IconInfoSquareRounded } from "@tabler/icons-react";
const useStyles = createStyles((theme) => ({
card:{
backgroundColor: 'var(--vscode-menu-background)',
fontFamily: 'var(--vscode-editor-font-familyy)',
fontSize: 'var(--vscode-editor-font-size)',
color: 'var(--vscode-menu-foreground)',
borderColor: 'var(--vscode-menu-border)',
card: {
backgroundColor: "var(--vscode-menu-background)",
fontFamily: "var(--vscode-editor-font-familyy)",
fontSize: "var(--vscode-editor-font-size)",
color: "var(--vscode-menu-foreground)",
borderColor: "var(--vscode-menu-border)",
},
cardDescription:{
cardDescription: {
marginTop: 10,
marginBottom: 10,
},
button:{
backgroundColor:"#ED6A45",
fontFamily: 'var(--vscode-editor-font-familyy)',
fontSize: 'var(--vscode-editor-font-size)',
color:"#fff",
"&:hover":{
backgroundColor:"#ED6A45",
button: {
backgroundColor: "#ED6A45",
fontFamily: "var(--vscode-editor-font-familyy)",
fontSize: "var(--vscode-editor-font-size)",
color: "#fff",
"&:hover": {
backgroundColor: "#ED6A45",
opacity: 0.8,
},
"&:focus":{
backgroundColor:"#ED6A45",
"&:focus": {
backgroundColor: "#ED6A45",
opacity: 0.8,
}
}
}));
},
},
}));
const MessageList = observer((props: any) => {
const { chat } = useMst();
const {classes} = useStyles();
const { classes } = useStyles();
return (<Stack spacing={0} sx={{margin:'0 10px 10px 10px'}}>
return (
<Stack spacing={0} sx={{ margin: "0 10px 10px 10px" }}>
{chat.messages.map((item, index: number) => {
const { message: messageText, type: messageType, hash: messageHash, contexts, confirm } = item;
const {
message: messageText,
type: messageType,
hash: messageHash,
contexts,
confirm,
} = item;
// setMessage(messageText);
return <Stack
return (
<Stack
spacing={0}
key={`message-${index}`}
sx={{
padding: 0,
margin: 0
}}>
margin: 0,
}}
>
<MessageAvatar
key={`message-header-${index}`}
showDelete={index === chat.messages.length - 2}
deleteHash={messageHash}
avatarType={messageType}
copyMessage={messageText}
messageContexts={contexts} />
messageContexts={contexts}
/>
<Box
key={`message-container-${index}`}
sx={{
margin: 0,
padding: 0,
pre: {
whiteSpace: 'break-spaces'
whiteSpace: "break-spaces",
},
}}>
{ messageType === 'bot' && confirm && <Card shadow="sm" padding="xs" radius="md" withBorder className={classes.card}>
}}
>
{messageType === "bot" && confirm && (
<Card
shadow="sm"
padding="xs"
radius="md"
withBorder
className={classes.card}
>
<Card.Section withBorder inheritPadding py="xs">
<Group position="left">
<IconInfoSquareRounded size={20} />
@ -78,26 +104,54 @@ const MessageList = observer((props: any) => {
</Group>
</Card.Section>
<Text className={classes.cardDescription}>
DevChat will make GPT-4 API calls to analyze up to ten source files, costing <strong>approximately $0.4 USD per question</strong>.
<br/>
<br/>
DevChat will make GPT-4 API calls to analyze up to ten
source files, costing{" "}
<strong>approximately $0.4 USD per question</strong>.
<br />
<br />
Would you like to proceed?
</Text>
<Group position="right" >
<Button size="compact-xs" className={classes.button} onClick={()=> chat.sendLastUserMessage() }>Yes</Button>
<Button size="compact-xs" className={classes.button} onClick={()=> chat.cancelDevchatAsk()}>No</Button>
<Group position="right">
<Button
size="compact-xs"
className={classes.button}
onClick={() => chat.sendLastUserMessage()}
>
Yes
</Button>
<Button
size="compact-xs"
className={classes.button}
onClick={() => chat.cancelDevchatAsk()}
>
No
</Button>
</Group>
</Card>}
<MessageContext key={`message-context-${index}`} contexts={contexts} />
<MessageBody key={`message-codeblock-${index}`} messageType={messageType} messageDone={!(index === chat.messages.length -1 && chat.generating)}>
</Card>
)}
<MessageContext
key={`message-context-${index}`}
contexts={contexts}
/>
<MessageBody
key={`message-codeblock-${index}`}
messageType={messageType}
messageDone={
!(index === chat.messages.length - 1 && chat.generating)
}
>
{messageText}
</MessageBody>
</Box >
{index !== chat.messages.length - 1 && <Divider my={3} key={`message-divider-${index}`} />}
</Stack >;
</Box>
{index !== chat.messages.length - 1 && (
<Divider my={3} key={`message-divider-${index}`} />
)}
</Stack>
);
})}
<CurrentMessage />
</Stack>);
</Stack>
);
});
export default MessageList;

View File

@ -1,36 +1,36 @@
//@ts-check
'use strict';
"use strict";
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { DefinePlugin } = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { DefinePlugin } = require("webpack");
const CopyWebpackPlugin = require("copy-webpack-plugin");
//@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/
/** @type WebpackConfig */
const extensionConfig = {
name: 'vscode extension',
target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
name: "vscode extension",
target: "node", // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: "none", // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
entry: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: 'extension.js',
libraryTarget: 'commonjs2'
path: path.resolve(__dirname, "dist"),
filename: "extension.js",
libraryTarget: "commonjs2",
},
externals: {
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
// modules added here also need to be added in the .vscodeignore file
},
resolve: {
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.json']
extensions: [".ts", ".json"],
},
module: {
rules: [
@ -39,45 +39,45 @@ const extensionConfig = {
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
loader: "babel-loader",
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
}
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
{
loader: 'ts-loader'
}
]
loader: "ts-loader",
},
]
],
},
devtool: 'nosources-source-map',
],
},
devtool: "nosources-source-map",
infrastructureLogging: {
level: "log", // enables logging required for problem matchers
},
plugins: []
plugins: [],
};
/** @type WebpackConfig */
const webviewConfig = {
name: 'webview',
target: 'web',
mode: 'development',
name: "webview",
target: "web",
mode: "development",
entry: './src/index.tsx',
entry: "./src/index.tsx",
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
path: path.resolve(__dirname, "dist"),
filename: "index.js",
publicPath: "/",
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
extensions: [".ts", ".tsx", ".js", ".json"],
alias: {
'@': path.resolve(__dirname, 'src/')
"@": path.resolve(__dirname, "src/"),
},
},
module: {
@ -87,89 +87,85 @@ const webviewConfig = {
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
loader: "babel-loader",
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
}
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
{
loader: 'ts-loader'
}
]
loader: "ts-loader",
},
],
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
use: [
{
loader: "babel-loader",
options: {
presets: [
[
'@babel/preset-env',
'@babel/preset-react',
],
]
presets: [["@babel/preset-env", "@babel/preset-react"]],
},
}]
},
],
},
{
test: /\.css$/i,
use: [
{
loader: 'style-loader',
loader: "style-loader",
},
{
loader: 'css-loader',
loader: "css-loader",
options: {
modules: {
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
}
localIdentName: "[name]__[local]___[hash:base64:5]",
},
},
},
],
include: /views/
include: /views/,
},
{
test: /\.json$/i,
use: 'json-loader',
type: 'asset/source'
use: "json-loader",
type: "asset/source",
},
{
test: /\.(png|jpg|jpeg|gif|svg)$/, // 匹配文件类型
use: [
{
loader: 'file-loader', // 使用file-loader
loader: "file-loader", // 使用file-loader
options: {
name: '[name].[ext]', // 输出文件的名称和扩展名
outputPath: 'assets/', // 输出文件的路径
name: "[name].[ext]", // 输出文件的名称和扩展名
outputPath: "assets/", // 输出文件的路径
},
},
],
}
]
},
devtool: 'source-map',
],
},
devtool: "source-map",
infrastructureLogging: {
level: "log",
},
plugins: [
// generate an HTML file that includes the extension's JavaScript file
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src', 'index.html'),
filename: 'index.html',
chunks: ['index']
template: path.resolve(__dirname, "src", "index.html"),
filename: "index.html",
chunks: ["index"],
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src', 'welcome.html'),
filename: 'welcome.html',
chunks: ['welcome']
template: path.resolve(__dirname, "src", "welcome.html"),
filename: "welcome.html",
chunks: ["welcome"],
}),
]
],
};
module.exports = [extensionConfig, webviewConfig];

105
webpack.idea.config.js Normal file
View File

@ -0,0 +1,105 @@
//@ts-check
"use strict";
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const webpack = require("webpack");
const webviewConfig = {
name: "webview",
target: "web",
mode: "production",
entry: "./src/index.tsx",
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
publicPath: "/",
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json"],
alias: {
"@": path.resolve(__dirname, "src/"),
},
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
{
loader: "ts-loader",
},
],
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: [["@babel/preset-env", "@babel/preset-react"]],
},
},
],
},
{
test: /\.css$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
},
},
],
include: /views/,
},
{
test: /\.json$/i,
use: "json-loader",
type: "asset/source",
},
{
test: /\.(png|jpg|jpeg|gif|svg)$/, // 匹配文件类型
type: "asset/inline",
},
],
},
devtool: false,
infrastructureLogging: {
level: "log",
},
plugins: [
// generate an HTML file that includes the extension's JavaScript file
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "main.html"),
filename: "main.html",
chunks: ["main"],
}),
new CleanWebpackPlugin(),
new webpack.ProgressPlugin(),
new webpack.DefinePlugin({
"process.env.platform": "idea",
}),
],
};
module.exports = webviewConfig;

8695
yarn.lock Normal file

File diff suppressed because it is too large Load Diff