My PWA had been working fine for several years until recently. Now, it seems there is a new problem with the keyboard because I cannot type anything at all.
My bug, in my opinion, is related to another well-known issue: "Web apps are resized against our will when we open the keyboard." (I'm wondering how Twitter does since it doesn't resize when I do click on the input).
These are some pieces of my code. I wrote them trying to prevent the app to be resized:
HTML:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
Javascript:
window.onresize = function() {
resizeScreen();
};
function resizeScreen() {
let scaleVal = window.innerHeight / 600;
if (window.innerHeight < 514) {
if (externalContainer === null) {
let bodyTmp = document.body;
let divTmp = document.createElement("div");
divTmp.id = 'externalContainer';
bodyTmp.insertBefore(divTmp, bodyTmp.firstChild);
}
externalContainer = document.getElementById('externalContainer');
let sContainer = document.getElementById('superContainer');
externalContainer.append(sContainer);
externalContainer.style.height = `${window.innerHeight}px`;
sContainer.style.transformOrigin = "50% 0% 0px";
setTimeout(function() {
sContainer.style.transform = `scale(${scaleVal})`;
setTimeout(function() {
let cHeight = (1 + scaleVal) * window.innerHeight;
if (cHeight < 514)
cHeight = 514;
sContainer.style.height = `${cHeight}px`;
}, 100);
}, 100);
} else {
let sContainer = document.getElementById('superContainer');
sContainer.style.height = `${window.innerHeight}px`;
sContainer.style.transformOrigin = "50% 0% 0px";
setTimeout(function() {
sContainer.style.transform = `scale(${scaleVal})`;
}, 100);
setTimeout(function() {
if (cmbSpeechType.getBoundingClientRect().width > window.outerWidth)
sContainer.style.transform = `scale(${scaleVal - (scaleVal - cmbSpeechType.getBoundingClientRect().width / window.outerWidth)})`;
}, 100);
}
}
In order to fix the "native app" (a custom version that I wrote), I added: android:windowSoftInputMode="adjustNothing"
, but I couldn't find any alternative in JS. I tried to emulate it using onfocus="window.location.href='#id'; return true;"
but it didn't work. This point about adjustNothing
has been suggested in Chromium since 2014.
I also tried setting a min-height
in CSS equals to the window height, but it didn't change the problem.
Furthermore, I tried this other crazy idea of making floating the control, it didn't work:
txtSpeaker.addEventListener("onfocus", function() {
window.body.style.zIndex = -1;
txtSpeaker.style.zIndex = 1000;
});
txtSpeaker.addEventListener("onblur", function() {
window.body.style.zIndex = "";
txtSpeaker.style.zIndex = "";
});
You can check the full source code here:
https://github.com/FANMixco/toastmasters-timer-material-design
Also, here is the app:
https://fanmixco.github.io/toastmasters-timer-material-design
The main source sections are here:
Any idea how to fix this odd issue?
P.S.:
This is an Android-specific bug because, on iOS and Windows 10, the PWA is working fine. After all, the view is not resized.
I kind of fixed it by doing the following:
function androidOrIOS() {
const userAgent = navigator.userAgent;
if(/android/i.test(userAgent)){
return 'android';
}
if(/iPad|iPhone|iPod/i.test(userAgent)){
return 'ios';
}
}
var os = androidOrIOS();
//Only resize if it´s Android
if (os !== "Android") {
window.onresize = function() {
resizeScreen();
};
}
//Change the location of the body based on the location that I "need".
if (os === "Android") {
txtSpeaker.addEventListener("onfocus", function() {
let y = document.getElementById("playControl").getBoundingClientRect().y;
document.body.marginTop = `-${y}px`;
});
txtSpeaker.addEventListener("onblur", function() {
document.body.marginTop = '0px';
});
}
The function androidOrIOS
is based on https://stackoverflow.com/a/51911220/1928691.