fix: reserve space for clarify dialogs
This commit is contained in:
1 parent
4ea762ae0d
commit
85e13a6121
4 files changed
+106
No files matched your search
@@ -3,6 +3,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Clarification dialogs now reserve transcript space while open or collapsed, so the question prompt no longer covers the assistant text needed to answer it.
|
||||
|
||||
## [v0.51.134] — 2026-05-25 — Release DF (stage-batch16 — single-PR Windows path defaults)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -2677,12 +2677,63 @@ function _syncClarifyCollapseButton(card) {
|
||||
collapse.title = label;
|
||||
}
|
||||
|
||||
let _clarifyResizeListenerReady = false;
|
||||
|
||||
function _clarifyMessagesNearBottom(messages) {
|
||||
if (!messages) return false;
|
||||
return messages.scrollHeight - messages.scrollTop - messages.clientHeight < 150;
|
||||
}
|
||||
|
||||
function _syncClarifyTranscriptSpace(card, opts) {
|
||||
opts = opts || {};
|
||||
const messages = $("messages");
|
||||
if (!messages) return;
|
||||
const wasNearBottom = _clarifyMessagesNearBottom(messages);
|
||||
if (!card || !card.classList.contains("visible")) {
|
||||
messages.classList.remove("clarify-open");
|
||||
messages.classList.remove("clarify-collapsed");
|
||||
messages.style.removeProperty("--clarify-card-height");
|
||||
messages.style.removeProperty("--clarify-dock-height");
|
||||
if (wasNearBottom && typeof scrollToBottom === "function" && typeof requestAnimationFrame === "function") {
|
||||
requestAnimationFrame(scrollToBottom);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const collapsed = card.classList.contains("collapsed");
|
||||
messages.classList.add("clarify-open");
|
||||
messages.classList.toggle("clarify-collapsed", collapsed);
|
||||
const measure = () => {
|
||||
if (!card.classList.contains("visible")) return;
|
||||
const target = collapsed ? card : (card.querySelector(".clarify-inner") || card);
|
||||
const h = target && target.getBoundingClientRect().height;
|
||||
if (h > 0) {
|
||||
messages.style.setProperty(collapsed ? "--clarify-dock-height" : "--clarify-card-height", Math.ceil(h + 24) + "px");
|
||||
}
|
||||
if (wasNearBottom && typeof scrollToBottom === "function") scrollToBottom();
|
||||
};
|
||||
if (opts.immediate) measure();
|
||||
if (typeof requestAnimationFrame === "function") requestAnimationFrame(measure);
|
||||
setTimeout(measure, 420);
|
||||
}
|
||||
|
||||
function _ensureClarifyResizeListener() {
|
||||
if (_clarifyResizeListenerReady || typeof window === "undefined") return;
|
||||
_clarifyResizeListenerReady = true;
|
||||
window.addEventListener("resize", () => {
|
||||
const card = $("clarifyCard");
|
||||
if (card && card.classList.contains("visible")) {
|
||||
_syncClarifyTranscriptSpace(card, {immediate: true});
|
||||
}
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
function toggleClarifyCardCollapsed(forceCollapsed) {
|
||||
const card = $("clarifyCard");
|
||||
if (!card) return;
|
||||
const collapsed = typeof forceCollapsed === "boolean" ? forceCollapsed : !card.classList.contains("collapsed");
|
||||
card.classList.toggle("collapsed", collapsed);
|
||||
_syncClarifyCollapseButton(card);
|
||||
_syncClarifyTranscriptSpace(card, {immediate: true});
|
||||
}
|
||||
|
||||
function _clearClarifyHideTimer() {
|
||||
@@ -2797,6 +2848,7 @@ function hideClarifyCard(force=false, reason="dismissed") {
|
||||
_clarifySessionId = null;
|
||||
_resetClarifyCardState();
|
||||
card.classList.remove("visible");
|
||||
_syncClarifyTranscriptSpace(null);
|
||||
if (typeof unlockComposerForClarify === "function") unlockComposerForClarify();
|
||||
$("clarifyQuestion").textContent = "";
|
||||
$("clarifyChoices").innerHTML = "";
|
||||
@@ -2911,8 +2963,10 @@ function showClarifyCard(pending) {
|
||||
lockComposerForClarify(question ? `Clarification needed: ${question}` : "Clarification needed");
|
||||
}
|
||||
_clarifySetControlsDisabled(false, false);
|
||||
_ensureClarifyResizeListener();
|
||||
card.classList.add("visible");
|
||||
_syncClarifyCollapseButton(card);
|
||||
_syncClarifyTranscriptSpace(card, {immediate: true});
|
||||
if (typeof applyLocaleToDOM === "function") applyLocaleToDOM();
|
||||
// Move focus to clarify input synchronously (not in setTimeout) and
|
||||
// only if the user wasn't mid-type in the composer textarea.
|
||||
|
||||
@@ -984,6 +984,8 @@
|
||||
.messages.terminal-open{padding-bottom:var(--terminal-card-height,320px);scroll-padding-bottom:var(--terminal-card-height,320px);transition:padding-bottom .26s cubic-bezier(.2,.8,.2,1);}
|
||||
.messages.terminal-collapsed{padding-bottom:var(--terminal-dock-height,72px);scroll-padding-bottom:var(--terminal-dock-height,72px);transition:padding-bottom .22s cubic-bezier(.2,.8,.2,1);}
|
||||
.messages.handoff-dock-visible{padding-bottom:var(--handoff-dock-height,72px);scroll-padding-bottom:var(--handoff-dock-height,72px);transition:padding-bottom .22s cubic-bezier(.2,.8,.2,1);}
|
||||
.messages.clarify-open{padding-bottom:var(--clarify-card-height,320px);scroll-padding-bottom:var(--clarify-card-height,320px);transition:padding-bottom .22s cubic-bezier(.2,.8,.2,1);}
|
||||
.messages.clarify-collapsed{padding-bottom:var(--clarify-dock-height,72px);scroll-padding-bottom:var(--clarify-dock-height,72px);}
|
||||
.messages.terminal-expanding-from-dock{transition:none!important;}
|
||||
.queue-card-inner{background:var(--surface);border:1px solid var(--border);border-bottom:none;border-radius:14px 14px 0 0;contain:paint;transform:translateY(100%);opacity:0;transition:transform .35s cubic-bezier(.32,.72,.16,1),opacity .2s ease;overflow:hidden;max-height:240px;overflow-y:auto;padding-bottom:4px;}
|
||||
.queue-card.visible .queue-card-inner{transform:translateY(0);opacity:1;}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
MESSAGES_JS = (ROOT / "static" / "messages.js").read_text(encoding="utf-8")
|
||||
STYLE_CSS = (ROOT / "static" / "style.css").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _compact(text: str) -> str:
|
||||
return "".join(text.split())
|
||||
|
||||
|
||||
def test_clarify_card_reserves_transcript_space():
|
||||
compact_css = _compact(STYLE_CSS)
|
||||
|
||||
assert ".messages.clarify-open" in STYLE_CSS
|
||||
assert "padding-bottom:var(--clarify-card-height,320px)" in compact_css
|
||||
assert "scroll-padding-bottom:var(--clarify-card-height,320px)" in compact_css
|
||||
|
||||
|
||||
def test_clarify_collapse_uses_smaller_transcript_space():
|
||||
compact_css = _compact(STYLE_CSS)
|
||||
compact_js = _compact(MESSAGES_JS)
|
||||
|
||||
assert ".messages.clarify-collapsed" in STYLE_CSS
|
||||
assert "padding-bottom:var(--clarify-dock-height,72px)" in compact_css
|
||||
assert 'classList.toggle("clarify-collapsed",collapsed)' in compact_js
|
||||
assert "--clarify-dock-height" in MESSAGES_JS
|
||||
|
||||
|
||||
def test_clarify_show_hide_toggle_messages_padding_classes():
|
||||
compact_js = _compact(MESSAGES_JS)
|
||||
|
||||
assert "_syncClarifyTranscriptSpace(card,{immediate:true})" in compact_js
|
||||
assert "_syncClarifyTranscriptSpace(null)" in compact_js
|
||||
assert 'classList.add("clarify-open")' in MESSAGES_JS
|
||||
assert 'classList.remove("clarify-open")' in MESSAGES_JS
|
||||
assert "--clarify-card-height" in MESSAGES_JS
|
||||
|
||||
|
||||
def test_clarify_padding_remeasures_on_resize():
|
||||
compact_js = _compact(MESSAGES_JS)
|
||||
|
||||
assert "function_ensureClarifyResizeListener()" in compact_js
|
||||
assert 'window.addEventListener("resize"' in MESSAGES_JS
|
||||
assert "_ensureClarifyResizeListener();" in MESSAGES_JS
|
||||
Reference in new issue
Block a user