diff --git a/tui/web_templates/app_index.html b/tui/web_templates/app_index.html index be72d94..f72f140 100644 --- a/tui/web_templates/app_index.html +++ b/tui/web_templates/app_index.html @@ -165,57 +165,44 @@ } })(); - // Mobile keyboard control: block virtual keyboard unless toggled open + // Mobile: floating button to dismiss keyboard (function() { if (!("ontouchstart" in window)) return; - var kbAllowed = false; - - // Floating toggle button var btn = document.createElement("div"); - btn.id = "kb-toggle"; - btn.textContent = "\u2328"; + btn.id = "kb-dismiss"; + btn.textContent = "\u2328\u2193"; btn.style.cssText = "position:fixed;bottom:12px;right:12px;z-index:9999;" + "width:48px;height:48px;border-radius:50%;background:rgba(94,11,167,0.9);" + - "color:#fff;font-size:24px;display:flex;align-items:center;justify-content:center;" + + "color:#fff;font-size:20px;display:none;align-items:center;justify-content:center;" + "cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.5);user-select:none;" + "-webkit-tap-highlight-color:transparent;touch-action:manipulation;"; document.addEventListener("DOMContentLoaded", function() { document.body.appendChild(btn); }); - btn.addEventListener("touchstart", function(e) { - e.preventDefault(); - e.stopPropagation(); - kbAllowed = !kbAllowed; - var ta = document.querySelector(".xterm-helper-textarea"); - if (kbAllowed) { - btn.style.background = "rgba(0,204,0,0.9)"; - btn.textContent = "\u2715"; - if (ta) { ta.inputMode = "text"; ta.focus(); } - } else { - btn.style.background = "rgba(94,11,167,0.9)"; - btn.textContent = "\u2328"; - if (ta) { ta.inputMode = "none"; ta.blur(); } - } - }, { passive: false }); - - // Intercept focus on xterm textarea — set inputmode=none if keyboard not allowed + // Show dismiss button when keyboard is likely open (textarea focused) document.addEventListener("focusin", function(e) { - if (kbAllowed) return; if (e.target && e.target.classList && e.target.classList.contains("xterm-helper-textarea")) { - e.target.inputMode = "none"; + btn.style.display = "flex"; } }, true); - // Set inputmode=none as soon as textarea appears - new MutationObserver(function(mutations, obs) { + // Dismiss keyboard on tap + btn.addEventListener("touchstart", function(e) { + e.preventDefault(); + e.stopPropagation(); var ta = document.querySelector(".xterm-helper-textarea"); - if (ta) { - ta.inputMode = "none"; - obs.disconnect(); + if (ta) ta.blur(); + btn.style.display = "none"; + }, { passive: false }); + + // Hide button when keyboard closes + document.addEventListener("focusout", function(e) { + if (e.target && e.target.classList && e.target.classList.contains("xterm-helper-textarea")) { + setTimeout(function() { btn.style.display = "none"; }, 300); } - }).observe(document.body, { childList: true, subtree: true }); + }, true); })(); // Touch-to-scroll: translate swipe into mouse wheel for Textual scrollable containers