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:
committed by
László Monda
parent
9844645409
commit
fef24613e4
@@ -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() {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -148,6 +148,12 @@ ul {
|
||||
right: 19px;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
&__macro_count {
|
||||
position: absolute;
|
||||
right: 11px;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu--bottom {
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
export * from './last-edited-key';
|
||||
export * from './macro-menu-item';
|
||||
export * from './side-menu-page-state';
|
||||
|
||||
5
packages/uhk-web/src/app/models/macro-menu-item.ts
Normal file
5
packages/uhk-web/src/app/models/macro-menu-item.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface MacroMenuItem {
|
||||
id: number;
|
||||
name: string;
|
||||
usageCount: number;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user