diff --git a/packages/uhk-web/src/app/app.component.ts b/packages/uhk-web/src/app/app.component.ts index 170ef188..e4dd9303 100644 --- a/packages/uhk-web/src/app/app.component.ts +++ b/packages/uhk-web/src/app/app.component.ts @@ -16,6 +16,7 @@ import { } from './store'; import { ProgressButtonState } from './store/reducers/progress-button-state'; import { UpdateInfo } from './models/update-info'; +import { KeyUpAction, KeyDownAction } from './store/actions/app'; @Component({ selector: 'main-app', @@ -95,6 +96,13 @@ export class MainAppComponent implements OnDestroy { this.enableUsbStackTest(); event.preventDefault(); } + + this.store.dispatch(new KeyDownAction(event)); + } + + @HostListener('document:keyup', ['$event']) + onKeyUp(event: KeyboardEvent) { + this.store.dispatch(new KeyUpAction(event)); } updateApp() { diff --git a/packages/uhk-web/src/app/components/agent/help-page/help-page.component.html b/packages/uhk-web/src/app/components/agent/help-page/help-page.component.html index 6bea1967..c02adabd 100644 --- a/packages/uhk-web/src/app/components/agent/help-page/help-page.component.html +++ b/packages/uhk-web/src/app/components/agent/help-page/help-page.component.html @@ -20,6 +20,7 @@
  • Right click on a key: Capture key
  • Hold Shift while clicking on a key: Remap on all keymaps
  • Hold Alt while clicking on a key: Remap on all layers
  • +
  • Hold Alt to see macro reference counts in the side menu
  • diff --git a/packages/uhk-web/src/app/components/side-menu/side-menu.component.html b/packages/uhk-web/src/app/components/side-menu/side-menu.component.html index 120f7daf..3724c6ca 100644 --- a/packages/uhk-web/src/app/components/side-menu/side-menu.component.html +++ b/packages/uhk-web/src/app/components/side-menu/side-menu.component.html @@ -91,6 +91,12 @@ diff --git a/packages/uhk-web/src/app/components/side-menu/side-menu.component.scss b/packages/uhk-web/src/app/components/side-menu/side-menu.component.scss index a1c6ce58..06bd59b1 100644 --- a/packages/uhk-web/src/app/components/side-menu/side-menu.component.scss +++ b/packages/uhk-web/src/app/components/side-menu/side-menu.component.scss @@ -148,6 +148,12 @@ ul { right: 19px; top: 3px; } + + &__macro_count { + position: absolute; + right: 11px; + top: 1px; + } } .menu--bottom { diff --git a/packages/uhk-web/src/app/models/index.ts b/packages/uhk-web/src/app/models/index.ts index 4c4f3c7d..51410952 100644 --- a/packages/uhk-web/src/app/models/index.ts +++ b/packages/uhk-web/src/app/models/index.ts @@ -1 +1,3 @@ export * from './last-edited-key'; +export * from './macro-menu-item'; +export * from './side-menu-page-state'; diff --git a/packages/uhk-web/src/app/models/macro-menu-item.ts b/packages/uhk-web/src/app/models/macro-menu-item.ts new file mode 100644 index 00000000..e231646f --- /dev/null +++ b/packages/uhk-web/src/app/models/macro-menu-item.ts @@ -0,0 +1,5 @@ +export interface MacroMenuItem { + id: number; + name: string; + usageCount: number; +} diff --git a/packages/uhk-web/src/app/models/side-menu-page-state.ts b/packages/uhk-web/src/app/models/side-menu-page-state.ts index 1ef86832..1cd5aa1f 100644 --- a/packages/uhk-web/src/app/models/side-menu-page-state.ts +++ b/packages/uhk-web/src/app/models/side-menu-page-state.ts @@ -1,4 +1,5 @@ import { Keymap, Macro } from 'uhk-common'; +import { MacroMenuItem } from './macro-menu-item'; export interface SideMenuPageState { showAddonMenu: boolean; @@ -6,6 +7,7 @@ export interface SideMenuPageState { updatingFirmware: boolean; deviceName: string; keymaps: Keymap[]; - macros: Macro[]; + macros: MacroMenuItem[]; restoreUserConfiguration: boolean; + macroUsageCountVisible: boolean; } diff --git a/packages/uhk-web/src/app/store/actions/app.ts b/packages/uhk-web/src/app/store/actions/app.ts index df9694d1..76d679ca 100644 --- a/packages/uhk-web/src/app/store/actions/app.ts +++ b/packages/uhk-web/src/app/store/actions/app.ts @@ -19,7 +19,9 @@ export enum ActionTypes { SetupPermissionError = '[app] Setup permission error', LoadAppStartInfo = '[app] Load app start info', StartKeypressCapturing = '[app] Start keypress capturing', - StopKeypressCapturing = '[app] Stop keypress capturing' + StopKeypressCapturing = '[app] Stop keypress capturing', + KeyDown = '[app] Key down', + KeyUp = '[app] Key up' } export class AppBootstrappedAction implements Action { @@ -110,6 +112,18 @@ export class StopKeypressCapturingAction implements Action { type = ActionTypes.StopKeypressCapturing; } +export class KeyDownAction implements Action { + readonly type = ActionTypes.KeyDown; + + constructor(public payload: KeyboardEvent) {} +} + +export class KeyUpAction implements Action { + readonly type = ActionTypes.KeyUp; + + constructor(public payload: KeyboardEvent) {} +} + export type Actions = AppStartedAction | AppBootstrappedAction @@ -127,4 +141,6 @@ export type Actions | LoadAppStartInfoAction | StartKeypressCapturingAction | StopKeypressCapturingAction + | KeyDownAction + | KeyUpAction ; diff --git a/packages/uhk-web/src/app/store/index.ts b/packages/uhk-web/src/app/store/index.ts index 1491af6a..7e4d8ed0 100644 --- a/packages/uhk-web/src/app/store/index.ts +++ b/packages/uhk-web/src/app/store/index.ts @@ -1,7 +1,7 @@ import { ActionReducerMap, createSelector, MetaReducer } from '@ngrx/store'; import { routerReducer, RouterReducerState } from '@ngrx/router-store'; import { storeFreeze } from 'ngrx-store-freeze'; -import { HardwareModules, Keymap, UserConfiguration } from 'uhk-common'; +import { HardwareModules, Keymap, UserConfiguration, PlayMacroAction } from 'uhk-common'; import * as fromUserConfig from './reducers/user-configuration'; import * as fromPreset from './reducers/preset'; @@ -16,6 +16,7 @@ import { environment } from '../../environments/environment'; import { RouterStateUrl } from './router-util'; import { PrivilagePageSate } from '../models/privilage-page-sate'; import { isVersionGte } from '../util'; +import { SideMenuPageState, MacroMenuItem } from '../models'; // State interface for the application export interface AppState { @@ -67,6 +68,7 @@ export const deviceConfigurationLoaded = createSelector(appState, fromApp.device export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo); export const getOperatingSystem = createSelector(appState, fromSelectors.getOperatingSystem); export const keypressCapturing = createSelector(appState, fromApp.keypressCapturing); +export const getMacroUsageCountVisible = createSelector(appState, fromApp.macroUsageCountVisible); export const runningOnNotSupportedWindows = createSelector(appState, fromApp.runningOnNotSupportedWindows); export const contributors = (state: AppState) => state.contributors; export const firmwareUpgradeAllowed = createSelector(runningOnNotSupportedWindows, notSupportedOs => !notSupportedOs); @@ -123,25 +125,57 @@ export const getPrivilegePageState = createSelector(appState, getUpdateUdevRules }; }); +export const getMacroMenuItems = (userConfiguration: UserConfiguration): MacroMenuItem[] => { + const macroMap = userConfiguration.macros.reduce((map, macro) => { + return map.set(macro.id, { + id: macro.id, + name: macro.name, + usageCount: 0 + }); + }, new Map()); + + for (const keymap of userConfiguration.keymaps) { + for (const layer of keymap.layers) { + for (const module of layer.modules) { + for (const keyAction of module.keyActions) { + if (!(keyAction instanceof PlayMacroAction)) { + continue; + } + + const menuItem = macroMap.get(keyAction.macroId); + menuItem.usageCount++; + } + } + } + } + + return Array + .from(macroMap.values()) + .sort((first: MacroMenuItem, second: MacroMenuItem) => first.name.localeCompare(second.name)); +}; + export const getSideMenuPageState = createSelector( showAddonMenu, runningInElectron, updatingFirmware, getUserConfiguration, getRestoreUserConfiguration, + getMacroUsageCountVisible, (showAddonMenuValue: boolean, runningInElectronValue: boolean, updatingFirmwareValue: boolean, userConfiguration: UserConfiguration, - restoreUserConfiguration: boolean) => { + restoreUserConfiguration: boolean, + macroUsageCountVisible): SideMenuPageState => { return { showAddonMenu: showAddonMenuValue, runInElectron: runningInElectronValue, updatingFirmware: updatingFirmwareValue, deviceName: userConfiguration.deviceName, keymaps: userConfiguration.keymaps, - macros: userConfiguration.macros, - restoreUserConfiguration + macros: getMacroMenuItems(userConfiguration), + restoreUserConfiguration, + macroUsageCountVisible }; } ); diff --git a/packages/uhk-web/src/app/store/reducers/app.reducer.ts b/packages/uhk-web/src/app/store/reducers/app.reducer.ts index e4edaaf0..c7a0fd5b 100644 --- a/packages/uhk-web/src/app/store/reducers/app.reducer.ts +++ b/packages/uhk-web/src/app/store/reducers/app.reducer.ts @@ -30,6 +30,7 @@ export interface State { platform?: string; osVersion?: string; keypressCapturing: boolean; + macroUsageCountVisible: boolean; } export const initialState: State = { @@ -40,7 +41,8 @@ export const initialState: State = { configLoading: true, agentVersionInfo: getVersions(), privilegeWhatWillThisDoClicked: false, - keypressCapturing: false + keypressCapturing: false, + macroUsageCountVisible: false }; export function reducer( @@ -156,7 +158,8 @@ export function reducer( case App.ActionTypes.StartKeypressCapturing: return { ...state, - keypressCapturing: true + keypressCapturing: true, + macroUsageCountVisible: false }; case App.ActionTypes.StopKeypressCapturing: @@ -165,6 +168,24 @@ export function reducer( keypressCapturing: false }; + case App.ActionTypes.KeyDown: { + const event = (action as App.KeyDownAction).payload; + + return { + ...state, + macroUsageCountVisible: !state.keypressCapturing && !event.defaultPrevented && event.altKey + }; + } + + case App.ActionTypes.KeyUp: { + const event = (action as App.KeyDownAction).payload; + + return { + ...state, + macroUsageCountVisible: event.altKey + }; + } + default: return state; } @@ -197,3 +218,4 @@ export const runningOnNotSupportedWindows = (state: State): boolean => { }; export const keypressCapturing = (state: State): boolean => state.keypressCapturing; +export const macroUsageCountVisible = (state: State): boolean => state.macroUsageCountVisible;