Skip to content

Commit 002dd14

Browse files
committed
fix(console): auto-scroll terminal and AI panels
1 parent 180a68f commit 002dd14

4 files changed

Lines changed: 21 additions & 3 deletions

File tree

frontend/src/components/main/IdePanel.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ import { nextTick, onMounted, ref, watch } from 'vue';
88
99
import { useIdePanel } from '@/composables/useIdePanel';
1010
11+
const props = defineProps<{ active?: boolean }>();
1112
const ide = useIdePanel();
1213
const chatAreaEl = ref<HTMLElement | null>(null);
1314
1415
onMounted(() => { ide.initialize(); });
1516
1617
watch(() => ide.turns.value.length, () => { void nextTick(scrollToBottom); });
1718
watch(() => ide.turns.value, () => { void nextTick(scrollToBottom); }, { deep: true });
19+
watch(() => props.active, (active) => {
20+
if (active) void nextTick(scrollToBottom);
21+
});
1822
1923
function scrollToBottom(): void {
2024
const el = chatAreaEl.value;

frontend/src/composables/useIdePanel.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,14 @@ function create(): IdePanelApi {
167167
return currentAssistant;
168168
}
169169

170+
function touchTurns(): void {
171+
turns.value = [...turns.value];
172+
}
173+
170174
function appendLine(kind: LineKind, text: string): void {
171175
const t = ensureAssistant();
172176
t.lines!.push({ kind, text });
177+
touchTurns();
173178
}
174179

175180
/** 流式增量追加 — 只拼接到最后一个 'stream' line。
@@ -184,6 +189,7 @@ function create(): IdePanelApi {
184189
} else {
185190
lines.push({ kind: 'stream', text });
186191
}
192+
touchTurns();
187193
}
188194

189195
function finalize(): void {

frontend/src/composables/useSessionTerminal.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ function create(): SessionTerminalApi {
195195
});
196196
}
197197

198+
function scrollTerminalToBottom(): void {
199+
requestAnimationFrame(() => {
200+
try { _term.scrollToBottom(); } catch { /* 静默 */ }
201+
});
202+
}
203+
198204
function getActiveBuffer(): string {
199205
return activeSessionId.value ? (sessionBuffers.get(activeSessionId.value) || '') : '';
200206
}
@@ -254,7 +260,8 @@ function create(): SessionTerminalApi {
254260

255261
activeSessionId.value = session.id;
256262
notifyLifecycle('session-change', { hostId, sessionId: session.id, forceReconnect });
257-
_term.write(sessionBuffers.get(session.id) || '');
263+
_term.write(sessionBuffers.get(session.id) || '', () => scrollTerminalToBottom());
264+
scrollTerminalToBottom();
258265
if (hostId !== LOCAL_HOST_ID) {
259266
const hint = `当前终端已切换到 ${host.name}`;
260267
terminalHint.value = hint;
@@ -379,7 +386,8 @@ function create(): SessionTerminalApi {
379386
sessionBuffers.set(sessionId, next);
380387
if (sessionId !== activeSessionId.value) return;
381388
notifyOutput({ sessionId, data: output });
382-
_term.write(output);
389+
_term.write(output, () => scrollTerminalToBottom());
390+
scrollTerminalToBottom();
383391
});
384392

385393
sock.on('session:status', (session: SessionInfo) => {

frontend/src/views/MainConsoleView.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ function onSplitDoubleClick(): void {
402402
</div>
403403
<div class="ai-side-tab-content">
404404
<AiChatPanel v-show="rightTab === 'chat'" />
405-
<IdePanel v-show="rightTab === 'ide'" />
405+
<IdePanel v-show="rightTab === 'ide'" :active="rightTab === 'ide'" />
406406
<AgentPanel v-show="rightTab === 'agent'" />
407407
</div>
408408
</aside>

0 commit comments

Comments
 (0)