fix: inconsistent mobile keyboard input bar positioning on Android (#86)
Co-authored-by: auroraflux <auroraflux@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
co-authored by
auroraflux
parent
cadcf0bcf6
commit
fa2223a0e7
@@ -143,12 +143,18 @@ export const MainLayout: React.FC = () => {
|
|||||||
stickyKeyboardInset = measuredInset;
|
stickyKeyboardInset = measuredInset;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const closingByHeight = height > previousHeight + 6;
|
// Only detect closing-by-height when focus is NOT on text input
|
||||||
|
// (prevents false positives during Android keyboard animation)
|
||||||
|
const closingByHeight = !isTextTarget && height > previousHeight + 6;
|
||||||
|
|
||||||
if (measuredInset === 0) {
|
if (measuredInset === 0) {
|
||||||
stickyKeyboardInset = 0;
|
stickyKeyboardInset = 0;
|
||||||
} else if (closingByHeight) {
|
} else if (closingByHeight) {
|
||||||
forceKeyboardClosed();
|
forceKeyboardClosed();
|
||||||
|
} else if (measuredInset > 0 && isTextTarget) {
|
||||||
|
// When focus is on text input, track actual inset (allows settling
|
||||||
|
// to correct value after Android animation fluctuations)
|
||||||
|
stickyKeyboardInset = measuredInset;
|
||||||
} else if (measuredInset > stickyKeyboardInset) {
|
} else if (measuredInset > stickyKeyboardInset) {
|
||||||
stickyKeyboardInset = measuredInset;
|
stickyKeyboardInset = measuredInset;
|
||||||
}
|
}
|
||||||
@@ -176,7 +182,22 @@ export const MainLayout: React.FC = () => {
|
|||||||
viewport?.addEventListener('scroll', updateVisualViewport);
|
viewport?.addEventListener('scroll', updateVisualViewport);
|
||||||
window.addEventListener('resize', updateVisualViewport);
|
window.addEventListener('resize', updateVisualViewport);
|
||||||
window.addEventListener('orientationchange', updateVisualViewport);
|
window.addEventListener('orientationchange', updateVisualViewport);
|
||||||
document.addEventListener('focusin', updateVisualViewport, true);
|
// Reset ignoreOpenUntilZero when focus moves to a text input.
|
||||||
|
// This allows keyboard detection to work when user taps input quickly
|
||||||
|
// while keyboard is still closing (common on Android).
|
||||||
|
const handleFocusIn = (event: FocusEvent) => {
|
||||||
|
const target = event.target as HTMLElement | null;
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tagName = target.tagName;
|
||||||
|
const isInput = tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';
|
||||||
|
if (isInput || target.isContentEditable) {
|
||||||
|
ignoreOpenUntilZero = false;
|
||||||
|
}
|
||||||
|
updateVisualViewport();
|
||||||
|
};
|
||||||
|
document.addEventListener('focusin', handleFocusIn, true);
|
||||||
|
|
||||||
const handleFocusOut = (event: FocusEvent) => {
|
const handleFocusOut = (event: FocusEvent) => {
|
||||||
const target = event.target as HTMLElement | null;
|
const target = event.target as HTMLElement | null;
|
||||||
@@ -205,7 +226,7 @@ export const MainLayout: React.FC = () => {
|
|||||||
viewport?.removeEventListener('scroll', updateVisualViewport);
|
viewport?.removeEventListener('scroll', updateVisualViewport);
|
||||||
window.removeEventListener('resize', updateVisualViewport);
|
window.removeEventListener('resize', updateVisualViewport);
|
||||||
window.removeEventListener('orientationchange', updateVisualViewport);
|
window.removeEventListener('orientationchange', updateVisualViewport);
|
||||||
document.removeEventListener('focusin', updateVisualViewport, true);
|
document.removeEventListener('focusin', handleFocusIn, true);
|
||||||
document.removeEventListener('focusout', handleFocusOut, true);
|
document.removeEventListener('focusout', handleFocusOut, true);
|
||||||
};
|
};
|
||||||
}, [isMobile]);
|
}, [isMobile]);
|
||||||
|
|||||||
Reference in New Issue
Block a user