fix(keyboard): support OPPO Facebook fallback
This commit is contained in:
@@ -7,42 +7,42 @@ function makeEnvironment(
|
||||
overrides: Partial<KeyboardAdaptEnvironment> = {},
|
||||
): KeyboardAdaptEnvironment {
|
||||
return {
|
||||
platform: "android",
|
||||
osName: "Android",
|
||||
osVersion: "16",
|
||||
deviceVendor: "Xiaomi",
|
||||
deviceModel: "2211133C",
|
||||
isAndroid: true,
|
||||
isIOS: false,
|
||||
isMobile: true,
|
||||
browserName: "Facebook",
|
||||
browserVersion: "566.0.0.48.73",
|
||||
isInAppBrowser: true,
|
||||
inAppBrowserName: "facebook",
|
||||
isXiaomiFamilyDevice: true,
|
||||
isOppoFamilyDevice: false,
|
||||
isFacebookInAppBrowser: true,
|
||||
hasVisualViewport: true,
|
||||
usesXiaomiFacebookFallback: true,
|
||||
usesAndroidFacebookFallback: true,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("shouldEnableKeyboardAdaptation", () => {
|
||||
it("enables only for Xiaomi Android Facebook in-app browser fallback", () => {
|
||||
it("enables for Xiaomi Android Facebook in-app browser fallback", () => {
|
||||
expect(shouldEnableKeyboardAdaptation(makeEnvironment())).toBe(true);
|
||||
});
|
||||
|
||||
it("enables for OPPO Android Facebook in-app browser fallback", () => {
|
||||
expect(
|
||||
shouldEnableKeyboardAdaptation(
|
||||
makeEnvironment({
|
||||
platform: "ios",
|
||||
osName: "iOS",
|
||||
osVersion: "18",
|
||||
deviceVendor: "Apple",
|
||||
deviceModel: "iPhone",
|
||||
isAndroid: false,
|
||||
isIOS: true,
|
||||
isXiaomiFamilyDevice: false,
|
||||
usesXiaomiFacebookFallback: false,
|
||||
isOppoFamilyDevice: true,
|
||||
usesAndroidFacebookFallback: true,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("disables for non-target platforms, browsers, and devices", () => {
|
||||
expect(
|
||||
shouldEnableKeyboardAdaptation(
|
||||
makeEnvironment({
|
||||
isAndroid: false,
|
||||
isXiaomiFamilyDevice: false,
|
||||
isOppoFamilyDevice: false,
|
||||
usesAndroidFacebookFallback: false,
|
||||
}),
|
||||
),
|
||||
).toBe(false);
|
||||
@@ -50,10 +50,9 @@ describe("shouldEnableKeyboardAdaptation", () => {
|
||||
expect(
|
||||
shouldEnableKeyboardAdaptation(
|
||||
makeEnvironment({
|
||||
browserName: "Instagram",
|
||||
inAppBrowserName: "instagram",
|
||||
isFacebookInAppBrowser: false,
|
||||
usesXiaomiFacebookFallback: false,
|
||||
usesAndroidFacebookFallback: false,
|
||||
}),
|
||||
),
|
||||
).toBe(false);
|
||||
@@ -61,10 +60,9 @@ describe("shouldEnableKeyboardAdaptation", () => {
|
||||
expect(
|
||||
shouldEnableKeyboardAdaptation(
|
||||
makeEnvironment({
|
||||
deviceVendor: "Samsung",
|
||||
deviceModel: "SM-G991B",
|
||||
isXiaomiFamilyDevice: false,
|
||||
usesXiaomiFacebookFallback: false,
|
||||
isOppoFamilyDevice: false,
|
||||
usesAndroidFacebookFallback: false,
|
||||
}),
|
||||
),
|
||||
).toBe(false);
|
||||
|
||||
@@ -8,32 +8,27 @@ export function getKeyboardAdaptEnvironment(
|
||||
const platform = PlatformDetector.getPlatformInfo(ua);
|
||||
const browser = BrowserDetector.getBrowserInfo(ua);
|
||||
const isXiaomiFamilyDevice = PlatformDetector.isXiaomiFamilyDevice(ua);
|
||||
const isOppoFamilyDevice = PlatformDetector.isOppoFamilyDevice(ua);
|
||||
const isFacebookInAppBrowser = BrowserDetector.isFacebookInAppBrowser(ua);
|
||||
const usesAndroidFacebookFallback =
|
||||
platform.isAndroid &&
|
||||
(isXiaomiFamilyDevice || isOppoFamilyDevice) &&
|
||||
isFacebookInAppBrowser;
|
||||
|
||||
return {
|
||||
platform: platform.platform,
|
||||
osName: platform.osName,
|
||||
osVersion: platform.osVersion,
|
||||
deviceVendor: platform.deviceVendor,
|
||||
deviceModel: platform.deviceModel,
|
||||
isAndroid: platform.isAndroid,
|
||||
isIOS: platform.isIOS,
|
||||
isMobile: platform.isMobile,
|
||||
browserName: browser.name,
|
||||
browserVersion: browser.version,
|
||||
isInAppBrowser: browser.isInAppBrowser,
|
||||
inAppBrowserName: browser.inAppBrowserName,
|
||||
isXiaomiFamilyDevice,
|
||||
isOppoFamilyDevice,
|
||||
isFacebookInAppBrowser,
|
||||
hasVisualViewport:
|
||||
typeof window !== "undefined" && window.visualViewport != null,
|
||||
usesXiaomiFacebookFallback:
|
||||
platform.isAndroid && isXiaomiFamilyDevice && isFacebookInAppBrowser,
|
||||
usesAndroidFacebookFallback,
|
||||
};
|
||||
}
|
||||
|
||||
export function shouldEnableKeyboardAdaptation(
|
||||
environment: KeyboardAdaptEnvironment,
|
||||
): boolean {
|
||||
return environment.usesXiaomiFacebookFallback;
|
||||
return environment.usesAndroidFacebookFallback;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
/**
|
||||
* 小米 Android + Facebook IAB 专用输入框避让 hook。
|
||||
* 特定 Android 设备 + Facebook IAB 专用输入框避让 hook。
|
||||
*
|
||||
* 这不是通用软键盘方案。它只解决一个已知 WebView 问题:
|
||||
* 输入框 focus 后键盘弹出,但 Facebook IAB 没有稳定调整页面 viewport,
|
||||
* 导致底部输入框被键盘遮挡。
|
||||
*
|
||||
* 策略:
|
||||
* - 非小米 Android Facebook IAB:完全不生效。
|
||||
* - 非目标 Android Facebook IAB 设备:完全不生效。
|
||||
* - focus 后短期多次测量输入框是否被 visibleViewport 遮挡。
|
||||
* - 若 viewport 没有可靠变化,则使用固定 fallback 抬升。
|
||||
* - 聚焦期间轻量轮询;一旦检测到 viewport 恢复,主动 blur 并清除抬升。
|
||||
@@ -67,7 +67,7 @@ export function useKeyboardHeight({
|
||||
if (!shouldEnableKeyboardAdaptation(environment)) {
|
||||
resetInputLiftVar();
|
||||
log.debug("[keyboard] disabled", {
|
||||
reason: "not-xiaomi-facebook-iab",
|
||||
reason: "not-android-facebook-fallback-device",
|
||||
environment,
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -7,20 +7,11 @@ export interface UseKeyboardHeightOptions {
|
||||
}
|
||||
|
||||
export interface KeyboardAdaptEnvironment {
|
||||
platform: string;
|
||||
osName: string;
|
||||
osVersion: string;
|
||||
deviceVendor: string;
|
||||
deviceModel: string;
|
||||
isAndroid: boolean;
|
||||
isIOS: boolean;
|
||||
isMobile: boolean;
|
||||
browserName: string;
|
||||
browserVersion: string;
|
||||
isInAppBrowser: boolean;
|
||||
inAppBrowserName: string | null;
|
||||
isXiaomiFamilyDevice: boolean;
|
||||
isOppoFamilyDevice: boolean;
|
||||
isFacebookInAppBrowser: boolean;
|
||||
hasVisualViewport: boolean;
|
||||
usesXiaomiFacebookFallback: boolean;
|
||||
usesAndroidFacebookFallback: boolean;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,12 @@ export class PlatformDetector {
|
||||
return /\b(Xiaomi|Redmi|POCO|Mi\s|MIX|MIUI)\b/i.test(target);
|
||||
}
|
||||
|
||||
static isOppoFamilyDevice(ua: string | null = null): boolean {
|
||||
const info = PlatformDetector.getPlatformInfo(ua);
|
||||
const target = `${info.deviceVendor} ${info.deviceModel} ${info.userAgent}`;
|
||||
return /\b(OPPO|OPlus|ColorOS|CPH\d{3,})\b/i.test(target);
|
||||
}
|
||||
|
||||
private static getUserAgent(ua: string | null = null): string {
|
||||
if (ua) return ua;
|
||||
if (typeof navigator === "undefined") return "";
|
||||
|
||||
Reference in New Issue
Block a user