From c71f8b8b1f3460132b687b8901b2abce179bba2e Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Tue, 11 Jun 2024 15:13:49 +0100 Subject: [PATCH] Keybinds: Allow move time range shortcuts (t left / t right) to be chained (#88904) * Allow for chaining timeshift shortcuts * ignore repeated shortcuts --- .../app/core/services/mousetrap/Mousetrap.ts | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/public/app/core/services/mousetrap/Mousetrap.ts b/public/app/core/services/mousetrap/Mousetrap.ts index 3f7d1503135..39eddc3670f 100644 --- a/public/app/core/services/mousetrap/Mousetrap.ts +++ b/public/app/core/services/mousetrap/Mousetrap.ts @@ -627,6 +627,18 @@ export class Mousetrap { // keep a list of which sequences were matches for later doNotReset[seq] = 1; this._fireCallback(callbacks[i].callback, e, callbacks[i].combo, seq); + + // When matching a callback, don't reset other callbacks that starts with this prefix + // This allows chaining of multiple shortcuts that share a prefix. e.g. if we have + // `t left` and `t right`, allow user to hit `t left`, `right` without resetting the sequence + const suffixPrefixIndex = seq.lastIndexOf(character); + const sequencePrefix = seq.slice(0, suffixPrefixIndex); + for (const [seq, level] of Object.entries(this._sequenceLevels)) { + if (level > 0 && seq.startsWith(sequencePrefix)) { + doNotReset[seq] = 1; + } + } + continue; } @@ -637,6 +649,14 @@ export class Mousetrap { } } + // Don't reset a sequence if this character is the start of a sequence that has already progressed. + // This allows `t left` to be hit immediately after a `t right` + for (const callback of this._callbacks[character] ?? []) { + if (callback.action === e.type && callback.seq && callback.level === 0) { + doNotReset[callback.seq] = 1; + } + } + // if the key you pressed matches the type of sequence without // being a modifier (ie "keyup" or "keypress") then we should // reset all sequences that were not matched by this event @@ -675,6 +695,11 @@ export class Mousetrap { } const event: KeyboardEvent = rawEvent; + // Don't trigger shortcuts when a key is just held down + if (event.repeat) { + return; + } + // normalize e.which for key events // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion if (typeof event.which !== 'number') { @@ -743,9 +768,9 @@ export class Mousetrap { this._ignoreNextKeyup = characterFromEvent(e); } - // weird race condition if a sequence ends with the key - // another sequence begins with - setTimeout(this._resetSequences, 10); + // Reset the sequence timer and allow for this shortcut to be + // triggered again just by repeating the last key + this._resetSequenceTimer(); }; // loop through keys one at a time and bind the appropriate callback