Skip to content

Commit 8903520

Browse files
author
克隆(宗可龙)
committed
Merge branch 'main' of https://github.com/onlook-dev/onlook into translation_zh
* 'main' of https://github.com/onlook-dev/onlook: Improve applyDiffs to handle failures robustly (onlook-dev#1663) Publish version v0.2.20 (onlook-dev#1662) Add Korean language translation file (onlook-dev#1657) Publish version v0.2.19 (onlook-dev#1659) Check port before starting project (onlook-dev#1661) More persistent port checking (onlook-dev#1660) Handle rate limited (onlook-dev#1658)
2 parents dd9641c + 3edbb38 commit 8903520

File tree

23 files changed

+511
-75
lines changed

23 files changed

+511
-75
lines changed

apps/studio/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"productName": "Onlook",
33
"name": "@onlook/studio",
4-
"version": "0.2.18",
4+
"version": "0.2.20",
55
"homepage": "https://onlook.com",
66
"main": "dist-electron/main/index.js",
77
"description": "The first-ever devtool for designers",

apps/studio/src/components/Modals/Subscription/PricingPage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ export const SubscriptionModal = observer(() => {
4646
const getPlan = async () => {
4747
const plan = await userManager.subscription.getPlanFromServer();
4848
if (plan === UsagePlanType.PRO) {
49-
editorEngine.chat.stream.clear();
49+
editorEngine.chat.stream.clearRateLimited();
50+
editorEngine.chat.stream.clearErrorMessage();
5051
}
5152
setIsCheckingOut(null);
5253
};

apps/studio/src/i18n.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import i18n from 'i18next';
22
import { initReactI18next } from 'react-i18next';
33
import enTranslation from './locales/en/translation.json';
44
import jaTranslation from './locales/ja/translation.json';
5+
import krTranslation from './locales/kr/translation.json';
56
import zhTranslation from './locales/zh/translation.json';
67

78
const resources = {
@@ -14,6 +15,9 @@ const resources = {
1415
zh: {
1516
translation: zhTranslation,
1617
},
18+
kr: {
19+
translation: krTranslation,
20+
},
1721
};
1822

1923
i18n.use(initReactI18next).init({

apps/studio/src/lib/editor/engine/chat/code.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { sendAnalytics } from '@/lib/utils';
33
import { CodeBlockProcessor } from '@onlook/ai';
44
import { ChatMessageRole, type AssistantChatMessage, type CodeBlock } from '@onlook/models/chat';
55
import type { CodeDiff } from '@onlook/models/code';
6+
import { toast } from '@onlook/ui/use-toast';
67
import { makeAutoObservable } from 'mobx';
78
import type { ChatManager } from '.';
89
import type { EditorEngine } from '..';
@@ -42,7 +43,16 @@ export class ChatCodeManager {
4243
}
4344
let content = originalContent;
4445
for (const block of codeBlocks) {
45-
content = await this.processor.applyDiff(content, block.content);
46+
const result = await this.processor.applyDiff(content, block.content);
47+
if (!result.success) {
48+
console.error('Failed to apply code block', block);
49+
toast({
50+
title: 'Failed to apply code block',
51+
variant: 'destructive',
52+
description: 'Please try again or prompt the AI to fix it.',
53+
});
54+
}
55+
content = result.text;
4656
}
4757

4858
const success = await this.writeFileContent(file, content, originalContent);

apps/studio/src/lib/editor/engine/chat/conversation/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class ConversationManager {
2929
}
3030

3131
async getCurrentProjectConversations(project: Project | null) {
32-
this.editorEngine.chat.stream.clear();
32+
this.editorEngine.chat.stream.dispose();
3333
if (!project) {
3434
return;
3535
}
@@ -84,7 +84,7 @@ export class ConversationManager {
8484
}
8585
this.current = new ChatConversationImpl(this.projectId, []);
8686
this.conversations.push(this.current);
87-
this.editorEngine.chat.stream.clear();
87+
this.editorEngine.chat.stream.dispose();
8888
sendAnalytics('start new conversation');
8989
}
9090

@@ -95,7 +95,7 @@ export class ConversationManager {
9595
return;
9696
}
9797
this.current = match;
98-
this.editorEngine.chat.stream.clear();
98+
this.editorEngine.chat.stream.dispose();
9999
sendAnalytics('select conversation');
100100
}
101101

@@ -124,7 +124,7 @@ export class ConversationManager {
124124
this.conversations.push(this.current);
125125
}
126126
}
127-
this.editorEngine.chat.stream.clear();
127+
this.editorEngine.chat.stream.dispose();
128128
sendAnalytics('delete conversation');
129129
}
130130

apps/studio/src/lib/editor/engine/chat/index.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class ChatManager {
104104
false,
105105
);
106106

107-
this.stream.clear();
107+
this.stream.clearBeforeSend();
108108
this.isWaiting = true;
109109
const messages = this.conversation.current.getMessagesForStream();
110110
const res: CompletedStreamResponse | null = await this.sendStreamRequest(
@@ -116,7 +116,7 @@ export class ChatManager {
116116
} else {
117117
console.error('No stream response found');
118118
}
119-
this.stream.clear();
119+
this.stream.clearAfterSend();
120120
this.isWaiting = false;
121121
sendAnalytics('receive chat response');
122122
}
@@ -163,7 +163,7 @@ export class ChatManager {
163163
}
164164

165165
async handleChatResponse(res: CompletedStreamResponse, requestType: StreamRequestType) {
166-
if (!res || !this.conversation.current) {
166+
if (!res) {
167167
console.error('No response found');
168168
return;
169169
}
@@ -176,6 +176,11 @@ export class ChatManager {
176176
return;
177177
}
178178

179+
if (!this.conversation.current) {
180+
console.error('No conversation found');
181+
return;
182+
}
183+
179184
if (res.usage) {
180185
this.conversation.current.updateTokenUsage(res.usage);
181186
}
@@ -247,7 +252,7 @@ export class ChatManager {
247252
}
248253

249254
dispose() {
250-
this.stream.clear();
255+
this.stream.dispose();
251256
this.code?.dispose();
252257
this.context?.dispose();
253258
if (this.conversation) {

apps/studio/src/lib/editor/engine/chat/stream.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ export class StreamResolver {
1919
window.api.on(MainChannels.CHAT_STREAM_PARTIAL, (args: PartialStreamResponse) => {
2020
const { payload } = args;
2121
this.resolveContent(payload);
22-
this.errorMessage = null;
23-
this.rateLimited = null;
2422
});
2523
}
2624

@@ -65,10 +63,29 @@ export class StreamResolver {
6563
return null;
6664
}
6765

68-
clear() {
66+
clearBeforeSend() {
6967
this.content = [];
7068
this.requestId = null;
69+
this.rateLimited = null;
7170
this.errorMessage = null;
71+
}
72+
73+
clearRateLimited() {
7274
this.rateLimited = null;
7375
}
76+
77+
clearErrorMessage() {
78+
this.errorMessage = null;
79+
}
80+
81+
clearAfterSend() {
82+
this.content = [];
83+
}
84+
85+
dispose() {
86+
this.content = [];
87+
this.requestId = null;
88+
this.rateLimited = null;
89+
this.errorMessage = null;
90+
}
7491
}

apps/studio/src/lib/projects/create.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export class CreateManager {
128128
this.clearSlowConnectionTimer();
129129

130130
setTimeout(() => {
131-
this.projectsManager.runner?.start();
131+
this.projectsManager.runner?.startIfPortAvailable();
132132
}, 1000);
133133
sendAnalytics('prompt create project success');
134134
} else {

apps/studio/src/lib/projects/port.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ export class PortManager {
77
isPortAvailable: boolean = true;
88
suggestedPort: number = 3000;
99
currentPort: number = 3000;
10+
portCheckInterval: Timer | null = null;
1011

1112
constructor(
1213
private runManager: RunManager,
1314
private project: Project,
1415
) {
1516
makeAutoObservable(this);
1617
this.currentPort = this.getPortFromProject();
18+
this.listenForPortChanges();
1719
reaction(
1820
() => this.runManager.state,
1921
() => {
@@ -24,6 +26,13 @@ export class PortManager {
2426
);
2527
}
2628

29+
listenForPortChanges() {
30+
this.clearPortCheckInterval();
31+
this.portCheckInterval = setInterval(async () => {
32+
await this.checkPort();
33+
}, 3000);
34+
}
35+
2736
getPortFromProject() {
2837
try {
2938
const url = this.project.url;
@@ -40,10 +49,10 @@ export class PortManager {
4049
this.currentPort = this.getPortFromProject();
4150
}
4251

43-
async checkPort(): Promise<void> {
52+
async checkPort(): Promise<boolean> {
4453
if (this.runManager.state !== RunState.STOPPED) {
4554
this.isPortAvailable = true;
46-
return;
55+
return this.isPortAvailable;
4756
}
4857

4958
const response: DetectedPortResults = await invokeMainChannel(
@@ -54,5 +63,17 @@ export class PortManager {
5463
);
5564
this.isPortAvailable = response.isPortAvailable;
5665
this.suggestedPort = response.availablePort;
66+
return this.isPortAvailable;
67+
}
68+
69+
clearPortCheckInterval() {
70+
if (this.portCheckInterval) {
71+
clearInterval(this.portCheckInterval);
72+
this.portCheckInterval = null;
73+
}
74+
}
75+
76+
dispose() {
77+
this.clearPortCheckInterval();
5778
}
5879
}

apps/studio/src/lib/projects/run.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ export class RunManager {
6868
this._state = state;
6969
}
7070

71+
async startIfPortAvailable() {
72+
const isPortAvailable = await this.portManager.checkPort();
73+
if (isPortAvailable) {
74+
this.start();
75+
}
76+
}
77+
7178
async start() {
7279
this.state = RunState.SETTING_UP;
7380
this.startLoadingTimer();
@@ -196,5 +203,6 @@ export class RunManager {
196203
this.cleanupLoadingTimer();
197204
}
198205
await this.stop();
206+
this.portManager.dispose();
199207
}
200208
}

0 commit comments

Comments
 (0)