diff --git a/src/lib/crypto/secure-storage.ts b/src/lib/crypto/secure-storage.ts index fa1dc149a..8e410d2b0 100644 --- a/src/lib/crypto/secure-storage.ts +++ b/src/lib/crypto/secure-storage.ts @@ -68,9 +68,7 @@ const BIOMETRIC_SUCCESS = 0; async function getDwebBiometric(): Promise { if (!isDwebEnvironment()) return null; try { - // 使用变量规避 Vite 静态分析 - const moduleName = '@plaoc/plugins'; - const module = await import(/* @vite-ignore */ moduleName); + const module = await import('@plaoc/plugins'); return module.biometricsPlugin as DwebBiometricPlugin; } catch { return null; diff --git a/src/lib/dweb-keyboard-overlay.test.ts b/src/lib/dweb-keyboard-overlay.test.ts index 419cdc73d..15bc3f649 100644 --- a/src/lib/dweb-keyboard-overlay.test.ts +++ b/src/lib/dweb-keyboard-overlay.test.ts @@ -1,7 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { applyDwebKeyboardOverlay, - startDwebKeyboardOverlay, type DwebPluginsModule, } from './dweb-keyboard-overlay' @@ -60,53 +59,4 @@ describe('dweb keyboard overlay', () => { warnSpy.mockRestore() }) - - it('retries until dweb environment is ready', async () => { - vi.useFakeTimers() - - const setOverlay = vi.fn<(overlay: boolean) => Promise>().mockResolvedValue() - const loadPlugins = vi.fn<() => Promise>().mockResolvedValue({ - virtualKeyboardPlugin: { setOverlay }, - }) - - let ready = false - const stop = startDwebKeyboardOverlay({ - isDweb: () => ready, - loadPlugins, - maxAttempts: 4, - retryDelayMs: 100, - }) - - expect(loadPlugins).not.toHaveBeenCalled() - - ready = true - await vi.advanceTimersByTimeAsync(120) - - expect(loadPlugins).toHaveBeenCalledTimes(1) - expect(setOverlay).toHaveBeenCalledWith(true) - - stop() - vi.useRealTimers() - }) - - it('stops retrying after cleanup', async () => { - vi.useFakeTimers() - - const loadPlugins = vi.fn<() => Promise>().mockResolvedValue({}) - const stop = startDwebKeyboardOverlay({ - isDweb: () => true, - loadPlugins, - maxAttempts: 10, - retryDelayMs: 100, - }) - - await vi.advanceTimersByTimeAsync(120) - expect(loadPlugins).toHaveBeenCalledTimes(2) - - stop() - await vi.advanceTimersByTimeAsync(500) - expect(loadPlugins).toHaveBeenCalledTimes(2) - - vi.useRealTimers() - }) }) diff --git a/src/lib/dweb-keyboard-overlay.ts b/src/lib/dweb-keyboard-overlay.ts index 83fd20a83..7c7aa79e1 100644 --- a/src/lib/dweb-keyboard-overlay.ts +++ b/src/lib/dweb-keyboard-overlay.ts @@ -13,14 +13,8 @@ export interface ApplyDwebKeyboardOverlayOptions { loadPlugins?: () => Promise } -export interface StartDwebKeyboardOverlayOptions extends ApplyDwebKeyboardOverlayOptions { - maxAttempts?: number - retryDelayMs?: number -} - async function defaultLoadPlugins(): Promise { - const moduleName = '@plaoc/plugins' - const module = await import(/* @vite-ignore */ moduleName) + const module = await import('@plaoc/plugins') return module as DwebPluginsModule } @@ -51,43 +45,3 @@ export async function applyDwebKeyboardOverlay( return false } } - -/** - * 启动键盘 overlay 应用流程(包含重试),用于规避运行时初始化时机过早导致的失效。 - */ -export function startDwebKeyboardOverlay( - options: StartDwebKeyboardOverlayOptions = {}, -): () => void { - const maxAttempts = Math.max(1, options.maxAttempts ?? 10) - const retryDelayMs = Math.max(50, options.retryDelayMs ?? 300) - let stopped = false - let timer: ReturnType | null = null - let attempts = 0 - - const run = async (): Promise => { - if (stopped) { - return - } - - const applied = await applyDwebKeyboardOverlay(options) - attempts += 1 - - if (applied || stopped || attempts >= maxAttempts) { - return - } - - timer = setTimeout(() => { - void run() - }, retryDelayMs) - } - - void run() - - return () => { - stopped = true - if (timer !== null) { - clearTimeout(timer) - timer = null - } - } -} diff --git a/src/providers/AppInitializer.tsx b/src/providers/AppInitializer.tsx index 5ff9aaf81..2f5d9db34 100644 --- a/src/providers/AppInitializer.tsx +++ b/src/providers/AppInitializer.tsx @@ -15,6 +15,7 @@ import { MigrationRequiredView } from '@/components/common/migration-required-vi import { LoadingSpinner } from '@/components/common' import { DwebUpdateDialog } from '@/components/common/dweb-update-dialog' import { dwebUpdateActions } from '@/stores/dweb-update' +import { applyDwebKeyboardOverlay } from '@/lib/dweb-keyboard-overlay' // 立即执行:在 React 渲染之前应用缓存的主题色,避免闪烁 initializeThemeHue() @@ -35,6 +36,10 @@ export function AppInitializer({ children }: { children: ReactNode }) { const chainConfigLoading = useChainConfigLoading() const walletLoading = useWalletLoading() + useEffect(() => { + void applyDwebKeyboardOverlay() + }, []) + useEffect(() => { // 统一初始化所有需要持久化的 store if (!addressBookState.isInitialized) { diff --git a/src/service-main.ts b/src/service-main.ts index 6dd03b6b6..527682f87 100644 --- a/src/service-main.ts +++ b/src/service-main.ts @@ -3,7 +3,6 @@ import { installLegacyAuthorizeHashRewriter, rewriteLegacyAuthorizeHashInPlace, } from '@/services/authorize/deep-link' -import { startDwebKeyboardOverlay } from '@/lib/dweb-keyboard-overlay' export type ServiceMainCleanup = () => void @@ -18,9 +17,6 @@ export function startServiceMain(): ServiceMainCleanup { // Normalize legacy mpay-style authorize deep links before Stackflow reads URL. rewriteLegacyAuthorizeHashInPlace() - // DWEB: keep viewport stable when soft keyboard appears. - const cleanupKeyboardOverlay = startDwebKeyboardOverlay() - // Initialize preference side effects (i18n + RTL) as early as possible. preferencesActions.initialize() @@ -37,6 +33,5 @@ export function startServiceMain(): ServiceMainCleanup { return () => { cleanupDeepLink() - cleanupKeyboardOverlay() } }