Skip to content

Commit

Permalink
fix history
Browse files Browse the repository at this point in the history
  • Loading branch information
daoauth committed Dec 13, 2024
1 parent c52cb4d commit 86b16e7
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 41 deletions.
10 changes: 7 additions & 3 deletions src/utilities/aptosAssistant.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as vscode from 'vscode';
import { RequestData } from '../webview/panel/src/utilities/commends';

const getContent = (str: string) => {
const { choices } = JSON.parse(str);
Expand All @@ -7,14 +8,14 @@ const getContent = (str: string) => {

let isLoading: boolean = false;
const history: {
user: string;
user: RequestData;
bot: string;
}[] = [];

export const getHistory = () => history;

export const aptosAssistant = async (
request: string,
request: RequestData,
onData: (data: string) => void,
onEnd: () => void,
): Promise<void> => {
Expand All @@ -38,7 +39,10 @@ export const aptosAssistant = async (
top: 3,
suggest_followup_questions: false,
},
history,
history: history.map((item) => ({
user: item.user.content,
bot: item.bot,
})),
}),
},
);
Expand Down
19 changes: 12 additions & 7 deletions src/webview/panel/src/App.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#loading-spinner {
animation: loading-spinner 1s linear infinite;
.skeleton {
background-color: var(--vscode-editorWidget-background);
border-radius: 4px;
animation: pulse 1.5s infinite;
}

@keyframes loading-spinner {
from {
transform: rotate(0deg);
@keyframes pulse {
0% {
opacity: 1;
}
to {
transform: rotate(360deg);
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
67 changes: 42 additions & 25 deletions src/webview/panel/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@ import { VSCodeTextField } from '@vscode/webview-ui-toolkit/react';

import './App.css';

import { COMMENDS } from './utilities/commends';
import { COMMENDS, RequestData } from './utilities/commends';
import { vscode } from './utilities/vscode';
import { User } from './components/User';
import { Bot } from './components/Bot';
import { Skeleton } from './components/Skeleton';

function App() {
const initialized = useRef<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [input, setInput] = useState<string>('');
const [htmlHistory, setHtmlHistory] = useState<
{ isBot: boolean; content: string }[]
>([]);
const messagesEndRef = useRef<HTMLDivElement>(null);
const [htmlHistory, setHtmlHistory] = useState<(string | RequestData)[]>([]);
const scrollContainerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
if (scrollContainerRef.current) {
scrollContainerRef.current.scrollTop =
scrollContainerRef.current.scrollHeight;
}
}, [htmlHistory]);

useEffect(() => {
Expand All @@ -30,23 +32,26 @@ function App() {
setIsLoading(() => true);
setHtmlHistory((old) => [
...old,
{ isBot: false, content: message.data },
{ isBot: true, content: '' },
{ code: true, content: message.data },
'',
]);
break;
case COMMENDS.AiHistory:
const temp: { isBot: boolean; content: string }[] = [];
message.data.forEach((item: { user: string; bot: string }) => {
temp.push({ isBot: false, content: item.user });
item.bot && temp.push({ isBot: true, content: item.bot });
const temp: (string | RequestData)[] = [];
message.data.forEach((item: { user: RequestData; bot: string }) => {
temp.push(item.user, item.bot);
});
setHtmlHistory(() => temp);
if (scrollContainerRef.current) {
setTimeout(() => {
scrollContainerRef.current!.scrollTop =
scrollContainerRef.current!.scrollHeight;
}, 5);
}
initialized.current = true;
break;
case COMMENDS.AiStream:
setHtmlHistory((old) => [
...old.slice(0, -1),
{ isBot: true, content: message.data },
]);
setHtmlHistory((old) => [...old.slice(0, -1), message.data]);
break;
case COMMENDS.AiStreamEnd:
setIsLoading(() => false);
Expand All @@ -57,19 +62,25 @@ function App() {
};

if (!initialized.current) {
initialized.current = true;
vscode.postMessage({ command: COMMENDS.Env });
}

window.addEventListener('message', handleMessage);

return () => {
window.removeEventListener('message', handleMessage);
};
}, []);

return (
<div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
<div
ref={scrollContainerRef}
style={{
flex: 1,
overflowY: 'auto',
display: 'flex',
flexDirection: 'column',
}}
>
{htmlHistory.length === 0 ? (
Expand All @@ -85,18 +96,24 @@ function App() {
height: '100%',
}}
>
No messages yet. Start a conversation!
👋 Hello, Aptos! Start a conversation. 💬
</div>
) : (
htmlHistory.map((item, key) =>
item.isBot ? (
<Bot key={key} data={item.content} />
typeof item === 'string' ? (
isLoading && key === htmlHistory.length - 1 && !item ? (
<Skeleton key={key} />
) : (
<Bot key={key} data={item} />
)
) : (
<User key={key} data={item.content} />
<User
key={key}
data={item.code ? 'Code Analysis...' : item.content}
/>
),
)
)}
<div ref={messagesEndRef} />
</div>
<div
style={{
Expand All @@ -110,7 +127,7 @@ function App() {
width: '100%',
color: 'var(--vscode-input-foreground)',
}}
disabled={isLoading}
disabled={isLoading || !initialized.current}
value={input}
placeholder="Message..."
onChange={(event) => {
Expand All @@ -127,8 +144,8 @@ function App() {
setIsLoading(() => true);
setHtmlHistory((old) => [
...old,
{ isBot: false, content: value },
{ isBot: true, content: '' },
{ code: false, content: value },
'',
]);
}
}}
Expand Down
3 changes: 0 additions & 3 deletions src/webview/panel/src/components/Bot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'highlight.js/styles/github-dark.css';

export const Bot = ({ data }: { data: string }) => {
const [html, setHtml] = useState<string>('');

useEffect(() => {
const renderer = {
code: ({ text, lang }: { text: string; lang?: string }) => {
Expand All @@ -18,13 +17,11 @@ export const Bot = ({ data }: { data: string }) => {
const renderedHtml = marked.parse(data, { async: false, gfm: true });
setHtml(() => renderedHtml);
}, [data]);

return (
<div
style={{
width: '80%',
textAlign: 'left',
marginBottom: '1rem',
}}
dangerouslySetInnerHTML={{ __html: html }}
/>
Expand Down
21 changes: 21 additions & 0 deletions src/webview/panel/src/components/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

export const Skeleton = () => {
const lineCount = Math.floor(Math.random() * (2 - 1 + 1)) + 1;
return (
<div style={{ width: '80%', textAlign: 'left', marginTop: '1rem' }}>
{Array.from({ length: lineCount }).map((_, index) => (
<div
key={index}
className="skeleton"
style={{
height: '16px',
marginBottom: '4px',
borderRadius: '4px',
width: `${Math.random() * (80 - 30) + 30}%`,
}}
/>
))}
</div>
);
};
5 changes: 5 additions & 0 deletions src/webview/panel/src/utilities/commends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ export enum COMMENDS {
OutputInfo = 'output:info',
OutputError = 'output:error',
}

export interface RequestData {
code: boolean;
content: string;
}
6 changes: 3 additions & 3 deletions src/webview/panelProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class PanelProvider implements vscode.WebviewViewProvider {
break;
case COMMENDS.AiQuestion:
aptosAssistant(
data,
{ code: false, content: data },
(stream) => {
this._view?.webview.postMessage({
command: COMMENDS.AiStream,
Expand Down Expand Up @@ -92,10 +92,10 @@ class PanelProvider implements vscode.WebviewViewProvider {
case 'aptos-extension.assistant.folder':
this._view?.webview.postMessage({
command: message.command,
data: 'Code Analysis...',
data: { code: true, content: '' },
});
aptosAssistant(
message.data,
{ code: true, content: message.data },
(stream) => {
this._view?.webview.postMessage({
command: COMMENDS.AiStream,
Expand Down

0 comments on commit 86b16e7

Please sign in to comment.