fix: Correctly handles unbound keybinds (#2854)

Resolves #2652 #2291

## Description:

Resolves a regression after a new design changes where keybinds
explicitly set to "Null" were incorrectly reverted to default values
instead of remaining unbound.

Updates the input handler to preserve "Null" as the designated value for
an unbound key. The UI now reflects this by displaying "None" for
keybinds that are set to "Null", providing clear user feedback.

Before/After:
<img width="378" height="371" alt="image"
src="https://github.com/user-attachments/assets/d1d640f2-93aa-47f1-be8e-7d8c68183aa1"
/> <img width="379" height="370" alt="image"
src="https://github.com/user-attachments/assets/f0512cce-c6e9-4180-9517-7669aed76f6f"
/>

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

webdev.js

Co-authored-by: antigrid <Stepan.Hembarovskyi@Inu.edu.ua>
This commit is contained in:
Stepan Hembarovskyi
2026-01-10 20:06:47 +02:00
committed by GitHub
parent a4209912a7
commit 97fffaf49e
3 changed files with 5 additions and 5 deletions
+1 -1
View File
@@ -185,7 +185,7 @@ export class InputHandler {
}
// Map invalid values to undefined (filtered later)
if (typeof val !== "string" || val === "Null") {
if (typeof val !== "string") {
return [k, undefined];
}
return [k, val];
@@ -78,7 +78,7 @@ export class SettingKeybind extends LitElement {
}
private displayKey(key: string): string {
if (!key) return translateText("user_setting.press_a_key");
if (!key || key === "Null") return translateText("common.none");
return formatKeyForDisplay(key);
}
+3 -3
View File
@@ -426,7 +426,7 @@ describe("InputHandler AutoUpgrade", () => {
expect((inputHandler as any).keybinds.moveUp).toBe("KeyX");
});
test("ignores non-string and 'Null' values and preserves defaults", () => {
test("ignores non-string values and preserves defaults, but keeps 'Null' for unbound keys", () => {
const mixed = {
moveUp: { key: "moveUp", value: null },
moveLeft: "Null",
@@ -435,9 +435,9 @@ describe("InputHandler AutoUpgrade", () => {
inputHandler.initialize();
// defaults from InputHandler should remain
expect((inputHandler as any).keybinds.moveUp).toBe("KeyW");
expect((inputHandler as any).keybinds.moveLeft).toBe("KeyA");
// "Null" is preserved to indicate unbound keybind
expect((inputHandler as any).keybinds.moveLeft).toBe("Null");
});
test("handles invalid JSON gracefully and warns", () => {