From 7a1e775de2537dd639b408fffb668d2db70ecf94 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 10 Apr 2025 17:41:31 +0300 Subject: [PATCH] feat(mobile): detect presence of the virtual keyboard --- src/public/app/layouts/desktop_layout.ts | 1 - src/public/app/layouts/mobile_layout.ts | 1 - .../app/widgets/containers/root_container.ts | 33 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/public/app/layouts/desktop_layout.ts b/src/public/app/layouts/desktop_layout.ts index 5745df470..38fb75b43 100644 --- a/src/public/app/layouts/desktop_layout.ts +++ b/src/public/app/layouts/desktop_layout.ts @@ -121,7 +121,6 @@ export default class DesktopLayout { return new RootContainer(true) .setParent(appContext) - .class((launcherPaneIsHorizontal ? "horizontal" : "vertical") + "-layout") .optChild( fullWidthTabBar, new FlexContainer("row") diff --git a/src/public/app/layouts/mobile_layout.ts b/src/public/app/layouts/mobile_layout.ts index f131c0c4f..259b440b0 100644 --- a/src/public/app/layouts/mobile_layout.ts +++ b/src/public/app/layouts/mobile_layout.ts @@ -122,7 +122,6 @@ export default class MobileLayout { getRootWidget(appContext: typeof AppContext) { return new RootContainer(true) .setParent(appContext) - .class("horizontal-layout") .cssBlock(MOBILE_CSS) .child(new FlexContainer("column").id("mobile-sidebar-container")) .child( diff --git a/src/public/app/widgets/containers/root_container.ts b/src/public/app/widgets/containers/root_container.ts index 1abde362d..251a92691 100644 --- a/src/public/app/widgets/containers/root_container.ts +++ b/src/public/app/widgets/containers/root_container.ts @@ -1,11 +1,44 @@ +import utils from "../../services/utils.js"; import type BasicWidget from "../basic_widget.js"; import FlexContainer from "./flex_container.js"; +/** + * The root container is the top-most widget/container, from which the entire layout derives. + * + * For convenience, the root container has a few class selectors that can be used to target some global state: + * + * - `#root-container.virtual-keyboard-opened`, on mobile devices if the virtual keyboard is open. + * - `#root-container.horizontal-layout`, if the current layout is horizontal. + * - `#root-container.vertical-layout`, if the current layout is horizontal. + */ export default class RootContainer extends FlexContainer { + private originalViewportHeight: number; + constructor(isHorizontalLayout: boolean) { super(isHorizontalLayout ? "column" : "row"); this.id("root-widget"); this.css("height", "100dvh"); + this.class((isHorizontalLayout ? "horizontal" : "vertical") + "-layout"); + this.originalViewportHeight = getViewportHeight(); } + + render(): JQuery { + if (utils.isMobile()) { + window.visualViewport?.addEventListener("resize", () => this.#onMobileResize()); + } + + return super.render(); + } + + #onMobileResize() { + const currentViewportHeight = getViewportHeight(); + const isKeyboardOpened = (currentViewportHeight < this.originalViewportHeight); + this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened); + } + +} + +function getViewportHeight() { + return window.visualViewport?.height ?? window.innerHeight; }