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
This commit is contained in:
committed by
László Monda
parent
46b97a9b62
commit
7baf9ad009
@@ -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 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = <KeystrokeAction>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: []
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user