Fix stray scrollbars and leftover spacing in instruct mode chat

This commit is contained in:
oobabooga
2026-05-31 19:33:40 -07:00
parent f9df9be982
commit fbaa8a3d90
3 changed files with 40 additions and 10 deletions

View File

@@ -507,7 +507,7 @@ audio {
.chat > .messages {
display: flex;
flex-direction: column;
min-height: calc(100vh - 225px);
min-height: calc(100dvh - 225px);
}
.chat > .messages > :first-child {

View File

@@ -298,18 +298,36 @@ function autoScrollToBottom() {
function updateInstructPadding() {
const chatElement = document.getElementById("chat");
if (chatElement && chatElement.getAttribute("data-mode") === "instruct") {
const messagesContainer = chatElement.querySelector(".messages");
const lastChild = messagesContainer?.lastElementChild;
const messagesContainer = chatElement?.querySelector(".messages");
if (!messagesContainer) return;
// The top-anchored buffer only applies in instruct mode with something to
// anchor against; everything else clears it, so the space can't leak across
// a mode switch.
let bufferHeight = 0;
if (chatElement.getAttribute("data-mode") === "instruct") {
const lastChild = messagesContainer.lastElementChild;
const prevSibling = lastChild?.previousElementSibling;
if (lastChild && prevSibling && chatElement.offsetHeight > 0) {
let bufferHeight = Math.max(0, Math.max(window.innerHeight - 128 - 119, window.innerHeight - prevSibling.offsetHeight - 119) - lastChild.offsetHeight);
if (window.innerWidth <= 924) {
bufferHeight = Math.max(0, bufferHeight - 32);
// Target the scroll container's *content* height — clientHeight minus
// its own vertical padding — so the buffer fills the viewport exactly
// instead of overshooting by that padding into a permanent scrollbar.
// The viewport-128 term floors the buffer so a tall previous message
// can't shrink it away.
const chatParent = document.querySelector(".chat-parent");
let viewport = window.innerHeight;
if (chatParent) {
const cs = getComputedStyle(chatParent);
viewport = chatParent.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom);
}
messagesContainer.style.paddingBottom = `${bufferHeight}px`;
bufferHeight = Math.max(0, Math.max(viewport - 128, viewport - prevSibling.offsetHeight) - lastChild.offsetHeight);
}
}
const next = bufferHeight ? `${bufferHeight}px` : "";
if (messagesContainer.style.paddingBottom !== next) {
messagesContainer.style.paddingBottom = next;
}
}
let pendingMorphdomData = null;
@@ -420,8 +438,14 @@ function applyMorphdomUpdate(data) {
}
);
if (messagesContainer && savedPaddingBottom) {
messagesContainer.style.paddingBottom = savedPaddingBottom;
// Re-apply the saved buffer only if the messages list still exists after
// morphdom. When the chat empties, morphdom repurposes that node into the
// welcome greeting (stripping its inline style); restoring the stale padding
// onto it would leave a phantom scrollbar that updateInstructPadding can't
// clear, since it keys off ".messages".
const messagesAfter = document.getElementsByClassName("messages")[0];
if (messagesAfter && savedPaddingBottom) {
messagesAfter.style.paddingBottom = savedPaddingBottom;
}
// Syntax highlighting and LaTeX

View File

@@ -240,6 +240,9 @@ window.doSyntaxHighlighting = function() {
{ left: "\\(", right: "\\)", display: false },
{ left: "\\[", right: "\\]", display: true },
],
// Render invalid LaTeX as an inline error instead of throwing,
// which would abort the update before paddings/scroll are fixed.
throwOnError: false,
});
}
});
@@ -1008,6 +1011,9 @@ document.fonts.addEventListener("loadingdone", (event) => {
// composer so the message-actions row isn't glued to it.
function syncMargin() {
chatParent.style.marginBottom = (chatInputRow.offsetHeight + 15) + "px";
// The instruct buffer is sized off chatParent.clientHeight, which the
// margin change above just shrank/grew, so recompute it here too.
window.updateInstructPadding?.();
if (!window.isScrolled) {
chatParent.scrollTop = chatParent.scrollHeight - chatParent.clientHeight;
}