feat(config): Read / write hardware configuration area (#423)
* add write-hca.js * refactor: Move config serializer into the uhk-common package * refactor: Move getTransferBuffers into the uhk-usb package * refactor: delete obsoleted classes * build: add uhk-usb build command * refactor: move eeprom transfer to uhk-usb package * fix: Fix write-hca.js * feat: load hardware config from the device and * style: fix ts lint errors * build: fix rxjs dependency resolve * test: Add jasmine unit test framework to the tet serializer * fix(user-config): A "type": "basic", properties to the "keystroke" action types * feat(usb): set chmod+x on write-hca.js * feat(usb): Create USB logger * style: Fix type * build: Add chalk to dependencies. Chalk will colorize the output
This commit is contained in:
committed by
László Monda
parent
1122784bdb
commit
9294bede50
@@ -32,7 +32,6 @@ install:
|
|||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- npm run build
|
- npm run build
|
||||||
- npm run build:test
|
|
||||||
- npm run lint
|
- npm run lint
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
|||||||
22
package-lock.json
generated
22
package-lock.json
generated
@@ -16,13 +16,19 @@
|
|||||||
"integrity": "sha1-ixuKArfpLRDOibzRbnroza5xKZ8=",
|
"integrity": "sha1-ixuKArfpLRDOibzRbnroza5xKZ8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "8.0.25"
|
"@types/node": "8.0.30"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/jasmine": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-1ZZdFvYA5zARDXPj5+VF0bwDZWH/o0QQWJVDc5srdC/DngcCZXskR33eR/4PielGvBjLQpQOd6KiQbmtqVkeZA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "8.0.25",
|
"version": "8.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.25.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.30.tgz",
|
||||||
"integrity": "sha512-zT+t9841g1HsjLtPMCYxmb1U4pcZ2TOegAKiomlmj6bIziuaEYHUavxLE9NRwdntY0vOCrgHho6OXjDX7fm/Kw==",
|
"integrity": "sha512-IaQtG3DWe9gRsmk1DqNnYyRVjGDVcBdZywkRVF2f62Boe8XKmlR7lNcwC6pk4V4W8nk+Zu+vdGMsOdRTDj1JPA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/node-hid": {
|
"@types/node-hid": {
|
||||||
@@ -37,7 +43,7 @@
|
|||||||
"integrity": "sha1-+9YF06q7WccUFqj1ku7krinppuE=",
|
"integrity": "sha1-+9YF06q7WccUFqj1ku7krinppuE=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "8.0.25"
|
"@types/node": "8.0.30"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"7zip": {
|
"7zip": {
|
||||||
@@ -8816,9 +8822,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "2.4.2",
|
"version": "2.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz",
|
||||||
"integrity": "sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=",
|
"integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
|
|||||||
15
package.json
15
package.json
@@ -16,7 +16,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/electron-devtools-installer": "^2.0.2",
|
"@types/electron-devtools-installer": "^2.0.2",
|
||||||
"@types/electron-settings": "^3.0.0",
|
"@types/electron-settings": "^3.0.0",
|
||||||
"@types/node": "~8.0.25",
|
"@types/jasmine": "2.6.0",
|
||||||
|
"@types/node": "8.0.30",
|
||||||
"@types/node-hid": "^0.5.2",
|
"@types/node-hid": "^0.5.2",
|
||||||
"@types/usb": "^1.1.3",
|
"@types/usb": "^1.1.3",
|
||||||
"autoprefixer": "^6.5.3",
|
"autoprefixer": "^6.5.3",
|
||||||
@@ -44,25 +45,27 @@
|
|||||||
"ts-loader": "^2.3.1",
|
"ts-loader": "^2.3.1",
|
||||||
"ts-node": "~3.0.4",
|
"ts-node": "~3.0.4",
|
||||||
"tslint": "~5.5.0",
|
"tslint": "~5.5.0",
|
||||||
"typescript": "^2.4.2",
|
"typescript": "2.5.2",
|
||||||
"webpack": "^2.4.1"
|
"webpack": "^2.4.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "lerna bootstrap",
|
"postinstall": "lerna bootstrap",
|
||||||
"test": "lerna exec --scope test-serializer npm test",
|
"test": "lerna exec --scope test-serializer npm test",
|
||||||
"lint": "run-s -scn lint:ts lint:style",
|
"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": "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",
|
"lint:ts:electron-main": "tslint --type-check --project ./packages/uhk-agent/tsconfig.json",
|
||||||
"lint:ts:electron-renderer": "tslint --type-check --project ./packages/uhk-web/src/tsconfig.renderer.json",
|
"lint:ts:electron-renderer": "tslint --type-check --project ./packages/uhk-web/src/tsconfig.renderer.json",
|
||||||
"lint:ts:web": "tslint --type-check --project ./packages/uhk-web/src/tsconfig.app.json",
|
"lint:ts:web": "tslint --type-check --project ./packages/uhk-web/src/tsconfig.app.json",
|
||||||
"lint:ts:test-serializer": "tslint --type-check --project ./packages/test-serializer/tsconfig.json",
|
"lint:ts:test-serializer": "tslint --type-check --project ./packages/test-serializer/tsconfig.json",
|
||||||
|
"lint:ts:uhk-usb": "tslint --type-check --project ./packages/uhk-usb/tsconfig.json",
|
||||||
"lint:style": "stylelint \"packages/uhk-agent/src/**/*.scss\" \"packages/uhk-web/src/**/*.scss\" --syntax scss",
|
"lint:style": "stylelint \"packages/uhk-agent/src/**/*.scss\" \"packages/uhk-web/src/**/*.scss\" --syntax scss",
|
||||||
"build": "run-s build:web build:electron",
|
"build": "run-s build:web build:electron build:usb build:common",
|
||||||
"build:web": "lerna exec --scope uhk-web npm run build",
|
"build:web": "lerna exec --scope uhk-web npm run build",
|
||||||
"build:electron": "cross-env AOT_BUILD=true run-s -sn build:electron:renderer build:electron:main",
|
"build:electron": "cross-env AOT_BUILD=true run-s -sn build:electron:renderer build:electron:main",
|
||||||
"build:electron:main": "lerna exec --scope uhk-agent npm run build",
|
"build:electron:main": "lerna exec --scope uhk-agent npm run build",
|
||||||
"build:electron:renderer": "lerna exec --scope uhk-web npm run build:renderer",
|
"build:electron:renderer": "lerna exec --scope uhk-web npm run build:renderer",
|
||||||
"build:test": "lerna exec --scope test-serializer npm run build",
|
"build:common": "lerna exec --scope uhk-common npm run build",
|
||||||
|
"build:usb": "lerna exec --scope uhk-usb npm run build",
|
||||||
"server:web": "lerna exec --scope uhk-web npm start",
|
"server:web": "lerna exec --scope uhk-web npm start",
|
||||||
"server:electron": "lerna exec --scope uhk-web npm run server:renderer",
|
"server:electron": "lerna exec --scope uhk-web npm run server:renderer",
|
||||||
"electron": "lerna exec --scope uhk-agent npm start",
|
"electron": "lerna exec --scope uhk-agent npm start",
|
||||||
@@ -70,6 +73,6 @@
|
|||||||
"pack": "node ./scripts/release.js",
|
"pack": "node ./scripts/release.js",
|
||||||
"sprites": "node ./scripts/generate-svg-sprites",
|
"sprites": "node ./scripts/generate-svg-sprites",
|
||||||
"release": "node ./scripts/release.js",
|
"release": "node ./scripts/release.js",
|
||||||
"clean": "lerna exec rimraf ./node_modules ./dist && rimraf ./node_modules ./dist package-lock.json"
|
"clean": "lerna exec rimraf ./node_modules ./dist && rimraf ./node_modules ./dist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
packages/test-serializer/.gitignore
vendored
7
packages/test-serializer/.gitignore
vendored
@@ -1,4 +1,3 @@
|
|||||||
uhk-config.bin
|
user-config.bin
|
||||||
uhk-config-serialized.json
|
user-config-serialized.json
|
||||||
uhk-config-serialized.bin
|
user-config-serialized.bin
|
||||||
test-serializer.js
|
|
||||||
|
|||||||
8
packages/test-serializer/jasmine.json
Normal file
8
packages/test-serializer/jasmine.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"spec_dir": "spec",
|
||||||
|
"spec_files": [
|
||||||
|
"**/*[sS]pec.ts"
|
||||||
|
],
|
||||||
|
"stopSpecOnExpectationFailure": true,
|
||||||
|
"random": false
|
||||||
|
}
|
||||||
1029
packages/test-serializer/package-lock.json
generated
Normal file
1029
packages/test-serializer/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,10 +16,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"uhk-web": "^1.0.0"
|
"@types/jasmine": "^2.6.0",
|
||||||
|
"@types/node": "8.0.30",
|
||||||
|
"jasmine": "^2.8.0",
|
||||||
|
"jasmine-core": "^2.8.0",
|
||||||
|
"jasmine-node": "2.0.0",
|
||||||
|
"jasmine-ts": "^0.2.1",
|
||||||
|
"ts-node": "3.3.0",
|
||||||
|
"uhk-common": "1.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack",
|
"test": "jasmine-ts --config=jasmine.json"
|
||||||
"test": "node ./test-serializer.js"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
packages/test-serializer/spec/test-serializer.spec.ts
Normal file
33
packages/test-serializer/spec/test-serializer.spec.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { UhkBuffer, UserConfiguration } from '../../uhk-common/index';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const userConfig = JSON.parse(fs.readFileSync('../uhk-web/src/app/services/user-config.json'));
|
||||||
|
|
||||||
|
describe('Test Serializer', () => {
|
||||||
|
it('full config match', () => {
|
||||||
|
const config1Js = userConfig;
|
||||||
|
const config1Ts: UserConfiguration = new UserConfiguration().fromJsonObject(config1Js);
|
||||||
|
const config1Buffer = new UhkBuffer();
|
||||||
|
config1Ts.toBinary(config1Buffer);
|
||||||
|
const config1BufferContent = config1Buffer.getBufferContent();
|
||||||
|
fs.writeFileSync('user-config.bin', config1BufferContent);
|
||||||
|
|
||||||
|
config1Buffer.offset = 0;
|
||||||
|
console.log();
|
||||||
|
const config2Ts = new UserConfiguration().fromBinary(config1Buffer);
|
||||||
|
console.log('\n');
|
||||||
|
const config2Js = config2Ts.toJsonObject();
|
||||||
|
const config2Buffer = new UhkBuffer();
|
||||||
|
config2Ts.toBinary(config2Buffer);
|
||||||
|
fs.writeFileSync('user-config-serialized.json', JSON.stringify(config2Js, undefined, 4));
|
||||||
|
const config2BufferContent = config1Buffer.getBufferContent();
|
||||||
|
fs.writeFileSync('user-config-serialized.bin', config2BufferContent);
|
||||||
|
|
||||||
|
expect(config1Js).toEqual(config2Js);
|
||||||
|
|
||||||
|
const buffersContentsAreEqual: boolean = Buffer.compare(config1BufferContent, config2BufferContent) === 0;
|
||||||
|
expect(buffersContentsAreEqual).toBe(true);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import { UserConfiguration } from '../uhk-web/src/app/config-serializer/config-items/user-configuration';
|
|
||||||
import { UhkBuffer } from '../uhk-web/src/app/config-serializer/uhk-buffer';
|
|
||||||
|
|
||||||
const assert = require('assert');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const userConfig = JSON.parse(fs.readFileSync('../uhk-web/src/app/config-serializer/user-config.json'));
|
|
||||||
|
|
||||||
const config1Js = userConfig;
|
|
||||||
const config1Ts: UserConfiguration = new UserConfiguration().fromJsonObject(config1Js);
|
|
||||||
const config1Buffer = new UhkBuffer();
|
|
||||||
config1Ts.toBinary(config1Buffer);
|
|
||||||
const config1BufferContent = config1Buffer.getBufferContent();
|
|
||||||
fs.writeFileSync('user-config.bin', config1BufferContent);
|
|
||||||
|
|
||||||
config1Buffer.offset = 0;
|
|
||||||
console.log();
|
|
||||||
const config2Ts = new UserConfiguration().fromBinary(config1Buffer);
|
|
||||||
console.log('\n');
|
|
||||||
const config2Js = config2Ts.toJsonObject();
|
|
||||||
const config2Buffer = new UhkBuffer();
|
|
||||||
config2Ts.toBinary(config2Buffer);
|
|
||||||
fs.writeFileSync('user-config-serialized.json', JSON.stringify(config2Js, undefined, 4));
|
|
||||||
const config2BufferContent = config1Buffer.getBufferContent();
|
|
||||||
fs.writeFileSync('user-config-serialized.bin', config2BufferContent);
|
|
||||||
|
|
||||||
console.log('\n');
|
|
||||||
let returnValue = 0;
|
|
||||||
try {
|
|
||||||
assert.deepEqual(config1Js, config2Js);
|
|
||||||
console.log('JSON configurations are identical.');
|
|
||||||
} catch (error) {
|
|
||||||
console.log('JSON configurations differ.');
|
|
||||||
returnValue = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffersContentsAreEqual: boolean = Buffer.compare(config1BufferContent, config2BufferContent) === 0;
|
|
||||||
if (buffersContentsAreEqual) {
|
|
||||||
console.log('Binary configurations are identical.');
|
|
||||||
} else {
|
|
||||||
console.log('Binary configurations differ.');
|
|
||||||
returnValue += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
process.exit(returnValue);
|
|
||||||
@@ -5,10 +5,7 @@
|
|||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"../node_modules/@types"
|
"./node_modules/@types"
|
||||||
],
|
|
||||||
"types": [
|
|
||||||
"node"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
12
packages/uhk-agent/package-lock.json
generated
12
packages/uhk-agent/package-lock.json
generated
@@ -392,9 +392,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "1.7.6",
|
"version": "1.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-1.7.6.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-1.7.5.tgz",
|
||||||
"integrity": "sha1-+2nqMb0D3w7/JH8m8LU4vSm27nI=",
|
"integrity": "sha1-BloxAr+LhxAt9QxQmF/v5sVpBFs=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "7.0.43",
|
"@types/node": "7.0.43",
|
||||||
"electron-download": "3.3.0",
|
"electron-download": "3.3.0",
|
||||||
@@ -432,9 +432,9 @@
|
|||||||
"integrity": "sha1-ihBD4ys6HaHD9VPc4oznZCRhZ+M="
|
"integrity": "sha1-ihBD4ys6HaHD9VPc4oznZCRhZ+M="
|
||||||
},
|
},
|
||||||
"electron-log": {
|
"electron-log": {
|
||||||
"version": "2.2.9",
|
"version": "2.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-2.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-2.2.6.tgz",
|
||||||
"integrity": "sha512-WNMSipQYurNxY14RO6IKgcxcZg1e4aNVpUUJK9q7Bqe0TZEKn1e5h4HiQKhTgVLqKrUn++ugOZrty450P9vpjA=="
|
"integrity": "sha1-zPo+CbOfMhRoyQpkJwE4CjQHnxo="
|
||||||
},
|
},
|
||||||
"electron-rebuild": {
|
"electron-rebuild": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
|
|||||||
@@ -22,7 +22,8 @@
|
|||||||
"electron-settings": "3.0.14",
|
"electron-settings": "3.0.14",
|
||||||
"electron-updater": "2.2.0",
|
"electron-updater": "2.2.0",
|
||||||
"node-hid": "0.5.4",
|
"node-hid": "0.5.4",
|
||||||
"sudo-prompt": "^7.0.0"
|
"sudo-prompt": "^7.0.0",
|
||||||
|
"uhk-usb": "1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"uhk-common": "^1.0.0"
|
"uhk-common": "^1.0.0"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { autoUpdater } from 'electron-updater';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
import * as commandLineArgs from 'command-line-args';
|
import * as commandLineArgs from 'command-line-args';
|
||||||
|
import { UhkHidDevice } from 'uhk-usb';
|
||||||
|
|
||||||
// import { ElectronDataStorageRepositoryService } from './services/electron-datastorage-repository.service';
|
// import { ElectronDataStorageRepositoryService } from './services/electron-datastorage-repository.service';
|
||||||
import { CommandLineArgs } from 'uhk-common';
|
import { CommandLineArgs } from 'uhk-common';
|
||||||
@@ -16,7 +17,6 @@ import { logger } from './services/logger.service';
|
|||||||
import { AppUpdateService } from './services/app-update.service';
|
import { AppUpdateService } from './services/app-update.service';
|
||||||
import { AppService } from './services/app.service';
|
import { AppService } from './services/app.service';
|
||||||
import { SudoService } from './services/sudo.service';
|
import { SudoService } from './services/sudo.service';
|
||||||
import { UhkHidDeviceService } from './services/uhk-hid-device.service';
|
|
||||||
|
|
||||||
const optionDefinitions = [
|
const optionDefinitions = [
|
||||||
{ name: 'addons', type: Boolean, defaultOption: false }
|
{ name: 'addons', type: Boolean, defaultOption: false }
|
||||||
@@ -33,7 +33,7 @@ let win: Electron.BrowserWindow;
|
|||||||
autoUpdater.logger = logger;
|
autoUpdater.logger = logger;
|
||||||
|
|
||||||
let deviceService: DeviceService;
|
let deviceService: DeviceService;
|
||||||
let uhkHidDeviceService: UhkHidDeviceService;
|
let uhkHidDeviceService: UhkHidDevice;
|
||||||
let appUpdateService: AppUpdateService;
|
let appUpdateService: AppUpdateService;
|
||||||
let appService: AppService;
|
let appService: AppService;
|
||||||
let sudoService: SudoService;
|
let sudoService: SudoService;
|
||||||
@@ -51,7 +51,7 @@ function createWindow() {
|
|||||||
});
|
});
|
||||||
win.setMenuBarVisibility(false);
|
win.setMenuBarVisibility(false);
|
||||||
win.maximize();
|
win.maximize();
|
||||||
uhkHidDeviceService = new UhkHidDeviceService(logger);
|
uhkHidDeviceService = new UhkHidDevice(logger);
|
||||||
deviceService = new DeviceService(logger, win, uhkHidDeviceService);
|
deviceService = new DeviceService(logger, win, uhkHidDeviceService);
|
||||||
appUpdateService = new AppUpdateService(logger, win, app);
|
appUpdateService = new AppUpdateService(logger, win, app);
|
||||||
appService = new AppService(logger, win, deviceService, options, uhkHidDeviceService);
|
appService = new AppService(logger, win, deviceService, options, uhkHidDeviceService);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { ipcMain, BrowserWindow } from 'electron';
|
import { ipcMain, BrowserWindow } from 'electron';
|
||||||
|
import { UhkHidDevice } from 'uhk-usb';
|
||||||
|
|
||||||
import { CommandLineArgs, IpcEvents, AppStartInfo, LogService } from 'uhk-common';
|
import { CommandLineArgs, IpcEvents, AppStartInfo, LogService } from 'uhk-common';
|
||||||
import { MainServiceBase } from './main-service-base';
|
import { MainServiceBase } from './main-service-base';
|
||||||
import { DeviceService } from './device.service';
|
import { DeviceService } from './device.service';
|
||||||
import { UhkHidDeviceService } from './uhk-hid-device.service';
|
|
||||||
|
|
||||||
export class AppService extends MainServiceBase {
|
export class AppService extends MainServiceBase {
|
||||||
constructor(protected logService: LogService,
|
constructor(protected logService: LogService,
|
||||||
protected win: Electron.BrowserWindow,
|
protected win: Electron.BrowserWindow,
|
||||||
private deviceService: DeviceService,
|
private deviceService: DeviceService,
|
||||||
private options: CommandLineArgs,
|
private options: CommandLineArgs,
|
||||||
private uhkHidDeviceService: UhkHidDeviceService) {
|
private uhkHidDeviceService: UhkHidDevice) {
|
||||||
super(logService, win);
|
super(logService, win);
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.app.getAppStartInfo, this.handleAppStartInfo.bind(this));
|
ipcMain.on(IpcEvents.app.getAppStartInfo, this.handleAppStartInfo.bind(this));
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { ipcMain } from 'electron';
|
import { ipcMain } from 'electron';
|
||||||
|
import { IpcEvents, LogService, IpcResponse, ConfigurationReply } from 'uhk-common';
|
||||||
import { Constants, IpcEvents, LogService, IpcResponse } from 'uhk-common';
|
import { Constants, EepromTransfer, SystemPropertyIds, UsbCommand } from 'uhk-usb';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { Device, devices } from 'node-hid';
|
import { Device, devices } from 'node-hid';
|
||||||
|
import { UhkHidDevice } from 'uhk-usb';
|
||||||
|
|
||||||
import 'rxjs/add/observable/interval';
|
import 'rxjs/add/observable/interval';
|
||||||
import 'rxjs/add/operator/startWith';
|
import 'rxjs/add/operator/startWith';
|
||||||
@@ -12,38 +12,6 @@ import 'rxjs/add/operator/map';
|
|||||||
import 'rxjs/add/operator/do';
|
import 'rxjs/add/operator/do';
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
|
||||||
import { UhkHidDeviceService } from './uhk-hid-device.service';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UHK USB Communications command. All communication package should have start with a command code.
|
|
||||||
*/
|
|
||||||
enum Command {
|
|
||||||
GetProperty = 0,
|
|
||||||
UploadConfig = 8,
|
|
||||||
ApplyConfig = 9,
|
|
||||||
LaunchEepromTransfer = 12,
|
|
||||||
ReadUserConfig = 15,
|
|
||||||
GetKeyboardState = 16
|
|
||||||
}
|
|
||||||
|
|
||||||
enum EepromTransfer {
|
|
||||||
ReadHardwareConfig = 0,
|
|
||||||
WriteHardwareConfig = 1,
|
|
||||||
ReadUserConfig = 2,
|
|
||||||
WriteUserConfig = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SystemPropertyIds {
|
|
||||||
UsbProtocolVersion = 0,
|
|
||||||
BridgeProtocolVersion = 1,
|
|
||||||
DataModelVersion = 2,
|
|
||||||
FirmwareVersion = 3,
|
|
||||||
HardwareConfigSize = 4,
|
|
||||||
UserConfigSize = 5
|
|
||||||
}
|
|
||||||
|
|
||||||
const snooze = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IpcMain pair of the UHK Communication
|
* IpcMain pair of the UHK Communication
|
||||||
* Functionality:
|
* Functionality:
|
||||||
@@ -57,10 +25,10 @@ export class DeviceService {
|
|||||||
|
|
||||||
constructor(private logService: LogService,
|
constructor(private logService: LogService,
|
||||||
private win: Electron.BrowserWindow,
|
private win: Electron.BrowserWindow,
|
||||||
private device: UhkHidDeviceService) {
|
private device: UhkHidDevice) {
|
||||||
this.pollUhkDevice();
|
this.pollUhkDevice();
|
||||||
ipcMain.on(IpcEvents.device.saveUserConfiguration, this.saveUserConfiguration.bind(this));
|
ipcMain.on(IpcEvents.device.saveUserConfiguration, this.saveUserConfiguration.bind(this));
|
||||||
ipcMain.on(IpcEvents.device.loadUserConfiguration, this.loadUserConfiguration.bind(this));
|
ipcMain.on(IpcEvents.device.loadConfigurations, this.loadConfigurations.bind(this));
|
||||||
logService.debug('[DeviceService] init success');
|
logService.debug('[DeviceService] init success');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,32 +44,64 @@ export class DeviceService {
|
|||||||
* Return with the actual UserConfiguration from UHK Device
|
* Return with the actual UserConfiguration from UHK Device
|
||||||
* @returns {Promise<Buffer>}
|
* @returns {Promise<Buffer>}
|
||||||
*/
|
*/
|
||||||
public async loadUserConfiguration(event: Electron.Event): Promise<void> {
|
public async loadConfigurations(event: Electron.Event): Promise<void> {
|
||||||
|
try {
|
||||||
|
const userConfiguration = await this.loadConfiguration(
|
||||||
|
SystemPropertyIds.UserConfigSize,
|
||||||
|
UsbCommand.ReadUserConfig,
|
||||||
|
'user configuration');
|
||||||
|
|
||||||
|
const hardwareConfiguration = await this.loadConfiguration(
|
||||||
|
SystemPropertyIds.HardwareConfigSize,
|
||||||
|
UsbCommand.ReadHardwareConfig,
|
||||||
|
'hardware configuration');
|
||||||
|
|
||||||
|
const response: ConfigurationReply = {
|
||||||
|
success: true,
|
||||||
|
userConfiguration,
|
||||||
|
hardwareConfiguration
|
||||||
|
};
|
||||||
|
event.sender.send(IpcEvents.device.loadConfigurationReply, JSON.stringify(response));
|
||||||
|
} catch (error) {
|
||||||
|
const response: ConfigurationReply = {
|
||||||
|
success: false,
|
||||||
|
error: error.message
|
||||||
|
};
|
||||||
|
event.sender.send(IpcEvents.device.loadConfigurationReply, JSON.stringify(response));
|
||||||
|
} finally {
|
||||||
|
this.device.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return with the actual user / hardware fonfiguration from UHK Device
|
||||||
|
* @returns {Promise<Buffer>}
|
||||||
|
*/
|
||||||
|
public async loadConfiguration(property: SystemPropertyIds, config: UsbCommand, configName: string): Promise<string> {
|
||||||
let response = [];
|
let response = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.logService.debug('[DeviceService] USB[T]: Read user configuration size from keyboard');
|
this.logService.debug(`[DeviceService] USB[T]: Read ${configName} size from keyboard`);
|
||||||
const configSize = await this.getUserConfigSizeFromKeyboard();
|
const configSize = await this.getConfigSizeFromKeyboard(property);
|
||||||
const chunkSize = 63;
|
const chunkSize = 63;
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let configBuffer = new Buffer(0);
|
let configBuffer = new Buffer(0);
|
||||||
|
|
||||||
this.logService.debug('[DeviceService] USB[T]: Read user configuration from keyboard');
|
this.logService.debug(`[DeviceService] USB[T]: Read ${configName} from keyboard`);
|
||||||
while (offset < configSize) {
|
while (offset < configSize) {
|
||||||
const chunkSizeToRead = Math.min(chunkSize, configSize - offset);
|
const chunkSizeToRead = Math.min(chunkSize, configSize - offset);
|
||||||
const writeBuffer = Buffer.from([Command.ReadUserConfig, chunkSizeToRead, offset & 0xff, offset >> 8]);
|
const writeBuffer = Buffer.from([config, chunkSizeToRead, offset & 0xff, offset >> 8]);
|
||||||
const readBuffer = await this.device.write(writeBuffer);
|
const readBuffer = await this.device.write(writeBuffer);
|
||||||
configBuffer = Buffer.concat([configBuffer, new Buffer(readBuffer.slice(1, chunkSizeToRead + 1))]);
|
configBuffer = Buffer.concat([configBuffer, new Buffer(readBuffer.slice(1, chunkSizeToRead + 1))]);
|
||||||
offset += chunkSizeToRead;
|
offset += chunkSizeToRead;
|
||||||
}
|
}
|
||||||
response = UhkHidDeviceService.convertBufferToIntArray(configBuffer);
|
response = UhkHidDevice.convertBufferToIntArray(configBuffer);
|
||||||
|
return Promise.resolve(JSON.stringify(response));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logService.error('[DeviceService] getUserConfigFromEeprom error', error);
|
const errMsg = `[DeviceService] ${configName} from eeprom error`;
|
||||||
} finally {
|
this.logService.error(errMsg, error);
|
||||||
this.device.close();
|
throw new Error(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.sender.send(IpcEvents.device.loadUserConfigurationReply, JSON.stringify(response));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,11 +127,11 @@ export class DeviceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the UserConfiguration size from the UHK Device
|
* Return the user / hardware configuration size from the UHK Device
|
||||||
* @returns {Promise<number>}
|
* @returns {Promise<number>}
|
||||||
*/
|
*/
|
||||||
private async getUserConfigSizeFromKeyboard(): Promise<number> {
|
private async getConfigSizeFromKeyboard(property: SystemPropertyIds): Promise<number> {
|
||||||
const buffer = await this.device.write(new Buffer([Command.GetProperty, SystemPropertyIds.UserConfigSize]));
|
const buffer = await this.device.write(new Buffer([UsbCommand.GetProperty, property]));
|
||||||
const configSize = buffer[1] + (buffer[2] << 8);
|
const configSize = buffer[1] + (buffer[2] << 8);
|
||||||
this.logService.debug('[DeviceService] User config size:', configSize);
|
this.logService.debug('[DeviceService] User config size:', configSize);
|
||||||
return configSize;
|
return configSize;
|
||||||
@@ -144,7 +144,7 @@ export class DeviceService {
|
|||||||
this.logService.debug('[DeviceService] USB[T]: Write user configuration to keyboard');
|
this.logService.debug('[DeviceService] USB[T]: Write user configuration to keyboard');
|
||||||
await this.sendUserConfigToKeyboard(json);
|
await this.sendUserConfigToKeyboard(json);
|
||||||
this.logService.debug('[DeviceService] USB[T]: Write user configuration to EEPROM');
|
this.logService.debug('[DeviceService] USB[T]: Write user configuration to EEPROM');
|
||||||
await this.writeUserConfigToEeprom();
|
await this.device.writeConfigToEeprom(EepromTransfer.WriteUserConfig);
|
||||||
|
|
||||||
response.success = true;
|
response.success = true;
|
||||||
}
|
}
|
||||||
@@ -168,48 +168,12 @@ export class DeviceService {
|
|||||||
*/
|
*/
|
||||||
private async sendUserConfigToKeyboard(json: string): Promise<void> {
|
private async sendUserConfigToKeyboard(json: string): Promise<void> {
|
||||||
const buffer: Buffer = new Buffer(JSON.parse(json).data);
|
const buffer: Buffer = new Buffer(JSON.parse(json).data);
|
||||||
const fragments = this.getTransferBuffers(buffer);
|
const fragments = UhkHidDevice.getTransferBuffers(UsbCommand.UploadUserConfig, buffer);
|
||||||
for (const fragment of fragments) {
|
for (const fragment of fragments) {
|
||||||
await this.device.write(fragment);
|
await this.device.write(fragment);
|
||||||
}
|
}
|
||||||
this.logService.debug('[DeviceService] USB[T]: Apply user configuration to keyboard');
|
this.logService.debug('[DeviceService] USB[T]: Apply user configuration to keyboard');
|
||||||
const applyBuffer = new Buffer([Command.ApplyConfig]);
|
const applyBuffer = new Buffer([UsbCommand.ApplyConfig]);
|
||||||
await this.device.write(applyBuffer);
|
await this.device.write(applyBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async writeUserConfigToEeprom(): Promise<void> {
|
|
||||||
await this.device.write(new Buffer([Command.LaunchEepromTransfer, EepromTransfer.WriteUserConfig]));
|
|
||||||
await this.waitUntilKeyboardBusy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async waitUntilKeyboardBusy(): Promise<void> {
|
|
||||||
while (true) {
|
|
||||||
const buffer = await this.device.write(new Buffer([Command.GetKeyboardState]));
|
|
||||||
if (buffer[1] === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.logService.debug('Keyboard is busy, wait...');
|
|
||||||
await snooze(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Split the whole UserConfiguration package into 64 byte fragments
|
|
||||||
* @param {Buffer} configBuffer
|
|
||||||
* @returns {Buffer[]}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
private getTransferBuffers(configBuffer: Buffer): Buffer[] {
|
|
||||||
const fragments: Buffer[] = [];
|
|
||||||
const MAX_SENDING_PAYLOAD_SIZE = Constants.MAX_PAYLOAD_SIZE - 4;
|
|
||||||
for (let offset = 0; offset < configBuffer.length; offset += MAX_SENDING_PAYLOAD_SIZE) {
|
|
||||||
const length = offset + MAX_SENDING_PAYLOAD_SIZE < configBuffer.length
|
|
||||||
? MAX_SENDING_PAYLOAD_SIZE
|
|
||||||
: configBuffer.length - offset;
|
|
||||||
const header = new Buffer([Command.UploadConfig, length, offset & 0xFF, offset >> 8]);
|
|
||||||
fragments.push(Buffer.concat([header, configBuffer.slice(offset, offset + length)]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return fragments;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './src/util';
|
export * from './src/util';
|
||||||
export * from './src/models';
|
export * from './src/models';
|
||||||
export * from './src/services';
|
export * from './src/services';
|
||||||
|
export * from './src/config-serializer';
|
||||||
|
|||||||
5
packages/uhk-common/package-lock.json
generated
5
packages/uhk-common/package-lock.json
generated
@@ -20,6 +20,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-2.2.3.tgz",
|
||||||
"integrity": "sha1-570RSfHEQgjxzEdENT8PmKDx9Xs="
|
"integrity": "sha1-570RSfHEQgjxzEdENT8PmKDx9Xs="
|
||||||
},
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "8.0.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz",
|
||||||
|
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ=="
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.7.1",
|
"version": "1.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz",
|
||||||
|
|||||||
@@ -3,15 +3,17 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Common Library contains the common code for uhk-agent (electron-main) and web (electron-renderer) modules",
|
"description": "Common Library contains the common code for uhk-agent (electron-main) and web (electron-renderer) modules",
|
||||||
"main": "src/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular/core": "^4.3.3",
|
"@angular/core": "4.3.3",
|
||||||
"@ngrx/core": "1.2.0",
|
"@ngrx/core": "1.2.0",
|
||||||
"@ngrx/store": "^2.2.3"
|
"@ngrx/store": "2.2.3",
|
||||||
|
"@types/node": "8.0.28"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ The configuration of the UHK is unusually complex for a keyboard, and is compose
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Given that the development dependencies are installed on your system you should be able to build the configuration serializer tester by executing `npm run build:test` in this directory, then start the test by running `node test-serializer.js`.
|
Given that the development dependencies are installed on your system you should be able to run the configuration serializer tester test by running `npm run test` in this directorx.
|
||||||
|
|
||||||
## Configuration representations
|
## Configuration representations
|
||||||
|
|
||||||
There are 3 different representations of the configuration, each filling a specific purpose.
|
There are 3 different representations of the configuration, each filling a specific purpose.
|
||||||
|
|
||||||
The **JavaScript representation** is optimally suited to be serialized as JSON, and saved to the file system, or transmitted over the network. As a plaintext format, it's human-readable and easily editable. See [user-config.json](user-config.json) for an example configuration.
|
The **JavaScript representation** is optimally suited to be serialized as JSON, and saved to the file system, or transmitted over the network. As a plaintext format, it's human-readable and easily editable. See [user-config.json](../../../uhk-web/src/app/services/user-config.json) for an example configuration.
|
||||||
|
|
||||||
The **TypeScript representation** is structurally similar to the JavaScript representation, but it features strongly typed TypeScript objects instead of typeless JavaScript objects. This representation is meant to be used by Agent. Extensive, per-property [assertion](assert.ts) takes place upon initializing the TypeScript objects to ensure the integrity of the configuration.
|
The **TypeScript representation** is structurally similar to the JavaScript representation, but it features strongly typed TypeScript objects instead of typeless JavaScript objects. This representation is meant to be used by Agent. Extensive, per-property [assertion](assert.ts) takes place upon initializing the TypeScript objects to ensure the integrity of the configuration.
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ KeyActions.toJsObject: <KeyActions length="9">
|
|||||||
|
|
||||||
## Testing the serializer
|
## Testing the serializer
|
||||||
|
|
||||||
[test-serializer.ts](test-serializer.ts) is designed to test the serializer by taking [user-config.json](user-config.json), and transforming it to TypeScript representation, then to binary representation, then finally back to JavaScript representation. This should exercise every major code path.
|
[test-serializer.ts](test-serializer.ts) is designed to test the serializer by taking [user-config.json](../../../uhk-web/src/app/services/user-config.json), and transforming it to TypeScript representation, then to binary representation, then finally back to JavaScript representation. This should exercise every major code path.
|
||||||
|
|
||||||
If the testing is successful the following should be displayed:
|
If the testing is successful the following should be displayed:
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export * from './key-action';
|
||||||
|
export * from './macro-action';
|
||||||
|
export * from './hardware-configuration';
|
||||||
|
export * from './key-modifiers';
|
||||||
|
export * from './keymap';
|
||||||
|
export * from './layer';
|
||||||
|
export * from './long-press-action';
|
||||||
|
export * from './macro';
|
||||||
|
export * from './module';
|
||||||
|
export * from './module-configuration';
|
||||||
|
export * from './user-configuration';
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
export * from './key-action';
|
export * from './key-action';
|
||||||
export * from './keystroke-action';
|
export * from './keystroke-action';
|
||||||
|
export * from './keystroke-type';
|
||||||
export * from './mouse-action';
|
export * from './mouse-action';
|
||||||
export * from './none-action';
|
export * from './none-action';
|
||||||
export * from './play-macro-action';
|
export * from './play-macro-action';
|
||||||
export * from './switch-keymap-action';
|
export * from './switch-keymap-action';
|
||||||
export * from './switch-layer-action';
|
export * from './switch-layer-action';
|
||||||
export * from './helper';
|
export { Helper as KeyActionHelper } from './helper';
|
||||||
@@ -3,7 +3,6 @@ import { Layer } from './layer';
|
|||||||
import { Macro } from './macro';
|
import { Macro } from './macro';
|
||||||
import { SwitchLayerAction } from './key-action/switch-layer-action';
|
import { SwitchLayerAction } from './key-action/switch-layer-action';
|
||||||
import { KeyAction } from './key-action/key-action';
|
import { KeyAction } from './key-action/key-action';
|
||||||
import { ConfigSerializer } from '../config-serializer';
|
|
||||||
import { UserConfiguration } from './user-configuration';
|
import { UserConfiguration } from './user-configuration';
|
||||||
|
|
||||||
export class Keymap {
|
export class Keymap {
|
||||||
@@ -2,7 +2,6 @@ import { UhkBuffer } from '../uhk-buffer';
|
|||||||
import { Macro } from './macro';
|
import { Macro } from './macro';
|
||||||
import { Module } from './module';
|
import { Module } from './module';
|
||||||
import { UserConfiguration } from './user-configuration';
|
import { UserConfiguration } from './user-configuration';
|
||||||
import { ConfigSerializer } from '../config-serializer';
|
|
||||||
|
|
||||||
export class Layer {
|
export class Layer {
|
||||||
|
|
||||||
@@ -5,4 +5,4 @@ export * from './move-mouse-macro-action';
|
|||||||
export * from './mouse-button-macro-action';
|
export * from './mouse-button-macro-action';
|
||||||
export * from './scroll-mouse-macro-action';
|
export * from './scroll-mouse-macro-action';
|
||||||
export * from './text-macro-action';
|
export * from './text-macro-action';
|
||||||
export * from './helper';
|
export { Helper as MacroActionHelper } from './helper';
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { assertUInt8 } from '../assert';
|
import { assertUInt8 } from '../assert';
|
||||||
import { UhkBuffer } from '../uhk-buffer';
|
import { UhkBuffer } from '../uhk-buffer';
|
||||||
import { Helper as MacroActionHelper, MacroAction } from './macro-action';
|
import { MacroAction } from './macro-action';
|
||||||
|
import { Helper as MacroActionHelper } from './macro-action/helper';
|
||||||
|
|
||||||
export class Macro {
|
export class Macro {
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { assertEnum, assertUInt8 } from '../assert';
|
import { assertEnum, assertUInt8 } from '../assert';
|
||||||
import { UhkBuffer } from '../uhk-buffer';
|
import { UhkBuffer } from '../uhk-buffer';
|
||||||
import { Helper as KeyActionHelper, KeyAction, NoneAction, PlayMacroAction, SwitchKeymapAction } from './key-action';
|
import { KeyActionHelper, KeyAction, NoneAction, PlayMacroAction, SwitchKeymapAction } from './key-action';
|
||||||
import { Macro } from './macro';
|
import { Macro } from './macro';
|
||||||
import { UserConfiguration } from './user-configuration';
|
import { UserConfiguration } from './user-configuration';
|
||||||
|
|
||||||
4
packages/uhk-common/src/config-serializer/index.ts
Normal file
4
packages/uhk-common/src/config-serializer/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export * from './config-items';
|
||||||
|
export * from './assert';
|
||||||
|
export * from './config-serializer';
|
||||||
|
export * from './uhk-buffer';
|
||||||
@@ -4,6 +4,24 @@ export class UhkBuffer {
|
|||||||
(<any>element).toBinary(buffer); // TODO: Remove any
|
(<any>element).toBinary(buffer); // TODO: Remove any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromArray(data: Array<number>): UhkBuffer {
|
||||||
|
if (data.length < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uhkBuffer = new UhkBuffer();
|
||||||
|
let hasNonZeroValue = false;
|
||||||
|
for (const num of data) {
|
||||||
|
if (num > 0) {
|
||||||
|
hasNonZeroValue = true;
|
||||||
|
}
|
||||||
|
uhkBuffer.writeUInt8(num);
|
||||||
|
}
|
||||||
|
uhkBuffer.offset = 0;
|
||||||
|
|
||||||
|
return uhkBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
private static eepromSize = 32 * 1024;
|
private static eepromSize = 32 * 1024;
|
||||||
private static maxCompactLength = 0xFFFF;
|
private static maxCompactLength = 0xFFFF;
|
||||||
private static longCompactLengthPrefix = 0xFF;
|
private static longCompactLengthPrefix = 0xFF;
|
||||||
6
packages/uhk-common/src/models/configuration-reply.ts
Normal file
6
packages/uhk-common/src/models/configuration-reply.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export interface ConfigurationReply {
|
||||||
|
success: boolean;
|
||||||
|
userConfiguration?: string;
|
||||||
|
hardwareConfiguration?: string;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
@@ -2,3 +2,4 @@ export * from './command-line-args';
|
|||||||
export * from './notification';
|
export * from './notification';
|
||||||
export * from './ipc-response';
|
export * from './ipc-response';
|
||||||
export * from './app-start-info';
|
export * from './app-start-info';
|
||||||
|
export * from './configuration-reply';
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class LogService {
|
export class LogService {
|
||||||
error(...args: any[]): void {
|
error(...args: any[]): void {
|
||||||
console.error(args);
|
console.error(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(...args: any[]): void {
|
debug(...args: any[]): void {
|
||||||
console.debug(args);
|
console.log(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
silly(...args: any[]): void {
|
silly(...args: any[]): void {
|
||||||
console.debug(args);
|
console.log(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
info(...args: any[]): void {
|
info(...args: any[]): void {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export { Constants } from './constants';
|
|
||||||
export { IpcEvents } from './ipcEvents';
|
export { IpcEvents } from './ipcEvents';
|
||||||
|
export * from './log';
|
||||||
|
|
||||||
// Source: http://stackoverflow.com/questions/13720256/javascript-regex-camelcase-to-sentence
|
// Source: http://stackoverflow.com/questions/13720256/javascript-regex-camelcase-to-sentence
|
||||||
export function camelCaseToSentence(camelCasedText: string): string {
|
export function camelCaseToSentence(camelCasedText: string): string {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class Device {
|
|||||||
public static readonly deviceConnectionStateChanged = 'device-connection-state-changed';
|
public static readonly deviceConnectionStateChanged = 'device-connection-state-changed';
|
||||||
public static readonly saveUserConfiguration = 'device-save-user-configuration';
|
public static readonly saveUserConfiguration = 'device-save-user-configuration';
|
||||||
public static readonly saveUserConfigurationReply = 'device-save-user-configuration-reply';
|
public static readonly saveUserConfigurationReply = 'device-save-user-configuration-reply';
|
||||||
public static readonly loadUserConfiguration = 'device-load-user-configuration';
|
public static readonly loadConfigurations = 'device-load-configuration';
|
||||||
public static readonly loadUserConfigurationReply = 'device-load-user-configuration-reply';
|
public static readonly loadConfigurationReply = 'device-load-configuration-reply';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class IpcEvents {
|
export class IpcEvents {
|
||||||
|
|||||||
6
packages/uhk-common/src/util/log.ts
Normal file
6
packages/uhk-common/src/util/log.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export namespace LogRegExps {
|
||||||
|
export const transferRegExp = /USB\[T]:/;
|
||||||
|
export const writeRegExp = /USB\[W]:/;
|
||||||
|
export const readRegExp = /USB\[R]: 00/;
|
||||||
|
export const errorRegExp = /(?:(USB\[R]: ([^0]|0[^0])))/;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
|||||||
1
packages/uhk-usb/index.ts
Normal file
1
packages/uhk-usb/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './src';
|
||||||
781
packages/uhk-usb/package-lock.json
generated
Normal file
781
packages/uhk-usb/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
packages/uhk-usb/package.json
Normal file
17
packages/uhk-usb/package.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "uhk-usb",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Agent preliminary USB code",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "8.0.28"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-hid": "0.5.4",
|
||||||
|
"uhk-common": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
35
packages/uhk-usb/src/constants.ts
Normal file
35
packages/uhk-usb/src/constants.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
export namespace Constants {
|
||||||
|
export const VENDOR_ID = 0x1D50;
|
||||||
|
export const PRODUCT_ID = 0x6122;
|
||||||
|
export const MAX_PAYLOAD_SIZE = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UHK USB Communications command. All communication package should have start with a command code.
|
||||||
|
*/
|
||||||
|
export enum UsbCommand {
|
||||||
|
GetProperty = 0,
|
||||||
|
UploadUserConfig = 8,
|
||||||
|
ApplyConfig = 9,
|
||||||
|
LaunchEepromTransfer = 12,
|
||||||
|
ReadHardwareConfig = 13,
|
||||||
|
WriteHardwareConfig = 14,
|
||||||
|
ReadUserConfig = 15,
|
||||||
|
GetKeyboardState = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EepromTransfer {
|
||||||
|
ReadHardwareConfig = 0,
|
||||||
|
WriteHardwareConfig = 1,
|
||||||
|
ReadUserConfig = 2,
|
||||||
|
WriteUserConfig = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SystemPropertyIds {
|
||||||
|
UsbProtocolVersion = 0,
|
||||||
|
BridgeProtocolVersion = 1,
|
||||||
|
DataModelVersion = 2,
|
||||||
|
FirmwareVersion = 3,
|
||||||
|
HardwareConfigSize = 4,
|
||||||
|
UserConfigSize = 5
|
||||||
|
}
|
||||||
2
packages/uhk-usb/src/index.ts
Normal file
2
packages/uhk-usb/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './constants';
|
||||||
|
export * from './uhk-hid-device';
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
import { Device, devices, HID } from 'node-hid';
|
import { Device, devices, HID } from 'node-hid';
|
||||||
|
import { LogService } from 'uhk-common';
|
||||||
|
|
||||||
import { Constants, LogService } from 'uhk-common';
|
import { Constants, EepromTransfer, UsbCommand } from './constants';
|
||||||
|
|
||||||
|
const snooze = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HID API wrapper to support unified logging and async write
|
* HID API wrapper to support unified logging and async write
|
||||||
*/
|
*/
|
||||||
export class UhkHidDeviceService {
|
export class UhkHidDevice {
|
||||||
/**
|
/**
|
||||||
* Convert the Buffer to number[]
|
* Convert the Buffer to number[]
|
||||||
* @param {Buffer} buffer
|
* @param {Buffer} buffer
|
||||||
@@ -17,6 +20,27 @@ export class UhkHidDeviceService {
|
|||||||
return Array.prototype.slice.call(buffer, 0);
|
return Array.prototype.slice.call(buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split the communication package into 64 byte fragments
|
||||||
|
* @param {UsbCommand} usbCommand
|
||||||
|
* @param {Buffer} configBuffer
|
||||||
|
* @returns {Buffer[]}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
public static getTransferBuffers(usbCommand: UsbCommand, configBuffer: Buffer): Buffer[] {
|
||||||
|
const fragments: Buffer[] = [];
|
||||||
|
const MAX_SENDING_PAYLOAD_SIZE = Constants.MAX_PAYLOAD_SIZE - 4;
|
||||||
|
for (let offset = 0; offset < configBuffer.length; offset += MAX_SENDING_PAYLOAD_SIZE) {
|
||||||
|
const length = offset + MAX_SENDING_PAYLOAD_SIZE < configBuffer.length
|
||||||
|
? MAX_SENDING_PAYLOAD_SIZE
|
||||||
|
: configBuffer.length - offset;
|
||||||
|
const header = new Buffer([usbCommand, length, offset & 0xFF, offset >> 8]);
|
||||||
|
fragments.push(Buffer.concat([header, configBuffer.slice(offset, offset + length)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragments;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the communication package that will send over USB and
|
* Create the communication package that will send over USB and
|
||||||
* - add usb report code as 1st byte
|
* - add usb report code as 1st byte
|
||||||
@@ -27,7 +51,7 @@ export class UhkHidDeviceService {
|
|||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
private static getTransferData(buffer: Buffer): number[] {
|
private static getTransferData(buffer: Buffer): number[] {
|
||||||
const data = UhkHidDeviceService.convertBufferToIntArray(buffer);
|
const data = UhkHidDevice.convertBufferToIntArray(buffer);
|
||||||
// if data start with 0 need to add additional leading zero because HID API remove it.
|
// if data start with 0 need to add additional leading zero because HID API remove it.
|
||||||
// https://github.com/node-hid/node-hid/issues/187
|
// https://github.com/node-hid/node-hid/issues/187
|
||||||
if (data.length > 0 && data[0] === 0 && process.platform === 'win32') {
|
if (data.length > 0 && data[0] === 0 && process.platform === 'win32') {
|
||||||
@@ -108,7 +132,7 @@ export class UhkHidDeviceService {
|
|||||||
this.logService.error('[UhkHidDevice] Transfer error: ', err);
|
this.logService.error('[UhkHidDevice] Transfer error: ', err);
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
const logString = UhkHidDeviceService.bufferToString(receivedData);
|
const logString = UhkHidDevice.bufferToString(receivedData);
|
||||||
this.logService.debug('[UhkHidDevice] USB[R]:', logString);
|
this.logService.debug('[UhkHidDevice] USB[R]:', logString);
|
||||||
|
|
||||||
if (receivedData[0] !== 0) {
|
if (receivedData[0] !== 0) {
|
||||||
@@ -118,12 +142,17 @@ export class UhkHidDeviceService {
|
|||||||
return resolve(Buffer.from(receivedData));
|
return resolve(Buffer.from(receivedData));
|
||||||
});
|
});
|
||||||
|
|
||||||
const sendData = UhkHidDeviceService.getTransferData(buffer);
|
const sendData = UhkHidDevice.getTransferData(buffer);
|
||||||
this.logService.debug('[UhkHidDevice] USB[W]:', UhkHidDeviceService.bufferToString(sendData));
|
this.logService.debug('[UhkHidDevice] USB[W]:', UhkHidDevice.bufferToString(sendData));
|
||||||
device.write(sendData);
|
device.write(sendData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async writeConfigToEeprom(transferType: EepromTransfer): Promise<void> {
|
||||||
|
await this.write(new Buffer([UsbCommand.LaunchEepromTransfer, transferType]));
|
||||||
|
await this.waitUntilKeyboardBusy();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the communication chanel with UHK Device
|
* Close the communication chanel with UHK Device
|
||||||
*/
|
*/
|
||||||
@@ -136,6 +165,17 @@ export class UhkHidDeviceService {
|
|||||||
this._device = null;
|
this._device = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async waitUntilKeyboardBusy(): Promise<void> {
|
||||||
|
while (true) {
|
||||||
|
const buffer = await this.write(new Buffer([UsbCommand.GetKeyboardState]));
|
||||||
|
if (buffer[1] === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.logService.debug('Keyboard is busy, wait...');
|
||||||
|
await snooze(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the stored version of HID device. If not exist try to initialize.
|
* Return the stored version of HID device. If not exist try to initialize.
|
||||||
* @returns {HID}
|
* @returns {HID}
|
||||||
21
packages/uhk-usb/tsconfig.json
Normal file
21
packages/uhk-usb/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"sourceMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"declaration": false,
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"target": "es2016",
|
||||||
|
"typeRoots": [
|
||||||
|
"node_modules/@types"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es2015.iterable",
|
||||||
|
"dom",
|
||||||
|
"es2016"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Component, HostListener, ViewEncapsulation } from '@angular/core';
|
|||||||
import { animate, style, transition, trigger } from '@angular/animations';
|
import { animate, style, transition, trigger } from '@angular/animations';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { Action, Store } from '@ngrx/store';
|
import { Action, Store } from '@ngrx/store';
|
||||||
|
import { UhkBuffer } from 'uhk-common';
|
||||||
|
|
||||||
import 'rxjs/add/operator/last';
|
import 'rxjs/add/operator/last';
|
||||||
|
|
||||||
@@ -14,7 +15,6 @@ import {
|
|||||||
saveToKeyboardState
|
saveToKeyboardState
|
||||||
} from './store';
|
} from './store';
|
||||||
import { getUserConfiguration } from './store/reducers/user-configuration';
|
import { getUserConfiguration } from './store/reducers/user-configuration';
|
||||||
import { UhkBuffer } from './config-serializer/uhk-buffer';
|
|
||||||
import { ProgressButtonState } from './store/reducers/progress-button-state';
|
import { ProgressButtonState } from './store/reducers/progress-button-state';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
<svg-keyboard *ngFor="let layer of layers; let index = index; trackBy: trackKeyboard"
|
<svg-keyboard *ngFor="let layer of layers; let index = index; trackBy: trackKeyboard"
|
||||||
[@layerState]="layerAnimationState[index]"
|
[@layerState]="layerAnimationState[index]"
|
||||||
[moduleConfig]="layer.modules"
|
[moduleConfig]="layer.modules"
|
||||||
[keybindAnimationEnabled]="keybindAnimationEnabled"
|
[keybindAnimationEnabled]="keybindAnimationEnabled"
|
||||||
[halvesSplit]="halvesSplit"
|
[halvesSplit]="halvesSplit"
|
||||||
[capturingEnabled]="capturingEnabled"
|
[capturingEnabled]="capturingEnabled"
|
||||||
[selectedKey]="selectedKey"
|
[selectedKey]="selectedKey"
|
||||||
[selected]="selectedKey?.layerId === index"
|
[selected]="selectedKey?.layerId === index"
|
||||||
(keyClick)="keyClick.emit($event)"
|
[keyboardLayout]="keyboardLayout"
|
||||||
(keyHover)="keyHover.emit($event)"
|
(keyClick)="keyClick.emit($event)"
|
||||||
(capture)="capture.emit($event)"
|
(keyHover)="keyHover.emit($event)"
|
||||||
|
(capture)="capture.emit($event)"
|
||||||
>
|
>
|
||||||
</svg-keyboard>
|
</svg-keyboard>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 511 B After Width: | Height: | Size: 659 B |
@@ -1,7 +1,8 @@
|
|||||||
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
||||||
import { animate, keyframes, state, style, transition, trigger } from '@angular/animations';
|
import { animate, keyframes, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
import { Layer } from 'uhk-common';
|
||||||
|
|
||||||
import { Layer } from '../../../config-serializer/config-items/layer';
|
import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum';
|
||||||
|
|
||||||
type AnimationKeyboard =
|
type AnimationKeyboard =
|
||||||
'leftIn' |
|
'leftIn' |
|
||||||
@@ -69,6 +70,7 @@ export class KeyboardSliderComponent implements OnChanges {
|
|||||||
@Input() capturingEnabled: boolean;
|
@Input() capturingEnabled: boolean;
|
||||||
@Input() halvesSplit: boolean;
|
@Input() halvesSplit: boolean;
|
||||||
@Input() selectedKey: { layerId: number, moduleId: number, keyId: number };
|
@Input() selectedKey: { layerId: number, moduleId: number, keyId: number };
|
||||||
|
@Input() keyboardLayout = KeyboardLayout.ANSI;
|
||||||
@Output() keyClick = new EventEmitter();
|
@Output() keyClick = new EventEmitter();
|
||||||
@Output() keyHover = new EventEmitter();
|
@Output() keyHover = new EventEmitter();
|
||||||
@Output() capture = new EventEmitter();
|
@Output() capture = new EventEmitter();
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
import { Keymap } from 'uhk-common';
|
||||||
|
|
||||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import 'rxjs/add/operator/combineLatest';
|
import 'rxjs/add/operator/combineLatest';
|
||||||
import 'rxjs/add/operator/publishReplay';
|
import 'rxjs/add/operator/publishReplay';
|
||||||
|
|
||||||
import { Keymap } from '../../../config-serializer/config-items/keymap';
|
|
||||||
import { AppState } from '../../../store';
|
import { AppState } from '../../../store';
|
||||||
import { KeymapActions } from '../../../store/actions';
|
import { KeymapActions } from '../../../store/actions';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CanActivate, Router } from '@angular/router';
|
import { CanActivate, Router } from '@angular/router';
|
||||||
|
import { Keymap } from 'uhk-common';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
@@ -10,7 +11,6 @@ import 'rxjs/add/operator/switchMap';
|
|||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { Keymap } from '../../../config-serializer/config-items/keymap';
|
|
||||||
import { AppState } from '../../../store/index';
|
import { AppState } from '../../../store/index';
|
||||||
import { getKeymaps } from '../../../store/reducers/user-configuration';
|
import { getKeymaps } from '../../../store/reducers/user-configuration';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<ng-template [ngIf]="keymap$ | async">
|
<ng-template [ngIf]="keymap$ | async">
|
||||||
<keymap-header [keymap]="keymap$ | async" [deletable]="deletable$ | async" (downloadClick)="downloadKeymap()"></keymap-header>
|
<keymap-header [keymap]="keymap$ | async"
|
||||||
<svg-keyboard-wrap [keymap]="keymap$ | async" [halvesSplit]="keyboardSplit"></svg-keyboard-wrap>
|
[deletable]="deletable$ | async"
|
||||||
|
(downloadClick)="downloadKeymap()"></keymap-header>
|
||||||
|
<svg-keyboard-wrap [keymap]="keymap$ | async"
|
||||||
|
[halvesSplit]="keyboardSplit"
|
||||||
|
[keyboardLayout]="keyboardLayout$ | async"></svg-keyboard-wrap>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<div *ngIf="!(keymap$ | async)" class="not-found">
|
<div *ngIf="!(keymap$ | async)" class="not-found">
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Component, HostListener, ViewChild } from '@angular/core';
|
import { Component, HostListener, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { Keymap } from 'uhk-common';
|
||||||
|
|
||||||
import '@ngrx/core/add/operator/select';
|
import '@ngrx/core/add/operator/select';
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import 'rxjs/add/operator/first';
|
import 'rxjs/add/operator/first';
|
||||||
@@ -15,11 +16,11 @@ import 'rxjs/add/operator/combineLatest';
|
|||||||
|
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
|
|
||||||
import { Keymap } from '../../../config-serializer/config-items/keymap';
|
import { AppState, getKeyboardLayout } from '../../../store';
|
||||||
import { AppState } from '../../../store';
|
|
||||||
import { getKeymap, getKeymaps, getUserConfiguration } from '../../../store/reducers/user-configuration';
|
import { getKeymap, getKeymaps, getUserConfiguration } from '../../../store/reducers/user-configuration';
|
||||||
import 'rxjs/add/operator/pluck';
|
import 'rxjs/add/operator/pluck';
|
||||||
import { SvgKeyboardWrapComponent } from '../../svg/wrap/svg-keyboard-wrap.component';
|
import { SvgKeyboardWrapComponent } from '../../svg/wrap/svg-keyboard-wrap.component';
|
||||||
|
import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'keymap-edit',
|
selector: 'keymap-edit',
|
||||||
@@ -37,6 +38,7 @@ export class KeymapEditComponent {
|
|||||||
|
|
||||||
deletable$: Observable<boolean>;
|
deletable$: Observable<boolean>;
|
||||||
keymap$: Observable<Keymap>;
|
keymap$: Observable<Keymap>;
|
||||||
|
keyboardLayout$: Observable<KeyboardLayout>;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
route: ActivatedRoute) {
|
route: ActivatedRoute) {
|
||||||
@@ -49,6 +51,8 @@ export class KeymapEditComponent {
|
|||||||
|
|
||||||
this.deletable$ = store.let(getKeymaps())
|
this.deletable$ = store.let(getKeymaps())
|
||||||
.map((keymaps: Keymap[]) => keymaps.length > 1);
|
.map((keymaps: Keymap[]) => keymaps.length > 1);
|
||||||
|
|
||||||
|
this.keyboardLayout$ = store.select(getKeyboardLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadKeymap() {
|
downloadKeymap() {
|
||||||
|
|||||||
@@ -10,11 +10,10 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { Keymap } from 'uhk-common';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { Keymap } from '../../../config-serializer/config-items/keymap';
|
|
||||||
|
|
||||||
import { AppState } from '../../../store';
|
import { AppState } from '../../../store';
|
||||||
import { KeymapActions } from '../../../store/actions';
|
import { KeymapActions } from '../../../store/actions';
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import {
|
|||||||
MoveMouseMacroAction,
|
MoveMouseMacroAction,
|
||||||
MouseButtonMacroAction,
|
MouseButtonMacroAction,
|
||||||
TextMacroAction,
|
TextMacroAction,
|
||||||
Helper as MacroActionHelper
|
MacroActionHelper
|
||||||
} from '../../../config-serializer/config-items/macro-action';
|
} from 'uhk-common';
|
||||||
import { MacroDelayTabComponent, MacroMouseTabComponent, MacroKeyTabComponent, MacroTextTabComponent } from './tab';
|
import { MacroDelayTabComponent, MacroMouseTabComponent, MacroKeyTabComponent, MacroTextTabComponent } from './tab';
|
||||||
|
|
||||||
enum TabName {
|
enum TabName {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {
|
|||||||
OnInit,
|
OnInit,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { DelayMacroAction } from 'uhk-common';
|
||||||
|
|
||||||
import { DelayMacroAction } from '../../../../../config-serializer/config-items/macro-action';
|
|
||||||
import { MacroBaseComponent } from '../macro-base.component';
|
import { MacroBaseComponent } from '../macro-base.component';
|
||||||
|
|
||||||
const INITIAL_DELAY = 0.5; // In seconds
|
const INITIAL_DELAY = 0.5; // In seconds
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Component, Input, OnInit, ViewChild } from '@angular/core';
|
import { Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||||
|
|
||||||
import { KeystrokeAction } from '../../../../../config-serializer/config-items/key-action';
|
import { KeyMacroAction, KeystrokeAction, MacroSubAction } from 'uhk-common';
|
||||||
import { KeyMacroAction, MacroSubAction } from '../../../../../config-serializer/config-items/macro-action';
|
|
||||||
import { KeypressTabComponent, Tab } from '../../../../popover/tab';
|
import { KeypressTabComponent, Tab } from '../../../../popover/tab';
|
||||||
import { MacroBaseComponent } from '../macro-base.component';
|
import { MacroBaseComponent } from '../macro-base.component';
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
MoveMouseMacroAction,
|
MoveMouseMacroAction,
|
||||||
ScrollMouseMacroAction,
|
ScrollMouseMacroAction,
|
||||||
MacroSubAction
|
MacroSubAction
|
||||||
} from '../../../../../config-serializer/config-items/macro-action';
|
} from 'uhk-common';
|
||||||
import { Tab } from '../../../../popover/tab';
|
import { Tab } from '../../../../popover/tab';
|
||||||
import { MacroBaseComponent } from '../macro-base.component';
|
import { MacroBaseComponent } from '../macro-base.component';
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import {
|
|||||||
Renderer,
|
Renderer,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { TextMacroAction } from 'uhk-common';
|
||||||
|
|
||||||
import { TextMacroAction } from '../../../../../config-serializer/config-items/macro-action';
|
|
||||||
import { MacroBaseComponent } from '../macro-base.component';
|
import { MacroBaseComponent } from '../macro-base.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
import { Component, OnDestroy } from '@angular/core';
|
import { Component, OnDestroy } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
import { Macro, MacroAction } from 'uhk-common';
|
||||||
|
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import 'rxjs/add/operator/pluck';
|
import 'rxjs/add/operator/pluck';
|
||||||
|
|
||||||
import { Macro } from '../../../config-serializer/config-items/macro';
|
|
||||||
import { MacroAction } from '../../../config-serializer/config-items/macro-action/macro-action';
|
|
||||||
|
|
||||||
import { MacroActions } from '../../../store/actions';
|
import { MacroActions } from '../../../store/actions';
|
||||||
import { AppState } from '../../../store/index';
|
import { AppState } from '../../../store/index';
|
||||||
import { getMacro } from '../../../store/reducers/user-configuration';
|
import { getMacro } from '../../../store/reducers/user-configuration';
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
import { Macro } from 'uhk-common';
|
||||||
import { Macro } from '../../../config-serializer/config-items/macro';
|
|
||||||
|
|
||||||
import { MacroActions } from '../../../store/actions';
|
import { MacroActions } from '../../../store/actions';
|
||||||
import { AppState } from '../../../store/index';
|
import { AppState } from '../../../store/index';
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import { Component, Input, Output, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
|
||||||
import { KeyModifiers } from '../../../config-serializer/config-items/key-modifiers';
|
|
||||||
import {
|
import {
|
||||||
DelayMacroAction,
|
DelayMacroAction,
|
||||||
KeyMacroAction,
|
KeyMacroAction,
|
||||||
|
KeyModifiers,
|
||||||
MacroAction,
|
MacroAction,
|
||||||
MouseButtonMacroAction,
|
MouseButtonMacroAction,
|
||||||
MoveMouseMacroAction,
|
MoveMouseMacroAction,
|
||||||
ScrollMouseMacroAction,
|
ScrollMouseMacroAction,
|
||||||
TextMacroAction
|
TextMacroAction
|
||||||
} from '../../../config-serializer/config-items/macro-action';
|
} from 'uhk-common';
|
||||||
|
|
||||||
import { MapperService } from '../../../services/mapper.service';
|
import { MapperService } from '../../../services/mapper.service';
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { Component, EventEmitter, Input, Output, QueryList, ViewChildren, forwardRef } from '@angular/core';
|
import { Component, EventEmitter, Input, Output, QueryList, ViewChildren, forwardRef } from '@angular/core';
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
|
||||||
import { DragulaService } from 'ng2-dragula/ng2-dragula';
|
import { DragulaService } from 'ng2-dragula/ng2-dragula';
|
||||||
|
import { Macro, MacroAction } from 'uhk-common';
|
||||||
|
|
||||||
import { Macro } from '../../../config-serializer/config-items/macro';
|
|
||||||
import { MacroAction } from '../../../config-serializer/config-items/macro-action';
|
|
||||||
import { MacroItemComponent } from '../item';
|
import { MacroItemComponent } from '../item';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CanActivate, Router } from '@angular/router';
|
import { CanActivate, Router } from '@angular/router';
|
||||||
|
import { Macro } from 'uhk-common';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
@@ -10,7 +11,6 @@ import { Store } from '@ngrx/store';
|
|||||||
|
|
||||||
import { AppState } from '../../../store/index';
|
import { AppState } from '../../../store/index';
|
||||||
import { getMacros } from '../../../store/reducers/user-configuration';
|
import { getMacros } from '../../../store/reducers/user-configuration';
|
||||||
import { Macro } from '../../../config-serializer/config-items/macro';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MacroNotFoundGuard implements CanActivate {
|
export class MacroNotFoundGuard implements CanActivate {
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ import 'rxjs/add/operator/map';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
KeyAction,
|
KeyAction,
|
||||||
|
Keymap,
|
||||||
KeystrokeAction,
|
KeystrokeAction,
|
||||||
MouseAction,
|
MouseAction,
|
||||||
PlayMacroAction,
|
PlayMacroAction,
|
||||||
SwitchKeymapAction,
|
SwitchKeymapAction,
|
||||||
SwitchLayerAction
|
SwitchLayerAction
|
||||||
} from '../../config-serializer/config-items/key-action';
|
} from 'uhk-common';
|
||||||
import { Keymap } from '../../config-serializer/config-items/keymap';
|
|
||||||
|
|
||||||
import { Tab } from './tab/tab';
|
import { Tab } from './tab/tab';
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||||
|
|
||||||
import { Select2OptionData } from 'ng2-select2/ng2-select2';
|
import { Select2OptionData } from 'ng2-select2/ng2-select2';
|
||||||
|
import { Keymap, KeyAction, SwitchKeymapAction } from 'uhk-common';
|
||||||
|
|
||||||
import { KeyAction, SwitchKeymapAction } from '../../../../config-serializer/config-items/key-action';
|
|
||||||
import { Keymap } from '../../../../config-serializer/config-items/keymap';
|
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { Component, Input, OnChanges } from '@angular/core';
|
import { Component, Input, OnChanges } from '@angular/core';
|
||||||
|
|
||||||
import { Select2OptionData, Select2TemplateFunction } from 'ng2-select2';
|
import { Select2OptionData, Select2TemplateFunction } from 'ng2-select2';
|
||||||
|
import { KeyAction, KeystrokeAction, KeystrokeType } from 'uhk-common';
|
||||||
import { KeyAction, KeystrokeAction } from '../../../../config-serializer/config-items/key-action';
|
|
||||||
|
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
import { MapperService } from '../../../../services/mapper.service';
|
import { MapperService } from '../../../../services/mapper.service';
|
||||||
import { KeystrokeType } from '../../../../config-serializer/config-items/key-action/keystroke-type';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'keypress-tab',
|
selector: 'keypress-tab',
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Component, HostBinding, Input, OnChanges, SimpleChanges } from '@angular/core';
|
import { Component, HostBinding, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||||
|
import { KeyAction, LayerName, SwitchLayerAction } from 'uhk-common';
|
||||||
import { KeyAction, LayerName, SwitchLayerAction } from '../../../../config-serializer/config-items/key-action';
|
|
||||||
|
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
|
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
import { Select2OptionData } from 'ng2-select2/ng2-select2';
|
import { Select2OptionData } from 'ng2-select2/ng2-select2';
|
||||||
|
import { KeyAction, Macro, PlayMacroAction } from 'uhk-common';
|
||||||
import { KeyAction, PlayMacroAction } from '../../../../config-serializer/config-items/key-action';
|
|
||||||
import { Macro } from '../../../../config-serializer/config-items/macro';
|
|
||||||
|
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Component, Input, OnChanges } from '@angular/core';
|
import { Component, Input, OnChanges } from '@angular/core';
|
||||||
|
import { KeyAction, MouseAction, MouseActionParam } from 'uhk-common';
|
||||||
|
|
||||||
import { KeyAction, MouseAction, MouseActionParam } from '../../../../config-serializer/config-items/key-action';
|
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { EventEmitter, Output } from '@angular/core';
|
import { EventEmitter, Output } from '@angular/core';
|
||||||
|
import { KeyAction } from 'uhk-common';
|
||||||
import { KeyAction } from '../../../config-serializer/config-items/key-action';
|
|
||||||
|
|
||||||
export abstract class Tab {
|
export abstract class Tab {
|
||||||
@Output() validAction = new EventEmitter<boolean>();
|
@Output() validAction = new EventEmitter<boolean>();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Component, Renderer } from '@angular/core';
|
import { Component, Renderer } from '@angular/core';
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
import { Keymap, Macro } from 'uhk-common';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
@@ -8,9 +9,6 @@ import 'rxjs/add/operator/do';
|
|||||||
import 'rxjs/add/operator/map';
|
import 'rxjs/add/operator/map';
|
||||||
import 'rxjs/add/operator/let';
|
import 'rxjs/add/operator/let';
|
||||||
|
|
||||||
import { Keymap } from '../../config-serializer/config-items/keymap';
|
|
||||||
import { Macro } from '../../config-serializer/config-items/macro';
|
|
||||||
|
|
||||||
import { AppState, showAddonMenu, runningInElectron } from '../../store';
|
import { AppState, showAddonMenu, runningInElectron } from '../../store';
|
||||||
import { MacroActions } from '../../store/actions';
|
import { MacroActions } from '../../store/actions';
|
||||||
import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
|
import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { animate, state, trigger, style, transition } from '@angular/animations';
|
import { animate, state, trigger, style, transition } from '@angular/animations';
|
||||||
|
import { Module } from 'uhk-common';
|
||||||
|
|
||||||
import { Module } from '../../../config-serializer/config-items/module';
|
|
||||||
import { SvgModule } from '../module';
|
import { SvgModule } from '../module';
|
||||||
import { SvgModuleProviderService } from '../../../services/svg-module-provider.service';
|
import { SvgModuleProviderService } from '../../../services/svg-module-provider.service';
|
||||||
|
import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'svg-keyboard',
|
selector: 'svg-keyboard',
|
||||||
@@ -29,6 +30,7 @@ export class SvgKeyboardComponent implements OnInit {
|
|||||||
@Input() selectedKey: { layerId: number, moduleId: number, keyId: number };
|
@Input() selectedKey: { layerId: number, moduleId: number, keyId: number };
|
||||||
@Input() selected: boolean;
|
@Input() selected: boolean;
|
||||||
@Input() halvesSplit: boolean;
|
@Input() halvesSplit: boolean;
|
||||||
|
@Input() keyboardLayout = KeyboardLayout.ANSI;
|
||||||
@Output() keyClick = new EventEmitter();
|
@Output() keyClick = new EventEmitter();
|
||||||
@Output() keyHover = new EventEmitter();
|
@Output() keyHover = new EventEmitter();
|
||||||
@Output() capture = new EventEmitter();
|
@Output() capture = new EventEmitter();
|
||||||
@@ -45,13 +47,17 @@ export class SvgKeyboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.modules = this.svgModuleProvider.getSvgModules();
|
this.setModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (changes.halvesSplit) {
|
if (changes.halvesSplit) {
|
||||||
this.updateModuleAnimationStates();
|
this.updateModuleAnimationStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changes['keyboardLayout']) {
|
||||||
|
this.setModules();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
|
onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
|
||||||
@@ -87,4 +93,7 @@ export class SvgKeyboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setModules() {
|
||||||
|
this.modules = this.svgModuleProvider.getSvgModules(this.keyboardLayout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ import { Subscription } from 'rxjs/Subscription';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
KeyAction,
|
KeyAction,
|
||||||
|
KeyModifiers,
|
||||||
KeystrokeAction,
|
KeystrokeAction,
|
||||||
LayerName,
|
LayerName,
|
||||||
|
Macro,
|
||||||
MouseAction,
|
MouseAction,
|
||||||
PlayMacroAction,
|
PlayMacroAction,
|
||||||
SwitchKeymapAction,
|
SwitchKeymapAction,
|
||||||
SwitchLayerAction
|
SwitchLayerAction
|
||||||
} from '../../../../config-serializer/config-items/key-action';
|
} from 'uhk-common';
|
||||||
import { KeyModifiers } from '../../../../config-serializer/config-items/key-modifiers';
|
|
||||||
import { Macro } from '../../../../config-serializer/config-items/macro';
|
|
||||||
|
|
||||||
import { CaptureService } from '../../../../services/capture.service';
|
import { CaptureService } from '../../../../services/capture.service';
|
||||||
import { MapperService } from '../../../../services/mapper.service';
|
import { MapperService } from '../../../../services/mapper.service';
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Component, Input, OnChanges, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, Input, OnChanges, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||||
|
import { KeyModifiers, KeystrokeAction } from 'uhk-common';
|
||||||
|
|
||||||
import { KeystrokeAction } from '../../../../config-serializer/config-items/key-action';
|
|
||||||
import { KeyModifiers } from '../../../../config-serializer/config-items/key-modifiers';
|
|
||||||
import { MapperService } from '../../../../services/mapper.service';
|
import { MapperService } from '../../../../services/mapper.service';
|
||||||
|
|
||||||
class SvgAttributes {
|
class SvgAttributes {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Component, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
|
||||||
|
|
||||||
import { MouseAction, MouseActionParam } from '../../../../config-serializer/config-items/key-action';
|
import { MouseAction, MouseActionParam } from 'uhk-common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'g[svg-mouse-key]',
|
selector: 'g[svg-mouse-key]',
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core';
|
||||||
|
import { KeyAction } from 'uhk-common';
|
||||||
import { KeyAction } from '../../../config-serializer/config-items/key-action';
|
|
||||||
|
|
||||||
import { SvgKeyboardKey } from '../keys';
|
import { SvgKeyboardKey } from '../keys';
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user