chore(chat): add keyboard adaptation diagnostics
This commit is contained in:
@@ -73,6 +73,7 @@ export function useKeyboardHeight({
|
|||||||
let lastInputLift = -1;
|
let lastInputLift = -1;
|
||||||
let lastMayBeKeyboardClose = false;
|
let lastMayBeKeyboardClose = false;
|
||||||
let fallbackWasApplied = false;
|
let fallbackWasApplied = false;
|
||||||
|
let lastEventType = "initial";
|
||||||
const environment = getKeyboardAdaptEnvironment();
|
const environment = getKeyboardAdaptEnvironment();
|
||||||
|
|
||||||
log.debug("[keyboard] environment", environment);
|
log.debug("[keyboard] environment", environment);
|
||||||
@@ -90,11 +91,45 @@ export function useKeyboardHeight({
|
|||||||
|
|
||||||
const metrics = readViewportMetrics();
|
const metrics = readViewportMetrics();
|
||||||
let activeNow = isKeyboardTargetActive(targetRef?.current, activeRef.current);
|
let activeNow = isKeyboardTargetActive(targetRef?.current, activeRef.current);
|
||||||
|
const shouldTryRelease =
|
||||||
|
activeNow &&
|
||||||
|
lastMayBeKeyboardClose &&
|
||||||
|
shouldReleaseKeyboardState(metrics, focusedAtRef.current);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
activeNow &&
|
activeNow &&
|
||||||
lastMayBeKeyboardClose &&
|
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);
|
releaseKeyboardState("keyboard-close-detected", metrics);
|
||||||
activeNow = false;
|
activeNow = false;
|
||||||
}
|
}
|
||||||
@@ -157,14 +192,31 @@ export function useKeyboardHeight({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const scheduleRechecks = (event?: Event) => {
|
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 (
|
if (
|
||||||
event &&
|
possibleKeyboardClose
|
||||||
isPossibleKeyboardCloseEvent(
|
|
||||||
event,
|
|
||||||
fallbackWasApplied || lastInputLift > 0,
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
lastMayBeKeyboardClose = true;
|
lastMayBeKeyboardClose = true;
|
||||||
|
log.debug("[keyboard] possible close detected", {
|
||||||
|
eventType: lastEventType,
|
||||||
|
hadInputLift,
|
||||||
|
fallbackWasApplied,
|
||||||
|
lastInputLift,
|
||||||
|
focusedForMs: getFocusedDurationMs(focusedAtRef.current),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
timeoutIds.forEach((id) => window.clearTimeout(id));
|
timeoutIds.forEach((id) => window.clearTimeout(id));
|
||||||
timeoutIds = RECHECK_DELAYS_MS.map((delay) =>
|
timeoutIds = RECHECK_DELAYS_MS.map((delay) =>
|
||||||
@@ -302,6 +354,23 @@ function shouldReleaseKeyboardState(
|
|||||||
return !hasDetectedKeyboard(metrics);
|
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 {
|
function hasDetectedKeyboard(metrics: ViewportMetrics): boolean {
|
||||||
return (
|
return (
|
||||||
metrics.keyboardHeight > 80 ||
|
metrics.keyboardHeight > 80 ||
|
||||||
|
|||||||
Reference in New Issue
Block a user