fix(hub): keep mobile PWA AI navigation visible

Fix keyboard detection in standalone app so top nav and AI tabs stay visible; recognize PWA display mode for mobile layout.
This commit is contained in:
dekun
2026-06-11 11:35:44 +08:00
parent 08ae171e48
commit 51252d5dda
3 changed files with 45 additions and 16 deletions
+29 -8
View File
@@ -3884,7 +3884,7 @@ body.hub-page-ai #page-ai {
}
/* 手机 AI:须在 .ai-layout 双列定义之后,避免被覆盖成半屏 */
@media (max-width: 720px) {
@media (max-width: 720px), ((display-mode: standalone) and (max-width: 960px)) {
html:has(body.hub-page-ai) {
height: 100%;
overflow: hidden;
@@ -3922,19 +3922,35 @@ body.hub-page-ai #page-ai {
font-size: 11px;
}
body.hub-page-ai.hub-ai-keyboard-open .app-header,
body.hub-page-ai.hub-ai-keyboard-open #page-ai .page-head {
body.hub-page-ai .app-header .brand {
display: none;
}
body.hub-page-ai.hub-ai-keyboard-open .ai-mobile-tabs,
body.hub-page-ai.hub-ai-keyboard-open .ai-chat-topbar,
body.hub-page-ai.hub-ai-keyboard-open .ai-chat-session-head {
body.hub-page-ai .header-right {
grid-template-columns: 1fr auto auto;
grid-template-rows: auto;
}
body.hub-page-ai .header-right .top-nav {
grid-column: 1 / -1;
order: 2;
}
body.hub-page-ai.hub-ai-keyboard-open .app-header .theme-toggle,
body.hub-page-ai.hub-ai-keyboard-open .app-header .sys-pill,
body.hub-page-ai.hub-ai-keyboard-open .app-header #btn-logout {
display: none;
}
body.hub-page-ai.hub-ai-keyboard-open .ai-mobile-tabs {
margin-bottom: 4px;
body.hub-page-ai.hub-ai-keyboard-open .app-header {
padding: 4px 0;
margin-bottom: 0;
}
body.hub-page-ai.hub-ai-keyboard-open .top-nav a {
min-height: 30px;
padding: 4px 8px;
font-size: 10px;
}
body.hub-page-ai #page-ai {
@@ -3950,6 +3966,11 @@ body.hub-page-ai #page-ai {
margin-bottom: 6px;
flex-shrink: 0;
width: 100%;
position: sticky;
top: 0;
z-index: 12;
padding: 4px 0 2px;
background: var(--bg);
}
body.hub-page-ai .ai-mobile-tab {
+13 -5
View File
@@ -900,7 +900,10 @@
}
function isMobileLayout() {
return window.matchMedia("(max-width: 720px)").matches;
if (window.matchMedia("(max-width: 720px)").matches) return true;
if (window.matchMedia("(display-mode: standalone)").matches) return true;
if (window.navigator && window.navigator.standalone === true) return true;
return false;
}
function positionHasContracts(p) {
@@ -1107,7 +1110,6 @@
let syncHubAiMobileViewport = () => {};
function initHubAiMobileViewport() {
const mq = window.matchMedia("(max-width: 720px)");
const shell = document.querySelector(".app-shell");
const chatInput = document.getElementById("ai-chat-input");
if (!shell || !window.visualViewport) {
@@ -1115,6 +1117,8 @@
return;
}
let baselineInnerH = Math.max(window.innerHeight, window.visualViewport.height || 0);
const scrollChatToEnd = () => {
const box = document.getElementById("ai-chat-messages");
if (box) requestAnimationFrame(() => { box.scrollTop = box.scrollHeight; });
@@ -1122,7 +1126,7 @@
syncHubAiMobileViewport = () => {
const onAi = document.body.classList.contains("hub-page-ai");
if (!onAi || !mq.matches) {
if (!onAi || !isMobileLayout()) {
shell.style.removeProperty("height");
shell.style.removeProperty("max-height");
shell.style.removeProperty("width");
@@ -1135,14 +1139,18 @@
const h = Math.max(240, Math.round(vv.height));
const top = Math.round(vv.offsetTop || 0);
const left = Math.round(vv.offsetLeft || 0);
const inputFocused = !!(chatInput && document.activeElement === chatInput);
if (!inputFocused) {
baselineInnerH = Math.max(baselineInnerH, window.innerHeight, h);
}
document.documentElement.style.setProperty("--hub-vvh", `${h}px`);
shell.style.height = `${h}px`;
shell.style.maxHeight = `${h}px`;
shell.style.width = `${Math.round(vv.width)}px`;
shell.style.transform =
top > 0 || left > 0 ? `translate(${left}px, ${top}px)` : "";
const keyboardLikely =
top > 0 || h < window.innerHeight * 0.82 || document.activeElement === chatInput;
const viewportShrunk = h < baselineInnerH * 0.72;
const keyboardLikely = inputFocused && (viewportShrunk || top > 48);
document.body.classList.toggle("hub-ai-keyboard-open", keyboardLikely);
};
+3 -3
View File
@@ -15,7 +15,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
<link rel="stylesheet" href="/assets/app.css?v=20260612-hub-ai-one-screen" />
<link rel="stylesheet" href="/assets/app.css?v=20260612-hub-ai-pwa-nav" />
<link rel="stylesheet" href="/assets/dashboard.css?v=20260612-dash-monitor-count" />
</head>
<body>
@@ -449,7 +449,7 @@
<button type="button" class="ai-mobile-tab" data-ai-tab="history" role="tab" aria-selected="false">历史</button>
<button type="button" class="ai-mobile-tab ai-mobile-tab-action" data-ai-tab="new" role="tab" aria-selected="false" title="新开对话">新开</button>
</div>
<div class="ai-layout" data-ai-mobile-tab="chat">
<div class="ai-layout" data-ai-mobile-tab="trading">
<section class="ai-panel ai-chat-panel" data-ai-panel="chat">
<div class="ai-chat-topbar">
<div class="ai-bot-bar" role="tablist" aria-label="聊天机器人">
@@ -557,6 +557,6 @@
<script src="/assets/funds.js?v=20260609-hub-funds-fold"></script>
<script src="/assets/dashboard.js?v=20260612-dash-monitor-count"></script>
<script src="/assets/ai_review_render.js?v=2"></script>
<script src="/assets/app.js?v=20260612-hub-monitor-expand"></script>
<script src="/assets/app.js?v=20260612-hub-ai-pwa-nav"></script>
</body>
</html>