initial commit
This commit is contained in:
commit
40cae008d8
191
.eslintrc.json
Normal file
191
.eslintrc.json
Normal file
@ -0,0 +1,191 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"airbnb",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier",
|
||||
"prettier/prettier",
|
||||
"plugin:import/typescript"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 9,
|
||||
"sourceType": "module",
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"plugins": [
|
||||
"react",
|
||||
"@typescript-eslint",
|
||||
"react-hooks"
|
||||
],
|
||||
"rules": {
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"react/jsx-uses-react": [
|
||||
"error"
|
||||
],
|
||||
"react/jsx-uses-vars": [
|
||||
"error"
|
||||
],
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
// Checks rules of Hooks
|
||||
"react-hooks/exhaustive-deps": [
|
||||
"warn",
|
||||
{
|
||||
"additionalHooks": ""
|
||||
}
|
||||
],
|
||||
// Checks effect dependencies
|
||||
"react/jsx-filename-extension": [
|
||||
"warn",
|
||||
{
|
||||
"extensions": [
|
||||
".tsx"
|
||||
]
|
||||
}
|
||||
],
|
||||
"import/extensions": [
|
||||
"error",
|
||||
"ignorePackages",
|
||||
{
|
||||
"js": "never",
|
||||
"jsx": "never",
|
||||
"ts": "never",
|
||||
"tsx": "never"
|
||||
}
|
||||
],
|
||||
"no-shadow": "off",
|
||||
"@typescript-eslint/no-shadow": [
|
||||
"error"
|
||||
],
|
||||
"lines-between-class-members": [
|
||||
"warn",
|
||||
"always",
|
||||
{
|
||||
"exceptAfterSingleLine": true
|
||||
}
|
||||
],
|
||||
"react/sort-comp": [
|
||||
"warn",
|
||||
{
|
||||
"order": [
|
||||
"static-variables",
|
||||
"instance-variables",
|
||||
"static-methods",
|
||||
"lifecycle",
|
||||
"render",
|
||||
"/^render.+$/",
|
||||
"instance-methods",
|
||||
"everything-else"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-return-assign": [
|
||||
"error",
|
||||
"except-parens"
|
||||
],
|
||||
"import/no-extraneous-dependencies": [
|
||||
"error",
|
||||
{
|
||||
"devDependencies": [
|
||||
"**/*",
|
||||
"src/pages/!(api)/**/*.tsx",
|
||||
"src/pages/**/*.tsx",
|
||||
"src/!(pages|models|app)/**/*.(tsx|ts)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"react/destructuring-assignment": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"ignoreClassFields": true
|
||||
}
|
||||
],
|
||||
"react/state-in-constructor": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"vars": "all",
|
||||
"ignoreRestSiblings": false,
|
||||
"argsIgnorePattern": "^_",
|
||||
"varsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"import/no-cycle": [
|
||||
"error",
|
||||
{
|
||||
"maxDepth": 1
|
||||
}
|
||||
],
|
||||
"no-promise-executor-return": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"no-console": "off",
|
||||
"no-use-before-define": "off",
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"import/order": "off",
|
||||
"import/prefer-default-export": "off",
|
||||
"react/prop-types": "off",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"react/jsx-props-no-spreading": "off",
|
||||
"react/jsx-boolean-value": "off",
|
||||
"no-plusplus": "off",
|
||||
"no-param-reassign": "off",
|
||||
"default-case": "off",
|
||||
"jsx-a11y/interactive-supports-focus": "off",
|
||||
"jsx-a11y/no-noninteractive-element-interactions": "off",
|
||||
"jsx-a11y/click-events-have-key-events": "off",
|
||||
"jsx-a11y/no-static-element-interactions": "off",
|
||||
"jsx-a11y/label-has-associated-control": "off",
|
||||
"react/require-default-props": "off"
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
},
|
||||
"import/resolver": {
|
||||
"typescript": {
|
||||
"extensions": [
|
||||
".js",
|
||||
".jsx",
|
||||
".ts",
|
||||
".tsx"
|
||||
]
|
||||
},
|
||||
"node": {
|
||||
"extensions": [
|
||||
".js",
|
||||
".jsx",
|
||||
".ts",
|
||||
".tsx"
|
||||
],
|
||||
"moduleDirectory": [
|
||||
"node_modules",
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
}
|
||||
}
|
||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
/node_modules/*
|
||||
node_modules/*
|
||||
|
||||
#idea-ide
|
||||
/.idea/*
|
||||
|
||||
/src/hotkeys.ts
|
||||
|
||||
dist
|
||||
2
.npnignore
Normal file
2
.npnignore
Normal file
@ -0,0 +1,2 @@
|
||||
/bin/
|
||||
boostrapReactMobile.ts
|
||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true
|
||||
}
|
||||
55
bin/build.js
Normal file
55
bin/build.js
Normal file
@ -0,0 +1,55 @@
|
||||
const path = require("path");
|
||||
const fs = require('fs');
|
||||
|
||||
const tmpFile = "./tmp/script.js";
|
||||
|
||||
function findNames(dir, excluded) {
|
||||
let names = {};
|
||||
if (excluded.includes(dir)) {
|
||||
return names;
|
||||
}
|
||||
|
||||
let files = fs.readdirSync(dir);
|
||||
files.forEach(file => {
|
||||
let stats = fs.statSync(dir + file);
|
||||
if (stats.isDirectory()) {
|
||||
let nameObject = findNames(dir + file + '/', excluded);
|
||||
names = Object.assign(names, nameObject);
|
||||
} else if ((file.endsWith(".ts") ) && !excluded.includes(dir + file)) {
|
||||
names[file.substring(0, file.length - 3)] = dir + file.substring(0, file.length - 3);
|
||||
}
|
||||
else if ((file.endsWith(".mjs") ) && !excluded.includes(dir + file)) {
|
||||
names[file.substring(0, file.length - 4)] = dir + file.substring(0, file.length - 4);
|
||||
}
|
||||
});
|
||||
return names;
|
||||
}
|
||||
|
||||
async function buildEntryPoints(fileOption, target) {
|
||||
const cutLengthFront = 0;
|
||||
|
||||
target = target || tmpFile;
|
||||
|
||||
const resultDir = path.resolve(process.cwd(), path.dirname(target));
|
||||
|
||||
let names = {};
|
||||
fileOption.input.forEach(dir => {
|
||||
Object.assign(names, findNames(dir + "/", []));
|
||||
});
|
||||
|
||||
let imports = '';
|
||||
for (let k in names) {
|
||||
imports += "export * from './" + path.relative(resultDir, path.resolve(process.cwd(), names[k].substring(cutLengthFront))) + "';\n";
|
||||
}
|
||||
|
||||
if (!fs.existsSync(resultDir)) {
|
||||
fs.mkdirSync(resultDir);
|
||||
}
|
||||
fs.writeFileSync(target, imports);
|
||||
}
|
||||
|
||||
buildEntryPoints({
|
||||
input: [
|
||||
path.resolve(process.cwd(), "src/"),
|
||||
],
|
||||
}, "./src/hotkeys.ts");
|
||||
39
bin/release.sh
Executable file
39
bin/release.sh
Executable file
@ -0,0 +1,39 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Exit when a command fails
|
||||
set -e
|
||||
|
||||
REPOSITORY=git@github.com:Ainias/js-helper.git
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "versioname not given!"
|
||||
exit;
|
||||
fi;
|
||||
|
||||
versionName=$1
|
||||
versionExists="$(git ls-remote $REPOSITORY refs/tags/"$versionName"| tr -d '\n')"
|
||||
|
||||
if [ -n "$versionExists" ]; then
|
||||
echo "Version existiert bereits!";
|
||||
exit 1;
|
||||
fi;
|
||||
WORKING_DIR=$(pwd)
|
||||
TMPDIR=$(mktemp -d)
|
||||
|
||||
cd "$TMPDIR";
|
||||
git clone $REPOSITORY project
|
||||
cd project
|
||||
|
||||
npm install
|
||||
npm run build
|
||||
git add -u
|
||||
git commit -m "pre-version-commit for version $versionName" || echo "no commit needed"
|
||||
npm version "$versionName"
|
||||
npm publish
|
||||
git push
|
||||
|
||||
cd "$WORKING_DIR"
|
||||
git pull;
|
||||
|
||||
echo "$TMPDIR"
|
||||
|
||||
101
bin/updateCopies.js
Normal file
101
bin/updateCopies.js
Normal file
@ -0,0 +1,101 @@
|
||||
const path = require("path");
|
||||
|
||||
const exec = require('child_process').exec;
|
||||
const fs = require('fs');
|
||||
|
||||
const packageName = require("../package.json").name;
|
||||
|
||||
let pathsToProjects = [
|
||||
"/Users/sguenter/Projekte/Privat/dnd",
|
||||
// "/home/silas/Projekte/web/nextjsTest/poc-nextjs",
|
||||
// "/home/silas/Projekte/web/project-echo",
|
||||
// "/home/silas/Projekte/web/smd-mail",
|
||||
// "/home/silas/Projekte/web/dnd",
|
||||
// "/home/silas/Projekte/web/bat",
|
||||
// "/home/silas/Projekte/web/typeorm-sync",
|
||||
// "/home/silas/Projekte/web/typeorm-sync-nextjs",
|
||||
// "/home/silas/Projekte/web/worktime",
|
||||
// "/home/silas/Projekte/web/TaskList",
|
||||
// "/home/silas/Projekte/web/hoffnungsfest",
|
||||
// "/home/silas/Projekte/web/geometry",
|
||||
// "/home/silas/Projekte/web/react-bootstrap-mobile",
|
||||
// "/home/silas/Projekte/web/react-bootstrap-mobile",
|
||||
// "/home/silas/Projekte/chrome/dmscreen",
|
||||
// "/home/silas/Projekte/web/smd-mail",
|
||||
// "/home/silas/Projekte/web/prayercircle",
|
||||
// "/home/silas/Projekte/Web/stories",
|
||||
// "/home/silas/Projekte/web/cordova-sites",
|
||||
// "/home/silas/Projekte/web/cordova-sites-easy-sync",
|
||||
// "/home/silas/Projekte/Web/cordova-sites-user-management",
|
||||
// "/home/silas/Projekte/i9/mbb",
|
||||
// "/home/silas/Projekte/Web/bible-lexicon",
|
||||
|
||||
// "/var/www/i9/mbb",
|
||||
// "/home/silas/PhpstormProjects/cordova-sites-user-management",
|
||||
// "/home/silas/PhpstormProjects/project-echo",
|
||||
];
|
||||
|
||||
const deleteFolderRecursive = function(path) {
|
||||
if (fs.existsSync(path)) {
|
||||
fs.readdirSync(path).forEach(function(file, index){
|
||||
let curPath = path + "/" + file;
|
||||
if (fs.lstatSync(curPath).isDirectory()) { // recurse
|
||||
deleteFolderRecursive(curPath);
|
||||
} else { // delete file
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(path);
|
||||
}
|
||||
};
|
||||
|
||||
async function execPromise(command) {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("executing " + command + "...");
|
||||
exec(command, (err, stdout, stderr) => {
|
||||
console.log(stdout);
|
||||
console.log(stderr);
|
||||
if (err) {
|
||||
reject([err, stdout, stderr]);
|
||||
} else {
|
||||
resolve([stdout, stderr]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
execPromise("npm pack").then(async (std) => {
|
||||
let thisPath = process.cwd();
|
||||
let name = std[0].trim();
|
||||
let pathToTar = path.resolve(thisPath, name);
|
||||
|
||||
if (!fs.existsSync("tmp")) {
|
||||
fs.mkdirSync("tmp");
|
||||
}
|
||||
process.chdir("tmp");
|
||||
await execPromise("tar -xvzf " + pathToTar + " -C ./");
|
||||
process.chdir("package");
|
||||
fs.unlinkSync("package.json");
|
||||
|
||||
let promise = Promise.resolve();
|
||||
pathsToProjects.forEach((project) => {
|
||||
promise = promise.then(async () => {
|
||||
let resultDir = path.resolve(project, "node_modules", packageName);
|
||||
console.log(resultDir, fs.existsSync(resultDir));
|
||||
if (!fs.existsSync(resultDir)) {
|
||||
fs.mkdirSync(resultDir);
|
||||
}
|
||||
return execPromise("cp -r ./* "+resultDir);
|
||||
});
|
||||
});
|
||||
await promise;
|
||||
|
||||
process.chdir(thisPath);
|
||||
fs.unlinkSync(name);
|
||||
deleteFolderRecursive("tmp");
|
||||
// fs.unlinkSync("tmp");
|
||||
|
||||
console.log("done!");
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
});
|
||||
32
package.json
Normal file
32
package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@ainias42/hotkeys",
|
||||
"version": "0.0.1",
|
||||
"description": "Hotkey manager",
|
||||
"main": "dist/hotkeys",
|
||||
"scripts": {
|
||||
"build": "node bin/build.js & tsc",
|
||||
"update packages": "npm run build && node bin/updateCopies.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Silas Günther",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.7.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||
"@typescript-eslint/parser": "^6.7.3",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "^5.2.2",
|
||||
"@ainias42/js-helper": "^0.8.9"
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
||||
5
src/AffectedEnum.ts
Normal file
5
src/AffectedEnum.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum AffectedEnum {
|
||||
NOT_FULL_FILLED = 0,
|
||||
FULL_FILLED = 1,
|
||||
FULL_FILLED_AND_CHANGED,
|
||||
}
|
||||
8
src/HotkeyDefinitionType.ts
Normal file
8
src/HotkeyDefinitionType.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { URecord } from '@ainias42/js-helper';
|
||||
|
||||
export const specialKeys = ['meta', 'control', 'alt', 'shift', 'tab'] as const;
|
||||
|
||||
export type HotkeyDefinitionType = {
|
||||
keys: string[];
|
||||
ignoreFormElements?: boolean;
|
||||
} & URecord<(typeof specialKeys)[number], boolean>;
|
||||
9
src/HotkeyListener.ts
Normal file
9
src/HotkeyListener.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { AffectedEnum } from './AffectedEnum';
|
||||
|
||||
export type HotkeyListenerEvent<SubKeys extends string | symbol | number> = {
|
||||
event: KeyboardEvent;
|
||||
type: 'keydown' | 'keyup';
|
||||
subKeys: Record<SubKeys, AffectedEnum>;
|
||||
};
|
||||
|
||||
export type HotkeyListener<SubKeys extends string | symbol | number> = (ev: HotkeyListenerEvent<SubKeys>) => unknown;
|
||||
171
src/HotkeyManager.ts
Normal file
171
src/HotkeyManager.ts
Normal file
@ -0,0 +1,171 @@
|
||||
import { HotkeyDefinitionType, specialKeys } from './HotkeyDefinitionType';
|
||||
import { HotkeyListener } from './HotkeyListener';
|
||||
import { JsonHelper, ObjectHelper } from '@ainias42/js-helper';
|
||||
import { AffectedEnum } from './AffectedEnum';
|
||||
|
||||
type HotkeyEntry<SubKeys extends string> = {
|
||||
keys: HotkeyDefinitionType[];
|
||||
subKeys: { [key in SubKeys]: HotkeyDefinitionType[] };
|
||||
callbacks: HotkeyListener<SubKeys>[];
|
||||
};
|
||||
|
||||
export class HotkeyManager<HotkeyConfig extends Record<string, HotkeyEntry<string>>> {
|
||||
private keyPressedMap = new Map<string, boolean>();
|
||||
private hotkeys: HotkeyConfig;
|
||||
private enabled = true;
|
||||
|
||||
constructor(hotkeys: HotkeyConfig) {
|
||||
this.hotkeys = hotkeys;
|
||||
this.addKeyListeners();
|
||||
}
|
||||
|
||||
private static isFormElement(element: EventTarget | null) {
|
||||
return (
|
||||
element instanceof HTMLInputElement ||
|
||||
element instanceof HTMLSelectElement ||
|
||||
element instanceof HTMLTextAreaElement
|
||||
);
|
||||
}
|
||||
|
||||
private static isEqual(a: HotkeyDefinitionType, b: HotkeyDefinitionType) {
|
||||
return JsonHelper.deepEqual(a, b);
|
||||
}
|
||||
|
||||
addListener<HotkeyName extends keyof HotkeyConfig>(
|
||||
hotkeyName: HotkeyName,
|
||||
callback: HotkeyListener<keyof HotkeyConfig[HotkeyName]['subKeys']>,
|
||||
) {
|
||||
const { callbacks } = this.hotkeys[hotkeyName];
|
||||
callbacks.push(callback);
|
||||
return () => {
|
||||
const index = callbacks.indexOf(callback);
|
||||
if (index > -1) {
|
||||
callbacks.splice(index, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
addHotKeyDefinition(hotkey: keyof HotkeyConfig, definition: HotkeyDefinitionType) {
|
||||
this.hotkeys[hotkey].keys.push(definition);
|
||||
}
|
||||
|
||||
removeHotkeyDefinition(hotkey: keyof HotkeyConfig, definition: HotkeyDefinitionType) {
|
||||
this.hotkeys[hotkey].keys = this.hotkeys[hotkey].keys.filter((key) => !HotkeyManager.isEqual(key, definition));
|
||||
}
|
||||
|
||||
setHotkeyDefinitions(hotkey: keyof HotkeyConfig, definitions: HotkeyDefinitionType[]) {
|
||||
this.hotkeys[hotkey].keys = definitions;
|
||||
}
|
||||
|
||||
addSubKeyDefinition<HotkeyName extends keyof HotkeyConfig>(
|
||||
hotkey: HotkeyName,
|
||||
subkey: keyof HotkeyConfig[HotkeyName]['subKeys'],
|
||||
definition: HotkeyDefinitionType,
|
||||
) {
|
||||
this.hotkeys[hotkey].subKeys[subkey as string].push(definition);
|
||||
}
|
||||
|
||||
removeSubKeyDefinition<HotkeyName extends keyof HotkeyConfig>(
|
||||
hotkey: HotkeyName,
|
||||
subkey: keyof HotkeyConfig[HotkeyName]['subKeys'],
|
||||
definition: HotkeyDefinitionType,
|
||||
) {
|
||||
const { subKeys } = this.hotkeys[hotkey];
|
||||
subKeys[subkey as string] = subKeys[subkey as string].filter((key) => !HotkeyManager.isEqual(key, definition));
|
||||
}
|
||||
|
||||
setSubKeyDefinitions<HotkeyName extends keyof HotkeyConfig>(
|
||||
hotkey: HotkeyName,
|
||||
subkey: keyof HotkeyConfig[HotkeyName]['subKeys'],
|
||||
definitions: HotkeyDefinitionType[],
|
||||
) {
|
||||
this.hotkeys[hotkey].subKeys[subkey as string] = definitions;
|
||||
}
|
||||
|
||||
getConfig() {
|
||||
return this.hotkeys;
|
||||
}
|
||||
|
||||
private addKeyListeners() {
|
||||
window.addEventListener('keydown', (e) => {
|
||||
this.keyPressedMap.set(e.key.toLowerCase(), true);
|
||||
this.checkHotkeys(e, 'keydown');
|
||||
});
|
||||
window.addEventListener('keyup', (e) => {
|
||||
// Check first as afterwards the keys are not set
|
||||
this.checkHotkeys(e, 'keyup');
|
||||
this.keyPressedMap.set(e.key.toLowerCase(), false);
|
||||
if (e.key === 'Meta') {
|
||||
this.keyPressedMap.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private checkHotkeyDefinition(keyDefinition: HotkeyDefinitionType, event: KeyboardEvent): AffectedEnum {
|
||||
if (!this.enabled) {
|
||||
return AffectedEnum.NOT_FULL_FILLED;
|
||||
}
|
||||
if (keyDefinition.ignoreFormElements !== false && HotkeyManager.isFormElement(event.target)) {
|
||||
return AffectedEnum.NOT_FULL_FILLED;
|
||||
}
|
||||
|
||||
if (keyDefinition.keys.some((key) => this.keyPressedMap.get(key) !== true)) {
|
||||
return AffectedEnum.NOT_FULL_FILLED;
|
||||
}
|
||||
|
||||
if (
|
||||
specialKeys.some(
|
||||
(key) => keyDefinition[key] !== undefined && this.keyPressedMap.get(key) !== keyDefinition[key],
|
||||
)
|
||||
) {
|
||||
return AffectedEnum.NOT_FULL_FILLED;
|
||||
}
|
||||
|
||||
// Check if key is inside keyDefinition
|
||||
const changedKey = event.key.toLowerCase();
|
||||
if (!keyDefinition.keys.includes(changedKey) && !(changedKey in keyDefinition)) {
|
||||
return AffectedEnum.FULL_FILLED;
|
||||
}
|
||||
|
||||
return AffectedEnum.FULL_FILLED_AND_CHANGED;
|
||||
}
|
||||
|
||||
private getKeyReducer(event: KeyboardEvent) {
|
||||
return (acc: AffectedEnum, key: HotkeyDefinitionType) => {
|
||||
if (acc === AffectedEnum.FULL_FILLED_AND_CHANGED) {
|
||||
return acc;
|
||||
}
|
||||
return Math.max(acc, this.checkHotkeyDefinition(key, event));
|
||||
};
|
||||
}
|
||||
|
||||
private checkHotkeys(event: KeyboardEvent, type: 'keydown' | 'keyup') {
|
||||
ObjectHelper.values(this.hotkeys).forEach((hotkey) => {
|
||||
const isAffected = hotkey.keys.reduce(this.getKeyReducer(event), AffectedEnum.NOT_FULL_FILLED);
|
||||
if (isAffected !== AffectedEnum.NOT_FULL_FILLED) {
|
||||
const subKeys = ObjectHelper.entries(hotkey.subKeys).reduce(
|
||||
(acc, [key, value]) => {
|
||||
acc[key] = value.reduce(this.getKeyReducer(event), AffectedEnum.NOT_FULL_FILLED);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, AffectedEnum>,
|
||||
);
|
||||
|
||||
if (
|
||||
isAffected === AffectedEnum.FULL_FILLED_AND_CHANGED ||
|
||||
ObjectHelper.values(subKeys).some((value) => value === AffectedEnum.FULL_FILLED_AND_CHANGED)
|
||||
) {
|
||||
hotkey.callbacks.forEach((callback) => callback({ event, subKeys, type }));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
39
tsconfig.json
Normal file
39
tsconfig.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"alwaysStrict": true,
|
||||
"baseUrl": "./src",
|
||||
"declaration": true,
|
||||
"isolatedModules": true,
|
||||
"lib": [
|
||||
"es6",
|
||||
"es2016",
|
||||
"es2017",
|
||||
"es2021",
|
||||
"dom"
|
||||
],
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "./dist",
|
||||
"resolveJsonModule": true,
|
||||
"sourceMap": true,
|
||||
"strict": false,
|
||||
"strictFunctionTypes": false,
|
||||
"strictNullChecks": true,
|
||||
"target": "es6",
|
||||
},
|
||||
"include": [
|
||||
"./src/hotkeys.ts",
|
||||
"./src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"bin",
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user