fix(ui): size mobile layout from the live visible viewport, not dvh
Brave Android (custom bottom toolbar) and some other mobile browsers report dvh taller than the actually visible area while position:fixed elements track the visible viewport — so 100dvh containers extended under the browser tab bar and the bottom of every page could never be scrolled into view. main.ts now keeps --visual-viewport-height synced to window.innerHeight (resize / orientationchange / visualViewport events — the same reference frame as the fixed tab bar), and the dashboard shell, chat, and app-session mobile heights consume it with 100dvh as fallback. The app now scales with the browser chrome as it shows/hides. Scroll clearance margin 16px → 28px. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -114,6 +114,24 @@ function recordError(source: string, err: unknown, info?: string) {
|
||||
|
||||
app.config.errorHandler = (err, _instance, info) => recordError('Vue Error', err, info)
|
||||
|
||||
// Keep --visual-viewport-height in sync with the REAL visible viewport.
|
||||
// Mobile browsers (notably Brave Android with its custom bottom toolbar)
|
||||
// misreport dvh, leaving 100dvh layouts taller than the visible area — the
|
||||
// bottom of every page then hides behind the browser chrome and can never be
|
||||
// scrolled into view. window.innerHeight shares the reference frame of
|
||||
// position:fixed elements (the mobile tab bar), so sizing the dashboard off
|
||||
// it keeps scroll containers and the fixed bars consistent on every browser.
|
||||
// CSS uses var(--visual-viewport-height, 100dvh) so this is a progressive fix.
|
||||
function syncViewportHeightVar() {
|
||||
try {
|
||||
document.documentElement.style.setProperty('--visual-viewport-height', `${window.innerHeight}px`)
|
||||
} catch { /* non-browser environment */ }
|
||||
}
|
||||
syncViewportHeightVar()
|
||||
window.addEventListener('resize', syncViewportHeightVar)
|
||||
window.addEventListener('orientationchange', syncViewportHeightVar)
|
||||
window.visualViewport?.addEventListener('resize', syncViewportHeightVar)
|
||||
|
||||
// After a frontend deploy the browser's cached index.html still points at the
|
||||
// OLD hashed chunks (e.g. AppSession-Cq93o4ao.js), which 404 — Vite then throws
|
||||
// "Failed to fetch dynamically imported module". The fix is to reload once so
|
||||
|
||||
Reference in New Issue
Block a user