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:
parent
e2ee6418c6
commit
ab58b0cffe
|
@ -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");
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue