From 4811af7ab2c5623746f69fe637d53bd7d2557bdb Mon Sep 17 00:00:00 2001 From: pewdiepie-archdaemon Date: Sat, 13 Jun 2026 07:21:18 +0900 Subject: [PATCH] AI reply menu: viewport-aware placement on mobile - Horizontal: max-width and left already clamped to viewport-16. - Vertical: prefer below the button, but flip ABOVE if there's more space there (e.g. button near the bottom of the viewport). - max-height clamped to viewport-16 with overflow:auto as a final guard so the menu can never extend past the screen edge. --- static/js/emailLibrary.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/static/js/emailLibrary.js b/static/js/emailLibrary.js index 31e8570e0..4e12db5ee 100644 --- a/static/js/emailLibrary.js +++ b/static/js/emailLibrary.js @@ -5899,16 +5899,30 @@ function _showAiReplyChoice(btn, em, data) { const rect = btn.getBoundingClientRect(); const menu = document.createElement('div'); menu.className = 'email-ai-reply-choice'; - /* Clamp width to viewport minus 16px margin so the menu (now wider - because of the note textarea) never spills off the right edge - on narrow mobile screens. */ + /* Clamp width to viewport minus 16px margin so the menu (textarea + + Fast/Full buttons) never spills off the right edge on narrow + mobile screens. */ const menuMaxW = Math.min(220, window.innerWidth - 16); const left = Math.max(8, Math.min(rect.left, window.innerWidth - menuMaxW - 8)); + /* Vertical placement: prefer below the button, but flip above if + there's not enough room (e.g. button near bottom of viewport). + Estimated menu height is ~150px (textarea + buttons + padding). */ + const estHeight = 150; + const spaceBelow = window.innerHeight - rect.bottom - 8; + const spaceAbove = rect.top - 8; + let top; + if (spaceBelow >= estHeight || spaceBelow >= spaceAbove) { + top = Math.max(8, Math.min(rect.bottom + 6, window.innerHeight - estHeight - 8)); + } else { + top = Math.max(8, rect.top - estHeight - 6); + } menu.style.cssText = [ 'position:fixed', `left:${left}px`, - `top:${Math.min(window.innerHeight - 96, rect.bottom + 6)}px`, + `top:${top}px`, `max-width:${menuMaxW}px`, + `max-height:${window.innerHeight - 16}px`, + 'overflow:auto', 'box-sizing:border-box', 'z-index:10060', 'display:flex',