Skip to content

Commit 053680a

Browse files
authored
refactor(chatView): Enhance chatView by avoiding webview destruction and boosting operation speed (#70)
* refactor(chatView): Enhance chatView by avoiding webview destruction and boosting operation speed * Optimize chatView request: Switch from loop waiting to waiting for chatView onLoad
1 parent c0c97ef commit 053680a

File tree

6 files changed

+77
-8
lines changed

6 files changed

+77
-8
lines changed

Diff for: src/base/common/defer.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
interface Deferred<T> {
2+
abort: () => void;
3+
resolve: (value: T) => void;
4+
reject: (reason?: unknown) => void;
5+
promise: Promise<T>;
6+
}
7+
8+
export function defer<T>(signal?: AbortSignal): Deferred<T> {
9+
const ac = new AbortController();
10+
const dtd = {} as Deferred<T>;
11+
12+
dtd.promise = new Promise((resolve, reject) => {
13+
dtd.resolve = resolve;
14+
dtd.reject = reject;
15+
});
16+
17+
function onDidAbort() {
18+
dtd.reject(new Error('user aborted'));
19+
}
20+
21+
ac.signal.addEventListener('abort', onDidAbort);
22+
23+
if (signal) {
24+
signal.addEventListener('abort', onDidAbort);
25+
}
26+
27+
dtd.abort = function () {
28+
ac.abort();
29+
};
30+
31+
return dtd;
32+
}

Diff for: src/commands/commandsService.ts

-6
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ export class CommandsService {
9090
return;
9191
}
9292

93-
// TODO hack message render empty
94-
await setTimeout(800);
9593

9694
const selection = editor.selection;
9795
if (selection.isEmpty) {
@@ -124,8 +122,6 @@ export class CommandsService {
124122

125123
await chat.show();
126124

127-
// TODO hack message render empty
128-
await setTimeout(800);
129125
await addHighlightedCodeToContext(editor, selection, chat);
130126

131127
await setTimeout(800);
@@ -147,8 +143,6 @@ export class CommandsService {
147143

148144
await chat.show();
149145

150-
// TODO hack message render empty
151-
await setTimeout(600);
152146
await addHighlightedCodeToContext(editor, selection, chat);
153147

154148
await setTimeout(800);

Diff for: src/commands/commandsUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export async function addHighlightedCodeToContext(editor: TextEditor, selection:
8181
},
8282
};
8383

84-
await chat.send('highlightedCode', {
84+
await chat.request('highlightedCode', {
8585
rangeInFileWithContents,
8686
});
8787
}

Diff for: src/editor/views/chat/chatViewService.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ export class ChatViewService {
2929
return this.continueViewProvider.send(type, message);
3030
}
3131

32+
request(type: string, message?: unknown) {
33+
return this.continueViewProvider.request(type, message);
34+
}
3235
postMessage(message: unknown) {
3336
return this.continueViewProvider.postMessage(message);
3437
}
@@ -46,6 +49,8 @@ export class ChatViewService {
4649
}
4750

4851
register() {
49-
return window.registerWebviewViewProvider(CHAT_VIEW_ID, this.continueViewProvider);
52+
return window.registerWebviewViewProvider(CHAT_VIEW_ID, this.continueViewProvider, {
53+
webviewOptions: { retainContextWhenHidden: true },
54+
});
5055
}
5156
}

Diff for: src/editor/views/chat/continue/continueMessages.ts

+6
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,9 @@ export class ContinueEvent<
209209
});
210210
}
211211
}
212+
213+
export interface Message<T = any> {
214+
messageType: string;
215+
messageId: string;
216+
data: T;
217+
}

Diff for: src/editor/views/chat/continue/continueViewProvider.ts

+32
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919

2020
import { CMD_CODEASPACE_ANALYSIS, CMD_CODEASPACE_KEYWORDS_ANALYSIS } from 'base/common/configuration/configuration';
2121
import { ConfigurationService } from 'base/common/configuration/configurationService';
22+
import { defer } from 'base/common/defer';
2223
import { ChatMessageRole, type IChatMessage } from 'base/common/language-models/languageModels';
2324
import { LanguageModelsService } from 'base/common/language-models/languageModelsService';
2425
import { logger } from 'base/common/log/log';
@@ -33,13 +34,15 @@ import {
3334
type FromWebviewMessage,
3435
type IChatMessageParam,
3536
IChatModelResource,
37+
Message,
3638
PersistedSessionInfo,
3739
SessionInfo,
3840
type ShowErrorMessage,
3941
} from './continueMessages';
4042

4143
export class ContinueViewProvider extends AbstractWebviewViewProvider implements WebviewViewProvider {
4244
private historySaveDir = path.join(os.homedir(), '.autodev/sessions');
45+
private _readyDefer = defer<void>();
4346

4447
constructor(
4548
private context: ExtensionContext,
@@ -48,6 +51,7 @@ export class ContinueViewProvider extends AbstractWebviewViewProvider implements
4851
) {
4952
super(context);
5053

54+
logger.debug('ContinueViewProvider init');
5155
// TODO disposable
5256
configService.onDidChange(event => {
5357
if (event.affectsConfiguration('autodev.chat.models')) {
@@ -59,6 +63,10 @@ export class ContinueViewProvider extends AbstractWebviewViewProvider implements
5963
});
6064
}
6165

66+
ready() {
67+
return this._readyDefer.promise;
68+
}
69+
6270
newSession(prompt?: string) {
6371
if (prompt) {
6472
this.send('newSessionWithPrompt', { prompt });
@@ -79,6 +87,28 @@ export class ContinueViewProvider extends AbstractWebviewViewProvider implements
7987
});
8088
}
8189

90+
async request(type: string, data?: unknown): Promise<boolean> {
91+
const messageId = randomUUID();
92+
93+
await this.ready();
94+
95+
return new Promise((resolve, reject) => {
96+
const disposable = this._webview!.onDidReceiveMessage((msg: Message) => {
97+
if (msg.messageId === messageId) {
98+
logger.debug(`message received, messageID: ${messageId}`);
99+
resolve(msg.data);
100+
disposable?.dispose();
101+
}
102+
});
103+
this.postMessage({
104+
messageId: messageId,
105+
messageType: type,
106+
data: data,
107+
});
108+
logger.debug(`send success, messageType:${type},messageID:${messageId}`);
109+
});
110+
}
111+
82112
async provideWebviewView(webviewView: WebviewView): Promise<void> {
83113
const webview = webviewView.webview;
84114
const extensionUri = this.context.extensionUri;
@@ -130,6 +160,7 @@ export class ContinueViewProvider extends AbstractWebviewViewProvider implements
130160

131161
switch (payload.messageType) {
132162
case 'onLoad':
163+
logger.debug('sidebar webview onLoad ');
133164
this.handleViewLoad(new ContinueEvent(webview, payload));
134165
break;
135166

@@ -209,6 +240,7 @@ export class ContinueViewProvider extends AbstractWebviewViewProvider implements
209240
vscMachineId: '1111',
210241
vscMediaUrl: '',
211242
});
243+
this._readyDefer.resolve();
212244
}
213245

214246
private handleGetOpenFiles(event: ContinueEvent<'getOpenFiles'>) {

0 commit comments

Comments
 (0)