Skip to content

Commit 331963b

Browse files
committed
fix: correct calculation of the height of last agent message when user sends a new message
AdminForth/1651/should-never-appear.-shrinking
1 parent 50b5cab commit 331963b

2 files changed

Lines changed: 20 additions & 7 deletions

File tree

custom/CustomAutoScrollContainer.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ const props = withDefaults(defineProps<{
2525
contentStyle?: Record<string, string>
2626
scrollBarAutoHide?: boolean
2727
scrollToBottomOnMount?: boolean
28+
debugMode?: boolean
2829
}>(), {
2930
enabled: true,
3031
threshold: 50,
3132
behavior: 'instant',
3233
scrollBarAutoHide: true,
33-
scrollToBottomOnMount: true
34+
scrollToBottomOnMount: true,
35+
debugMode: false
3436
})
3537
3638
const containerRef = ref<HTMLDivElement | null>(null)
@@ -104,11 +106,12 @@ function isNearBottom(customThreshold?: number): boolean {
104106
}
105107
106108
function scrollToBottom(force = false): void {
107-
console.log('scrollToBottom called with force:', force)
109+
if (props.debugMode) console.log('scrollToBottom called with force:', force)
108110
const container = containerRef.value?.scrollEl
109111
if (!container) return
110112
111113
if (isUserScrolledUp.value && !force) return
114+
if (props.debugMode) console.log('Scrolling to bottom...:', container.scrollHeight)
112115
container.scrollTo({
113116
top: container.scrollHeight,
114117
behavior: props.behavior

custom/conversation_area/ConversationArea.vue

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,17 @@ function getHeightOfLastUserMessage() {
208208
}
209209
210210
function getHeightOfLastAgentMessage() {
211-
return getLastMessageElement('assistant')?.clientHeight ?? 0;
211+
const lastUserIndex = props.messages.findLastIndex((message: IMessage) => message.role === 'user');
212+
const lastAgentIndex = props.messages.findLastIndex((message: IMessage) => message.role === 'assistant');
213+
// Only reserve spacer space for the current turn's answer, i.e. an assistant message that comes
214+
// after the last user message. Right after a send the "Thinking" placeholder isn't pushed yet, so
215+
// findLastIndex would return the previous turn's answer (which sits above the just-sent user
216+
// message). Subtracting its height shrinks the spacer, making scrollToBottom stop short — and once
217+
// the real placeholder arrives the spacer grows and the true bottom drops below where we scrolled.
218+
if (lastAgentIndex <= lastUserIndex) {
219+
return 0;
220+
}
221+
return messagesRefs.value[lastAgentIndex]?.clientHeight ?? 0;
212222
}
213223
214224
function getScrollClientHeight() {
@@ -221,15 +231,14 @@ async function updateSpacerHeight() {
221231
}
222232
223233
const clientHeight = getScrollClientHeight();
224-
225234
if (!clientHeight) {
226235
return;
227236
}
228237
229238
const lastUserMessageHeight = getHeightOfLastUserMessage();
230239
const lastAgentMessageHeight = getHeightOfLastAgentMessage();
231-
232-
spacerHeight.value = Math.max(0, clientHeight - (lastUserMessageHeight + MASK_HEIGHT + lastAgentMessageHeight));
240+
const newSpacerHeight = Math.max(0, clientHeight - (lastUserMessageHeight + MASK_HEIGHT + lastAgentMessageHeight));
241+
spacerHeight.value = newSpacerHeight;
233242
}
234243
235244
function scheduleSpacerHeightUpdate() {
@@ -310,8 +319,9 @@ async function handleSendMessage() {
310319
311320
if (clientHeight) {
312321
showBottomSpacer.value = true;
322+
await nextTick(); // render the just-sent user message + spacer before measuring their heights
313323
await updateSpacerHeight();
314-
await nextTick();
324+
await nextTick(); // apply the computed spacer height before scrolling
315325
scrollContainer.value?.scrollToBottom();
316326
}
317327
}

0 commit comments

Comments
 (0)