Procházet zdrojové kódy

fix(web): 手柄轮询回归常驻逻辑,保留已确认的修复

按贡献者反馈与最终决策,将手柄轮询恢复为常驻运行(无条件
requestAnimationFrame 自调度),移除无手柄时停止轮询的省电优化与
disposeXboxGamepad,避免依赖 gamepadconnected 事件恢复检测。
保留已确认的修复:
- 目录切换经 Vue 状态回调控制 popCataVisible
- 全屏 promise 拒绝捕获
- 按键/摇杆边沿状态按手柄 index 分键
HapeLee před 3 měsíci
rodič
revize
d43c778511

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
app/src/main/assets/web/vue/assets/BookChapter-CvxOa6WY.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
app/src/main/assets/web/vue/assets/BookShelf-CPpNHFqF.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 1
app/src/main/assets/web/vue/assets/index-CV282XDP.js


+ 1 - 1
app/src/main/assets/web/vue/index.html

@@ -4,7 +4,7 @@
         <meta charset="UTF-8" />
         <link rel="icon" href="./favicon.ico" />
     <meta name="viewport" content="width=device-width,initial-scale=1.0" />
-      <script type="module" crossorigin src="./assets/index-CyERTl8r.js"></script>
+      <script type="module" crossorigin src="./assets/index-CV282XDP.js"></script>
       <link rel="modulepreload" crossorigin href="./assets/vendor-DQqeohSF.js">
       <link rel="stylesheet" crossorigin href="./assets/vendor-CXe1BRiH.css">
       <link rel="stylesheet" crossorigin href="./assets/index-CpkaNQMA.css">

+ 15 - 87
modules/web/src/utils/xboxGamepad.ts

@@ -97,8 +97,6 @@ function log(...args: any[]): void {
 
 let running = false
 
-let loopId: number | null = null
-
 let onToggleCatalog: (() => void) | null = null
 
 // 每个手柄独立一份按键/摇杆边沿状态,避免多手柄互相串触发
@@ -320,97 +318,35 @@ function handleGamepad(gp: Gamepad): void {
 // 主循环
 // =====================================================
 
-function stopLoop(): void {
-  running = false
-
-  if (loopId !== null) {
-    cancelAnimationFrame(loopId)
-
-    loopId = null
-  }
-}
-
-function startLoop(): void {
-  if (running) return
-
-  running = true
-
-  loopId = requestAnimationFrame(gamepadLoop)
-}
-
-function hasConnectedGamepad(): boolean {
-  if (typeof navigator.getGamepads !== 'function') return false
-
-  const gamepads = navigator.getGamepads()
-
-  for (const gp of gamepads) {
-    if (gp) return true
-  }
-
-  return false
-}
-
 function gamepadLoop(): void {
-  // 不支持 getGamepads 的环境直接停止轮询
-  if (typeof navigator.getGamepads !== 'function') {
-    stopLoop()
-
-    return
-  }
-
-  const gamepads = navigator.getGamepads()
+  const gamepads = navigator.getGamepads?.() || []
 
   for (const gp of gamepads) {
     if (gp) handleGamepad(gp)
   }
 
-  // 没有已连接手柄时停止 60fps 轮询,等下次 gamepadconnected 再启动
-  if (hasConnectedGamepad()) {
-    loopId = requestAnimationFrame(gamepadLoop)
-  } else {
-    stopLoop()
-  }
+  requestAnimationFrame(gamepadLoop)
 }
 
 // =====================================================
 // 连接 / 断开事件
 // =====================================================
 
-let listenersRegistered = false
-
-function onGamepadConnected(e: GamepadEvent): void {
+window.addEventListener('gamepadconnected', (e: GamepadEvent) => {
   log('🎮 手柄已连接:', e.gamepad.id)
 
-  startLoop()
-}
+  if (!running) {
+    running = true
+
+    requestAnimationFrame(gamepadLoop)
+  }
+})
 
-function onGamepadDisconnected(e: GamepadEvent): void {
+window.addEventListener('gamepaddisconnected', (e: GamepadEvent) => {
   log('🎮 手柄断开:', e.gamepad.id)
 
   gamepadStates.delete(e.gamepad.index)
-
-  if (!hasConnectedGamepad()) stopLoop()
-}
-
-function registerListeners(): void {
-  if (listenersRegistered) return
-
-  window.addEventListener('gamepadconnected', onGamepadConnected)
-
-  window.addEventListener('gamepaddisconnected', onGamepadDisconnected)
-
-  listenersRegistered = true
-}
-
-function unregisterListeners(): void {
-  if (!listenersRegistered) return
-
-  window.removeEventListener('gamepadconnected', onGamepadConnected)
-
-  window.removeEventListener('gamepaddisconnected', onGamepadDisconnected)
-
-  listenersRegistered = false
-}
+})
 
 // =====================================================
 // 外部调用
@@ -419,17 +355,9 @@ function unregisterListeners(): void {
 export function initXboxGamepad(options?: XboxGamepadOptions): void {
   onToggleCatalog = options?.onToggleCatalog ?? null
 
-  registerListeners()
+  if (!running) {
+    running = true
 
-  startLoop()
-}
-
-export function disposeXboxGamepad(): void {
-  stopLoop()
-
-  unregisterListeners()
-
-  gamepadStates.clear()
-
-  onToggleCatalog = null
+    requestAnimationFrame(gamepadLoop)
+  }
 }

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů