From 82533390640c635e8aa6963252ce50ccc71d8d65 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:11:11 +0300 Subject: [PATCH 01/37] fix(quick-restart): handle quick restart in long tests (@Leonabcd123) --- frontend/src/ts/input/hotkeys/quickrestart.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 1b25dbc22179..b0784cbf110a 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -27,7 +27,10 @@ function quickRestart(e: KeyboardEvent): void { createHotkey( () => hotkeys.quickRestart, quickRestart, - () => ({ enabled: !isLongTest() || getConfig.quickRestart !== "enter" }), + () => ({ + enabled: !isLongTest() || getConfig.quickRestart !== "enter", + conflictBehavior: "allow", + }), ); // We also want to have a hotkey for quick restart key without shift, so when the From e1d61f722a946ef3d6f351f1e8e1e00af47b6eb2 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:28:08 +0300 Subject: [PATCH 02/37] Different approach --- frontend/src/ts/input/hotkeys/quickrestart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index b0784cbf110a..d12fedf8b6e2 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -7,6 +7,7 @@ import { hotkeys, quickRestartHotkeyMap } from "../../states/hotkeys"; import { createHotkey } from "./utils"; import { getConfig } from "../../config/store"; import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; +import { untrack } from "solid-js"; function quickRestart(e: KeyboardEvent): void { if (isAnyPopupVisible()) { @@ -28,8 +29,7 @@ createHotkey( () => hotkeys.quickRestart, quickRestart, () => ({ - enabled: !isLongTest() || getConfig.quickRestart !== "enter", - conflictBehavior: "allow", + enabled: untrack(() => !isLongTest() || getConfig.quickRestart !== "enter"), }), ); From e333ec30638e385cccb47a39507a84ed94d3ab1f Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:37:37 +0300 Subject: [PATCH 03/37] Revert "Different approach" This reverts commit e1d61f722a946ef3d6f351f1e8e1e00af47b6eb2. --- frontend/src/ts/input/hotkeys/quickrestart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index d12fedf8b6e2..b0784cbf110a 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -7,7 +7,6 @@ import { hotkeys, quickRestartHotkeyMap } from "../../states/hotkeys"; import { createHotkey } from "./utils"; import { getConfig } from "../../config/store"; import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; -import { untrack } from "solid-js"; function quickRestart(e: KeyboardEvent): void { if (isAnyPopupVisible()) { @@ -29,7 +28,8 @@ createHotkey( () => hotkeys.quickRestart, quickRestart, () => ({ - enabled: untrack(() => !isLongTest() || getConfig.quickRestart !== "enter"), + enabled: !isLongTest() || getConfig.quickRestart !== "enter", + conflictBehavior: "allow", }), ); From 94fce17c24a8040163f6f6138528a593df93e7d6 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 13:33:14 +0300 Subject: [PATCH 04/37] Another approach --- frontend/src/ts/input/hotkeys/quickrestart.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index b0784cbf110a..a5e01d07214e 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -29,7 +29,6 @@ createHotkey( quickRestart, () => ({ enabled: !isLongTest() || getConfig.quickRestart !== "enter", - conflictBehavior: "allow", }), ); @@ -38,7 +37,11 @@ createHotkey( // notification when the user tries to press the quick restart key without shift, // and we'll restart when it's pressed with shift. createHotkey( - () => quickRestartHotkeyMap[getConfig.quickRestart], + () => { + // Update hotkey when quick restart hotkey changes. + void hotkeys.quickRestart; + return quickRestartHotkeyMap[getConfig.quickRestart]; + }, quickRestart, () => ({ enabled: From 26cbc896ba3897015ade1a8d652e2026b7fa3e30 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 13:34:25 +0300 Subject: [PATCH 05/37] Format --- frontend/src/ts/input/hotkeys/quickrestart.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index a5e01d07214e..ec9e63c67e23 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -27,9 +27,7 @@ function quickRestart(e: KeyboardEvent): void { createHotkey( () => hotkeys.quickRestart, quickRestart, - () => ({ - enabled: !isLongTest() || getConfig.quickRestart !== "enter", - }), + () => ({ enabled: !isLongTest() || getConfig.quickRestart !== "enter" }), ); // We also want to have a hotkey for quick restart key without shift, so when the From bc9b927109f06d358b818912b208f1092bccac1d Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 13:57:06 +0300 Subject: [PATCH 06/37] Another --- frontend/src/ts/input/hotkeys/quickrestart.ts | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index ec9e63c67e23..0565feaa3a0d 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -7,6 +7,7 @@ import { hotkeys, quickRestartHotkeyMap } from "../../states/hotkeys"; import { createHotkey } from "./utils"; import { getConfig } from "../../config/store"; import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; +import { untrack } from "solid-js"; function quickRestart(e: KeyboardEvent): void { if (isAnyPopupVisible()) { @@ -22,14 +23,6 @@ function quickRestart(e: KeyboardEvent): void { } } -// Disable restart when we're in long test and quick restart key is enter, because `shift + enter, shift + -// enter` is already reserved for bail out keybind. -createHotkey( - () => hotkeys.quickRestart, - quickRestart, - () => ({ enabled: !isLongTest() || getConfig.quickRestart !== "enter" }), -); - // We also want to have a hotkey for quick restart key without shift, so when the // test is considered long (which means that we can't quick restart), we show a // notification when the user tries to press the quick restart key without shift, @@ -38,13 +31,25 @@ createHotkey( () => { // Update hotkey when quick restart hotkey changes. void hotkeys.quickRestart; - return quickRestartHotkeyMap[getConfig.quickRestart]; + return untrack(() => quickRestartHotkeyMap[getConfig.quickRestart]); }, quickRestart, () => ({ - enabled: - isLongTest() && - !(wordsHaveTab() && getConfig.quickRestart === "tab") && - !(wordsHaveNewline() && getConfig.quickRestart === "enter"), + enabled: untrack( + () => + isLongTest() && + !(wordsHaveTab() && getConfig.quickRestart === "tab") && + !(wordsHaveNewline() && getConfig.quickRestart === "enter"), + ), + }), +); + +// Disable restart when we're in long test and quick restart key is enter, because `shift + enter, shift + +// enter` is already reserved for bail out keybind. +createHotkey( + () => hotkeys.quickRestart, + quickRestart, + () => ({ + enabled: untrack(() => !isLongTest() || getConfig.quickRestart !== "enter"), }), ); From 72fad7c19bb3bb44f468354ac097a556b6eebda9 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:00:23 +0300 Subject: [PATCH 07/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 0565feaa3a0d..56fdd7fadffd 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -23,7 +23,7 @@ function quickRestart(e: KeyboardEvent): void { } } -// We also want to have a hotkey for quick restart key without shift, so when the +// We want to have a hotkey for quick restart key without shift, so when the // test is considered long (which means that we can't quick restart), we show a // notification when the user tries to press the quick restart key without shift, // and we'll restart when it's pressed with shift. From bdb68dbfd7440174b51cce18a9883343dd44f498 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:02:42 +0300 Subject: [PATCH 08/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 56fdd7fadffd..1490891cd608 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -23,6 +23,14 @@ function quickRestart(e: KeyboardEvent): void { } } +// Notes: +// +// - The order of these hotkeys is important. If the first one came after the second one, +// then the second one would override it when test isn't long, and make the quick restart +// hotkey disabled. +// - Both hotkeys should only rerun when `hotkeys.quickRestart` changes. All other signals +// should be accessed inside an `untrack` block. + // We want to have a hotkey for quick restart key without shift, so when the // test is considered long (which means that we can't quick restart), we show a // notification when the user tries to press the quick restart key without shift, From abd6a199e5550938381efb952630d5d3864629f7 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:03:37 +0300 Subject: [PATCH 09/37] Comments --- frontend/src/ts/input/hotkeys/quickrestart.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 1490891cd608..451ce5677302 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -26,10 +26,10 @@ function quickRestart(e: KeyboardEvent): void { // Notes: // // - The order of these hotkeys is important. If the first one came after the second one, -// then the second one would override it when test isn't long, and make the quick restart -// hotkey disabled. +// then it would override it when test isn't long, and make the quick restart hotkey +// disabled. // - Both hotkeys should only rerun when `hotkeys.quickRestart` changes. All other signals -// should be accessed inside an `untrack` block. +// are accessed inside an `untrack` block. // We want to have a hotkey for quick restart key without shift, so when the // test is considered long (which means that we can't quick restart), we show a From 5aeda0b44357c558f3f696007853d3ce65a53121 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:05:24 +0300 Subject: [PATCH 10/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 451ce5677302..76ba107c214c 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -52,8 +52,9 @@ createHotkey( }), ); -// Disable restart when we're in long test and quick restart key is enter, because `shift + enter, shift + +// Disable restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + // enter` is already reserved for bail out keybind. +// This is the primary hotkey for quick restart. createHotkey( () => hotkeys.quickRestart, quickRestart, From 4e5fa5e09c748302780f9f3363f1e64b1531eb3f Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:06:19 +0300 Subject: [PATCH 11/37] Comments --- frontend/src/ts/input/hotkeys/quickrestart.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 76ba107c214c..a6f7fae6f063 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -31,6 +31,8 @@ function quickRestart(e: KeyboardEvent): void { // - Both hotkeys should only rerun when `hotkeys.quickRestart` changes. All other signals // are accessed inside an `untrack` block. +// Secondary hotkey used in long tests. + // We want to have a hotkey for quick restart key without shift, so when the // test is considered long (which means that we can't quick restart), we show a // notification when the user tries to press the quick restart key without shift, @@ -52,9 +54,10 @@ createHotkey( }), ); -// Disable restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + +// Primary hotkey for quick restart. + +// Disable quick restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + // enter` is already reserved for bail out keybind. -// This is the primary hotkey for quick restart. createHotkey( () => hotkeys.quickRestart, quickRestart, From 58b028a639575f0a3420872e3757b9ac9339e1e7 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:08:17 +0300 Subject: [PATCH 12/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index a6f7fae6f063..e057af3acc9e 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -25,9 +25,8 @@ function quickRestart(e: KeyboardEvent): void { // Notes: // -// - The order of these hotkeys is important. If the first one came after the second one, -// then it would override it when test isn't long, and make the quick restart hotkey -// disabled. +// - The order of these hotkeys is important. If the secondary one was created after the// primary one, the secondary one would override the primary one when the test isn't long, +// which would make the quick restart hotkey disabled. // - Both hotkeys should only rerun when `hotkeys.quickRestart` changes. All other signals // are accessed inside an `untrack` block. From 55623995db1e41e544ce4e4fa1057820ea3affce Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:09:39 +0300 Subject: [PATCH 13/37] Primary --- frontend/src/ts/input/hotkeys/quickrestart.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index e057af3acc9e..64cc94c159dd 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -25,7 +25,8 @@ function quickRestart(e: KeyboardEvent): void { // Notes: // -// - The order of these hotkeys is important. If the secondary one was created after the// primary one, the secondary one would override the primary one when the test isn't long, +// - The order of these hotkeys is important. If the secondary one was created after the +// primary one, the secondary one would override the primary one when the test isn't long, // which would make the quick restart hotkey disabled. // - Both hotkeys should only rerun when `hotkeys.quickRestart` changes. All other signals // are accessed inside an `untrack` block. From 6e79f3aff898bd010fa59f9c2e1e60cc726d16f8 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:11:48 +0300 Subject: [PATCH 14/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 64cc94c159dd..3045140afbed 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -23,7 +23,7 @@ function quickRestart(e: KeyboardEvent): void { } } -// Notes: +// Notes about the following two hotkeys: // // - The order of these hotkeys is important. If the secondary one was created after the // primary one, the secondary one would override the primary one when the test isn't long, From c3cf1822abb63244245c5954a9a02fc26d30bdba Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:22:35 +0300 Subject: [PATCH 15/37] Safety --- frontend/src/ts/input/hotkeys/quickrestart.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 3045140afbed..8cac378dcaf5 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -51,6 +51,7 @@ createHotkey( !(wordsHaveTab() && getConfig.quickRestart === "tab") && !(wordsHaveNewline() && getConfig.quickRestart === "enter"), ), + conflictBehavior: "allow", }), ); From 1d96608c9cfc71d2942a33ab8b10fc8c19416a9b Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:24:54 +0300 Subject: [PATCH 16/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 8cac378dcaf5..c584f4c17956 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -25,11 +25,10 @@ function quickRestart(e: KeyboardEvent): void { // Notes about the following two hotkeys: // -// - The order of these hotkeys is important. If the secondary one was created after the -// primary one, the secondary one would override the primary one when the test isn't long, -// which would make the quick restart hotkey disabled. -// - Both hotkeys should only rerun when `hotkeys.quickRestart` changes. All other signals -// are accessed inside an `untrack` block. +// - The order of hotkeys in this file should be preserved, so we won't have conflicting +// hotkeys. +// - Both hotkeys only rerun when `hotkeys.quickRestart` changes. All other signals are +// accessed inside an `untrack` block. // Secondary hotkey used in long tests. From ce15b01c9e3ae0794c5dae4ce51fdfdb00e2cda7 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:26:41 +0300 Subject: [PATCH 17/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index c584f4c17956..d12e3d3294c1 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -50,6 +50,8 @@ createHotkey( !(wordsHaveTab() && getConfig.quickRestart === "tab") && !(wordsHaveNewline() && getConfig.quickRestart === "enter"), ), + // This is here to make sure that if this hotkey is ever ran after the primary one + // (say `hotkeys.quickRestart` changes and this reruns last), it won't replace it. conflictBehavior: "allow", }), ); From 399feae12a5c067e6acb1d3a3658d6689881fff6 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:51:52 +0300 Subject: [PATCH 18/37] Start --- frontend/src/ts/input/hotkeys/quickrestart.ts | 49 +++++++++---------- frontend/src/ts/input/hotkeys/utils.ts | 22 +++++++++ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index d12e3d3294c1..b741703d69be 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -4,9 +4,9 @@ import { navigate } from "../../controllers/route-controller"; import { restartTestEvent } from "../../events/test"; import { getActivePage } from "../../states/core"; import { hotkeys, quickRestartHotkeyMap } from "../../states/hotkeys"; -import { createHotkey } from "./utils"; +import { createHotkeys } from "./utils"; import { getConfig } from "../../config/store"; -import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; +//import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; import { untrack } from "solid-js"; function quickRestart(e: KeyboardEvent): void { @@ -36,34 +36,29 @@ function quickRestart(e: KeyboardEvent): void { // test is considered long (which means that we can't quick restart), we show a // notification when the user tries to press the quick restart key without shift, // and we'll restart when it's pressed with shift. -createHotkey( - () => { - // Update hotkey when quick restart hotkey changes. - void hotkeys.quickRestart; - return untrack(() => quickRestartHotkeyMap[getConfig.quickRestart]); +createHotkeys(() => [ + { + hotkey: untrack(() => quickRestartHotkeyMap[getConfig.quickRestart]), + callback: quickRestart, + // options: () => ({ + // enabled: untrack( + // () => + // isLongTest() && + // !(wordsHaveTab() && getConfig.quickRestart === "tab") && + // !(wordsHaveNewline() && getConfig.quickRestart === "enter"), + // ), + // }), }, - quickRestart, - () => ({ - enabled: untrack( - () => - isLongTest() && - !(wordsHaveTab() && getConfig.quickRestart === "tab") && - !(wordsHaveNewline() && getConfig.quickRestart === "enter"), - ), - // This is here to make sure that if this hotkey is ever ran after the primary one - // (say `hotkeys.quickRestart` changes and this reruns last), it won't replace it. - conflictBehavior: "allow", - }), -); + { + hotkey: hotkeys.quickRestart, + callback: quickRestart, + // options: () => ({ + // enabled: untrack(() => !isLongTest() || getConfig.quickRestart !== "enter"), + // }), + }, +]); // Primary hotkey for quick restart. // Disable quick restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + // enter` is already reserved for bail out keybind. -createHotkey( - () => hotkeys.quickRestart, - quickRestart, - () => ({ - enabled: untrack(() => !isLongTest() || getConfig.quickRestart !== "enter"), - }), -); diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 5093d103f0da..b6052ad6056b 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -1,9 +1,11 @@ import { CreateHotkeyOptions, + CreateHotkeyDefinition, Hotkey, HotkeyCallback, HotkeyCallbackContext, createHotkey as registerHotkey, + createHotkeys as registerHotkeys, } from "@tanstack/solid-hotkeys"; import { isAnyPopupVisible } from "../../utils/misc"; import { isInputElementFocused } from "../input-element"; @@ -41,6 +43,26 @@ export function createHotkey( ); } +export function createHotkeys( + hotkeys: CreateHotkeyDefinition[] | (() => CreateHotkeyDefinition[]), + commonOptions: () => Partial< + Omit< + CreateHotkeyOptions, + "ignoreInputs" | "stopPropagation" | "preventDefault" + > + > = () => ({}), +): void { + registerHotkeys(hotkeys, () => ({ + ignoreInputs: false, //hotkeys are active on the words input, but not on other interactive elements + stopPropagation: false, //we set stopPropagation in the callback if the hotkey executes + preventDefault: false, //we set preventDefault in the callback if the hotkey executes + requireReset: true, + conflictBehavior: "replace", + enabled: true, + ...commonOptions(), + })); +} + function isInteractiveElementFocused(): boolean { if (isInputElementFocused()) return false; From 74a4334033b9e9b980b9540a532dbf198b033918 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:54:49 +0300 Subject: [PATCH 19/37] Options --- frontend/src/ts/input/hotkeys/quickrestart.ts | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index b741703d69be..250ca5504c8f 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -6,7 +6,7 @@ import { getActivePage } from "../../states/core"; import { hotkeys, quickRestartHotkeyMap } from "../../states/hotkeys"; import { createHotkeys } from "./utils"; import { getConfig } from "../../config/store"; -//import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; +import { isLongTest, wordsHaveNewline, wordsHaveTab } from "../../states/test"; import { untrack } from "solid-js"; function quickRestart(e: KeyboardEvent): void { @@ -40,21 +40,23 @@ createHotkeys(() => [ { hotkey: untrack(() => quickRestartHotkeyMap[getConfig.quickRestart]), callback: quickRestart, - // options: () => ({ - // enabled: untrack( - // () => - // isLongTest() && - // !(wordsHaveTab() && getConfig.quickRestart === "tab") && - // !(wordsHaveNewline() && getConfig.quickRestart === "enter"), - // ), - // }), + options: { + enabled: untrack( + () => + isLongTest() && + !(wordsHaveTab() && getConfig.quickRestart === "tab") && + !(wordsHaveNewline() && getConfig.quickRestart === "enter"), + ), + }, }, { hotkey: hotkeys.quickRestart, callback: quickRestart, - // options: () => ({ - // enabled: untrack(() => !isLongTest() || getConfig.quickRestart !== "enter"), - // }), + options: { + enabled: untrack( + () => !isLongTest() || getConfig.quickRestart !== "enter", + ), + }, }, ]); From 49b3e19d8e6da922cda13b440c02e24f95f8f9ae Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:55:13 +0300 Subject: [PATCH 20/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 250ca5504c8f..481e26e3bf89 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -25,8 +25,6 @@ function quickRestart(e: KeyboardEvent): void { // Notes about the following two hotkeys: // -// - The order of hotkeys in this file should be preserved, so we won't have conflicting -// hotkeys. // - Both hotkeys only rerun when `hotkeys.quickRestart` changes. All other signals are // accessed inside an `untrack` block. From f5e6970cb89c872f94a4c747a7adc861af25df65 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:58:24 +0300 Subject: [PATCH 21/37] Default --- frontend/src/ts/input/hotkeys/utils.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index b6052ad6056b..dedeb2d8faa0 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -13,6 +13,14 @@ import * as CompositionState from "../../legacy-states/composition"; export const NoKey = "" as Hotkey; +const defaultOptions = { + ignoreInputs: false, //hotkeys are active on the words input, but not on other interactive elements + stopPropagation: false, //we set stopPropagation in the callback if the hotkey executes + preventDefault: false, //we set preventDefault in the callback if the hotkey executes + requireReset: true, + conflictBehavior: "replace", +} as Partial; + export function createHotkey( hotkey: Hotkey | (() => Hotkey), callback: HotkeyCallback, @@ -32,11 +40,7 @@ export function createHotkey( callback(e, context); }, () => ({ - ignoreInputs: false, //hotkeys are active on the words input, but not on other interactive elements - stopPropagation: false, //we set stopPropagation in the callback if the hotkey executes - preventDefault: false, //we set preventDefault in the callback if the hotkey executes - requireReset: true, - conflictBehavior: "replace", + ...defaultOptions, enabled: (typeof hotkey === "function" ? hotkey() : hotkey) !== NoKey, ...options(), }), @@ -53,12 +57,7 @@ export function createHotkeys( > = () => ({}), ): void { registerHotkeys(hotkeys, () => ({ - ignoreInputs: false, //hotkeys are active on the words input, but not on other interactive elements - stopPropagation: false, //we set stopPropagation in the callback if the hotkey executes - preventDefault: false, //we set preventDefault in the callback if the hotkey executes - requireReset: true, - conflictBehavior: "replace", - enabled: true, + ...defaultOptions, ...commonOptions(), })); } From 5b0683b1f8f4735c2244ee937dbbd0b77d472c81 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:58:44 +0300 Subject: [PATCH 22/37] Not partial --- frontend/src/ts/input/hotkeys/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index dedeb2d8faa0..a6c49d6106d1 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -19,7 +19,7 @@ const defaultOptions = { preventDefault: false, //we set preventDefault in the callback if the hotkey executes requireReset: true, conflictBehavior: "replace", -} as Partial; +} as CreateHotkeyOptions; export function createHotkey( hotkey: Hotkey | (() => Hotkey), From 0865af0c289338fd7869477fe00a97fa410acfab Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:58:54 +0300 Subject: [PATCH 23/37] Not partial --- frontend/src/ts/input/hotkeys/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index a6c49d6106d1..4dc16f994e66 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -19,7 +19,7 @@ const defaultOptions = { preventDefault: false, //we set preventDefault in the callback if the hotkey executes requireReset: true, conflictBehavior: "replace", -} as CreateHotkeyOptions; +} satisfies CreateHotkeyOptions; export function createHotkey( hotkey: Hotkey | (() => Hotkey), From 45121c55dc0b844e87271e9a7c2ca506e61aaef2 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:59:37 +0300 Subject: [PATCH 24/37] Semi --- frontend/src/ts/input/hotkeys/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 4dc16f994e66..03ea00b828cd 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -13,13 +13,13 @@ import * as CompositionState from "../../legacy-states/composition"; export const NoKey = "" as Hotkey; -const defaultOptions = { +const defaultOptions: CreateHotkeyOptions = { ignoreInputs: false, //hotkeys are active on the words input, but not on other interactive elements stopPropagation: false, //we set stopPropagation in the callback if the hotkey executes preventDefault: false, //we set preventDefault in the callback if the hotkey executes requireReset: true, conflictBehavior: "replace", -} satisfies CreateHotkeyOptions; +}; export function createHotkey( hotkey: Hotkey | (() => Hotkey), From 3a398445e19e25833e8dc07e706acc73495cfa70 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:01:07 +0300 Subject: [PATCH 25/37] Comments --- frontend/src/ts/input/hotkeys/quickrestart.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 481e26e3bf89..bf3247c22687 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -28,13 +28,13 @@ function quickRestart(e: KeyboardEvent): void { // - Both hotkeys only rerun when `hotkeys.quickRestart` changes. All other signals are // accessed inside an `untrack` block. -// Secondary hotkey used in long tests. - -// We want to have a hotkey for quick restart key without shift, so when the -// test is considered long (which means that we can't quick restart), we show a -// notification when the user tries to press the quick restart key without shift, -// and we'll restart when it's pressed with shift. createHotkeys(() => [ + // Secondary hotkey used in long tests. + + // We want to have a hotkey for quick restart key without shift, so when the + // test is considered long (which means that we can't quick restart), we show a + // notification when the user tries to press the quick restart key without shift, + // and we'll restart when it's pressed with shift. { hotkey: untrack(() => quickRestartHotkeyMap[getConfig.quickRestart]), callback: quickRestart, @@ -47,6 +47,11 @@ createHotkeys(() => [ ), }, }, + + // Primary hotkey for quick restart. + + // Disable quick restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + + // enter` is already reserved for bail out keybind. { hotkey: hotkeys.quickRestart, callback: quickRestart, @@ -57,8 +62,3 @@ createHotkeys(() => [ }, }, ]); - -// Primary hotkey for quick restart. - -// Disable quick restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + -// enter` is already reserved for bail out keybind. From 14aafe6f1195316038375eef55c2e913cf18d80b Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:58:08 +0300 Subject: [PATCH 26/37] Before callback --- frontend/src/ts/input/hotkeys/utils.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 03ea00b828cd..daa43cb4762f 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -21,6 +21,15 @@ const defaultOptions: CreateHotkeyOptions = { conflictBehavior: "replace", }; +function beforeCallback( + e: KeyboardEvent, + context: HotkeyCallbackContext, +): void { + if (handleHotkeyOnInteractiveElement(e, context)) return; + e.stopPropagation(); + e.preventDefault(); +} + export function createHotkey( hotkey: Hotkey | (() => Hotkey), callback: HotkeyCallback, @@ -34,9 +43,7 @@ export function createHotkey( registerHotkey( hotkey, (e, context) => { - if (handleHotkeyOnInteractiveElement(e, context)) return; - e.stopPropagation(); - e.preventDefault(); + beforeCallback(e, context); callback(e, context); }, () => ({ @@ -56,6 +63,13 @@ export function createHotkeys( > > = () => ({}), ): void { + const resolvedHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; + resolvedHotkeys.forEach((hotkey) => { + hotkey.callback = function (e, context) { + beforeCallback(e, context); + hotkey.callback(e, context); + }; + }); registerHotkeys(hotkeys, () => ({ ...defaultOptions, ...commonOptions(), From 16225ade065a29a1f0eb4616c4caa313022a198c Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:01:49 +0300 Subject: [PATCH 27/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index bf3247c22687..2bfbf2346d34 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -25,6 +25,9 @@ function quickRestart(e: KeyboardEvent): void { // Notes about the following two hotkeys: // +// - The order of the hotkeys in the array passed to `createHotkeys` is important. If +// the order was reversed, then the secondary hotkey will override the primary hotkey +// when test isn't long, which would cause the quick restart hotkey to be disabled. // - Both hotkeys only rerun when `hotkeys.quickRestart` changes. All other signals are // accessed inside an `untrack` block. From c0c7871169dd61c0d84d53fee032a090634a07f3 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:02:18 +0300 Subject: [PATCH 28/37] Comment --- frontend/src/ts/input/hotkeys/quickrestart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index 2bfbf2346d34..a1516f4ddaa1 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -27,7 +27,7 @@ function quickRestart(e: KeyboardEvent): void { // // - The order of the hotkeys in the array passed to `createHotkeys` is important. If // the order was reversed, then the secondary hotkey will override the primary hotkey -// when test isn't long, which would cause the quick restart hotkey to be disabled. +// when the test isn't long, which would cause the quick restart hotkey to be disabled. // - Both hotkeys only rerun when `hotkeys.quickRestart` changes. All other signals are // accessed inside an `untrack` block. From 4c1181a0398271a5a7010e764f728b690c058bf5 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 17:07:33 +0300 Subject: [PATCH 29/37] Refactor --- frontend/src/ts/input/hotkeys/utils.ts | 36 ++++++++++---------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index daa43cb4762f..1c251df9483d 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -21,13 +21,13 @@ const defaultOptions: CreateHotkeyOptions = { conflictBehavior: "replace", }; -function beforeCallback( - e: KeyboardEvent, - context: HotkeyCallbackContext, -): void { - if (handleHotkeyOnInteractiveElement(e, context)) return; - e.stopPropagation(); - e.preventDefault(); +function attachBeforeCallback(callback: HotkeyCallback): HotkeyCallback { + return (e, context) => { + if (handleHotkeyOnInteractiveElement(e, context)) return; + e.stopPropagation(); + e.preventDefault(); + callback(e, context); + }; } export function createHotkey( @@ -40,18 +40,11 @@ export function createHotkey( > > = () => ({}), ): void { - registerHotkey( - hotkey, - (e, context) => { - beforeCallback(e, context); - callback(e, context); - }, - () => ({ - ...defaultOptions, - enabled: (typeof hotkey === "function" ? hotkey() : hotkey) !== NoKey, - ...options(), - }), - ); + registerHotkey(hotkey, attachBeforeCallback(callback), () => ({ + ...defaultOptions, + enabled: (typeof hotkey === "function" ? hotkey() : hotkey) !== NoKey, + ...options(), + })); } export function createHotkeys( @@ -65,10 +58,7 @@ export function createHotkeys( ): void { const resolvedHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; resolvedHotkeys.forEach((hotkey) => { - hotkey.callback = function (e, context) { - beforeCallback(e, context); - hotkey.callback(e, context); - }; + hotkey.callback = attachBeforeCallback(hotkey.callback); }); registerHotkeys(hotkeys, () => ({ ...defaultOptions, From 57e514914385a67da7b1e79f7714567b3d5ff33c Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 17:11:24 +0300 Subject: [PATCH 30/37] Resolved --- frontend/src/ts/input/hotkeys/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 1c251df9483d..5097c1fb2271 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -60,7 +60,7 @@ export function createHotkeys( resolvedHotkeys.forEach((hotkey) => { hotkey.callback = attachBeforeCallback(hotkey.callback); }); - registerHotkeys(hotkeys, () => ({ + registerHotkeys(resolvedHotkeys, () => ({ ...defaultOptions, ...commonOptions(), })); From d90a1d23ab5e6582602e4aa24ec3be78b7305e82 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 17:13:12 +0300 Subject: [PATCH 31/37] Revert "Resolved" This reverts commit 57e514914385a67da7b1e79f7714567b3d5ff33c. --- frontend/src/ts/input/hotkeys/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 5097c1fb2271..1c251df9483d 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -60,7 +60,7 @@ export function createHotkeys( resolvedHotkeys.forEach((hotkey) => { hotkey.callback = attachBeforeCallback(hotkey.callback); }); - registerHotkeys(resolvedHotkeys, () => ({ + registerHotkeys(hotkeys, () => ({ ...defaultOptions, ...commonOptions(), })); From beead9489491f3836d079fcd00241f6c6d3abfbf Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 18:33:52 +0300 Subject: [PATCH 32/37] Fix --- frontend/src/ts/input/hotkeys/utils.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 1c251df9483d..13299f657ca3 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -56,11 +56,14 @@ export function createHotkeys( > > = () => ({}), ): void { - const resolvedHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; - resolvedHotkeys.forEach((hotkey) => { - hotkey.callback = attachBeforeCallback(hotkey.callback); - }); - registerHotkeys(hotkeys, () => ({ + const resolvedHotkeys = (): CreateHotkeyDefinition[] => { + const tempHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; + tempHotkeys.forEach((hotkey) => { + hotkey.callback = attachBeforeCallback(hotkey.callback); + }); + return tempHotkeys; + }; + registerHotkeys(resolvedHotkeys, () => ({ ...defaultOptions, ...commonOptions(), })); From b0e96a9e43d2d23992e1a446a55fb4599fd8feeb Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 18:35:09 +0300 Subject: [PATCH 33/37] Rename --- frontend/src/ts/input/hotkeys/utils.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 13299f657ca3..5394faa06829 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -56,14 +56,14 @@ export function createHotkeys( > > = () => ({}), ): void { - const resolvedHotkeys = (): CreateHotkeyDefinition[] => { - const tempHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; - tempHotkeys.forEach((hotkey) => { + const modifiedHotkeys = (): CreateHotkeyDefinition[] => { + const resolvedHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; + resolvedHotkeys.forEach((hotkey) => { hotkey.callback = attachBeforeCallback(hotkey.callback); }); - return tempHotkeys; + return resolvedHotkeys; }; - registerHotkeys(resolvedHotkeys, () => ({ + registerHotkeys(modifiedHotkeys, () => ({ ...defaultOptions, ...commonOptions(), })); From 96622b63435c17e2ba00c69b3b1bad8c2b242e53 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 18:44:25 +0300 Subject: [PATCH 34/37] NoKey --- frontend/src/ts/input/hotkeys/utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/ts/input/hotkeys/utils.ts b/frontend/src/ts/input/hotkeys/utils.ts index 5394faa06829..68cb96e7bd46 100644 --- a/frontend/src/ts/input/hotkeys/utils.ts +++ b/frontend/src/ts/input/hotkeys/utils.ts @@ -60,6 +60,8 @@ export function createHotkeys( const resolvedHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys; resolvedHotkeys.forEach((hotkey) => { hotkey.callback = attachBeforeCallback(hotkey.callback); + hotkey.options ??= {}; + hotkey.options.enabled ??= hotkey.hotkey !== NoKey; }); return resolvedHotkeys; }; From fac53e3e81da52ef2712fe562252366a30219f75 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:57:24 +0300 Subject: [PATCH 35/37] Less untracks --- frontend/src/ts/input/hotkeys/quickrestart.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index a1516f4ddaa1..e58a7c08a1eb 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -38,18 +38,16 @@ createHotkeys(() => [ // test is considered long (which means that we can't quick restart), we show a // notification when the user tries to press the quick restart key without shift, // and we'll restart when it's pressed with shift. - { - hotkey: untrack(() => quickRestartHotkeyMap[getConfig.quickRestart]), + untrack(() => ({ + hotkey: quickRestartHotkeyMap[getConfig.quickRestart], callback: quickRestart, options: { - enabled: untrack( - () => - isLongTest() && - !(wordsHaveTab() && getConfig.quickRestart === "tab") && - !(wordsHaveNewline() && getConfig.quickRestart === "enter"), - ), + enabled: + isLongTest() && + !(wordsHaveTab() && getConfig.quickRestart === "tab") && + !(wordsHaveNewline() && getConfig.quickRestart === "enter"), }, - }, + })), // Primary hotkey for quick restart. From 350e8e32e1eacc98da5eb08a8dc09c3e7edfd1b1 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 21:38:50 +0300 Subject: [PATCH 36/37] Comments --- frontend/src/ts/input/hotkeys/quickrestart.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index e58a7c08a1eb..f1b733500f41 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -35,9 +35,9 @@ createHotkeys(() => [ // Secondary hotkey used in long tests. // We want to have a hotkey for quick restart key without shift, so when the - // test is considered long (which means that we can't quick restart), we show a - // notification when the user tries to press the quick restart key without shift, - // and we'll restart when it's pressed with shift. + // test is considered long (which means that we can't quick restart) and the user + // tries to press the quick restart key without shift, we'll show a notification, and + // when the user presses the quick restart key with shift, we'll restart. untrack(() => ({ hotkey: quickRestartHotkeyMap[getConfig.quickRestart], callback: quickRestart, @@ -51,13 +51,13 @@ createHotkeys(() => [ // Primary hotkey for quick restart. - // Disable quick restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + - // enter` is already reserved for bail out keybind. { hotkey: hotkeys.quickRestart, callback: quickRestart, options: { enabled: untrack( + // Disable quick restart when we're in a long test and quick restart key is enter, because `shift + enter, shift + + // enter` is already reserved for bail out keybind. () => !isLongTest() || getConfig.quickRestart !== "enter", ), }, From fb406c8a661469f9486c020a745ea37999d76347 Mon Sep 17 00:00:00 2001 From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com> Date: Fri, 5 Jun 2026 21:39:28 +0300 Subject: [PATCH 37/37] Space --- frontend/src/ts/input/hotkeys/quickrestart.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/ts/input/hotkeys/quickrestart.ts b/frontend/src/ts/input/hotkeys/quickrestart.ts index f1b733500f41..310b3bf39fb3 100644 --- a/frontend/src/ts/input/hotkeys/quickrestart.ts +++ b/frontend/src/ts/input/hotkeys/quickrestart.ts @@ -50,7 +50,6 @@ createHotkeys(() => [ })), // Primary hotkey for quick restart. - { hotkey: hotkeys.quickRestart, callback: quickRestart,