From 972625757792641490a01efa12f59edfaa314fb8 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Thu, 22 May 2025 14:46:44 +0300 Subject: [PATCH] fix: do not display capture lock message when possilbe (avoid flickering - do strategy switch) feat: make tab (players list) keybindign configurable and add a way to assign to a gamepad button --- package.json | 2 +- pnpm-lock.yaml | 16 +++++++------- src/controls.ts | 5 +++++ src/react/GlobalOverlayHints.tsx | 2 +- src/react/PlayerListOverlayProvider.tsx | 29 ++++++------------------- src/utils.ts | 9 ++++---- 6 files changed, 27 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 7d3a5011..655cd394 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "browserify-zlib": "^0.2.0", "buffer": "^6.0.3", "constants-browserify": "^1.0.0", - "contro-max": "^0.1.8", + "contro-max": "^0.1.9", "crypto-browserify": "^3.12.0", "cypress-esbuild-preprocessor": "^1.0.2", "eslint": "^8.50.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9be7ee5..60086040 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -304,8 +304,8 @@ importers: specifier: ^1.0.0 version: 1.0.0 contro-max: - specifier: ^0.1.8 - version: 0.1.8(typescript@5.5.4) + specifier: ^0.1.9 + version: 0.1.9(typescript@5.5.4) crypto-browserify: specifier: ^3.12.0 version: 3.12.1 @@ -4237,8 +4237,8 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - contro-max@0.1.8: - resolution: {integrity: sha512-5SoeudO8Zzfj/gbFTDrMRFJny02+MY1lBtb2NyCNiBLtHAfvhWZxZs/Z3yJvKL2rY/qKUZs9gTQOIDygBcBrdw==} + contro-max@0.1.9: + resolution: {integrity: sha512-zH9FB60EzhHKublD92d11QuarYRTdYci5rvDgwDr5XXwUqae5mr6IgzXGcr78T2odnO/Aeqmrf32RDwJIl5GfQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} convert-source-map@1.9.0: @@ -9751,7 +9751,7 @@ snapshots: '@babel/core': 7.26.9 '@babel/helper-compilation-targets': 7.26.5 '@babel/helper-plugin-utils': 7.26.5 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.1 lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -13322,7 +13322,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.1 transitivePeerDependencies: - supports-color optional: true @@ -14225,7 +14225,7 @@ snapshots: content-type@1.0.5: {} - contro-max@0.1.8(typescript@5.5.4): + contro-max@0.1.9(typescript@5.5.4): dependencies: events: 3.3.0 lodash-es: 4.17.21 @@ -17268,7 +17268,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.1 decode-named-character-reference: 1.1.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 diff --git a/src/controls.ts b/src/controls.ts index f8160cfd..9b2c3cbf 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -27,6 +27,7 @@ import { onCameraMove, onControInit } from './cameraRotationControls' import { createNotificationProgressReporter } from './core/progressReporter' import { appStorage } from './react/appStorageProvider' import { switchGameMode } from './packetsReplay/replayPackets' +import { tabListState } from './react/PlayerListOverlayProvider' export const customKeymaps = proxy(appStorage.keybindings) @@ -65,6 +66,7 @@ export const contro = new ControMax({ // client side zoom: ['KeyC'], viewerConsole: ['Backquote'], + playersList: ['Tab'], }, ui: { toggleFullscreen: ['F11'], @@ -405,6 +407,9 @@ const onTriggerOrReleased = (command: Command, pressed: boolean) => { case 'general.rotateCameraDown': cameraRotationControls.handleCommand(command, pressed) break + case 'general.playersList': + tabListState.isOpen = pressed + break } } } diff --git a/src/react/GlobalOverlayHints.tsx b/src/react/GlobalOverlayHints.tsx index aa340953..ddbb1116 100644 --- a/src/react/GlobalOverlayHints.tsx +++ b/src/react/GlobalOverlayHints.tsx @@ -6,7 +6,7 @@ import PixelartIcon, { pixelartIcons } from './PixelartIcon' import { useUsingTouch } from './utilsApp' export const displayHintsState = proxy({ - captureMouseHint: true + captureMouseHint: false }) export default () => { diff --git a/src/react/PlayerListOverlayProvider.tsx b/src/react/PlayerListOverlayProvider.tsx index 478fd1d2..3ff69c41 100644 --- a/src/react/PlayerListOverlayProvider.tsx +++ b/src/react/PlayerListOverlayProvider.tsx @@ -1,4 +1,4 @@ -import { useSnapshot } from 'valtio' +import { proxy, useSnapshot } from 'valtio' import { useState, useEffect, useMemo } from 'react' import { isGameActive } from '../globalState' import PlayerListOverlay from './PlayerListOverlay' @@ -9,28 +9,18 @@ const MAX_ROWS_PER_COL = 10 type Players = typeof bot.players +export const tabListState = proxy({ + isOpen: false, +}) + export default () => { + const { isOpen } = useSnapshot(tabListState) + const serverIp = lastConnectOptions.value?.server const [clientId, setClientId] = useState(bot._client.uuid) const [players, setPlayers] = useState({}) - const [isOpen, setIsOpen] = useState(false) const [counter, setCounter] = useState(0) - const handleKeyDown = (e) => { - if (!isGameActive(true)) return - if (e.key === 'Tab') { - setIsOpen(prev => true) - e.preventDefault() - } - } - - const handleKeyUp = (e) => { - if (e.key === 'Tab') { - setIsOpen(prev => false) - e.preventDefault() - } - } - useEffect(() => { function requestUpdate () { setPlayers(bot?.players ?? {}) @@ -58,15 +48,10 @@ export default () => { }) } - document.addEventListener('keydown', handleKeyDown) - document.addEventListener('keyup', handleKeyUp) - const playerlistHeader = () => setCounter(prev => prev + 1) bot._client.on('playerlist_header', playerlistHeader) return () => { - document.removeEventListener('keydown', handleKeyDown) - document.removeEventListener('keyup', handleKeyUp) bot?._client.removeListener('playerlist_header', playerlistHeader) } }, [serverIp]) diff --git a/src/utils.ts b/src/utils.ts index 8ea6d3aa..d48fbbc3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -39,14 +39,14 @@ export const pointerLock = { if (options.autoFullScreen) { void goFullscreen() } - const displayBrowserProblem = () => { + const displayMouseCaptureFailure = () => { // if (notificationProxy.id === 'auto-login') return // prevent notification hide // showNotification('Browser Delay Limitation', navigator['keyboard'] ? 'Click on screen, enable Auto Fullscreen or F11' : 'Click on screen or use fullscreen in Chrome') // notificationProxy.id = 'pointerlockchange' displayHintsState.captureMouseHint = true } if (!(document.fullscreenElement && navigator['keyboard']) && this.justHitEscape) { - displayBrowserProblem() + displayMouseCaptureFailure() } else { //@ts-expect-error const promise: any = document.documentElement.requestPointerLock({ @@ -58,9 +58,10 @@ export const pointerLock = { document.documentElement.requestPointerLock() } else if (error.name === 'SecurityError') { // cause: https://discourse.threejs.org/t/how-to-avoid-pointerlockcontrols-error/33017/4 - displayBrowserProblem() + displayMouseCaptureFailure() } else { - console.error(error) + displayMouseCaptureFailure() + console.warn('Failed to request pointer lock:', error) } }) }