chore(chat): add keyboard adaptation diagnostics
This commit is contained in:
@@ -73,6 +73,7 @@ export function useKeyboardHeight({
|
||||
let lastInputLift = -1;
|
||||
let lastMayBeKeyboardClose = false;
|
||||
let fallbackWasApplied = false;
|
||||
let lastEventType = "initial";
|
||||
const environment = getKeyboardAdaptEnvironment();
|
||||
|
||||
log.debug("[keyboard] environment", environment);
|
||||
@@ -90,11 +91,45 @@ export function useKeyboardHeight({
|
||||
|
||||
const metrics = readViewportMetrics();
|
||||
let activeNow = isKeyboardTargetActive(targetRef?.current, activeRef.current);
|
||||
const shouldTryRelease =
|
||||
activeNow &&
|
||||
lastMayBeKeyboardClose &&
|
||||
shouldReleaseKeyboardState(metrics, focusedAtRef.current);
|
||||
|
||||
if (
|
||||
activeNow &&
|
||||
lastMayBeKeyboardClose &&
|
||||
shouldReleaseKeyboardState(metrics, focusedAtRef.current)
|
||||
!shouldTryRelease
|
||||
) {
|
||||
log.debug("[keyboard] release skipped", {
|
||||
reason: getReleaseSkipReason(metrics, focusedAtRef.current),
|
||||
lastEventType,
|
||||
environment,
|
||||
active: activeNow,
|
||||
reactActive: activeRef.current,
|
||||
fallbackAllowed: fallbackAllowedRef.current,
|
||||
lastInputLift,
|
||||
fallbackWasApplied,
|
||||
focusedForMs: getFocusedDurationMs(focusedAtRef.current),
|
||||
metrics: formatMetrics(metrics),
|
||||
});
|
||||
}
|
||||
|
||||
if (shouldTryRelease) {
|
||||
log.debug("[keyboard] release confirmed", {
|
||||
lastEventType,
|
||||
environment,
|
||||
active: activeNow,
|
||||
reactActive: activeRef.current,
|
||||
fallbackAllowed: fallbackAllowedRef.current,
|
||||
lastInputLift,
|
||||
fallbackWasApplied,
|
||||
focusedForMs: getFocusedDurationMs(focusedAtRef.current),
|
||||
metrics: formatMetrics(metrics),
|
||||
});
|
||||
}
|
||||
|
||||
if (shouldTryRelease) {
|
||||
releaseKeyboardState("keyboard-close-detected", metrics);
|
||||
activeNow = false;
|
||||
}
|
||||
@@ -157,14 +192,31 @@ export function useKeyboardHeight({
|
||||
};
|
||||
|
||||
const scheduleRechecks = (event?: Event) => {
|
||||
lastEventType = event?.type ?? "manual";
|
||||
const hadInputLift = fallbackWasApplied || lastInputLift > 0;
|
||||
const possibleKeyboardClose =
|
||||
event != null && isPossibleKeyboardCloseEvent(event, hadInputLift);
|
||||
log.debug("[keyboard] schedule rechecks", {
|
||||
eventType: lastEventType,
|
||||
possibleKeyboardClose,
|
||||
hadInputLift,
|
||||
fallbackWasApplied,
|
||||
lastInputLift,
|
||||
active: activeRef.current,
|
||||
fallbackAllowed: fallbackAllowedRef.current,
|
||||
focusedForMs: getFocusedDurationMs(focusedAtRef.current),
|
||||
});
|
||||
if (
|
||||
event &&
|
||||
isPossibleKeyboardCloseEvent(
|
||||
event,
|
||||
fallbackWasApplied || lastInputLift > 0,
|
||||
)
|
||||
possibleKeyboardClose
|
||||
) {
|
||||
lastMayBeKeyboardClose = true;
|
||||
log.debug("[keyboard] possible close detected", {
|
||||
eventType: lastEventType,
|
||||
hadInputLift,
|
||||
fallbackWasApplied,
|
||||
lastInputLift,
|
||||
focusedForMs: getFocusedDurationMs(focusedAtRef.current),
|
||||
});
|
||||
}
|
||||
timeoutIds.forEach((id) => window.clearTimeout(id));
|
||||
timeoutIds = RECHECK_DELAYS_MS.map((delay) =>
|
||||
@@ -302,6 +354,23 @@ function shouldReleaseKeyboardState(
|
||||
return !hasDetectedKeyboard(metrics);
|
||||
}
|
||||
|
||||
function getFocusedDurationMs(focusedAt: number): number | null {
|
||||
if (focusedAt <= 0) return null;
|
||||
return Math.round(performance.now() - focusedAt);
|
||||
}
|
||||
|
||||
function getReleaseSkipReason(
|
||||
metrics: ViewportMetrics,
|
||||
focusedAt: number,
|
||||
): string {
|
||||
if (focusedAt <= 0) return "not-focused-by-hook";
|
||||
if (performance.now() - focusedAt < FALLBACK_CLOSE_GRACE_MS) {
|
||||
return "within-close-grace-window";
|
||||
}
|
||||
if (hasDetectedKeyboard(metrics)) return "keyboard-still-detected";
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
function hasDetectedKeyboard(metrics: ViewportMetrics): boolean {
|
||||
return (
|
||||
metrics.keyboardHeight > 80 ||
|
||||
|
||||
Reference in New Issue
Block a user