fix(chat): adapt input bar to soft keyboard in FB in-app browser

FB IAB on Xiaomi (and similar WebViews that don't shrink 100dvh) keeps
the chat input covered by the soft keyboard. Fix by writing the
visualViewport-derived keyboard height to a CSS variable on <html> and
consuming it as padding-bottom on the chat input bar.

- Add useKeyboardHeight hook (visualViewport + rAF batching, no re-renders)
- Apply --keyboard-height + env(safe-area-inset-bottom) to .bar padding
- Add scrollIntoView on textarea focus so the input stays visible
- Add viewportFit: cover so safe-area-inset-bottom is reported
This commit is contained in:
2026-06-24 14:13:01 +08:00
parent 42c03f8901
commit 853ae776f9
6 changed files with 109 additions and 4 deletions
+6
View File
@@ -5,6 +5,7 @@ import Image from "next/image";
import { useRouter } from "next/navigation";
import { useAuthState } from "@/stores/auth/auth-context";
import { useKeyboardHeight } from "@/hooks/use-keyboard-height";
import type { LoginStatus } from "@/data/dto/auth";
import { AppStorage } from "@/data/storage/app/app_storage";
import { AuthStorage } from "@/data/storage/auth/auth_storage";
@@ -42,6 +43,11 @@ export function ChatScreen() {
const [showExternalBrowserDialog, setShowExternalBrowserDialog] =
useState(false);
// 全局副作用:把软键盘高度写到 <html> 的 --keyboard-height CSS 变量,
// 让 .bar 的 padding-bottom 跟着调整,修复 FB IAB / 小米 WebView 输入框被键盘遮挡的问题。
// 详见 src/hooks/use-keyboard-height.ts
useKeyboardHeight();
// isGuest 派生(chat-screen 是唯一知道这个值的地方 —— chat 机器无 isGuest 字段)
const isGuest = deriveIsGuest(authState.loginStatus);