mirror of
https://github.com/discourse/discourse.git
synced 2025-02-06 03:18:23 +00:00
DEV: introduces waitForClosedKeyboard (#26363)
This lib will allow us to wait for a keyboard state change. Not waiting for the keyboard to be closed could cause issues when showing a modal at the same time on iOS for example. Example usage: - blurSomeInput() - await waitForClosedKeyboard(this) - showSomeModal() Note that this actual behavior has been baked in modals when we call show so you don't have to call the lib yourself.
This commit is contained in:
parent
01c11dff91
commit
f350cea5d2
@ -66,7 +66,8 @@ export default {
|
||||
} else {
|
||||
let viewportWindowDiff =
|
||||
this.windowInnerHeight - window.visualViewport.height;
|
||||
if (viewportWindowDiff > 0) {
|
||||
const IPAD_HARDWARE_KEYBOARD_TOOLBAR_HEIGHT = 71.5;
|
||||
if (viewportWindowDiff > IPAD_HARDWARE_KEYBOARD_TOOLBAR_HEIGHT) {
|
||||
keyboardVisible = true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
import { getOwner } from "@ember/application";
|
||||
|
||||
export async function waitForClosedKeyboard(context) {
|
||||
if (!window.visualViewport) {
|
||||
return;
|
||||
}
|
||||
|
||||
const owner = getOwner(context);
|
||||
const site = owner.lookup("service:site");
|
||||
const capabilities = owner.lookup("service:capabilities");
|
||||
|
||||
if (!capabilities.isIpadOS && site.desktopView) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!document.documentElement.classList.contains("keyboard-visible")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let timeout;
|
||||
let viewportListener;
|
||||
const initialWindowHeight = window.innerHeight;
|
||||
|
||||
await Promise.race([
|
||||
new Promise((resolve) => {
|
||||
timeout = setTimeout(() => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("Keyboard visibility didnt change after 1s.");
|
||||
|
||||
resolve();
|
||||
}, 1000);
|
||||
}),
|
||||
new Promise((resolve) =>
|
||||
window.visualViewport.addEventListener(
|
||||
"resize",
|
||||
(viewportListener = resolve),
|
||||
{ once: true, passive: true }
|
||||
)
|
||||
),
|
||||
]);
|
||||
|
||||
clearTimeout(timeout);
|
||||
window.visualViewport.removeEventListener("resize", viewportListener);
|
||||
|
||||
if ("virtualKeyboard" in navigator) {
|
||||
if (navigator.virtualKeyboard.boundingRect.height > 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("Expected virtual keyboard to be closed but it wasn't.");
|
||||
return;
|
||||
}
|
||||
} else if (capabilities.isFirefox && capabilities.isAndroid) {
|
||||
const KEYBOARD_DETECT_THRESHOLD = 150;
|
||||
if (
|
||||
Math.abs(
|
||||
initialWindowHeight -
|
||||
Math.min(window.innerHeight, window.visualViewport.height)
|
||||
) > KEYBOARD_DETECT_THRESHOLD
|
||||
) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("Expected virtual keyboard to be closed but it wasn't.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
let viewportWindowDiff = initialWindowHeight - window.visualViewport.height;
|
||||
if (viewportWindowDiff > 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("Expected virtual keyboard to be closed but it wasn't.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import Service, { service } from "@ember/service";
|
||||
import { CLOSE_INITIATED_BY_MODAL_SHOW } from "discourse/components/d-modal";
|
||||
import { clearAllBodyScrollLocks } from "discourse/lib/body-scroll-lock";
|
||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||
import { waitForClosedKeyboard } from "discourse/lib/wait-for-keyboard";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
|
||||
const LEGACY_OPTS = new Set([
|
||||
@ -39,7 +40,7 @@ export default class ModalService extends Service {
|
||||
*
|
||||
* @returns {Promise} A promise that resolves when the modal is closed, with any data passed to closeModal
|
||||
*/
|
||||
show(modal, opts) {
|
||||
async show(modal, opts) {
|
||||
if (typeof modal === "string") {
|
||||
this.dialog.alert(
|
||||
`Error: the '${modal}' modal needs updating to work with the latest version of Discourse. See https://meta.discourse.org/t/268057.`
|
||||
@ -59,6 +60,8 @@ export default class ModalService extends Service {
|
||||
|
||||
this.close({ initiatedBy: CLOSE_INITIATED_BY_MODAL_SHOW });
|
||||
|
||||
await waitForClosedKeyboard(this);
|
||||
|
||||
let resolveShowPromise;
|
||||
const promise = new Promise((resolve) => {
|
||||
resolveShowPromise = resolve;
|
||||
|
Loading…
x
Reference in New Issue
Block a user