Skip to content

Instantly share code, notes, and snippets.

@ova2
Created January 12, 2025 20:03
Show Gist options
  • Save ova2/a60800f6cd11b657b15ca73dd976042b to your computer and use it in GitHub Desktop.
Save ova2/a60800f6cd11b657b15ca73dd976042b to your computer and use it in GitHub Desktop.
private singleShortcut$(keyCodes: string[]): Observable<KeyboardEvent[] | undefined> {
const keyEvents$: Observable<KeyboardEvent> = this.createKeyEvents();
const pressedKeys = new Set<string>();
// create event stream for every shortcut key
const shortcutKeys$: Observable<KeyboardEvent>[] = keyCodes.map(keyCode => keyEvents$
.pipe(
filter(keyboardEvent => keyboardEvent.code === keyCode),
tap(keyboardEvent => {
if (keyboardEvent.type === 'keydown') {
pressedKeys.add(keyboardEvent.code);
} else {
pressedKeys.delete(keyboardEvent.code);
}
})
));
// emit only when all specified keys are pressed at the same time or released completely
return combineLatest(shortcutKeys$)
.pipe(
filter(keyboardEvents => this.checkPressedKeys(keyboardEvents, pressedKeys.size)),
map(keyboardEvents => pressedKeys.size === 0 ? undefined : keyboardEvents)
);
}
private createKeyEvents(): Observable<KeyboardEvent> {
const keydown$ = fromEvent<KeyboardEvent>(document, 'keydown');
const keyup$ = fromEvent<KeyboardEvent>(document, 'keyup');
return merge(keydown$, keyup$)
.pipe(
distinctUntilChanged((a, b) => a.code === b.code && a.type === b.type),
share()
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment