From 7baf9ad009bfa9e5fbd3e06f73617588d7eb2f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Kiss?= Date: Fri, 13 Oct 2017 12:25:57 +0200 Subject: [PATCH] fix(user-config): Layer switcher key behaviour on non-base layers (#440) * refactor(user-config): Optimize imports * feat(user-config): Clone SwitchLayerAction to destination layer * fix(user-config): Fix Keymap SwitchLayerAction normalization * test(user-config): Remove spy callThrough * build: Add uhk-common test runner * build: delete test serialization files * fix(user-config): Add missing "type": "basic" properties to the user-config.json * test(user-config): Add KeyMacroAction tests * fix(user-config): Delete SwitchLayerAction from non destination layer * fix(user-config): Keymap normalize delete SwitchLayerActions from non base layers * ci: turn of uhk-web tests * ci: turn off karma watch mode in uhk-web test --- .travis.yml | 4 + appveyor.yml | 2 + package.json | 5 +- .../user-config-serialized.bin | Bin 3871 -> 0 bytes .../user-config-serialized.json | 7442 ----------------- packages/test-serializer/user-config.bin | Bin 3871 -> 0 bytes .../config-serializer/config-items/keymap.ts | 75 +- .../macro-action/key-macro-action.spec.ts | 29 + .../config-items/macro-action/keymap.spec.ts | 257 + .../config-items/user-configuration.spec.ts | 1157 --- packages/uhk-web/package.json | 3 +- .../uhk-web/src/app/services/user-config.json | 8 +- .../store/reducers/user-configuration.spec.ts | 396 + .../app/store/reducers/user-configuration.ts | 43 +- packages/uhk-web/test/user-config-helper.ts | 164 + web/src/app.module.ts | 0 16 files changed, 948 insertions(+), 8637 deletions(-) delete mode 100644 packages/test-serializer/user-config-serialized.bin delete mode 100644 packages/test-serializer/user-config-serialized.json delete mode 100644 packages/test-serializer/user-config.bin create mode 100644 packages/uhk-common/src/config-serializer/config-items/macro-action/key-macro-action.spec.ts create mode 100644 packages/uhk-common/src/config-serializer/config-items/macro-action/keymap.spec.ts create mode 100644 packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts create mode 100644 packages/uhk-web/test/user-config-helper.ts delete mode 100644 web/src/app.module.ts diff --git a/.travis.yml b/.travis.yml index 2ff64b02..b75b8499 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,12 +25,16 @@ addons: - libudev-dev - build-essential - libusb-1.0-0-dev + chrome: stable install: - nvm install - npm install before_script: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - sleep 3 # give xvfb some time to start - npm run build - npm run lint diff --git a/appveyor.yml b/appveyor.yml index 72a42c71..1d31cbd8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,7 @@ shallow_clone: true install: - ps: Install-Product node $env:nodejs_version + - choco install chromium - set CI=true - set PATH=%APPDATA%\npm;%PATH% - node -v @@ -27,5 +28,6 @@ install: test_script: - appveyor-retry npm run build - npm run lint + - set CHROME_BIN="C:\Program Files (x86)\Chromium\Application\chrome.exe" - npm run test - npm run release diff --git a/package.json b/package.json index 19055167..8fe24876 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,10 @@ }, "scripts": { "postinstall": "lerna bootstrap", - "test": "lerna exec --scope test-serializer npm test", + "test":"run-p -sn test:test-serializer test:uhk-common test:uhk-web", + "test:test-serializer": "lerna exec --scope test-serializer npm test", + "test:uhk-common": "lerna exec --scope uhk-common npm test", + "test:uhk-web": "lerna exec --scope uhk-web npm test", "lint": "run-s -scn lint:ts lint:style", "lint:ts": "run-p -sn lint:ts:electron-main lint:ts:electron-renderer lint:ts:web lint:ts:test-serializer lint:ts:uhk-usb", "lint:ts:electron-main": "tslint --type-check --project ./packages/uhk-agent/tsconfig.json", diff --git a/packages/test-serializer/user-config-serialized.bin b/packages/test-serializer/user-config-serialized.bin deleted file mode 100644 index 9ff0f1d361ed653410de4d8ae8d59bebaaa7ddbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3871 zcmds)-E!MR6vxkhCHbq48zm&JowP`DDfws$nS>I)BgbkI99xMCWO~6xm}Vx-FjIzP z7`W@S!wYc16%PRyd^`dV!3Dz|JOP*dS8F-015MrG!bM|irCsgWv%5c?^Or3EoL`in z(E8FlxO?}r!{g&I@1B1<_;mb3_i*B?^?X>YA8p+K>sM)rc*#w^BA!bPlL6?3=%7vs2zSFxr%!F7-RK-9Xruf{=3uiy%vhX)@4 z?-ubKs>oqVQ1&=M8`H=l&zUOTUB(PDsK8NBIc3vMVo%tnL~2+^h&ndVK!hEvDnM{r-5Vt+va48)4`Rvi)CrpdU}zK;P~dh=5rs8kvWz@oC=-WiVl&5WbqGe4 z+j*H&KOc zo}swGxZ9Udly4772E)wgCY0r^PzrH7TG|TRji~XDaQutf(7QV*H<+ZD-*8?17jlCs z1tz<8ZqFxjjjO}bE!+GY9rM>3;>Rt%AUlN zHsLW+<54eE&F^XrNu&n5CF)7AqnEX9w3A?4`>-lHW_J~bUSHZ0*4J3*BcS96IB#C1 znnMpx)e+>WCJJou_yaqo+rp~kV25sJ_6Tx4#lqgEtC@B>sMQR2rPPe>)Z?(zSZu}b z-;NA2slBtV^gBY`;U%6t86m{$v3m4r0MV=Y)O={+^B6kPW$N3T9vn6WI)BgbkI99xMCWO~6xm}Vx-FjIzP z7`W@S!wYc16%PRyd^`dV!3Dz|JOP*dS8F-015MrG!bM|irCsgWv%5c?^Or3EoL`in z(E8FlxO?}r!{g&I@1B1<_;mb3_i*B?^?X>YA8p+K>sM)rc*#w^BA!bPlL6?3=%7vs2zSFxr%!F7-RK-9Xruf{=3uiy%vhX)@4 z?-ubKs>oqVQ1&=M8`H=l&zUOTUB(PDsK8NBIc3vMVo%tnL~2+^h&ndVK!hEvDnM{r-5Vt+va48)4`Rvi)CrpdU}zK;P~dh=5rs8kvWz@oC=-WiVl&5WbqGe4 z+j*H&KOc zo}swGxZ9Udly4772E)wgCY0r^PzrH7TG|TRji~XDaQutf(7QV*H<+ZD-*8?17jlCs z1tz<8ZqFxjjjO}bE!+GY9rM>3;>Rt%AUlN zHsLW+<54eE&F^XrNu&n5CF)7AqnEX9w3A?4`>-lHW_J~bUSHZ0*4J3*BcS96IB#C1 znnMpx)e+>WCJJou_yaqo+rp~kV25sJ_6Tx4#lqgEtC@B>sMQR2rPPe>)Z?(zSZu}b z-;NA2slBtV^gBY`;U%6t86m{$v3m4r0MV=Y)O={+^B6kPW$N3T9vn6W { - if (keyAction instanceof SwitchLayerAction) { - return undefined; - } - return keyAction; - }); - } + if (this.layers.length < 1) { + return; } - // Adds the SwitchLayerActions from the base layer to any none base layer - const baseLayerModules = this.layers[0].modules; - for (let i = 0; i < baseLayerModules.length; ++i) { - baseLayerModules[i].keyActions.forEach((keyAction: KeyAction, keyActionIndex: number) => { - if (keyAction instanceof SwitchLayerAction) { - for (let j = 1; j < this.layers.length; ++j) { - this.layers[j].modules[i].keyActions[keyActionIndex] = new SwitchLayerAction(keyAction); + for (let moduleId = 0; moduleId < this.layers[0].modules.length && moduleId < 2; moduleId++) { + const baseModule = this.layers[0].modules[moduleId]; + for (let keyActionId = 0; keyActionId < baseModule.keyActions.length; keyActionId++) { + const baseKeyAction = baseModule.keyActions[keyActionId]; + + if (baseKeyAction instanceof SwitchLayerAction) { + const destinationLayerId = baseKeyAction.layer + 1; + if (this.layers.length < destinationLayerId) { + // TODO: What should we do??? + console.error(`${this.name} has not enough layer. Need: ${destinationLayerId}`); } } - }); + for (let currentLayerId = 1; currentLayerId < this.layers.length; currentLayerId++) { + const currentLayer = this.layers[currentLayerId]; + if (currentLayer.modules.length < moduleId) { + // TODO: What should we do??? + console.error(`${this.name}.layers[${currentLayerId}] has not enough module. Need: ${moduleId}`); + continue; + } + const currentModule = currentLayer.modules[moduleId]; + const currentKeyAction = currentModule.keyActions[keyActionId]; + + if (baseKeyAction instanceof SwitchLayerAction) { + if (currentLayerId - 1 === baseKeyAction.layer) { + if (currentKeyAction instanceof SwitchLayerAction) { + if (currentKeyAction.layer === baseKeyAction.layer && + currentKeyAction.isLayerToggleable === baseKeyAction.isLayerToggleable) { + continue; + } + // tslint:disable-next-line: max-line-length + const error = `${this.name}.layers[${currentLayerId}]modules[${moduleId}].keyActions[${keyActionId}]` + + ` is different switch layer. ${currentKeyAction} will be override with ${baseKeyAction}`; + console.warn(error); + } else { + // tslint:disable-next-line: max-line-length + const error = `${this.name}.layers[${currentLayerId}]modules[${moduleId}].keyActions[${keyActionId}]` + + ` is not switch layer. ${currentKeyAction} will be override with ${baseKeyAction}`; + console.warn(error); + } + currentModule.keyActions[keyActionId] = KeyActionHelper.createKeyAction(baseKeyAction); + } + } + else { + if (currentKeyAction instanceof SwitchLayerAction) { + // tslint:disable-next-line: max-line-length + const error = `${this.name}.layers[${currentLayerId}]modules[${moduleId}].keyActions[${keyActionId}]` + + ` is switch layer action, but the base key action is not switch layer action, so will delete`; + console.warn(error); + currentModule.keyActions[keyActionId] = null; + } + } + } + } } } - } diff --git a/packages/uhk-common/src/config-serializer/config-items/macro-action/key-macro-action.spec.ts b/packages/uhk-common/src/config-serializer/config-items/macro-action/key-macro-action.spec.ts new file mode 100644 index 00000000..80cf8e8d --- /dev/null +++ b/packages/uhk-common/src/config-serializer/config-items/macro-action/key-macro-action.spec.ts @@ -0,0 +1,29 @@ +import { KeyMacroAction } from './key-macro-action'; +import { binaryDefaultHelper, jsonDefaultHelper } from '../../../../test/serializer-test-helper'; +import { MacroSubAction } from './macro-action'; +import { KeystrokeType } from '../key-action'; + +describe('key-macro-action', () => { + it('should be instantiate', () => { + const action = new KeyMacroAction(); + expect(action).toBeTruthy(); + }); + + describe('full serialization', () => { + it('should json match', () => { + const action = new KeyMacroAction(); + action.action = MacroSubAction.hold; + action.type = KeystrokeType.basic; + action.scancode = 100; + jsonDefaultHelper(action); + }); + + it('should binary match', () => { + const action = new KeyMacroAction(); + action.action = MacroSubAction.hold; + action.type = KeystrokeType.basic; + action.scancode = 100; + binaryDefaultHelper(action); + }); + }); +}); diff --git a/packages/uhk-common/src/config-serializer/config-items/macro-action/keymap.spec.ts b/packages/uhk-common/src/config-serializer/config-items/macro-action/keymap.spec.ts new file mode 100644 index 00000000..02b09d7a --- /dev/null +++ b/packages/uhk-common/src/config-serializer/config-items/macro-action/keymap.spec.ts @@ -0,0 +1,257 @@ +import { UserConfiguration } from '../user-configuration'; + +describe('keymap', () => { + it('should normalize SwitchLayerAction if non base layer action is not SwitchLayerAction', () => { + const inputJsonConfig = { + dataModelVersion: 1, + moduleConfigurations: [], + macros: [], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 44 + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + } + ] + } + ] + }; + const expectedJsonConfig = { + dataModelVersion: 1, + moduleConfigurations: [], + macros: [], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + } + ] + } + ] + }; + spyOn(console, 'warn'); + const inputUserConfig = new UserConfiguration().fromJsonObject(inputJsonConfig); + + expect(inputUserConfig.toJsonObject()).toEqual(expectedJsonConfig); + // tslint:disable-next-line: max-line-length + expect(console.warn).toHaveBeenCalledWith('QWERTY.layers[1]modules[0].keyActions[0] is not switch layer. will be override with '); + }); + + it('should normalize SwitchLayerAction if non base layer action is other SwitchLayerAction', () => { + const inputJsonConfig = { + dataModelVersion: 1, + moduleConfigurations: [], + macros: [], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'fn', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + } + ] + } + ] + }; + const expectedJsonConfig = { + dataModelVersion: 1, + moduleConfigurations: [], + macros: [], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + }, + { + modules: [{ + id: 0, + pointerRole: 'move', + keyActions: [ + null + ] + }] + } + ] + } + ] + }; + spyOn(console, 'warn'); + const inputUserConfig = new UserConfiguration().fromJsonObject(inputJsonConfig); + + expect(inputUserConfig.toJsonObject()).toEqual(expectedJsonConfig); + // tslint:disable-next-line: max-line-length + expect(console.warn).toHaveBeenCalledWith('QWERTY.layers[1]modules[0].keyActions[0] is different switch layer. will be override with '); + }); +}); diff --git a/packages/uhk-common/src/config-serializer/config-items/user-configuration.spec.ts b/packages/uhk-common/src/config-serializer/config-items/user-configuration.spec.ts index beec45e1..ce0bcf20 100644 --- a/packages/uhk-common/src/config-serializer/config-items/user-configuration.spec.ts +++ b/packages/uhk-common/src/config-serializer/config-items/user-configuration.spec.ts @@ -39,1163 +39,6 @@ describe('user-configuration', () => { ] }); }); - - xit('', () => { - jsonTester({ - dataModelVersion: 1, - moduleConfigurations: [], - macros: [], - keymaps: [ - { - isDefault: false, - abbreviation: '1HA', - name: 'ONE-HANDED', - description: '', - layers: [ - { - modules: [ - { - id: 0, - pointerRole: 'move', - keyActions: [ - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 36 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 37 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 38 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 39 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 45 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 46 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 42 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 24 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 12 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 18 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 19 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 47 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 48 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 49 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 28 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 13 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 14 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 15 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 51 - }, - { - keyActionType: 'switchLayer', - layer: 'mouse', - toggle: false - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 40 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 11 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 17 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 16 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 54 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 55 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 56 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 32 - }, - null, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 44 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 64 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 128 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 16 - } - ] - }, - { - id: 1, - pointerRole: 'move', - keyActions: [ - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 53 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 30 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 31 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 32 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 33 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 34 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 35 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 43 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 20 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 26 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 8 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 21 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 23 - }, - { - keyActionType: 'switchLayer', - layer: 'mouse', - toggle: false - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 4 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 22 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 7 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 9 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 10 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 2 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 29 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 27 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 6 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 25 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 5 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 1 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 8 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 4 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 44 - }, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - null - ] - }, - { - id: 2, - pointerRole: 'scroll', - keyActions: [] - } - ] - }, - { - modules: [ - { - id: 0, - pointerRole: 'none', - keyActions: [ - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 35 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 34 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 33 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 32 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 31 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 30 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 53 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 21 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 8 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 26 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 20 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 43 - }, - null, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 23 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 9 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 7 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 22 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 4 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 19 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 10 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 5 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 25 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 6 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 27 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 29 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 32 - }, - null, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 64 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 128 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 16 - } - ] - }, - { - id: 1, - pointerRole: 'none', - keyActions: [ - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 42 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 46 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 45 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 39 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 38 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 37 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 36 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 49 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 19 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 18 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 12 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 24 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 28 - }, - { - keyActionType: 'switchLayer', - layer: 'mouse', - toggle: false - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 51 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 15 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 14 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 13 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 11 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 2 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 56 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 55 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 54 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 16 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 17 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 1 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 8 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 4 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 40 - }, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - null - ] - } - ] - }, - { - modules: [ - { - id: 0, - pointerRole: 'move', - keyActions: [ - null, - null, - null, - null, - null, - null, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 74 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 82 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 77 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 76 - }, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'WOR' - }, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'KAP' - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 75 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 80 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 81 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 79 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 73 - }, - { - keyActionType: 'keystroke', - type: 'system', - scancode: 131 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 78 - }, - null, - null, - null, - null, - { - keyActionType: 'keystroke', - type: 'system', - scancode: 130 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 32 - }, - null, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 64 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 128 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 16 - } - ] - }, - { - id: 1, - pointerRole: 'scroll', - keyActions: [ - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'QWR' - }, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'DVO' - }, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'COL' - }, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'WOR' - }, - null, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'KAP' - }, - { - keyActionType: 'switchKeymap', - keymapAbbreviation: 'EGG' - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 75 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 74 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 82 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 77 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 76 - }, - { - keyActionType: 'switchLayer', - layer: 'mouse', - toggle: false - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 78 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 80 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 81 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 79 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 73 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 2 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 52 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 47 - }, - { - keyActionType: 'keystroke', - type: 'basic', - scancode: 48 - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 1 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 8 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 4 - }, - null, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - null - ] - } - ] - }, - { - modules: [ - { - id: 0, - pointerRole: 'move', - keyActions: [ - null, - null, - null, - null, - null, - null, - null, - { - keyActionType: 'mouse', - mouseAction: 'leftClick' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveUp' - }, - { - keyActionType: 'mouse', - mouseAction: 'rightClick' - }, - null, - null, - null, - null, - { - keyActionType: 'mouse', - mouseAction: 'scrollUp' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveLeft' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveDown' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveRight' - }, - null, - null, - null, - { - keyActionType: 'mouse', - mouseAction: 'scrollDown' - }, - null, - { - keyActionType: 'mouse', - mouseAction: 'scrollLeft' - }, - { - keyActionType: 'mouse', - mouseAction: 'middleClick' - }, - { - keyActionType: 'mouse', - mouseAction: 'scrollRight' - }, - null, - null, - null, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 64 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 128 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 16 - } - ] - }, - { - id: 1, - pointerRole: 'move', - keyActions: [ - null, - null, - null, - null, - null, - null, - null, - null, - { - keyActionType: 'mouse', - mouseAction: 'scrollUp' - }, - { - keyActionType: 'mouse', - mouseAction: 'leftClick' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveUp' - }, - { - keyActionType: 'mouse', - mouseAction: 'rightClick' - }, - null, - null, - { - keyActionType: 'switchLayer', - layer: 'mouse', - toggle: false - }, - { - keyActionType: 'mouse', - mouseAction: 'scrollDown' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveLeft' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveDown' - }, - { - keyActionType: 'mouse', - mouseAction: 'moveRight' - }, - null, - null, - null, - null, - null, - { - keyActionType: 'mouse', - mouseAction: 'scrollLeft' - }, - { - keyActionType: 'mouse', - mouseAction: 'middleClick' - }, - { - keyActionType: 'mouse', - mouseAction: 'scrollRight' - }, - null, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 1 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 8 - }, - { - keyActionType: 'keystroke', - type: 'basic', - modifierMask: 4 - }, - null, - { - keyActionType: 'switchLayer', - layer: 'fn', - toggle: false - }, - { - keyActionType: 'switchLayer', - layer: 'mod', - toggle: false - }, - null - ] - } - ] - } - ] - } - ] - }); - }); }); function jsonTester(json: any): void { diff --git a/packages/uhk-web/package.json b/packages/uhk-web/package.json index 3d1190a5..8141c729 100644 --- a/packages/uhk-web/package.json +++ b/packages/uhk-web/package.json @@ -6,7 +6,7 @@ "ng": "ng", "start": "ng serve", "build": "ng build --prod --aot --base-href=\"\"", - "test": "ng test", + "test": "ng test --watch false", "lint": "ng lint", "e2e": "ng e2e", "build:renderer": "webpack --config webpack.config.js", @@ -66,6 +66,7 @@ "karma-jasmine": "1.1.0", "karma-jasmine-html-reporter": "0.2.2", "less-loader": "4.0.5", + "lodash": "4.17.4", "ng2-dragula": "1.5.0", "ng2-select2": "1.0.0-beta.10", "ngrx-store-freeze": "0.1.9", diff --git a/packages/uhk-web/src/app/services/user-config.json b/packages/uhk-web/src/app/services/user-config.json index 4e3c7789..d7013dca 100644 --- a/packages/uhk-web/src/app/services/user-config.json +++ b/packages/uhk-web/src/app/services/user-config.json @@ -7074,7 +7074,8 @@ "macroActionType": "key", "action": "press", "scancode": 15, - "modifierMask": 1 + "modifierMask": 1, + "type": "basic" }, { "macroActionType": "text", @@ -7083,7 +7084,8 @@ { "macroActionType": "key", "action": "press", - "scancode": 40 + "scancode": 40, + "type": "basic" } ] }, @@ -7099,4 +7101,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts b/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts new file mode 100644 index 00000000..7fb36c51 --- /dev/null +++ b/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts @@ -0,0 +1,396 @@ +import { reducer, initialState } from './user-configuration'; +import { KeystrokeAction, KeystrokeType, SwitchLayerAction, UserConfiguration, LayerName, Keymap } from 'uhk-common'; + +import { getDefaultUserConfig } from '../../../../test/user-config-helper'; +import { KeymapActions } from '../actions'; + +describe('user-configuration reducer', () => { + it('should be initiate with default state', () => { + const result = reducer(undefined, {} as any); + expect(result).toEqual(initialState); + }); + + describe('SAVE_KEY', () => { + it('should process KeyStrokeAction', () => { + const defaultUserConfig = new UserConfiguration().fromJsonObject(getDefaultUserConfig()); + const state = new UserConfiguration().fromJsonObject(getDefaultUserConfig()); + const keystrokeAction = new KeystrokeAction({_scancode: 100, type: KeystrokeType.basic} as any); + const saveKeyAction: KeymapActions.SaveKeyAction = { + type: KeymapActions.SAVE_KEY, + payload: { + keymap: new Keymap(defaultUserConfig.keymaps[0]), + layer: 0, + module: 0, + key: 0, + keyAction: keystrokeAction + } + }; + const result = reducer(state, saveKeyAction); + const expectedKeyAction = result.keymaps[0].layers[0].modules[0].keyActions[0]; + expect(expectedKeyAction).toEqual(keystrokeAction); + expect(result).not.toBe(defaultUserConfig); + // check key actions not changed on other layers + for (let i = 1; i < result.keymaps[0].layers.length; i++) { + const keyAction = result.keymaps[0].layers[i].modules[0].keyActions[0]; + const defaultKeyAction = defaultUserConfig.keymaps[0].layers[i].modules[0].keyActions[0]; + + expect(keyAction).toEqual(defaultKeyAction); + } + }); + + it('should copy the SwitchLayerAction to the destination layer', () => { + const defaultUserConfig = new UserConfiguration().fromJsonObject(getDefaultUserConfig()); + const state = new UserConfiguration().fromJsonObject(getDefaultUserConfig()); + const destinationLayerId = LayerName.mod; + const switchLayerAction = new SwitchLayerAction({isLayerToggleable: false, layer: destinationLayerId} as any); + const saveKeyAction: KeymapActions.SaveKeyAction = { + type: KeymapActions.SAVE_KEY, + payload: { + keymap: new Keymap(defaultUserConfig.keymaps[0]), + layer: 0, + module: 0, + key: 0, + keyAction: switchLayerAction + } + }; + const result = reducer(state, saveKeyAction); + expect(result).not.toBe(defaultUserConfig); + expect(result.toJsonObject()).toEqual({ + dataModelVersion: 4, + moduleConfigurations: [ + { + id: 1, + initialPointerSpeed: 1, + pointerAcceleration: 5, + maxPointerSpeed: 200 + } + ], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 37 + }, + { + 'keyActionType': 'switchLayer', + 'layer': 'mod', + 'toggle': false + } + ] + }, + { + id: 1, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 53 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 30 + }, + null + ] + }, + { + id: 2, + pointerRole: 'scroll', + keyActions: [] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'none', + keyActions: [ + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 65 + }, + { + 'keyActionType': 'switchLayer', + 'layer': 'mod', + 'toggle': false + } + ] + }, + { + id: 1, + pointerRole: 'none', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 41 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 58 + }, + null + ] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + }, + { + id: 1, + pointerRole: 'scroll', + keyActions: [ + null, + { + keyActionType: 'switchKeymap', + keymapAbbreviation: 'DVO' + }, + null + ] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + }, + { + id: 1, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + } + ] + } + ] + } + ], + macros: [] + }); + }); + + it('should copy the SwitchLayerAction to the destination layer and clear the modified', () => { + const defaultUserConfig = new UserConfiguration().fromJsonObject(getDefaultUserConfig()); + const state = new UserConfiguration().fromJsonObject(getDefaultUserConfig()); + const destinationLayerId = LayerName.fn; + const switchLayerAction = new SwitchLayerAction({isLayerToggleable: false, layer: destinationLayerId} as any); + const saveKeyAction: KeymapActions.SaveKeyAction = { + type: KeymapActions.SAVE_KEY, + payload: { + keymap: new Keymap(defaultUserConfig.keymaps[0]), + layer: 0, + module: 0, + key: 2, + keyAction: switchLayerAction + } + }; + const result = reducer(state, saveKeyAction); + expect(result).not.toBe(defaultUserConfig); + expect(result.toJsonObject()).toEqual({ + dataModelVersion: 4, + moduleConfigurations: [ + { + id: 1, + initialPointerSpeed: 1, + pointerAcceleration: 5, + maxPointerSpeed: 200 + } + ], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 36 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 37 + }, + { + 'keyActionType': 'switchLayer', + 'layer': 'fn', + 'toggle': false + } + ] + }, + { + id: 1, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 53 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 30 + }, + null + ] + }, + { + id: 2, + pointerRole: 'scroll', + keyActions: [] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'none', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 64 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 65 + }, + null + ] + }, + { + id: 1, + pointerRole: 'none', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 41 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 58 + }, + null + ] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + null, + null, + { + keyActionType: 'switchLayer', + layer: 'fn', + toggle: false + } + ] + }, + { + id: 1, + pointerRole: 'scroll', + keyActions: [ + null, + { + keyActionType: 'switchKeymap', + keymapAbbreviation: 'DVO' + }, + null + ] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + }, + { + id: 1, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + } + ] + } + ] + } + ], + macros: [] + }); + }); + + }); +}); diff --git a/packages/uhk-web/src/app/store/reducers/user-configuration.ts b/packages/uhk-web/src/app/store/reducers/user-configuration.ts index afcd276e..ba970066 100644 --- a/packages/uhk-web/src/app/store/reducers/user-configuration.ts +++ b/packages/uhk-web/src/app/store/reducers/user-configuration.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/map'; -import { Keymap, KeyActionHelper, Layer, Macro, Module, UserConfiguration } from 'uhk-common'; +import { KeyAction, Keymap, KeyActionHelper, Layer, Macro, Module, SwitchLayerAction, UserConfiguration } from 'uhk-common'; import { KeymapActions, MacroActions } from '../actions'; import { AppState } from '../index'; import { ActionTypes } from '../actions/user-config'; @@ -107,21 +107,31 @@ export function reducer(state = initialState, action: Action & { payload?: any } break; case KeymapActions.SAVE_KEY: { + const keyIndex: number = action.payload.key; + const layerIndex: number = action.payload.layer; + const moduleIndex: number = action.payload.module; + const newKeyAction = KeyActionHelper.createKeyAction(action.payload.keyAction); const newKeymap: Keymap = Object.assign(new Keymap(), action.payload.keymap); newKeymap.layers = newKeymap.layers.slice(); - const layerIndex: number = action.payload.layer; - const newLayer: Layer = Object.assign(new Layer(), newKeymap.layers[layerIndex]); - newKeymap.layers[layerIndex] = newLayer; + newKeymap.layers = newKeymap.layers.map((layer, index) => { + const newLayer = Object.assign(new Layer(), layer); - const moduleIndex: number = action.payload.module; - const newModule: Module = Object.assign(new Module(), newLayer.modules[moduleIndex]); - newLayer.modules = newLayer.modules.slice(); - newLayer.modules[moduleIndex] = newModule; - - const keyIndex: number = action.payload.key; - newModule.keyActions = newModule.keyActions.slice(); - newModule.keyActions[keyIndex] = KeyActionHelper.createKeyAction(action.payload.keyAction); + if (index === layerIndex) { + setKeyActionToLayer(newLayer, moduleIndex, keyIndex, newKeyAction); + } + // If the key action is a SwitchLayerAction then set the same SwitchLayerAction + // on the target layer + else if (newKeyAction instanceof SwitchLayerAction) { + if (index - 1 === newKeyAction.layer) { + const clonedAction = KeyActionHelper.createKeyAction(action.payload.keyAction); + setKeyActionToLayer(newLayer, moduleIndex, keyIndex, clonedAction); + }else { + setKeyActionToLayer(newLayer, moduleIndex, keyIndex, null); + } + } + return newLayer; + }); changedUserConfiguration.keymaps = state.keymaps.map(keymap => { if (keymap.abbreviation === newKeymap.abbreviation) { @@ -357,3 +367,12 @@ function checkExistence(layers: Layer[], property: string, value: any): Layer[] return newLayers; } + +function setKeyActionToLayer(newLayer: Layer, moduleIndex: number, keyIndex: number, newKeyAction: KeyAction): void { + const newModule: Module = Object.assign(new Module(), newLayer.modules[moduleIndex]); + newLayer.modules = newLayer.modules.slice(); + newLayer.modules[moduleIndex] = newModule; + + newModule.keyActions = newModule.keyActions.slice(); + newModule.keyActions[keyIndex] = newKeyAction; +} diff --git a/packages/uhk-web/test/user-config-helper.ts b/packages/uhk-web/test/user-config-helper.ts new file mode 100644 index 00000000..e37593ab --- /dev/null +++ b/packages/uhk-web/test/user-config-helper.ts @@ -0,0 +1,164 @@ +import { cloneDeep } from 'lodash'; + +const defaultUserConfig = { + dataModelVersion: 4, + moduleConfigurations: [ + { + id: 1, + initialPointerSpeed: 1, + pointerAcceleration: 5, + maxPointerSpeed: 200 + } + ], + keymaps: [ + { + isDefault: true, + abbreviation: 'QWR', + name: 'QWERTY', + description: '', + layers: [ + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 36 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 37 + }, + { + 'keyActionType': 'switchLayer', + 'layer': 'mod', + 'toggle': false + } + ] + }, + { + id: 1, + pointerRole: 'move', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 53 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 30 + }, + null + ] + }, + { + id: 2, + pointerRole: 'scroll', + keyActions: [] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'none', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 64 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 65 + }, + { + keyActionType: 'switchLayer', + layer: 'mod', + toggle: false + } + ] + }, + { + id: 1, + pointerRole: 'none', + keyActions: [ + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 41 + }, + { + keyActionType: 'keystroke', + type: 'basic', + scancode: 58 + }, + null + ] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + }, + { + id: 1, + pointerRole: 'scroll', + keyActions: [ + null, + { + keyActionType: 'switchKeymap', + keymapAbbreviation: 'DVO' + }, + null + ] + } + ] + }, + { + modules: [ + { + id: 0, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + }, + { + id: 1, + pointerRole: 'move', + keyActions: [ + null, + null, + null + ] + } + ] + } + ] + } + ], + macros: [] +}; + +export function getDefaultUserConfig() { + return cloneDeep(defaultUserConfig); +} diff --git a/web/src/app.module.ts b/web/src/app.module.ts deleted file mode 100644 index e69de29b..00000000