fix(ui): keep minimized windows above composer (#1197)
This commit is contained in:
@@ -165,6 +165,39 @@ window.addEventListener('pageshow', clearFreshComposerRestore);
|
|||||||
window.addEventListener('resize', _sync);
|
window.addEventListener('resize', _sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Keep minimized tool chips above the composer. Both the current modalManager
|
||||||
|
dock and the legacy fallback dock consume this root-level clearance. */
|
||||||
|
{
|
||||||
|
const root = document.documentElement;
|
||||||
|
const chatBar = document.querySelector('.chat-input-bar');
|
||||||
|
const attachStrip = document.getElementById('attach-strip');
|
||||||
|
const chatContainer = document.getElementById('chat-container');
|
||||||
|
const _syncComposerClearance = () => {
|
||||||
|
let top = window.innerHeight;
|
||||||
|
for (const el of [attachStrip, chatBar]) {
|
||||||
|
if (!el) continue;
|
||||||
|
const rect = el.getBoundingClientRect();
|
||||||
|
if (rect.height > 0) top = Math.min(top, rect.top);
|
||||||
|
}
|
||||||
|
const clearance = Math.max(12, Math.ceil(window.innerHeight - top + 8));
|
||||||
|
root.style.setProperty('--composer-clearance', clearance + 'px');
|
||||||
|
};
|
||||||
|
requestAnimationFrame(_syncComposerClearance);
|
||||||
|
if (typeof ResizeObserver !== 'undefined') {
|
||||||
|
const ro = new ResizeObserver(_syncComposerClearance);
|
||||||
|
if (chatBar) ro.observe(chatBar);
|
||||||
|
if (attachStrip) ro.observe(attachStrip);
|
||||||
|
}
|
||||||
|
if (chatContainer && typeof MutationObserver !== 'undefined') {
|
||||||
|
new MutationObserver(_syncComposerClearance).observe(chatContainer, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['class'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (chatBar) chatBar.addEventListener('transitionend', _syncComposerClearance);
|
||||||
|
window.addEventListener('resize', _syncComposerClearance);
|
||||||
|
}
|
||||||
|
|
||||||
/* ---- Resizable sidebar — drag edge to resize, collapse if small, drag rail edge to expand ---- */
|
/* ---- Resizable sidebar — drag edge to resize, collapse if small, drag rail edge to expand ---- */
|
||||||
{
|
{
|
||||||
const sidebar = document.getElementById('sidebar');
|
const sidebar = document.getElementById('sidebar');
|
||||||
|
|||||||
@@ -838,7 +838,7 @@ body.bg-pattern-sparkles {
|
|||||||
#tile-ghost.visible { opacity: 1; transform: scale(1); }
|
#tile-ghost.visible { opacity: 1; transform: scale(1); }
|
||||||
/* Bottom dock — chip per minimized modal */
|
/* Bottom dock — chip per minimized modal */
|
||||||
#minimized-dock {
|
#minimized-dock {
|
||||||
position: fixed; bottom: 12px; left: 50%; transform: translateX(-50%);
|
position: fixed; bottom: var(--composer-clearance, 12px); left: 50%; transform: translateX(-50%);
|
||||||
display: flex; gap: 6px; flex-wrap: wrap;
|
display: flex; gap: 6px; flex-wrap: wrap;
|
||||||
max-width: calc(100vw - 24px);
|
max-width: calc(100vw - 24px);
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
@@ -4901,7 +4901,7 @@ body.bg-pattern-sparkles {
|
|||||||
/* Bottom dock for minimized modals */
|
/* Bottom dock for minimized modals */
|
||||||
#modal-dock {
|
#modal-dock {
|
||||||
position:fixed;
|
position:fixed;
|
||||||
bottom:0;
|
bottom:var(--composer-clearance, 0px);
|
||||||
left:0;
|
left:0;
|
||||||
right:0;
|
right:0;
|
||||||
display:flex;
|
display:flex;
|
||||||
|
|||||||
18
tests/test_modal_dock_composer_clearance.py
Normal file
18
tests/test_modal_dock_composer_clearance.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
CSS = Path("static/style.css").read_text(encoding="utf-8")
|
||||||
|
INIT_JS = Path("static/js/init.js").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def test_both_minimized_window_docks_clear_the_composer():
|
||||||
|
assert "#minimized-dock {" in CSS
|
||||||
|
assert "bottom: var(--composer-clearance, 12px);" in CSS
|
||||||
|
assert "#modal-dock {" in CSS
|
||||||
|
assert "bottom:var(--composer-clearance, 0px);" in CSS
|
||||||
|
|
||||||
|
|
||||||
|
def test_composer_clearance_tracks_input_and_attachment_height():
|
||||||
|
assert "const chatBar = document.querySelector('.chat-input-bar');" in INIT_JS
|
||||||
|
assert "const attachStrip = document.getElementById('attach-strip');" in INIT_JS
|
||||||
|
assert "root.style.setProperty('--composer-clearance', clearance + 'px');" in INIT_JS
|
||||||
Reference in New Issue
Block a user