Browse Source

fix: calibrate initial keyboard estimate dynamically based on viewport height and latch intermediate animation frames

master
mortezaei 4 days ago
parent
commit
fe51e90efd
  1. 38
      src/components/Componentes/question-viewport-coordinator.ts

38
src/components/Componentes/question-viewport-coordinator.ts

@ -82,6 +82,14 @@ export function isActiveQuestionKeyboardInput(
);
}
function getDefaultKeyboardHeight(): number {
if (typeof window !== "undefined" && window.innerHeight > 0) {
// 37.5% of screen height matches standard mobile soft keyboards (e.g. 287px on 765px screen, 316px on 844px screen)
return Math.round(window.innerHeight * 0.375);
}
return 285;
}
function setLift(nextLift: number) {
const prevLift = currentLift;
currentLift = Math.max(0, Math.round(nextLift));
@ -94,9 +102,8 @@ function setLift(nextLift: number) {
function getKeyboardTop() {
if (!keyboardVisible || !activeQuestionInput) return null;
// Expected full keyboard height for mobile devices is ~320px
const fullKeyboardHeight =
lastKeyboardHeight > 250 ? lastKeyboardHeight : 320;
lastKeyboardHeight > 200 ? lastKeyboardHeight : getDefaultKeyboardHeight();
const targetHeight = Math.max(keyboardHeight, fullKeyboardHeight);
const flutterTop = window.innerHeight - targetHeight;
@ -180,17 +187,20 @@ export function updateQuestionKeyboardHeight(height: number) {
if (nextHeight > 0) {
keyboardVisible = true;
if (nextHeight > 250) {
lastKeyboardHeight = Math.max(lastKeyboardHeight, nextHeight);
keyboardHeight = nextHeight;
} else if (activeQuestionInput) {
// Keyboard is opening with incremental animation frames (e.g. Samsung 11.3px, 26.3px, 32px)
// Keep expected target height so lift doesn't bounce/collapse during animation frames.
const expectedHeight = lastKeyboardHeight > 250 ? lastKeyboardHeight : 320;
keyboardHeight = Math.max(nextHeight, expectedHeight);
const defaultKHeight = getDefaultKeyboardHeight();
const expectedHeight =
lastKeyboardHeight > 200 ? lastKeyboardHeight : defaultKHeight;
if (activeQuestionInput && nextHeight < expectedHeight - 15) {
// Keyboard is in the middle of opening animation frames (e.g. Samsung 8.7px, 182px, 205px, 246px, 262px, 273px)
// Keep keyboardHeight at expectedHeight so lift doesn't stutter/jitter during intermediate animation frames.
keyboardHeight = expectedHeight;
} else {
// Settled at or above target height
lastKeyboardHeight = Math.max(lastKeyboardHeight, nextHeight);
keyboardHeight = nextHeight;
}
if (isActiveQuestionKeyboardInput(document.activeElement)) {
activeQuestionInput = document.activeElement;
}
@ -216,7 +226,11 @@ export function resetQuestionKeyboardState() {
window.cancelAnimationFrame(geometryFrame);
geometryFrame = null;
}
if (isActiveQuestionKeyboardInput(document.activeElement)) {
if (
typeof document !== "undefined" &&
document.activeElement instanceof HTMLElement &&
isActiveQuestionKeyboardInput(document.activeElement)
) {
document.activeElement.blur();
}
keyboardVisible = false;
@ -233,7 +247,7 @@ export function useQuestionViewportCoordinator() {
if (!isActiveQuestionKeyboardInput(event.target)) return;
activeQuestionInput = event.target;
const expectedHeight =
lastKeyboardHeight > 250 ? lastKeyboardHeight : 320;
lastKeyboardHeight > 200 ? lastKeyboardHeight : getDefaultKeyboardHeight();
keyboardHeight = expectedHeight;
keyboardVisible = true;
console.log('[Coord] focusin on input:', (event.target as HTMLElement).tagName, 'targetKHeight:', expectedHeight);

Loading…
Cancel
Save