feat: show macro usage count (#1030)

* feat: show macro usage count

* feat: show macro reference count only when ALT key hold down

* fix: the macro reference help text
This commit is contained in:
Róbert Kiss
2019-09-03 21:42:27 +02:00
committed by László Monda
parent 9844645409
commit fef24613e4
10 changed files with 110 additions and 8 deletions

View File

@@ -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() {

View File

@@ -20,6 +20,7 @@
<li>Right click on a key: Capture key</li>
<li>Hold Shift while clicking on a key: Remap on all keymaps</li>
<li>Hold Alt while clicking on a key: Remap on all layers</li>
<li>Hold Alt to see macro reference counts in the side menu</li>
</ul>
</div>
</div>

View File

@@ -91,6 +91,12 @@
<div class="sidebar__level-2" [routerLinkActive]="['active']">
<a [routerLink]="['/macro', macro.id]"
[class.disabled]="state.updatingFirmware">{{macro.name}}</a>
<span *ngIf="state.macroUsageCountVisible"
class="sidebar__macro_count badge"
title="This is the number of times the macro is used across all keymaps."
data-toggle="tooltip"
data-placement="bottom"
data-container="body">{{ macro.usageCount }}</span>
</div>
</li>
</ul>

View File

@@ -148,6 +148,12 @@ ul {
right: 19px;
top: 3px;
}
&__macro_count {
position: absolute;
right: 11px;
top: 1px;
}
}
.menu--bottom {

View File

@@ -1 +1,3 @@
export * from './last-edited-key';
export * from './macro-menu-item';
export * from './side-menu-page-state';

View File

@@ -0,0 +1,5 @@
export interface MacroMenuItem {
id: number;
name: string;
usageCount: number;
}

View File

@@ -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;
}

View File

@@ -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
;

View File

@@ -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<number, MacroMenuItem>());
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
};
}
);

View File

@@ -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;