Files
advanced-camera-card/src/card-controller/keyboard-state-manager.ts
T

60 lines
1.7 KiB
TypeScript

import { CardKeyboardStateAPI, KeysState } from './types';
import isEqual from 'lodash/isEqual';
export class KeyboardStateManager {
protected _api: CardKeyboardStateAPI;
protected _state: KeysState = {};
constructor(api: CardKeyboardStateAPI) {
this._api = api;
}
public initialize(): void {
const element = this._api.getCardElementManager().getElement();
element.addEventListener('keydown', this._handleKeydown);
element.addEventListener('keyup', this._handleKeyup);
element.addEventListener('blur', this._handleBlur);
}
public uninitialize(): void {
const element = this._api.getCardElementManager().getElement();
element.removeEventListener('keydown', this._handleKeydown);
element.removeEventListener('keyup', this._handleKeyup);
element.removeEventListener('blur', this._handleBlur);
}
protected _handleKeydown = (ev: KeyboardEvent): void => {
const keyObj = {
state: 'down' as const,
ctrl: ev.ctrlKey,
alt: ev.altKey,
meta: ev.metaKey,
shift: ev.shiftKey,
};
if (!isEqual(this._state[ev.key], keyObj)) {
this._state[ev.key] = keyObj;
this._processStateChange();
}
};
protected _handleKeyup = (ev: KeyboardEvent): void => {
if (ev.key in this._state && this._state[ev.key].state === 'down') {
this._state[ev.key].state = 'up';
this._processStateChange();
}
};
protected _handleBlur = (): void => {
if (Object.keys(this._state).length) {
// State is emptied if the element loses focus.
this._state = {};
this._processStateChange();
}
};
protected _processStateChange(): void {
this._api.getConditionsManager().setState({ keys: this._state });
}
}