|
|
|
@ -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); |
|
|
|
|