Skip to content

Commit

Permalink
[Hotkeys] Hide hotkeys dialog on 'shift + ?' keypress (#1301)
Browse files Browse the repository at this point in the history
* Hide dialog after delay on 'shift + ?' press

* Respond to CR feedback

* Fix build

* Move function comment
  • Loading branch information
cmslewis authored Jul 27, 2017
1 parent 94d68e8 commit 842db8f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
27 changes: 24 additions & 3 deletions packages/core/src/components/hotkeys/hotkeysDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export interface IHotkeysDialogProps extends IDialogProps {
globalHotkeysGroup?: string;
}

/**
* The delay before showing or hiding the dialog. Should be long enough to
* allow all registered hotkey listeners to execute first.
*/
const DELAY_IN_MS = 10;

class HotkeysDialog {
public componentProps = {
globalHotkeysGroup: "Global hotkeys",
Expand All @@ -30,7 +36,8 @@ class HotkeysDialog {
private container: HTMLElement;
private hotkeysQueue = [] as IHotkeyProps[][];
private isDialogShowing = false;
private timeoutToken = 0;
private showTimeoutToken: number;
private hideTimeoutToken: number;

public render() {
if (this.container == null) {
Expand Down Expand Up @@ -59,8 +66,13 @@ class HotkeysDialog {
this.hotkeysQueue.push(hotkeys);

// reset timeout for debounce
clearTimeout(this.timeoutToken);
this.timeoutToken = setTimeout(this.show, 10);
clearTimeout(this.showTimeoutToken);
this.showTimeoutToken = setTimeout(this.show, DELAY_IN_MS);
}

public hideAfterDelay() {
clearTimeout(this.hideTimeoutToken);
this.hideTimeoutToken = setTimeout(this.hide, DELAY_IN_MS);
}

public show = () => {
Expand Down Expand Up @@ -141,3 +153,12 @@ export function showHotkeysDialog(hotkeys: IHotkeyProps[]) {
export function hideHotkeysDialog() {
HOTKEYS_DIALOG.hide();
}

/**
* Use this function instead of `hideHotkeysDialog` if you need to ensure that all hotkey listeners
* have time to execute with the dialog in a consistent open state. This can avoid flickering the
* dialog between open and closed states as successive listeners fire.
*/
export function hideHotkeysDialogAfterDelay() {
HOTKEYS_DIALOG.hideAfterDelay();
}
14 changes: 8 additions & 6 deletions packages/core/src/components/hotkeys/hotkeysEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { safeInvoke } from "../../common/utils";
import { Hotkey, IHotkeyProps } from "./hotkey";
import { comboMatches, getKeyCombo, IKeyCombo, parseKeyCombo } from "./hotkeyParser";
import { IHotkeysProps } from "./hotkeys";
import { isHotkeysDialogShowing, showHotkeysDialog } from "./hotkeysDialog";
import { hideHotkeysDialogAfterDelay, isHotkeysDialogShowing, showHotkeysDialog } from "./hotkeysDialog";

const SHOW_DIALOG_KEY = "?";

Expand Down Expand Up @@ -53,15 +53,17 @@ export class HotkeysEvents {
}

public handleKeyDown = (e: KeyboardEvent) => {
if (isHotkeysDialogShowing()) {
return;
}

const combo = getKeyCombo(e);
const isTextInput = this.isTextInput(e);

if (!isTextInput && comboMatches(parseKeyCombo(SHOW_DIALOG_KEY), combo)) {
showHotkeysDialog(this.actions.map((action) => action.props));
if (isHotkeysDialogShowing()) {
hideHotkeysDialogAfterDelay();
} else {
showHotkeysDialog(this.actions.map((action) => action.props));
}
return;
} else if (isHotkeysDialogShowing()) {
return;
}

Expand Down

1 comment on commit 842db8f

@blueprint-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hotkeys] Hide hotkeys dialog on 'shift + ?' keypress (#1301)

Preview: documentation
Coverage: core | datetime

Please sign in to comment.