Reimplement send and stop buttons (#523)

This commit is contained in:
Logan Yang 2024-08-22 17:15:03 -07:00 committed by GitHub
parent 321193993c
commit 87bef4849d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 135 additions and 56 deletions

View file

@ -1,23 +1,29 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"env": { "node": true },
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@typescript-eslint/ban-ts-comment": "off",
"no-prototype-builtins": "off",
"@typescript-eslint/no-empty-function": "off"
}
}
"root": true,
"parser": "@typescript-eslint/parser",
"env": { "node": true },
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@typescript-eslint/ban-ts-comment": "off",
"no-prototype-builtins": "off",
"@typescript-eslint/no-empty-function": "off"
},
"overrides": [
{
"files": ["*.json", "*.jsonc", ".eslintrc"],
"parser": "jsonc-eslint-parser",
"rules": {
"jsonc/auto": "error"
}
}
]
}

101
package-lock.json generated
View file

@ -53,6 +53,7 @@
"electron": "^27.3.2",
"esbuild": "0.17.3",
"eslint": "^8.57.0",
"eslint-plugin-json": "^4.0.1",
"husky": "^9.1.5",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.5.0",
@ -2985,9 +2986,9 @@
}
},
"node_modules/@types/jest": {
"version": "29.5.11",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz",
"integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==",
"version": "29.5.12",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz",
"integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@ -3856,11 +3857,11 @@
}
},
"node_modules/axios": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz",
"integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==",
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
"dependencies": {
"follow-redirects": "^1.15.0",
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
@ -5510,6 +5511,19 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-plugin-json": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-4.0.1.tgz",
"integrity": "sha512-3An5ISV5dq/kHfXdNyY5TUe2ONC3yXFSkLX2gu+W8xAhKhfvrRvkSAeKXCxZqZ0KJLX15ojBuLPyj+UikQMkOA==",
"dev": true,
"dependencies": {
"lodash": "^4.17.21",
"vscode-json-languageservice": "^4.1.6"
},
"engines": {
"node": ">=18.0"
}
},
"node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@ -5814,9 +5828,9 @@
"dev": true
},
"node_modules/fast-glob": {
"version": "3.2.12",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
"dev": true,
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@ -7722,18 +7736,18 @@
"dev": true
},
"node_modules/jest-environment-jsdom": {
"version": "29.5.0",
"resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.5.0.tgz",
"integrity": "sha512-/KG8yEK4aN8ak56yFVdqFDzKNHgF4BAymCx2LbPNPsUshUlfAl0eX402Xm1pt+eoG9SLZEUVifqXtX8SK74KCw==",
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz",
"integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==",
"dev": true,
"dependencies": {
"@jest/environment": "^29.5.0",
"@jest/fake-timers": "^29.5.0",
"@jest/types": "^29.5.0",
"@jest/environment": "^29.7.0",
"@jest/fake-timers": "^29.7.0",
"@jest/types": "^29.6.3",
"@types/jsdom": "^20.0.0",
"@types/node": "*",
"jest-mock": "^29.5.0",
"jest-util": "^29.5.0",
"jest-mock": "^29.7.0",
"jest-util": "^29.7.0",
"jsdom": "^20.0.0"
},
"engines": {
@ -8544,6 +8558,12 @@
"node": ">=6"
}
},
"node_modules/jsonc-parser": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
"integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
"dev": true
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@ -12530,9 +12550,9 @@
}
},
"node_modules/ts-jest": {
"version": "29.1.0",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz",
"integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==",
"version": "29.1.1",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz",
"integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==",
"dev": true,
"dependencies": {
"bs-logger": "0.x",
@ -12541,7 +12561,7 @@
"json5": "^2.2.3",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
"semver": "^7.5.3",
"yargs-parser": "^21.0.1"
},
"bin": {
@ -12921,6 +12941,43 @@
"node": ">=0.10.0"
}
},
"node_modules/vscode-json-languageservice": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz",
"integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==",
"dev": true,
"dependencies": {
"jsonc-parser": "^3.0.0",
"vscode-languageserver-textdocument": "^1.0.3",
"vscode-languageserver-types": "^3.16.0",
"vscode-nls": "^5.0.0",
"vscode-uri": "^3.0.3"
}
},
"node_modules/vscode-languageserver-textdocument": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
"integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
"dev": true
},
"node_modules/vscode-languageserver-types": {
"version": "3.17.5",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
"dev": true
},
"node_modules/vscode-nls": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz",
"integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==",
"dev": true
},
"node_modules/vscode-uri": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
"integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==",
"dev": true
},
"node_modules/vuvuzela": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz",

View file

@ -46,6 +46,7 @@
"electron": "^27.3.2",
"esbuild": "0.17.3",
"eslint": "^8.57.0",
"eslint-plugin-json": "^4.0.1",
"husky": "^9.1.5",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.5.0",

View file

@ -301,8 +301,11 @@ const Chat: React.FC<ChatProps> = ({
const handleStopGenerating = () => {
if (abortController) {
console.log("User stopping generation...");
if (plugin.settings.debug) {
console.log("User stopping generation...");
}
abortController.abort();
setLoading(false);
}
};
@ -457,7 +460,6 @@ const Chat: React.FC<ChatProps> = ({
setCurrentModel={setModel}
currentChain={currentChain}
setCurrentChain={setChain}
onStopGenerating={handleStopGenerating}
onNewChat={() => {
clearMessages();
clearChatMemory();
@ -479,6 +481,8 @@ const Chat: React.FC<ChatProps> = ({
handleSendMessage={handleSendMessage}
handleKeyDown={handleKeyDown}
getChatVisibility={getChatVisibility}
isGenerating={loading}
onStopGenerating={handleStopGenerating}
/>
</div>
</div>

View file

@ -11,7 +11,6 @@ import {
RefreshIcon,
SaveAsNoteIcon,
SendActiveNoteToPromptIcon,
StopIcon,
UseActiveNoteAsContextIcon,
} from "@/components/Icons";
import { stringToChainType } from "@/utils";
@ -21,7 +20,6 @@ interface ChatIconsProps {
setCurrentModel: (model: string) => void;
currentChain: ChainType;
setCurrentChain: (chain: ChainType, options?: SetChainOptions) => void;
onStopGenerating: () => void;
onNewChat: () => void;
onSaveAsNote: () => void;
onSendActiveNoteToPrompt: () => void;
@ -39,7 +37,6 @@ const ChatIcons: React.FC<ChatIconsProps> = ({
setCurrentModel,
currentChain,
setCurrentChain,
onStopGenerating,
onNewChat,
onSaveAsNote,
onSendActiveNoteToPrompt,
@ -191,10 +188,6 @@ const ChatIcons: React.FC<ChatIconsProps> = ({
<span className="tooltip-text">Model Selection</span>
</div>
</div>
<button className="chat-icon-button" onClick={onStopGenerating}>
<StopIcon className="icon-scaler" />
<span className="tooltip-text">Stop Generating</span>
</button>
<button className="chat-icon-button" onClick={onNewChat}>
<RefreshIcon className="icon-scaler" />
<span className="tooltip-text">

View file

@ -1,4 +1,5 @@
import { NoteTitleModal } from "@/components/NoteTitleModal";
import { IconPlayerStopFilled, IconSend } from "@tabler/icons-react";
import React, { useEffect, useRef, useState } from "react";
interface ChatInputProps {
@ -7,6 +8,8 @@ interface ChatInputProps {
handleKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
handleSendMessage: () => void;
getChatVisibility: () => Promise<boolean>;
isGenerating: boolean;
onStopGenerating: () => void;
}
const ChatInput: React.FC<ChatInputProps> = ({
@ -15,6 +18,8 @@ const ChatInput: React.FC<ChatInputProps> = ({
handleKeyDown,
handleSendMessage,
getChatVisibility,
isGenerating,
onStopGenerating,
}) => {
const [rows, setRows] = useState(1);
const [shouldFocus, setShouldFocus] = useState(false);
@ -82,7 +87,12 @@ const ChatInput: React.FC<ChatInputProps> = ({
onKeyDown={handleKeyDown}
rows={rows}
/>
<button onClick={handleSendMessage}>Send</button>
<button
onClick={isGenerating ? onStopGenerating : handleSendMessage}
aria-label={isGenerating ? "Stop generating" : "Send message"}
>
{isGenerating ? <IconPlayerStopFilled size={18} /> : <IconSend size={18} />}
</button>
</div>
);
};

View file

@ -141,17 +141,21 @@ If your plugin does not need CSS, delete this file.
flex-grow: 1;
width: 100%;
order: 2;
position: relative;
}
.chat-input-container textarea {
width: 100%;
margin-right: 8px;
margin-right: 0;
margin-bottom: 8px;
resize: none;
overflow: auto;
min-height: 60px;
max-height: 200px;
box-sizing: border-box;
border: 1px solid gray;
border-radius: 10px;
padding: 15px 60px 15px 15px;
}
.chat-input-container textarea::placeholder {
@ -160,8 +164,12 @@ If your plugin does not need CSS, delete this file.
}
.chat-input-container button {
position: absolute;
right: 22px;
bottom: 31px;
padding: 8px;
margin: 8px;
margin: 0;
z-index: 1;
}
.chat-messages {