Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
547ab738c2 | ||
|
|
3de9e9aa84 | ||
|
|
01ac4c1e8b | ||
|
|
a0c8849f13 | ||
|
|
2a3dfcb0d0 | ||
|
|
2b3462c33f | ||
|
|
a0b838b2e9 | ||
|
|
90f56c350e | ||
|
|
5ceca41e0f | ||
|
|
721a4dc6e7 | ||
|
|
c9f03b4e57 | ||
|
|
bbb6839f7e | ||
|
|
dd973c80ea | ||
|
|
48574a121a | ||
|
|
8bc2462589 | ||
|
|
975ab8a5e9 | ||
|
|
f0a54768d4 |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [1.0.3] - 2017-12-28
|
||||
|
||||
Firmware: [8.0.**0**](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/8.0.**0**) | Device Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Add LED brightness settings.
|
||||
- Some key actions, for example Left Arrow were displayed as text with modifiers and as icon without modifires. Now, they're always displayed as icons.
|
||||
- Clean up firmware update console messages a bit.
|
||||
- Remove the add keymap button because this feature is not only useless but confusing until it gets reimplemented.
|
||||
- Explicitly mention on the macro tab of the key action popover that macro playback is not implemented yet.
|
||||
- Downgrade to firmware 8.0.0 because the left I2C watchdog of firmware 8.0.1 is not proven yet.
|
||||
|
||||
## [1.0.2] - 2017-12-25
|
||||
|
||||
Firmware: [**8.0.1**](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/8.0.1) | Device Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Fix firmware upgrade on Linux.
|
||||
|
||||
## [1.0.1] - 2017-12-22
|
||||
|
||||
Firmware: [7.0.0](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/7.0.0) | Device Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
19
README.md
19
README.md
@@ -7,7 +7,17 @@ Agent is the configuration application of the [Ultimate Hacking Keyboard](https:
|
||||
|
||||
[Give it a whirl!](http://ultimatehackingkeyboard.github.io/agent/)
|
||||
|
||||
## Set up instructions
|
||||
## Two builds to rule them all
|
||||
|
||||
It's worth mentioning that Agent has two builds.
|
||||
|
||||
The **electron build** is the desktop application which is meant to be used if you have an actual UHK at hand. It starts with an opening screen which detects your UHK. You cannot get past this screen without connecting a UHK via USB.
|
||||
|
||||
The **web build** is meant to be used for demonstation purposes, so people who don't yet own a UHK can get a feel of Agent and its capabilities in their browser. Eventually, WebUSB support will be added to the web build, making it able to communicate with the UHK. Given the sandboxed nature of browers, the web build will always lack features that the electron build offers, so this won't make the electron build obsolete.
|
||||
|
||||
The two builds share code as much as possible.
|
||||
|
||||
## Building the electron application
|
||||
|
||||
First up, make sure that node >=8.1.x and npm >=5.1.x are installed on your system. Next up:
|
||||
|
||||
@@ -24,6 +34,13 @@ npm run electron
|
||||
|
||||
At this point, Agent should be running on your machine.
|
||||
|
||||
## Developing the web application
|
||||
|
||||
- The frontend code is located in `packages/uhk-web/`
|
||||
- Run the project locally with `npm run server:web`
|
||||
- View the app at `http://localhost:8080`
|
||||
- The app will automatically reload when you make changes
|
||||
|
||||
## Contributing
|
||||
|
||||
Wanna contribute? Please let us show you [how](CONTRIBUTING.md).
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uhk-agent",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"author": "Ultimate Gadget Laboratories",
|
||||
"main": "electron/dist/electron-main.js",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "Agent is the configuration application of the Ultimate Hacking Keyboard.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
"dependencies": {
|
||||
"node-hid": "0.5.7"
|
||||
},
|
||||
"firmwareVersion": "7.0.0",
|
||||
"firmwareVersion": "8.0.0",
|
||||
"deviceProtocolVersion": "4.0.0",
|
||||
"moduleProtocolVersion": "3.0.0",
|
||||
"userConfigVersion": "4.0.0",
|
||||
"hardwareConfigVersion": "1.0.0"
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ export class UhkBlhost {
|
||||
let blhostPath;
|
||||
switch (process.platform) {
|
||||
case 'linux':
|
||||
blhostPath = 'linux/amd64/blhost';
|
||||
blhostPath = 'linux/x86_64/blhost';
|
||||
break;
|
||||
case 'darwin':
|
||||
blhostPath = 'mac/blhost';
|
||||
|
||||
@@ -26,7 +26,7 @@ export class UhkOperations {
|
||||
await this.blhost.runBlhostCommand([...prefix, 'flash-erase-region', '0xc000', '475136']);
|
||||
await this.blhost.runBlhostCommand([...prefix, 'flash-image', `"${firmwarePath}"`]);
|
||||
await this.blhost.runBlhostCommand([...prefix, 'reset']);
|
||||
this.logService.debug('[UhkOperations] End flashing right firmware');
|
||||
this.logService.debug('[UhkOperations] Right firmware successfully flashed');
|
||||
}
|
||||
|
||||
public async updateLeftModule(firmwarePath = this.getLeftModuleFirmwarePath()) {
|
||||
@@ -58,7 +58,8 @@ export class UhkOperations {
|
||||
await this.device.sendKbootCommandToModule(ModuleSlotToI2cAddress.leftHalf, KbootCommands.idle);
|
||||
this.device.close();
|
||||
|
||||
this.logService.debug('[UhkOperations] End flashing left module firmware');
|
||||
this.logService.debug('[UhkOperations] Left firmware successfully flashed');
|
||||
this.logService.debug('[UhkOperations] Both left and right firmwares successfully flashed');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -89,7 +89,7 @@ export async function retry(command: Function, maxTry = 3, logService?: LogServi
|
||||
throw err;
|
||||
} else {
|
||||
if (logService) {
|
||||
logService.error(`[retry] failed, but try run FUNCTION:\n ${command}, \n retry: ${retryCount}`);
|
||||
logService.info(`[retry] failed, but try run FUNCTION:\n ${command}, \n retry: ${retryCount}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"../node_modules/nouislider/distribute/nouislider.min.css",
|
||||
"styles.scss"
|
||||
],
|
||||
"scripts": [
|
||||
"../node_modules/bootstrap/dist/js/bootstrap.js",
|
||||
"../node_modules/select2/dist/js/select2.full.js"
|
||||
"../node_modules/select2/dist/js/select2.full.js",
|
||||
"../node_modules/nouislider/distribute/nouislider.js"
|
||||
],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
"environments": {
|
||||
|
||||
2356
packages/uhk-web/package-lock.json
generated
2356
packages/uhk-web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -69,9 +69,11 @@
|
||||
"less-loader": "4.0.5",
|
||||
"lodash": "4.17.4",
|
||||
"ng2-dragula": "1.5.0",
|
||||
"ng2-nouislider": "^1.7.6",
|
||||
"ng2-select2": "1.0.0-beta.10",
|
||||
"ngrx-store-freeze": "0.1.9",
|
||||
"node-hid": "0.5.4",
|
||||
"nouislider": "^10.1.0",
|
||||
"postcss-loader": "1.3.3",
|
||||
"postcss-url": "5.1.2",
|
||||
"protractor": "5.1.2",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Routes } from '@angular/router';
|
||||
import { DeviceConfigurationComponent } from './configuration/device-configuration.component';
|
||||
import { DeviceFirmwareComponent } from './firmware/device-firmware.component';
|
||||
import { MouseSpeedComponent } from './mouse-speed/mouse-speed.component';
|
||||
import { LEDBrightnessComponent } from './led-brightness/led-brightness.component';
|
||||
|
||||
export const deviceRoutes: Routes = [
|
||||
{
|
||||
@@ -21,6 +22,10 @@ export const deviceRoutes: Routes = [
|
||||
path: 'mouse-speed',
|
||||
component: MouseSpeedComponent
|
||||
},
|
||||
{
|
||||
path: 'led-brightness',
|
||||
component: LEDBrightnessComponent
|
||||
},
|
||||
{
|
||||
path: 'firmware',
|
||||
component: DeviceFirmwareComponent
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './configuration/device-configuration.component';
|
||||
export * from './firmware/device-firmware.component';
|
||||
export * from './mouse-speed/mouse-speed.component';
|
||||
export * from './led-brightness/led-brightness.component';
|
||||
export * from './device.routes';
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<h1>
|
||||
<i class="fa fa-sliders"></i>
|
||||
<span>LED brightness</span>
|
||||
</h1>
|
||||
<div class="row led-setting">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<label>LED display icon and layer texts brightness</label>
|
||||
<div class="slider-wrapper-container">
|
||||
<slider-wrapper
|
||||
[min]="0"
|
||||
[max]="255"
|
||||
[step]="1"
|
||||
[pips]="sliderPips"
|
||||
[(ngModel)]="iconsAndLayerTextsBrightness"
|
||||
(ngModelChange)="onSetPropertyValue('iconsAndLayerTextsBrightness', $event)"></slider-wrapper>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row led-setting">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<label>LED display alphanumeric segments brightness</label>
|
||||
<div class="slider-wrapper-container">
|
||||
<slider-wrapper
|
||||
[min]="0"
|
||||
[max]="255"
|
||||
[step]="1"
|
||||
[pips]="sliderPips"
|
||||
[(ngModel)]="alphanumericSegmentsBrightness"
|
||||
(ngModelChange)="onSetPropertyValue('alphanumericSegmentsBrightness', $event)"></slider-wrapper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row led-setting">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<label>Key backlight brightness</label>
|
||||
<div class="slider-wrapper-container">
|
||||
<slider-wrapper
|
||||
[min]="0"
|
||||
[max]="255"
|
||||
[step]="1"
|
||||
[pips]="sliderPips"
|
||||
[(ngModel)]="keyBacklightBrightness"
|
||||
(ngModelChange)="onSetPropertyValue('keyBacklightBrightness', $event)"></slider-wrapper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
:host {
|
||||
overflow-y: auto;
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.led-setting {
|
||||
margin-bottom: 6rem;
|
||||
}
|
||||
|
||||
.slider-wrapper-container {
|
||||
margin-left: 1.6rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { AfterViewInit, Component, OnInit, OnDestroy, ViewChildren, QueryList } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState, getUserConfiguration } from '../../../store';
|
||||
import { SetUserConfigurationValueAction } from '../../../store/actions/user-config';
|
||||
import { SliderPips } from '../../slider-wrapper/slider-wrapper.component';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { UserConfiguration } from 'uhk-common';
|
||||
|
||||
@Component({
|
||||
selector: 'device-led-brightness',
|
||||
templateUrl: './led-brightness.component.html',
|
||||
styleUrls: ['./led-brightness.component.scss'],
|
||||
host: {
|
||||
'class': 'container-fluid'
|
||||
}
|
||||
})
|
||||
export class LEDBrightnessComponent implements OnInit, OnDestroy {
|
||||
public iconsAndLayerTextsBrightness: number = 0;
|
||||
public alphanumericSegmentsBrightness: number = 0;
|
||||
public keyBacklightBrightness: number = 0;
|
||||
public sliderPips: SliderPips = {
|
||||
mode: 'positions',
|
||||
values: [0, 50, 100],
|
||||
density: 6,
|
||||
stepped: true
|
||||
};
|
||||
|
||||
private userConfig$: Store<UserConfiguration>;
|
||||
private userConfigSubscription: Subscription;
|
||||
|
||||
constructor(private store: Store<AppState>) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.userConfig$ = this.store.select(getUserConfiguration);
|
||||
this.userConfigSubscription = this.userConfig$.subscribe(config => {
|
||||
this.iconsAndLayerTextsBrightness = config.iconsAndLayerTextsBrightness;
|
||||
this.alphanumericSegmentsBrightness = config.alphanumericSegmentsBrightness;
|
||||
this.keyBacklightBrightness = config.keyBacklightBrightness;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.userConfigSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
onSetPropertyValue(propertyName: string, value: number): void {
|
||||
this.store.dispatch(new SetUserConfigurationValueAction({
|
||||
propertyName,
|
||||
value
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
<span> No macros are available to choose from. Create a macro first! </span>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="macroOptions.length > 0">
|
||||
<p><i>Please note that macro playback is not implemented yet. You can bind macros, but they don't have any effect.</i></p>
|
||||
<div class="macro-selector">
|
||||
<b> Play macro: </b>
|
||||
<select2 [data]="macroOptions" [value]="macroOptions[selectedMacroIndex].id" (valueChanged)="onChange($event)" [width]="'100%'"></select2>
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
[class.disabled]="updatingFirmware$ | async">Mouse speed</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/led-brightness']"
|
||||
[class.disabled]="updatingFirmware$ | async">LED brightness</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/configuration']"
|
||||
@@ -40,11 +46,11 @@
|
||||
<li class="sidebar__level-1--item">
|
||||
<div class="sidebar__level-1">
|
||||
<i class="fa fa-keyboard-o"></i> Keymaps
|
||||
<a [routerLink]="['/keymap/add']"
|
||||
<!--a [routerLink]="['/keymap/add']"
|
||||
class="btn btn-default pull-right btn-sm"
|
||||
[class.disabled]="updatingFirmware$ | async">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</a-->
|
||||
<i class="fa fa-chevron-up pull-right"
|
||||
(click)="toggleHide($event, 'keymap')"></i>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="slider-container">
|
||||
<nouislider
|
||||
[min]="min"
|
||||
[max]="max"
|
||||
[step]="step"
|
||||
[keyboard]="true"
|
||||
[tooltips]="true"
|
||||
[(ngModel)]="value"
|
||||
(ngModelChange)="onSliderChange($event)"></nouislider>
|
||||
</div>
|
||||
<div class="slider-value">
|
||||
<div class="value-indicator">{{value}} {{valueUnit}}</div>
|
||||
</div>
|
||||
@@ -0,0 +1,17 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.slider-container {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.slider-value {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.value-indicator {
|
||||
margin: 1rem 1rem 1rem 3rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import { AfterViewInit, Component, EventEmitter, forwardRef, Input, Output, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { NouisliderComponent } from 'ng2-nouislider/src/nouislider';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
|
||||
export interface SliderPips {
|
||||
mode: string;
|
||||
values: number[];
|
||||
density: number;
|
||||
stepped?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'slider-wrapper',
|
||||
templateUrl: './slider-wrapper.component.html',
|
||||
styleUrls: ['./slider-wrapper.component.scss'],
|
||||
providers: [
|
||||
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SliderWrapperComponent), multi: true }
|
||||
]
|
||||
})
|
||||
export class SliderWrapperComponent implements AfterViewInit, ControlValueAccessor, OnDestroy {
|
||||
@ViewChild(NouisliderComponent) slider: NouisliderComponent;
|
||||
@Input() min: number;
|
||||
@Input() max: number;
|
||||
@Input() step: number;
|
||||
@Input() pips: SliderPips;
|
||||
@Input() valueUnit: string;
|
||||
@Output() onChange = new EventEmitter<number>();
|
||||
|
||||
public value: number;
|
||||
private changeObserver$: Observer<number>;
|
||||
private changeDebounceTime: number = 300;
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
if (this.pips) {
|
||||
this.slider.slider.pips(this.pips);
|
||||
}
|
||||
|
||||
// Hide tooltips and show them when dragging slider handle
|
||||
this.slider.slider.target.querySelector('.noUi-tooltip').style.display = 'none';
|
||||
|
||||
this.slider.slider.on('start', function() {
|
||||
this.target.querySelector('.noUi-tooltip').style.display = 'block';
|
||||
});
|
||||
this.slider.slider.on('end', function() {
|
||||
this.target.querySelector('.noUi-tooltip').style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.changeObserver$) {
|
||||
this.changeObserver$.complete();
|
||||
}
|
||||
}
|
||||
|
||||
writeValue(value: number): void {
|
||||
this.value = value || this.min;
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched() {}
|
||||
|
||||
onSliderChange(value: number): void {
|
||||
if (!this.changeObserver$) {
|
||||
Observable.create(observer => {
|
||||
this.changeObserver$ = observer;
|
||||
}).debounceTime(this.changeDebounceTime)
|
||||
.distinctUntilChanged()
|
||||
.subscribe(this.propagateChange);
|
||||
|
||||
return; // No change event on first change as the value is just being set
|
||||
}
|
||||
this.changeObserver$.next(value);
|
||||
}
|
||||
|
||||
private propagateChange: any = () => {};
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
<svg [attr.viewBox]="viewBox" [attr.width]="textContainer.width" [attr.height]="textContainer.height"
|
||||
[attr.x]="textContainer.x" [attr.y]="textContainer.y" [ngSwitch]="labelType">
|
||||
<svg:g svg-single-icon-key *ngSwitchCase="'icon'"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[icon]="labelSource">
|
||||
</svg:g>
|
||||
<svg:g svg-one-line-text-key *ngSwitchCase="'one-line'"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -127,21 +127,23 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
let newLabelSource: string[];
|
||||
if (this.keystrokeAction.hasScancode()) {
|
||||
const scancode: number = this.keystrokeAction.scancode;
|
||||
newLabelSource = this.mapper.scanCodeToText(scancode, this.keystrokeAction.type);
|
||||
if (newLabelSource) {
|
||||
if (newLabelSource.length === 1) {
|
||||
this.labelSource = newLabelSource[0];
|
||||
this.labelType = 'one-line';
|
||||
} else {
|
||||
this.labelSource = newLabelSource;
|
||||
this.labelType = 'two-line';
|
||||
}
|
||||
} else {
|
||||
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode, this.keystrokeAction.type);
|
||||
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode, this.keystrokeAction.type);
|
||||
if (this.labelSource) {
|
||||
this.labelType = 'icon';
|
||||
} else {
|
||||
let newLabelSource: string[];
|
||||
newLabelSource = this.mapper.scanCodeToText(scancode, this.keystrokeAction.type);
|
||||
if (newLabelSource) {
|
||||
if (newLabelSource.length === 1) {
|
||||
this.labelSource = newLabelSource[0];
|
||||
this.labelType = 'one-line';
|
||||
} else {
|
||||
this.labelSource = newLabelSource;
|
||||
this.labelType = 'two-line';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.labelType = 'empty';
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface UserConfigurationValue {
|
||||
propertyName: string;
|
||||
value: number;
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { Component } from '@angular/core';
|
||||
@Component({
|
||||
selector: 'main-page',
|
||||
templateUrl: './main.page.html',
|
||||
styles: [':host{height:100%; display: inline-block; width: 100%}']
|
||||
styles: [':host{height:100%; width:100%}']
|
||||
})
|
||||
export class MainPage {
|
||||
|
||||
|
||||
@@ -71,7 +71,11 @@ export class MapperService {
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
return 'assets/compiled_sprite.svg#' + map.get(scanCode);
|
||||
const id = map.get(scanCode);
|
||||
if (!id) {
|
||||
return undefined;
|
||||
}
|
||||
return `assets/compiled_sprite.svg#${id}`;
|
||||
}
|
||||
|
||||
public getIcon(iconName: string): string {
|
||||
|
||||
@@ -7,13 +7,15 @@ import { ConfirmationPopoverModule } from 'angular-confirmation-popover';
|
||||
|
||||
import { DragulaModule } from 'ng2-dragula/ng2-dragula';
|
||||
import { Select2Module } from 'ng2-select2/ng2-select2';
|
||||
import { NouisliderModule } from 'ng2-nouislider';
|
||||
|
||||
import { AddOnComponent } from './components/add-on';
|
||||
import { KeyboardSliderComponent } from './components/keyboard/slider';
|
||||
import {
|
||||
DeviceConfigurationComponent,
|
||||
DeviceFirmwareComponent,
|
||||
MouseSpeedComponent
|
||||
MouseSpeedComponent,
|
||||
LEDBrightnessComponent
|
||||
} from './components/device';
|
||||
import { KeymapAddComponent, KeymapEditComponent, KeymapHeaderComponent } from './components/keymap';
|
||||
import { LayersComponent } from './components/layers';
|
||||
@@ -98,6 +100,7 @@ import { LoadingDevicePageComponent } from './pages/loading-page/loading-device.
|
||||
import { UhkDeviceLoadingGuard } from './services/uhk-device-loading.guard';
|
||||
import { UhkDeviceLoadedGuard } from './services/uhk-device-loaded.guard';
|
||||
import { XtermComponent } from './components/xterm/xterm.component';
|
||||
import { SliderWrapperComponent } from './components/slider-wrapper/slider-wrapper.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -105,6 +108,7 @@ import { XtermComponent } from './components/xterm/xterm.component';
|
||||
DeviceConfigurationComponent,
|
||||
DeviceFirmwareComponent,
|
||||
MouseSpeedComponent,
|
||||
LEDBrightnessComponent,
|
||||
KeymapEditComponent,
|
||||
KeymapHeaderComponent,
|
||||
NotificationComponent,
|
||||
@@ -163,7 +167,8 @@ import { XtermComponent } from './components/xterm/xterm.component';
|
||||
MainPage,
|
||||
ProgressButtonComponent,
|
||||
LoadingDevicePageComponent,
|
||||
XtermComponent
|
||||
XtermComponent,
|
||||
SliderWrapperComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
@@ -172,6 +177,7 @@ import { XtermComponent } from './components/xterm/xterm.component';
|
||||
DragulaModule,
|
||||
routing,
|
||||
Select2Module,
|
||||
NouisliderModule,
|
||||
NotifierModule.withConfig(angularNotifierConfig),
|
||||
ConfirmationPopoverModule.forRoot({
|
||||
confirmButtonType: 'danger' // set defaults here
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { type, UserConfiguration, ConfigurationReply } from 'uhk-common';
|
||||
import { UserConfigurationValue } from '../../models/user-configuration-value';
|
||||
|
||||
const PREFIX = '[user-config] ';
|
||||
|
||||
@@ -13,7 +14,8 @@ export const ActionTypes = {
|
||||
SAVE_USER_CONFIG_IN_JSON_FILE: type(PREFIX + 'Save User Config in JSON file'),
|
||||
SAVE_USER_CONFIG_IN_BIN_FILE: type(PREFIX + 'Save User Config in binary file'),
|
||||
LOAD_RESET_USER_CONFIGURATION: type(PREFIX + 'Load reset user configuration'),
|
||||
RENAME_USER_CONFIGURATION: type(PREFIX + 'Rename user configuration')
|
||||
RENAME_USER_CONFIGURATION: type(PREFIX + 'Rename user configuration'),
|
||||
SET_USER_CONFIGURATION_VALUE: type(PREFIX + 'Set user configuration value')
|
||||
};
|
||||
|
||||
export class LoadUserConfigAction implements Action {
|
||||
@@ -67,6 +69,13 @@ export class RenameUserConfigurationAction implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class SetUserConfigurationValueAction implements Action {
|
||||
type = ActionTypes.SET_USER_CONFIGURATION_VALUE;
|
||||
|
||||
constructor(public payload: UserConfigurationValue) {
|
||||
}
|
||||
}
|
||||
|
||||
export type Actions
|
||||
= LoadUserConfigAction
|
||||
| LoadUserConfigSuccessAction
|
||||
@@ -77,4 +86,5 @@ export type Actions
|
||||
| SaveUserConfigInBinaryFileAction
|
||||
| LoadResetUserConfigurationAction
|
||||
| RenameUserConfigurationAction
|
||||
| SetUserConfigurationValueAction
|
||||
;
|
||||
|
||||
@@ -72,7 +72,7 @@ export class UserConfigEffects {
|
||||
KeymapActions.SET_DEFAULT, KeymapActions.REMOVE, KeymapActions.SAVE_KEY,
|
||||
MacroActions.ADD, MacroActions.DUPLICATE, MacroActions.EDIT_NAME, MacroActions.REMOVE, MacroActions.ADD_ACTION,
|
||||
MacroActions.SAVE_ACTION, MacroActions.DELETE_ACTION, MacroActions.REORDER_ACTION,
|
||||
ActionTypes.RENAME_USER_CONFIGURATION) as
|
||||
ActionTypes.RENAME_USER_CONFIGURATION, ActionTypes.SET_USER_CONFIGURATION_VALUE) as
|
||||
Observable<KeymapAction | MacroAction | RenameUserConfigurationAction>)
|
||||
.withLatestFrom(this.store.select(getUserConfiguration), this.store.select(getPrevUserConfiguration))
|
||||
.mergeMap(([action, config, prevUserConfiguration]) => {
|
||||
|
||||
@@ -246,6 +246,11 @@ export function reducer(state = initialState, action: Action & { payload?: any }
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionTypes.SET_USER_CONFIGURATION_VALUE: {
|
||||
changedUserConfiguration[action.payload.propertyName] = action.payload.value;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -90,3 +90,7 @@ a.disabled {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.noUi-value {
|
||||
top: 2rem;
|
||||
}
|
||||
|
||||
@@ -85,10 +85,12 @@ module.exports = {
|
||||
],
|
||||
"scripts": [
|
||||
"script-loader!./node_modules/bootstrap/dist/js/bootstrap.js",
|
||||
"script-loader!./node_modules/select2/dist/js/select2.full.js"
|
||||
"script-loader!./node_modules/select2/dist/js/select2.full.js",
|
||||
"script-loader!./node_modules/nouislider/distribute/nouislider.js"
|
||||
],
|
||||
"styles": [
|
||||
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"./node_modules/nouislider/distribute/nouislider.min.css",
|
||||
"./src/styles.scss"
|
||||
]
|
||||
},
|
||||
@@ -126,6 +128,7 @@ module.exports = {
|
||||
{
|
||||
"exclude": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.css$/,
|
||||
@@ -150,6 +153,7 @@ module.exports = {
|
||||
{
|
||||
"exclude": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.scss$|\.sass$/,
|
||||
@@ -182,6 +186,7 @@ module.exports = {
|
||||
{
|
||||
"exclude": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.less$/,
|
||||
@@ -212,6 +217,7 @@ module.exports = {
|
||||
{
|
||||
"exclude": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.styl$/,
|
||||
@@ -243,6 +249,7 @@ module.exports = {
|
||||
{
|
||||
"include": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.css$/,
|
||||
@@ -267,6 +274,7 @@ module.exports = {
|
||||
{
|
||||
"include": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.scss$|\.sass$/,
|
||||
@@ -299,6 +307,7 @@ module.exports = {
|
||||
{
|
||||
"include": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.less$/,
|
||||
@@ -329,6 +338,7 @@ module.exports = {
|
||||
{
|
||||
"include": [
|
||||
path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
|
||||
path.join(process.cwd(), "node_modules/nouislider/distribute/nouislider.min.css"),
|
||||
path.join(process.cwd(), "src/styles.scss")
|
||||
],
|
||||
"test": /\.styl$/,
|
||||
|
||||
1
packages/usb/zadic/install-win-driver-ia32.bat
Normal file
1
packages/usb/zadic/install-win-driver-ia32.bat
Normal file
@@ -0,0 +1 @@
|
||||
zadic-ia32.exe --vid 0x1d50 --pid 0x6120 --iface 0 --usealldevices --noprompt
|
||||
1
packages/usb/zadic/install-win-driver-x64.bat
Normal file
1
packages/usb/zadic/install-win-driver-x64.bat
Normal file
@@ -0,0 +1 @@
|
||||
zadic-x64.exe --vid 0x1d50 --pid 0x6120 --iface 0 --usealldevices --noprompt
|
||||
BIN
packages/usb/zadic/zadic-ia32.exe
Normal file
BIN
packages/usb/zadic/zadic-ia32.exe
Normal file
Binary file not shown.
BIN
packages/usb/zadic/zadic-x64.exe
Normal file
BIN
packages/usb/zadic/zadic-x64.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user