Seperate electron and web target building
This commit is contained in:
committed by
József Farkas
parent
517aed1b1c
commit
983eb72892
2
shared/src/store/actions/index.ts
Normal file
2
shared/src/store/actions/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './keymap';
|
||||
export * from './macro';
|
||||
85
shared/src/store/actions/keymap.ts
Normal file
85
shared/src/store/actions/keymap.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { KeyAction } from '../../config-serializer/config-items/key-action';
|
||||
import { Keymap } from '../../config-serializer/config-items/Keymap';
|
||||
import { Macro } from '../../config-serializer/config-items/Macro';
|
||||
|
||||
export namespace KeymapActions {
|
||||
export const PREFIX = '[Keymap] ';
|
||||
export const ADD = KeymapActions.PREFIX + 'Add keymap';
|
||||
export const DUPLICATE = KeymapActions.PREFIX + 'Duplicate keymap';
|
||||
export const EDIT_ABBR = KeymapActions.PREFIX + 'Edit keymap abbreviation';
|
||||
export const EDIT_NAME = KeymapActions.PREFIX + 'Edit keymap title';
|
||||
export const SAVE_KEY = KeymapActions.PREFIX + 'Save key action';
|
||||
export const SET_DEFAULT = KeymapActions.PREFIX + 'Set default option';
|
||||
export const REMOVE = KeymapActions.PREFIX + 'Remove keymap';
|
||||
export const CHECK_MACRO = KeymapActions.PREFIX + 'Check deleted macro';
|
||||
|
||||
export function addKeymap(item: Keymap): Action {
|
||||
return {
|
||||
type: KeymapActions.ADD,
|
||||
payload: item
|
||||
};
|
||||
}
|
||||
|
||||
export function setDefault(abbr: string): Action {
|
||||
return {
|
||||
type: KeymapActions.SET_DEFAULT,
|
||||
payload: abbr
|
||||
};
|
||||
}
|
||||
|
||||
export function removeKeymap(abbr: string): Action {
|
||||
return {
|
||||
type: KeymapActions.REMOVE,
|
||||
payload: abbr
|
||||
};
|
||||
}
|
||||
|
||||
export function duplicateKeymap(keymap: Keymap): Action {
|
||||
return {
|
||||
type: KeymapActions.DUPLICATE,
|
||||
payload: keymap
|
||||
};
|
||||
}
|
||||
|
||||
export function editKeymapName(abbr: string, name: string): Action {
|
||||
return {
|
||||
type: KeymapActions.EDIT_NAME,
|
||||
payload: {
|
||||
abbr: abbr,
|
||||
name: name
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function editKeymapAbbr(abbr: string, newAbbr: string): Action {
|
||||
return {
|
||||
type: KeymapActions.EDIT_ABBR,
|
||||
payload: {
|
||||
abbr: abbr,
|
||||
newAbbr: newAbbr
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function saveKey(keymap: Keymap, layer: number, module: number, key: number, keyAction: KeyAction): Action {
|
||||
return {
|
||||
type: KeymapActions.SAVE_KEY,
|
||||
payload: {
|
||||
keymap,
|
||||
layer,
|
||||
module,
|
||||
key,
|
||||
keyAction
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function checkMacro(macro: Macro): Action {
|
||||
return {
|
||||
type: KeymapActions.CHECK_MACRO,
|
||||
payload: macro
|
||||
};
|
||||
}
|
||||
}
|
||||
91
shared/src/store/actions/macro.ts
Normal file
91
shared/src/store/actions/macro.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { Macro } from '../../config-serializer/config-items/Macro';
|
||||
import { MacroAction } from '../../config-serializer/config-items/macro-action';
|
||||
|
||||
export namespace MacroActions {
|
||||
export const PREFIX = '[Macro] ';
|
||||
|
||||
export const DUPLICATE = MacroActions.PREFIX + 'Duplicate macro';
|
||||
export const EDIT_NAME = MacroActions.PREFIX + 'Edit macro title';
|
||||
export const REMOVE = MacroActions.PREFIX + 'Remove macro';
|
||||
export const ADD = MacroActions.PREFIX + 'Add macro';
|
||||
|
||||
export const ADD_ACTION = MacroActions.PREFIX + 'Add macro action';
|
||||
export const SAVE_ACTION = MacroActions.PREFIX + 'Save macro action';
|
||||
export const DELETE_ACTION = MacroActions.PREFIX + 'Delete macro action';
|
||||
export const REORDER_ACTION = MacroActions.PREFIX + 'Reorder macro action';
|
||||
|
||||
export function addMacro(): Action {
|
||||
return {
|
||||
type: MacroActions.ADD
|
||||
};
|
||||
}
|
||||
|
||||
export function removeMacro(macroId: number): Action {
|
||||
return {
|
||||
type: MacroActions.REMOVE,
|
||||
payload: macroId
|
||||
};
|
||||
}
|
||||
|
||||
export function duplicateMacro(macro: Macro): Action {
|
||||
return {
|
||||
type: MacroActions.DUPLICATE,
|
||||
payload: macro
|
||||
};
|
||||
}
|
||||
|
||||
export function editMacroName(id: number, name: string): Action {
|
||||
return {
|
||||
type: MacroActions.EDIT_NAME,
|
||||
payload: {
|
||||
id: id,
|
||||
name: name
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function addMacroAction(id: number, action: MacroAction): Action {
|
||||
return {
|
||||
type: MacroActions.ADD_ACTION,
|
||||
payload: {
|
||||
id: id,
|
||||
action: action
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function saveMacroAction(id: number, index: number, action: MacroAction): Action {
|
||||
return {
|
||||
type: MacroActions.SAVE_ACTION,
|
||||
payload: {
|
||||
id: id,
|
||||
index: index,
|
||||
action: action
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function deleteMacroAction(id: number, index: number, action: MacroAction): Action {
|
||||
return {
|
||||
type: MacroActions.DELETE_ACTION,
|
||||
payload: {
|
||||
id: id,
|
||||
index: index,
|
||||
action: action
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function reorderMacroAction(id: number, oldIndex: number, newIndex: number): Action {
|
||||
return {
|
||||
type: MacroActions.REORDER_ACTION,
|
||||
payload: {
|
||||
id: id,
|
||||
oldIndex: oldIndex,
|
||||
newIndex: newIndex
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
2
shared/src/store/effects/index.ts
Normal file
2
shared/src/store/effects/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './keymap';
|
||||
export * from './macro';
|
||||
60
shared/src/store/effects/keymap.ts
Normal file
60
shared/src/store/effects/keymap.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { Actions, Effect } from '@ngrx/effects';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/withLatestFrom';
|
||||
|
||||
import { KeymapActions } from '../actions';
|
||||
import { AppState } from '../index';
|
||||
|
||||
import { Keymap } from '../../config-serializer/config-items/Keymap';
|
||||
|
||||
@Injectable()
|
||||
export class KeymapEffects {
|
||||
|
||||
@Effect({ dispatch: false })add$: any = this.actions$
|
||||
.ofType(KeymapActions.ADD)
|
||||
.withLatestFrom(this.store)
|
||||
.do((latest) => {
|
||||
const state: AppState = latest[1];
|
||||
const entities: Keymap[] = state.keymaps.entities;
|
||||
this.router.navigate(['/keymap', entities[entities.length - 1].abbreviation]);
|
||||
});
|
||||
|
||||
@Effect({ dispatch: false }) duplicate$: any = this.actions$
|
||||
.ofType(KeymapActions.DUPLICATE)
|
||||
.withLatestFrom(this.store)
|
||||
.do((latest) => {
|
||||
const state: AppState = latest[1];
|
||||
const entities: Keymap[] = state.keymaps.entities;
|
||||
this.router.navigate(['/keymap', entities[entities.length - 1].abbreviation]);
|
||||
});
|
||||
|
||||
@Effect({ dispatch: false })remove$: any = this.actions$
|
||||
.ofType(KeymapActions.REMOVE)
|
||||
.withLatestFrom(this.store)
|
||||
.do((latest) => {
|
||||
const state: AppState = latest[1];
|
||||
|
||||
if (state.keymaps.entities.length === 0) {
|
||||
this.router.navigate(['/keymap/add']);
|
||||
} else {
|
||||
const favourite: Keymap = state.keymaps.entities.find(keymap => keymap.isDefault);
|
||||
this.router.navigate(['/keymap', favourite.abbreviation]);
|
||||
}
|
||||
});
|
||||
|
||||
@Effect({ dispatch: false }) editAbbr$: any = this.actions$
|
||||
.ofType(KeymapActions.EDIT_ABBR)
|
||||
.withLatestFrom(this.store)
|
||||
.do((latest) => {
|
||||
const state: AppState = latest[1];
|
||||
this.router.navigate(['/keymap', state.keymaps.newAbbr]);
|
||||
});
|
||||
|
||||
constructor(private actions$: Actions, private router: Router, private store: Store<AppState>) {}
|
||||
}
|
||||
45
shared/src/store/effects/macro.ts
Normal file
45
shared/src/store/effects/macro.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { Actions, Effect } from '@ngrx/effects';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/withLatestFrom';
|
||||
|
||||
import { Macro } from '../../config-serializer/config-items/Macro';
|
||||
|
||||
import { KeymapActions, MacroActions } from '../actions';
|
||||
import { AppState } from '../index';
|
||||
|
||||
@Injectable()
|
||||
export class MacroEffects {
|
||||
|
||||
@Effect({dispatch: false}) remove$: any = this.actions$
|
||||
.ofType(MacroActions.REMOVE)
|
||||
.map(action => this.store.dispatch(KeymapActions.checkMacro(action.payload)))
|
||||
.withLatestFrom(this.store)
|
||||
.do((latest) => {
|
||||
const state: AppState = latest[1];
|
||||
const macro: Macro[] = state.macros.entities;
|
||||
|
||||
if (state.macros.entities.length === 0) {
|
||||
this.router.navigate(['/macro']);
|
||||
} else {
|
||||
this.router.navigate(['/macro', macro[0].id]);
|
||||
}
|
||||
});
|
||||
|
||||
@Effect({dispatch: false}) add$: any = this.actions$
|
||||
.ofType(MacroActions.ADD)
|
||||
.withLatestFrom(this.store)
|
||||
.do((latest) => {
|
||||
const state: AppState = latest[1];
|
||||
const macro: Macro = state.macros.entities[state.macros.entities.length - 1];
|
||||
|
||||
this.router.navigate(['/macro', macro.id, 'new']);
|
||||
});
|
||||
|
||||
constructor(private actions$: Actions, private router: Router, private store: Store<AppState>) {}
|
||||
}
|
||||
18
shared/src/store/index.ts
Normal file
18
shared/src/store/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Keymap } from '../config-serializer/config-items/Keymap';
|
||||
import { Macro } from '../config-serializer/config-items/Macro';
|
||||
|
||||
export interface KeymapState {
|
||||
entities: Keymap[];
|
||||
newAbbr?: string;
|
||||
}
|
||||
|
||||
export interface MacroState {
|
||||
entities: Macro[];
|
||||
}
|
||||
|
||||
// State interface for the application
|
||||
export interface AppState {
|
||||
keymaps: KeymapState;
|
||||
macros: MacroState;
|
||||
presetKeymaps: Keymap[];
|
||||
}
|
||||
5
shared/src/store/reducers/index.ts
Normal file
5
shared/src/store/reducers/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import keymapReducer, { getKeymapEntities } from './keymap';
|
||||
import macroReducer, { getMacroEntities } from './macro';
|
||||
import presetReducer from './preset';
|
||||
|
||||
export { keymapReducer, macroReducer, presetReducer, getKeymapEntities, getMacroEntities };
|
||||
238
shared/src/store/reducers/keymap.ts
Normal file
238
shared/src/store/reducers/keymap.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
import '@ngrx/core/add/operator/select';
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import 'rxjs/add/operator/map';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { Helper as KeyActionHelper, KeyAction } from '../../config-serializer/config-items/key-action';
|
||||
import { Keymap } from '../../config-serializer/config-items/Keymap';
|
||||
import { Layer } from '../../config-serializer/config-items/Layer';
|
||||
import { Module } from '../../config-serializer/config-items/Module';
|
||||
import { KeymapActions } from '../actions';
|
||||
import { AppState, KeymapState } from '../index';
|
||||
|
||||
const initialState: KeymapState = {
|
||||
entities: []
|
||||
};
|
||||
|
||||
export default function (state = initialState, action: Action): KeymapState {
|
||||
let newState: Keymap[];
|
||||
let changedKeymap: Keymap = new Keymap();
|
||||
|
||||
switch (action.type) {
|
||||
case KeymapActions.ADD:
|
||||
case KeymapActions.DUPLICATE:
|
||||
{
|
||||
let newKeymap: Keymap = new Keymap(action.payload);
|
||||
|
||||
newKeymap.abbreviation = generateAbbr(state.entities, newKeymap.abbreviation);
|
||||
newKeymap.name = generateName(state.entities, newKeymap.name);
|
||||
newKeymap.isDefault = (state.entities.length === 0);
|
||||
|
||||
return {
|
||||
entities: [...state.entities, newKeymap]
|
||||
};
|
||||
}
|
||||
/* tslint:disable:no-switch-case-fall-through */
|
||||
// tslint bug: https://github.com/palantir/tslint/issues/1538
|
||||
case KeymapActions.EDIT_NAME:
|
||||
/* tslint:enable:no-switch-case-fall-through */
|
||||
let name: string = generateName(state.entities, action.payload.name);
|
||||
|
||||
newState = state.entities.map((keymap: Keymap) => {
|
||||
if (keymap.abbreviation === action.payload.abbr) {
|
||||
keymap.name = name;
|
||||
}
|
||||
|
||||
return keymap;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case KeymapActions.EDIT_ABBR:
|
||||
let abbr: string = generateAbbr(state.entities, action.payload.newAbbr);
|
||||
|
||||
newState = state.entities.map((keymap: Keymap) => {
|
||||
if (keymap.abbreviation === action.payload.abbr) {
|
||||
keymap.abbreviation = abbr;
|
||||
}
|
||||
|
||||
return keymap;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState,
|
||||
newAbbr: abbr
|
||||
};
|
||||
|
||||
case KeymapActions.SET_DEFAULT:
|
||||
newState = state.entities.map((keymap: Keymap) => {
|
||||
if (keymap.abbreviation === action.payload || keymap.isDefault) {
|
||||
let newKeymap: Keymap = new Keymap();
|
||||
Object.assign(newKeymap, keymap);
|
||||
keymap = newKeymap;
|
||||
keymap.isDefault = keymap.abbreviation === action.payload;
|
||||
}
|
||||
|
||||
return keymap;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case KeymapActions.REMOVE:
|
||||
let isDefault: boolean;
|
||||
|
||||
let filtered: Keymap[] = state.entities.filter((keymap: Keymap) => {
|
||||
if (keymap.abbreviation === action.payload) {
|
||||
isDefault = keymap.isDefault;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// If deleted one is default set default keymap to the first on the list of keymaps
|
||||
if (isDefault && filtered.length > 0) {
|
||||
filtered[0].isDefault = true;
|
||||
}
|
||||
|
||||
// Check for the deleted keymap in other keymaps
|
||||
newState = filtered.map((keymap: Keymap) => {
|
||||
changedKeymap = new Keymap();
|
||||
Object.assign(changedKeymap, keymap);
|
||||
changedKeymap.layers = checkExistence(changedKeymap.layers, 'keymapAbbreviation', action.payload);
|
||||
|
||||
return changedKeymap;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case KeymapActions.SAVE_KEY:
|
||||
{
|
||||
const keymap: Keymap = action.payload.keymap;
|
||||
Object.assign(changedKeymap, keymap);
|
||||
|
||||
const layerIndex: number = action.payload.layer;
|
||||
const layer: Layer = changedKeymap.layers[layerIndex];
|
||||
const changedLayer: Layer = new Layer();
|
||||
Object.assign(changedLayer, layer);
|
||||
changedKeymap.layers = changedKeymap.layers.slice();
|
||||
changedKeymap.layers[layerIndex] = changedLayer;
|
||||
|
||||
const moduleIndex: number = action.payload.module;
|
||||
const module: Module = changedLayer.modules[moduleIndex];
|
||||
const changedModule: Module = new Module();
|
||||
Object.assign(changedModule, module);
|
||||
changedLayer.modules[moduleIndex] = changedModule;
|
||||
|
||||
const keyIndex: number = action.payload.key;
|
||||
changedModule.keyActions[keyIndex] = KeyActionHelper.createKeyAction(action.payload.keyAction);
|
||||
|
||||
newState = state.entities.map((_keymap: Keymap) => {
|
||||
if (_keymap.abbreviation === changedKeymap.abbreviation) {
|
||||
_keymap = changedKeymap;
|
||||
}
|
||||
|
||||
return _keymap;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
}
|
||||
/* tslint:disable:no-switch-case-fall-through */
|
||||
// tslint bug: https://github.com/palantir/tslint/issues/1538
|
||||
case KeymapActions.CHECK_MACRO:
|
||||
/* tslint:enable:no-switch-case-fall-through */
|
||||
newState = state.entities.map((keymap: Keymap) => {
|
||||
changedKeymap = new Keymap();
|
||||
Object.assign(changedKeymap, keymap);
|
||||
changedKeymap.layers = checkExistence(changedKeymap.layers, '_macroId', action.payload);
|
||||
|
||||
return changedKeymap;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getKeymapEntities(): (state$: Observable<AppState>) => Observable<Keymap[]> {
|
||||
return (state$: Observable<AppState>) => state$
|
||||
.select(state => state.keymaps.entities);
|
||||
}
|
||||
|
||||
export function getKeymap(abbr: string) {
|
||||
if (abbr === undefined) {
|
||||
return getDefault();
|
||||
}
|
||||
|
||||
return (state$: Observable<AppState>) => state$
|
||||
.select(appState => appState.keymaps.entities)
|
||||
.map((keymaps: Keymap[]) =>
|
||||
keymaps.find((keymap: Keymap) => keymap.abbreviation === abbr)
|
||||
);
|
||||
}
|
||||
|
||||
export function getDefault() {
|
||||
return (state$: Observable<AppState>) => state$
|
||||
.select(appState => appState.keymaps.entities)
|
||||
.map((keymaps: Keymap[]) =>
|
||||
keymaps.find((keymap: Keymap) => keymap.isDefault)
|
||||
);
|
||||
}
|
||||
|
||||
function generateAbbr(keymaps: Keymap[], abbr: string): string {
|
||||
const chars: string[] = '23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||
let position = 0;
|
||||
|
||||
while (keymaps.some((keymap: Keymap) => keymap.abbreviation === abbr)) {
|
||||
abbr = abbr.substring(0, abbr.length - 1) + chars[position];
|
||||
++position;
|
||||
}
|
||||
|
||||
return abbr;
|
||||
}
|
||||
|
||||
function generateName(keymaps: Keymap[], name: string) {
|
||||
let suffix = 2;
|
||||
const oldName: string = name;
|
||||
|
||||
while (keymaps.some((keymap: Keymap) => keymap.name === name)) {
|
||||
name = oldName + ` (${suffix})`;
|
||||
++suffix;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function checkExistence(layers: Layer[], property: string, value: any) {
|
||||
let newLayers = layers.map((layer) => {
|
||||
let newLayer = new Layer(layer);
|
||||
|
||||
newLayer.modules = layer.modules.map((module: Module) => {
|
||||
module.keyActions.forEach((action: KeyAction, index: number) => {
|
||||
if (action && action.hasOwnProperty(property) && action[property] === value) {
|
||||
module.keyActions[index] = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
return newLayer;
|
||||
});
|
||||
|
||||
return newLayers;
|
||||
}
|
||||
184
shared/src/store/reducers/macro.ts
Normal file
184
shared/src/store/reducers/macro.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
import '@ngrx/core/add/operator/select';
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/operator/map';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { Macro } from '../../config-serializer/config-items/Macro';
|
||||
|
||||
import { MacroActions } from '../actions';
|
||||
import { AppState, MacroState } from '../index';
|
||||
|
||||
const initialState: MacroState = {
|
||||
entities: []
|
||||
};
|
||||
|
||||
export default function (state = initialState, action: Action): MacroState {
|
||||
let newMacro: Macro;
|
||||
let newState: Macro[];
|
||||
|
||||
switch (action.type) {
|
||||
case MacroActions.ADD:
|
||||
newMacro = new Macro();
|
||||
newMacro.id = generateId(state.entities);
|
||||
newMacro.name = generateName(state.entities, 'New macro');
|
||||
newMacro.isLooped = false;
|
||||
newMacro.isPrivate = true;
|
||||
newMacro.macroActions = [];
|
||||
|
||||
return {
|
||||
entities: [...state.entities, newMacro]
|
||||
};
|
||||
|
||||
case MacroActions.DUPLICATE:
|
||||
|
||||
newMacro = new Macro(action.payload);
|
||||
newMacro.name = generateName(state.entities, newMacro.name);
|
||||
newMacro.id = generateId(state.entities);
|
||||
|
||||
return {
|
||||
entities: [...state.entities, newMacro]
|
||||
};
|
||||
|
||||
case MacroActions.EDIT_NAME:
|
||||
let name: string = generateName(state.entities, action.payload.name);
|
||||
|
||||
newState = state.entities.map((macro: Macro) => {
|
||||
if (macro.id === action.payload.id) {
|
||||
macro.name = name;
|
||||
}
|
||||
|
||||
return macro;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case MacroActions.REMOVE:
|
||||
newState = state.entities.filter((macro: Macro) => macro.id !== action.payload);
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case MacroActions.ADD_ACTION:
|
||||
newState = state.entities.map((macro: Macro) => {
|
||||
if (macro.id === action.payload.id) {
|
||||
newMacro = new Macro(macro);
|
||||
newMacro.macroActions.push(action.payload.action);
|
||||
|
||||
return newMacro;
|
||||
}
|
||||
|
||||
return macro;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case MacroActions.SAVE_ACTION:
|
||||
newState = state.entities.map((macro: Macro) => {
|
||||
if (macro.id === action.payload.id) {
|
||||
newMacro = new Macro(macro);
|
||||
newMacro.macroActions[action.payload.index] = action.payload.action;
|
||||
|
||||
return newMacro;
|
||||
}
|
||||
|
||||
return macro;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case MacroActions.DELETE_ACTION:
|
||||
newState = state.entities.map((macro: Macro) => {
|
||||
if (macro.id === action.payload.id) {
|
||||
newMacro = new Macro(macro);
|
||||
newMacro.macroActions.splice(action.payload.index, 1);
|
||||
|
||||
return newMacro;
|
||||
}
|
||||
|
||||
return macro;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
case MacroActions.REORDER_ACTION:
|
||||
newState = state.entities.map((macro: Macro) => {
|
||||
if (macro.id === action.payload.id) {
|
||||
let newIndex: number = action.payload.newIndex;
|
||||
|
||||
// We need to reduce the new index for one when we are moving action down
|
||||
if (newIndex > action.payload.oldIndex) {
|
||||
--newIndex;
|
||||
}
|
||||
|
||||
newMacro = new Macro(macro);
|
||||
newMacro.macroActions.splice(
|
||||
newIndex,
|
||||
0,
|
||||
newMacro.macroActions.splice(action.payload.oldIndex, 1)[0]
|
||||
);
|
||||
|
||||
return newMacro;
|
||||
}
|
||||
|
||||
return macro;
|
||||
});
|
||||
|
||||
return {
|
||||
entities: newState
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export function getMacroEntities(): (state$: Observable<AppState>) => Observable<Macro[]> {
|
||||
return (state$: Observable<AppState>) => state$
|
||||
.select(state => state.macros.entities);
|
||||
}
|
||||
|
||||
export function getMacro(id: number) {
|
||||
if (isNaN(id)) {
|
||||
return () => Observable.of<Macro>(undefined);
|
||||
} else {
|
||||
return (state$: Observable<AppState>) => state$
|
||||
.select(appState => appState.macros.entities)
|
||||
.map((macros: Macro[]) => macros.find((macro: Macro) => macro.id === id));
|
||||
}
|
||||
}
|
||||
|
||||
function generateName(macros: Macro[], name: string) {
|
||||
let suffix = 2;
|
||||
const oldName: string = name;
|
||||
|
||||
while (macros.some((macro: Macro) => macro.name === name)) {
|
||||
name = oldName + ` (${suffix})`;
|
||||
++suffix;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function generateId(macros: Macro[]) {
|
||||
let newId = 0;
|
||||
|
||||
macros.forEach((macro: Macro) => {
|
||||
if (macro.id > newId) {
|
||||
newId = macro.id;
|
||||
}
|
||||
});
|
||||
|
||||
return ++newId;
|
||||
|
||||
}
|
||||
7
shared/src/store/reducers/preset.ts
Normal file
7
shared/src/store/reducers/preset.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Keymap } from '../../config-serializer/config-items/Keymap';
|
||||
|
||||
const initialState: Keymap[] = [];
|
||||
|
||||
export default function(state = initialState): Keymap[] {
|
||||
return state;
|
||||
}
|
||||
13
shared/src/store/storage/electron.ts
Normal file
13
shared/src/store/storage/electron.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { UserConfiguration } from '../../config-serializer/config-items/UserConfiguration';
|
||||
|
||||
export class Electron {
|
||||
getConfig(): UserConfiguration {
|
||||
// TODO implement load logic
|
||||
return;
|
||||
}
|
||||
|
||||
/* tslint:disable:no-unused-variable */
|
||||
saveConfig(config: UserConfiguration): void {
|
||||
// TODO implement save logic
|
||||
}
|
||||
}
|
||||
97
shared/src/store/storage/index.ts
Normal file
97
shared/src/store/storage/index.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { Keymap } from '../../config-serializer/config-items/Keymap';
|
||||
import { Macro } from '../../config-serializer/config-items/Macro';
|
||||
import { UserConfiguration } from '../../config-serializer/config-items/UserConfiguration';
|
||||
|
||||
import { KeymapActions, MacroActions } from '../actions';
|
||||
import { AppState } from '../index';
|
||||
import { Electron } from './electron';
|
||||
import { Local } from './local';
|
||||
|
||||
@Injectable()
|
||||
export class DataStorage {
|
||||
|
||||
private _environment: Local | Electron;
|
||||
private defaultUserConfiguration: UserConfiguration;
|
||||
private uhkPresets: Keymap[];
|
||||
|
||||
constructor() {
|
||||
this.initUHKJson();
|
||||
this.detectEnvironment();
|
||||
}
|
||||
|
||||
initialState(): AppState {
|
||||
const config: UserConfiguration = this.getConfiguration();
|
||||
return {
|
||||
keymaps: {
|
||||
entities: config.keymaps
|
||||
},
|
||||
macros: {
|
||||
entities: config.macros
|
||||
},
|
||||
presetKeymaps: this.uhkPresets
|
||||
};
|
||||
}
|
||||
|
||||
detectEnvironment(): void {
|
||||
// Electron
|
||||
// TODO check if we can remove <any> when electron will be implemented (maybe use process.versions['electron'])
|
||||
if (typeof window !== 'undefined' && (<any>window).process && (<any>window).process.type === 'renderer') {
|
||||
this._environment = new Electron();
|
||||
}
|
||||
// Local storage
|
||||
else {
|
||||
this._environment = new Local(this.defaultUserConfiguration.dataModelVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add type for state
|
||||
saveState(reducer: any): (state: any, action: Action) => AppState {
|
||||
return (state: any, action: Action) => {
|
||||
let nextState = reducer(state, action);
|
||||
let config: UserConfiguration;
|
||||
|
||||
// Save elements to the UhkConfiguration
|
||||
if (
|
||||
action.type.startsWith(KeymapActions.PREFIX) &&
|
||||
(
|
||||
(nextState.entities && nextState.entities.length && nextState.entities[0] instanceof Keymap) ||
|
||||
(state.entities && state.entities.length && state.entities[0] instanceof Keymap)
|
||||
)
|
||||
) {
|
||||
config = this.getConfiguration();
|
||||
config.keymaps = Object.values(nextState.entities);
|
||||
this._environment.saveConfig(config);
|
||||
} else if (
|
||||
action.type.startsWith(MacroActions.PREFIX) &&
|
||||
(
|
||||
(nextState.entities && nextState.entities.length && nextState.entities[0] instanceof Macro) ||
|
||||
(state.entities && state.entities.length && state.entities[0] instanceof Macro)
|
||||
)
|
||||
) {
|
||||
config = this.getConfiguration();
|
||||
config.macros = Object.values(nextState.entities);
|
||||
this._environment.saveConfig(config);
|
||||
}
|
||||
return nextState;
|
||||
};
|
||||
}
|
||||
|
||||
initUHKJson() {
|
||||
this.defaultUserConfiguration = new UserConfiguration()
|
||||
.fromJsonObject(require('json!../../config-serializer/user-config.json'));
|
||||
this.uhkPresets = (<any[]>require('json!../../config-serializer/preset-keymaps.json'))
|
||||
.map(keymap => new Keymap().fromJsonObject(keymap));
|
||||
}
|
||||
|
||||
getConfiguration(): UserConfiguration {
|
||||
let config: UserConfiguration = this._environment.getConfig();
|
||||
if (!config) {
|
||||
config = this.defaultUserConfiguration;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
24
shared/src/store/storage/local.ts
Normal file
24
shared/src/store/storage/local.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { UserConfiguration } from '../../config-serializer/config-items/UserConfiguration';
|
||||
|
||||
export class Local {
|
||||
|
||||
constructor(private dataModelVersion: number) { }
|
||||
|
||||
getConfig(): UserConfiguration {
|
||||
let configJsonString = localStorage.getItem('config');
|
||||
let config: UserConfiguration;
|
||||
|
||||
if (configJsonString) {
|
||||
const configJsonObject = JSON.parse(configJsonString);
|
||||
if (configJsonObject.dataModelVersion === this.dataModelVersion) {
|
||||
config = new UserConfiguration().fromJsonObject(configJsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
saveConfig(config: UserConfiguration): void {
|
||||
localStorage.setItem('config', JSON.stringify(config.toJsonObject()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user