FIX: Better virtual keyboard detect on Android (#18298)

* FIX: Better virtual keyboard detect on Android

Firefox has a bug where *sometimes* the visualViewport.height won't be
updated when the keyboard pops up until you scroll, making our composer
stay hidden behind the keyboard. This commit uses both window.innerHeight
and  window.visualViewport.height using the minimum of both to check for
height changes.

For Chrome/Edge we feature detect the new VirtualKeyboard API and
opt-into it when the composer opens and use it to detect if a keyboard
is being draw. Opting into the API changes how the viewport is
calculated so we have to also change how the full height composer is
calculated. To minimize breakage we opt-out when the composer component
is destroyed.

This commit also moves the `--composer-ipad-padding` to only happen on
iPads.

Bug report at https://meta.discourse.org/t/-/228382
This commit is contained in:
Rafael dos Santos Silva 2022-09-26 17:35:58 -03:00 committed by GitHub
parent e2ee6418c6
commit ab58b0cffe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 12 deletions

View File

@ -6,9 +6,9 @@ export default {
initialize(container) {
const site = container.lookup("service:site");
const capabilities = container.lookup("capabilities:main");
this.capabilities = container.lookup("capabilities:main");
if (!capabilities.isIpadOS && !site.mobileView) {
if (!this.capabilities.isIpadOS && !site.mobileView) {
return;
}
@ -21,27 +21,67 @@ export default {
this.onViewportResize();
window.visualViewport.addEventListener("resize", this.onViewportResize);
if ("virtualKeyboard" in navigator) {
navigator.virtualKeyboard.overlaysContent = true;
navigator.virtualKeyboard.addEventListener(
"geometrychange",
this.onViewportResize
);
}
},
teardown() {
window.visualViewport.removeEventListener("resize", this.onViewportResize);
if ("virtualKeyboard" in navigator) {
navigator.virtualKeyboard.overlaysContent = false;
navigator.virtualKeyboard.removeEventListener(
"geometrychange",
this.onViewportResize
);
}
},
@bind
onViewportResize() {
const composerVH = window.visualViewport.height * 0.01;
const doc = document.documentElement;
const composerVH = window.visualViewport.height * 0.01,
doc = document.documentElement,
KEYBOARD_DETECT_THRESHOLD = 150;
doc.style.setProperty("--composer-vh", `${composerVH}px`);
const heightDiff = this.windowInnerHeight - window.visualViewport.height;
doc.classList.toggle("keyboard-visible", heightDiff > 0);
let keyboardVisible = false;
if ("virtualKeyboard" in navigator) {
if (navigator.virtualKeyboard.boundingRect.height > 0) {
keyboardVisible = true;
}
} else if (this.capabilities.isFirefox && this.capabilities.isAndroid) {
if (
Math.abs(
this.windowInnerHeight -
Math.min(window.innerHeight, window.visualViewport.height)
) > KEYBOARD_DETECT_THRESHOLD
) {
keyboardVisible = true;
}
} else {
let viewportWindowDiff =
this.windowInnerHeight - window.visualViewport.height;
if (viewportWindowDiff > 0) {
keyboardVisible = true;
}
// Add bottom padding when using a hardware keyboard and the accessory bar
// is visible accessory bar height is 55px, using 75 allows a small buffer
// adds bottom padding when using a hardware keyboard and the accessory bar is visible
// accessory bar height is 55px, using 75 allows a small buffer
if (this.capabilities.isIpadOS) {
doc.style.setProperty(
"--composer-ipad-padding",
`${heightDiff < 75 ? heightDiff : 0}px`
`${viewportWindowDiff < 75 ? viewportWindowDiff : 0}px`
);
}
}
keyboardVisible
? doc.classList.add("keyboard-visible")
: doc.classList.remove("keyboard-visible");
},
};

View File

@ -539,6 +539,7 @@ body:not(.ios-safari-composer-hacks) {
min-height: calc(var(--min-height) - 4em);
}
padding-bottom: var(--composer-ipad-padding);
padding-bottom: calc(10px + env(keyboard-inset-height));
}
}

View File

@ -24,6 +24,7 @@
.keyboard-visible &.open {
height: 100%; // Android: Reduces composer jumpiness when the keyboard toggles
height: calc(100% - (10px + env(keyboard-inset-height)));
}
.keyboard-visible body.ios-safari-composer-hacks &.open {