diff --git a/packages/uhk-web/.gitignore b/packages/uhk-web/.gitignore new file mode 100644 index 00000000..d03e1b28 --- /dev/null +++ b/packages/uhk-web/.gitignore @@ -0,0 +1 @@ +out-tsc/ diff --git a/packages/uhk-web/src/app/components/macro/action-editor/macro-action-editor.component.html b/packages/uhk-web/src/app/components/macro/action-editor/macro-action-editor.component.html index 85e88142..d8868227 100644 --- a/packages/uhk-web/src/app/components/macro/action-editor/macro-action-editor.component.html +++ b/packages/uhk-web/src/app/components/macro/action-editor/macro-action-editor.component.html @@ -43,4 +43,4 @@ - \ No newline at end of file + diff --git a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts index e0337700..052ca2e1 100644 --- a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts +++ b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts @@ -29,8 +29,18 @@ export class KeypressTabComponent extends Tab implements OnChanges { constructor(private mapper: MapperService) { super(); - this.leftModifiers = ['LShift', 'LCtrl', 'LSuper', 'LAlt']; - this.rightModifiers = ['RShift', 'RCtrl', 'RSuper', 'RAlt']; + this.leftModifiers = [ + 'LShift', + 'LCtrl', + mapper.getOsSpecificText('LSuper'), + mapper.getOsSpecificText('LAlt') + ]; + this.rightModifiers = [ + 'RShift', + 'RCtrl', + mapper.getOsSpecificText('RSuper'), + mapper.getOsSpecificText('RAlt') + ]; this.scanCodeGroups = [{ id: '0', text: 'None' diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts index 4d77d231..36fa7744 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts @@ -27,6 +27,7 @@ import { MapperService } from '../../../../services/mapper.service'; import { AppState } from '../../../../store'; import { getMacros } from '../../../../store/reducers/user-configuration'; import { SvgKeyCaptureEvent, SvgKeyClickEvent } from '../../../../models/svg-key-events'; +import { OperatingSystem } from '../../../../models/operating-system'; enum LabelTypes { KeystrokeKey, @@ -293,29 +294,32 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy { } } } else if (keyAction.hasOnlyOneActiveModifier() && !keyAction.hasScancode()) { - newLabelSource = []; switch (keyAction.modifierMask) { case KeyModifiers.leftCtrl: case KeyModifiers.rightCtrl: - newLabelSource.push('Ctrl'); + this.labelSource = ['Ctrl']; break; case KeyModifiers.leftShift: case KeyModifiers.rightShift: - newLabelSource.push('Shift'); + this.labelSource = ['Shift']; break; case KeyModifiers.leftAlt: case KeyModifiers.rightAlt: - newLabelSource.push('Alt'); + this.labelSource = [this.mapper.getOsSpecificText('Alt')]; break; case KeyModifiers.leftGui: case KeyModifiers.rightGui: - newLabelSource.push('Super'); + if (this.mapper.getOperatingSystem() === OperatingSystem.Windows) { + this.labelSource = this.mapper.getIcon('command'); + this.labelType = LabelTypes.SingleIcon; + } else { + this.labelSource = [this.mapper.getOsSpecificText('Super')]; + } break; default: - newLabelSource.push('Undefined'); + this.labelSource = ['Undefined']; break; } - this.labelSource = newLabelSource; } else { this.labelType = LabelTypes.KeystrokeKey; this.labelSource = this.keyAction; diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.html index 8bc3395a..29473e58 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.html @@ -28,10 +28,12 @@ - + + A - + + S diff --git a/packages/uhk-web/src/app/models/operating-system.ts b/packages/uhk-web/src/app/models/operating-system.ts new file mode 100644 index 00000000..7f91aea6 --- /dev/null +++ b/packages/uhk-web/src/app/models/operating-system.ts @@ -0,0 +1,5 @@ +export enum OperatingSystem { + Linux, + Mac, + Windows +} diff --git a/packages/uhk-web/src/app/services/mapper.service.ts b/packages/uhk-web/src/app/services/mapper.service.ts index fb7c2f0d..2ba0e5e5 100644 --- a/packages/uhk-web/src/app/services/mapper.service.ts +++ b/packages/uhk-web/src/app/services/mapper.service.ts @@ -1,22 +1,37 @@ import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; import { KeystrokeType } from 'uhk-common'; +import { Subscription } from 'rxjs/Subscription'; + +import { AppState, getOperatingSystem } from '../store'; +import { OperatingSystem } from '../models/operating-system'; @Injectable() export class MapperService { private basicScanCodeTextMap: Map; private mediaScanCodeTextMap: Map; - private sytemScanCodeTextMap: Map; + private systemScanCodeTextMap: Map; private basicScancodeIcons: Map; private mediaScancodeIcons: Map; private systemScancodeIcons: Map; private nameToFileName: Map; + private osSpecificTexts: Map; - constructor() { - this.initScanCodeTextMap(); - this.initScancodeIcons(); - this.initNameToFileNames(); + private operatingSystem: OperatingSystem; + private osSubscription: Subscription; + + constructor(private store: Store) { + this.osSubscription = store + .select(getOperatingSystem) + .subscribe(os => { + this.operatingSystem = os; + this.initOsSpecificText(); + this.initScanCodeTextMap(); + this.initScancodeIcons(); + this.initNameToFileNames(); + }); } public scanCodeToText(scanCode: number, type: KeystrokeType = KeystrokeType.basic): string[] { @@ -27,7 +42,7 @@ export class MapperService { map = this.mediaScanCodeTextMap; break; case KeystrokeType.system: - map = this.sytemScanCodeTextMap; + map = this.systemScanCodeTextMap; break; default: map = this.basicScanCodeTextMap; @@ -79,7 +94,10 @@ export class MapperService { } public getIcon(iconName: string): string { - return 'assets/compiled_sprite.svg#' + this.nameToFileName.get(iconName); + const mappedIconName = this.nameToFileName.get(iconName); + if (mappedIconName) { + return 'assets/compiled_sprite.svg#' + mappedIconName; + } } public modifierMapper(x: number) { @@ -90,6 +108,33 @@ export class MapperService { } } + public getOperatingSystem(): OperatingSystem { + return this.operatingSystem; + } + + public getOsSpecificText(key: string): string { + const text = this.osSpecificTexts.get(key); + + return text ? text : key; + } + + private initOsSpecificText(): void { + this.osSpecificTexts = new Map(); + + if (this.operatingSystem === OperatingSystem.Mac) { + this.osSpecificTexts.set('Enter', 'Return'); + this.osSpecificTexts.set('Alt', 'Option'); + this.osSpecificTexts.set('Super', 'Cmd'); + this.osSpecificTexts.set('LSuper', 'LCmd'); + this.osSpecificTexts.set('RSuper', 'RCmd'); + this.osSpecificTexts.set('LAlt', 'LOption'); + this.osSpecificTexts.set('RAlt', 'ROption'); + } else if (this.operatingSystem === OperatingSystem.Windows) { + this.osSpecificTexts.set('LSuper', 'LWindows'); + this.osSpecificTexts.set('RSuper', 'RWindows'); + } + } + // TODO: read the mapping from JSON private initScanCodeTextMap(): void { this.basicScanCodeTextMap = new Map(); @@ -129,7 +174,7 @@ export class MapperService { this.basicScanCodeTextMap.set(37, ['8', '*']); this.basicScanCodeTextMap.set(38, ['9', '(']); this.basicScanCodeTextMap.set(39, ['0', ')']); - this.basicScanCodeTextMap.set(40, ['Enter']); + this.basicScanCodeTextMap.set(40, [this.getOsSpecificText('Enter')]); this.basicScanCodeTextMap.set(41, ['Esc']); this.basicScanCodeTextMap.set(42, ['Backspace']); this.basicScanCodeTextMap.set(43, ['Tab']); @@ -177,7 +222,7 @@ export class MapperService { this.basicScanCodeTextMap.set(85, ['*']); this.basicScanCodeTextMap.set(86, ['-']); this.basicScanCodeTextMap.set(87, ['+']); - this.basicScanCodeTextMap.set(88, ['Enter']); + this.basicScanCodeTextMap.set(88, [this.getOsSpecificText('Enter')]); this.basicScanCodeTextMap.set(89, ['end', '1']); this.basicScanCodeTextMap.set(90, ['2']); this.basicScanCodeTextMap.set(91, ['pgdn', '3']); @@ -224,10 +269,10 @@ export class MapperService { this.mediaScanCodeTextMap.set(394, ['Launch Email Client']); this.mediaScanCodeTextMap.set(402, ['Launch Calculator']); - this.sytemScanCodeTextMap = new Map(); - this.sytemScanCodeTextMap.set(129, ['Power Down']); - this.sytemScanCodeTextMap.set(130, ['Sleep']); - this.sytemScanCodeTextMap.set(131, ['Wake Up']); + this.systemScanCodeTextMap = new Map(); + this.systemScanCodeTextMap.set(129, ['Power Down']); + this.systemScanCodeTextMap.set(130, ['Sleep']); + this.systemScanCodeTextMap.set(131, ['Wake Up']); } private initScancodeIcons(): void { @@ -266,8 +311,12 @@ export class MapperService { this.nameToFileName.set('switch-keymap', 'icon-kbd__mod--switch-keymap'); this.nameToFileName.set('macro', 'icon-icon__macro'); this.nameToFileName.set('shift', 'icon-kbd__default--modifier-shift'); - this.nameToFileName.set('option', 'icon-kbd__default--modifier-option'); - this.nameToFileName.set('command', 'icon-kbd__default--modifier-command'); + if (this.operatingSystem === OperatingSystem.Mac) { + this.nameToFileName.set('option', 'icon-kbd__default--modifier-option'); + this.nameToFileName.set('command', 'icon-kbd__default--modifier-command'); + } else if (this.operatingSystem === OperatingSystem.Windows) { + this.nameToFileName.set('command', 'icon-kbd__default--modifier-windows'); + } this.nameToFileName.set('mouse', 'icon-kbd__mouse'); this.nameToFileName.set('left-arrow', 'icon-kbd__mod--arrow-left'); this.nameToFileName.set('right-arrow', 'icon-kbd__mod--arrow-right'); diff --git a/packages/uhk-web/src/app/store/index.ts b/packages/uhk-web/src/app/store/index.ts index f4d8c8ae..31c25d17 100644 --- a/packages/uhk-web/src/app/store/index.ts +++ b/packages/uhk-web/src/app/store/index.ts @@ -10,6 +10,7 @@ import * as fromAppUpdate from './reducers/app-update.reducer'; import * as autoUpdateSettings from './reducers/auto-update-settings'; import * as fromApp from './reducers/app.reducer'; import * as fromDevice from './reducers/device'; +import * as fromSelectors from './reducers/selectors'; import { initProgressButtonState } from './reducers/progress-button-state'; import { environment } from '../../environments/environment'; import { RouterStateUrl } from './router-util'; @@ -52,6 +53,7 @@ export const getKeyboardLayout = createSelector(appState, fromApp.getKeyboardLay export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded); export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo); export const getPrivilegePageState = createSelector(appState, fromApp.getPrivilagePageState); +export const getOperatingSystem = createSelector(appState, fromSelectors.getOperatingSystem); export const runningOnNotSupportedWindows = createSelector(appState, fromApp.runningOnNotSupportedWindows); export const firmwareUpgradeAllowed = createSelector(runningOnNotSupportedWindows, notSupportedOs => !notSupportedOs); diff --git a/packages/uhk-web/src/app/store/reducers/get-operating-system.selector.ts b/packages/uhk-web/src/app/store/reducers/get-operating-system.selector.ts new file mode 100644 index 00000000..b40a58ee --- /dev/null +++ b/packages/uhk-web/src/app/store/reducers/get-operating-system.selector.ts @@ -0,0 +1,29 @@ +import { OperatingSystem } from '../../models/operating-system'; +import { State } from './app.reducer'; + +export const getOperatingSystem = (state: State): OperatingSystem => { + if (state.runningInElectron) { + switch (state.platform) { + case 'darwin': + return OperatingSystem.Mac; + + case 'win32': + return OperatingSystem.Windows; + + default: + return OperatingSystem.Linux; + } + } + + const platform = navigator.platform.toLowerCase(); + + if (platform.indexOf('mac') > -1) { + return OperatingSystem.Mac; + } + + if (platform.indexOf('win') > -1) { + return OperatingSystem.Windows; + } + + return OperatingSystem.Linux; +}; diff --git a/packages/uhk-web/src/app/store/reducers/selectors.ts b/packages/uhk-web/src/app/store/reducers/selectors.ts new file mode 100644 index 00000000..d214d21a --- /dev/null +++ b/packages/uhk-web/src/app/store/reducers/selectors.ts @@ -0,0 +1 @@ +export * from './get-operating-system.selector';