Skip to content

Commit cdc4a16

Browse files
ert78gbmondalaci
authored andcommitted
feat(config): Add deviceName to the user config (#474)
* add device name to configuration * feat(config): Rename user configuration * style: fix tslint error * test: Fix unit tests * test: Add UserConfiguration device name test * set device name if faild the user-config read from device * feat(device): Remove the first 0 from USB[W] dump
1 parent 9885439 commit cdc4a16

File tree

13 files changed

+141
-18
lines changed

13 files changed

+141
-18
lines changed

packages/uhk-common/src/config-serializer/config-items/macro-action/keymap.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ describe('keymap', () => {
44
it('should normalize SwitchLayerAction if non base layer action is not SwitchLayerAction', () => {
55
const inputJsonConfig = {
66
dataModelVersion: 1,
7+
deviceName: 'My UHK',
78
moduleConfigurations: [],
89
macros: [],
910
keymaps: [
@@ -63,6 +64,7 @@ describe('keymap', () => {
6364
};
6465
const expectedJsonConfig = {
6566
dataModelVersion: 1,
67+
deviceName: 'My UHK',
6668
moduleConfigurations: [],
6769
macros: [],
6870
keymaps: [
@@ -131,6 +133,7 @@ describe('keymap', () => {
131133
it('should normalize SwitchLayerAction if non base layer action is other SwitchLayerAction', () => {
132134
const inputJsonConfig = {
133135
dataModelVersion: 1,
136+
deviceName: 'My UHK',
134137
moduleConfigurations: [],
135138
macros: [],
136139
keymaps: [
@@ -190,6 +193,7 @@ describe('keymap', () => {
190193
};
191194
const expectedJsonConfig = {
192195
dataModelVersion: 1,
196+
deviceName: 'My UHK',
193197
moduleConfigurations: [],
194198
macros: [],
195199
keymaps: [

packages/uhk-common/src/config-serializer/config-items/user-configuration.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ describe('user-configuration', () => {
99
it('should transform an empty config', () => {
1010
jsonTester({
1111
dataModelVersion: 1,
12+
deviceName: 'My UHK',
1213
moduleConfigurations: [],
1314
macros: [],
1415
keymaps: []
@@ -18,6 +19,7 @@ describe('user-configuration', () => {
1819
it('should transform a null keyActionType ', () => {
1920
jsonTester({
2021
dataModelVersion: 1,
22+
deviceName: 'My UHK',
2123
moduleConfigurations: [],
2224
macros: [],
2325
keymaps: [
@@ -39,6 +41,21 @@ describe('user-configuration', () => {
3941
]
4042
});
4143
});
44+
45+
it('Should set the device name to "My UHK" if not exists in the config', () => {
46+
const original = {
47+
dataModelVersion: 1,
48+
moduleConfigurations: [],
49+
macros: [],
50+
keymaps: []
51+
};
52+
53+
const config = new UserConfiguration();
54+
config.fromJsonObject(original);
55+
56+
expect(config.deviceName).toEqual('My UHK');
57+
});
58+
4259
});
4360

4461
function jsonTester(json: any): void {

packages/uhk-common/src/config-serializer/config-items/user-configuration.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@ export class UserConfiguration {
1010
@assertUInt16
1111
dataModelVersion: number;
1212

13+
deviceName: string;
14+
1315
moduleConfigurations: ModuleConfiguration[] = [];
1416

1517
keymaps: Keymap[] = [];
1618

1719
macros: Macro[] = [];
1820

21+
constructor() {
22+
this.setDefaultDeviceName();
23+
}
24+
1925
fromJsonObject(jsonObject: any): UserConfiguration {
2026
this.dataModelVersion = jsonObject.dataModelVersion;
27+
this.deviceName = jsonObject.deviceName;
28+
this.setDefaultDeviceName();
2129
this.moduleConfigurations = jsonObject.moduleConfigurations.map((moduleConfiguration: any) => {
2230
return new ModuleConfiguration().fromJsonObject(moduleConfiguration);
2331
});
@@ -32,6 +40,8 @@ export class UserConfiguration {
3240

3341
fromBinary(buffer: UhkBuffer): UserConfiguration {
3442
this.dataModelVersion = buffer.readUInt16();
43+
this.deviceName = buffer.readString();
44+
this.setDefaultDeviceName();
3545
this.moduleConfigurations = buffer.readArray<ModuleConfiguration>(uhkBuffer => {
3646
return new ModuleConfiguration().fromBinary(uhkBuffer);
3747
});
@@ -48,6 +58,7 @@ export class UserConfiguration {
4858
toJsonObject(): any {
4959
return {
5060
dataModelVersion: this.dataModelVersion,
61+
deviceName: this.deviceName,
5162
moduleConfigurations: this.moduleConfigurations.map(moduleConfiguration => moduleConfiguration.toJsonObject()),
5263
keymaps: this.keymaps.map(keymap => keymap.toJsonObject(this.macros)),
5364
macros: this.macros.map(macro => macro.toJsonObject())
@@ -56,6 +67,7 @@ export class UserConfiguration {
5667

5768
toBinary(buffer: UhkBuffer): void {
5869
buffer.writeUInt16(this.dataModelVersion);
70+
buffer.writeString(this.deviceName);
5971
buffer.writeArray(this.moduleConfigurations);
6072
buffer.writeArray(this.macros);
6173
buffer.writeArray(this.keymaps, (uhkBuffer: UhkBuffer, keymap: Keymap) => {
@@ -75,4 +87,9 @@ export class UserConfiguration {
7587
return this.macros.find(macro => macroId === macro.id);
7688
}
7789

90+
private setDefaultDeviceName(): void {
91+
if (!this.deviceName || this.deviceName.trim().length === 0) {
92+
this.deviceName = 'My UHK';
93+
}
94+
}
7895
}

packages/uhk-usb/src/uhk-hid-device.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class UhkHidDevice {
143143
});
144144

145145
const sendData = UhkHidDevice.getTransferData(buffer);
146-
this.logService.debug('[UhkHidDevice] USB[W]:', UhkHidDevice.bufferToString(sendData));
146+
this.logService.debug('[UhkHidDevice] USB[W]:', UhkHidDevice.bufferToString(sendData).substr(3));
147147
device.write(sendData);
148148
});
149149
}

packages/uhk-web/src/app/components/macro/action-editor/tab/mouse/macro-mouse.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,5 @@ export class MacroMouseTabComponent extends MacroBaseComponent implements OnInit
139139
default:
140140
return true;
141141
}
142-
};
142+
}
143143
}

packages/uhk-web/src/app/components/side-menu/side-menu.component.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<ul class="menu--top">
22
<li class="sidebar__level-0--item">
33
<div class="sidebar__level-0">
4-
<i class="uhk-icon uhk-icon-0401-usb-stick rotate-right"></i> UHK 60
4+
<i class="uhk-icon uhk-icon-0401-usb-stick rotate-right"></i>
5+
<input #deviceName cancelable
6+
class="pane-title__name"
7+
type="text"
8+
(change)="editDeviceName($event.target.value)"
9+
(keyup.enter)="deviceName.blur()"
10+
(keyup)="calculateHeaderTextWidth($event.target.value)">
511
<i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'device')"></i>
612
</div>
713
<ul [@toggler]="animation['device']">

packages/uhk-web/src/app/components/side-menu/side-menu.component.scss

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ ul {
3434
padding: 0.5rem 1rem 0.5rem 2rem;
3535
}
3636

37-
&__level-0 ,
37+
&__level-0,
3838
&__level-1 {
3939
font-size: 2rem;
4040
line-height: 3rem;
@@ -150,3 +150,22 @@ ul {
150150
}
151151
}
152152
}
153+
154+
.pane-title {
155+
margin-bottom: 1em;
156+
157+
&__name {
158+
border: none;
159+
border-bottom: 2px dotted #999;
160+
padding: 0;
161+
margin: 0 0.25rem;
162+
text-overflow: ellipsis;
163+
background-color: inherit;
164+
165+
&:focus {
166+
box-shadow: 0 0 0 1px #ccc, 0 0 5px 0 #ccc;
167+
border-color: transparent;
168+
background-color: inherit;
169+
}
170+
}
171+
}

packages/uhk-web/src/app/components/side-menu/side-menu.component.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Renderer } from '@angular/core';
1+
import { AfterContentInit, Component, ElementRef, Renderer2, ViewChild } from '@angular/core';
22
import { animate, state, style, transition, trigger } from '@angular/animations';
33
import { Keymap, Macro } from 'uhk-common';
44

@@ -9,9 +9,11 @@ import 'rxjs/add/operator/do';
99
import 'rxjs/add/operator/map';
1010
import 'rxjs/add/operator/let';
1111

12-
import { AppState, showAddonMenu, runningInElectron } from '../../store';
12+
import { AppState, getDeviceName, showAddonMenu, runningInElectron } from '../../store';
1313
import { MacroActions } from '../../store/actions';
1414
import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
15+
import * as util from '../../util';
16+
import { RenameUserConfigurationAction } from '../../store/actions/user-config';
1517

1618
@Component({
1719
animations: [
@@ -29,15 +31,18 @@ import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
2931
templateUrl: './side-menu.component.html',
3032
styleUrls: ['./side-menu.component.scss']
3133
})
32-
export class SideMenuComponent {
34+
export class SideMenuComponent implements AfterContentInit {
3335
showAddonMenu$: Observable<boolean>;
3436
runInElectron$: Observable<boolean>;
3537

38+
deviceName$: Observable<string>;
3639
keymaps$: Observable<Keymap[]>;
3740
macros$: Observable<Macro[]>;
3841
animation: { [key: string]: 'active' | 'inactive' };
42+
deviceNameValue: string;
43+
@ViewChild('deviceName') deviceName: ElementRef;
3944

40-
constructor(private store: Store<AppState>, private renderer: Renderer) {
45+
constructor(private store: Store<AppState>, private renderer: Renderer2) {
4146
this.animation = {
4247
device: 'active',
4348
configuration: 'active',
@@ -60,6 +65,15 @@ export class SideMenuComponent {
6065

6166
this.showAddonMenu$ = this.store.select(showAddonMenu);
6267
this.runInElectron$ = this.store.select(runningInElectron);
68+
this.deviceName$ = store.select(getDeviceName);
69+
this.deviceName$.subscribe(name => {
70+
this.deviceNameValue = name;
71+
this.setDeviceName();
72+
});
73+
}
74+
75+
ngAfterContentInit(): void {
76+
this.setDeviceName();
6377
}
6478

6579
toggleHide(event: Event, type: string) {
@@ -73,11 +87,34 @@ export class SideMenuComponent {
7387
this.animation[type] = 'inactive';
7488
}
7589

76-
this.renderer.setElementClass(event.target, 'fa-chevron-up', show);
77-
this.renderer.setElementClass(event.target, 'fa-chevron-down', !show);
90+
if (show) {
91+
this.renderer.addClass(event.target, 'fa-chevron-up');
92+
this.renderer.removeClass(event.target, 'fa-chevron-down');
93+
} else {
94+
this.renderer.removeClass(event.target, 'fa-chevron-up');
95+
this.renderer.addClass(event.target, 'fa-chevron-down');
96+
}
7897
}
7998

8099
addMacro() {
81100
this.store.dispatch(MacroActions.addMacro());
82101
}
102+
103+
editDeviceName(name): void {
104+
this.store.dispatch(new RenameUserConfigurationAction(name));
105+
}
106+
107+
calculateHeaderTextWidth(text): void {
108+
const htmlInput = this.deviceName.nativeElement as HTMLInputElement;
109+
const maxWidth = htmlInput.parentElement.offsetWidth * 0.66;
110+
const textWidth = util.getContentWidth(window.getComputedStyle(htmlInput), text);
111+
this.renderer.setStyle(htmlInput, 'width', Math.min(maxWidth, textWidth) + 'px');
112+
}
113+
114+
private setDeviceName(): void {
115+
if (this.deviceName) {
116+
this.renderer.setProperty(this.deviceName.nativeElement, 'value', this.deviceNameValue);
117+
this.calculateHeaderTextWidth(this.deviceName.nativeElement.value);
118+
}
119+
}
83120
}

packages/uhk-web/src/app/services/user-config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"dataModelVersion": 4,
3+
"deviceName": "My UHK",
34
"moduleConfigurations": [
45
{
56
"id": 1,

packages/uhk-web/src/app/store/actions/user-config.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export const ActionTypes = {
1212
SAVE_USER_CONFIG_SUCCESS: type(PREFIX + 'Save User Config Success'),
1313
SAVE_USER_CONFIG_IN_JSON_FILE: type(PREFIX + 'Save User Config in JSON file'),
1414
SAVE_USER_CONFIG_IN_BIN_FILE: type(PREFIX + 'Save User Config in binary file'),
15-
LOAD_RESET_USER_CONFIGURATION: type(PREFIX + 'Load reset user configuration')
15+
LOAD_RESET_USER_CONFIGURATION: type(PREFIX + 'Load reset user configuration'),
16+
RENAME_USER_CONFIGURATION: type(PREFIX + 'Rename user configuration')
1617
};
1718

1819
export class LoadUserConfigAction implements Action {
@@ -26,19 +27,22 @@ export class LoadConfigFromDeviceAction implements Action {
2627
export class LoadConfigFromDeviceReplyAction implements Action {
2728
type = ActionTypes.LOAD_CONFIG_FROM_DEVICE_REPLY;
2829

29-
constructor(public payload: ConfigurationReply) { }
30+
constructor(public payload: ConfigurationReply) {
31+
}
3032
}
3133

3234
export class LoadUserConfigSuccessAction implements Action {
3335
type = ActionTypes.LOAD_USER_CONFIG_SUCCESS;
3436

35-
constructor(public payload: UserConfiguration) { }
37+
constructor(public payload: UserConfiguration) {
38+
}
3639
}
3740

3841
export class SaveUserConfigSuccessAction implements Action {
3942
type = ActionTypes.SAVE_USER_CONFIG_SUCCESS;
4043

41-
constructor(public payload: UserConfiguration) { }
44+
constructor(public payload: UserConfiguration) {
45+
}
4246
}
4347

4448
export class SaveUserConfigInJsonFileAction implements Action {
@@ -52,7 +56,15 @@ export class SaveUserConfigInBinaryFileAction implements Action {
5256
export class LoadResetUserConfigurationAction implements Action {
5357
type = ActionTypes.LOAD_RESET_USER_CONFIGURATION;
5458

55-
constructor(public payload: UserConfiguration) { }
59+
constructor(public payload: UserConfiguration) {
60+
}
61+
}
62+
63+
export class RenameUserConfigurationAction implements Action {
64+
type = ActionTypes.RENAME_USER_CONFIGURATION;
65+
66+
constructor(public payload: string) {
67+
}
5668
}
5769

5870
export type Actions
@@ -64,4 +76,5 @@ export type Actions
6476
| SaveUserConfigInJsonFileAction
6577
| SaveUserConfigInBinaryFileAction
6678
| LoadResetUserConfigurationAction
79+
| RenameUserConfigurationAction
6780
;

0 commit comments

Comments
 (0)