From c605cd8c4d88bd3f7aef67edbd8ce4bb820bc030 Mon Sep 17 00:00:00 2001 From: Alexander Drozdov Date: Wed, 4 May 2022 20:04:01 +0300 Subject: [PATCH] Shortcuts for Stopwatch, closes #368 --- ipc/ipc-event.ts | 9 +++- ipc/widgets.ts | 2 + main/src/shortcuts.ts | 47 ++++++++++++++++---- renderer/src/web/background/IPC.ts | 6 ++- renderer/src/web/overlay/WidgetTimer.vue | 24 ++++++++-- renderer/src/web/settings/SettingsWindow.vue | 6 ++- renderer/src/web/settings/stopwatch.vue | 44 ++++++++++++++++++ 7 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 renderer/src/web/settings/stopwatch.vue diff --git a/ipc/ipc-event.ts b/ipc/ipc-event.ts index b035b6bf..2394ec00 100644 --- a/ipc/ipc-event.ts +++ b/ipc/ipc-event.ts @@ -18,7 +18,8 @@ export type IpcEvent = IpcOpenCraftOfExile | IpcImportFile | IpcToggleDelveGrid | - IpcClientLog + IpcClientLog | + IpcStopwatchAction export type IpcEventPayload = T extends { name: Name } ? T['payload'] : never @@ -103,6 +104,12 @@ export type IpcClientLog = lines: string[] }> +export type IpcStopwatchAction = + Event<'MAIN->OVERLAY::stopwatch', { + wmId: number + type: 'start-stop' | 'reset' + }> + interface Event { name: TName payload: TPayload diff --git a/ipc/widgets.ts b/ipc/widgets.ts index 4a5902c0..51f8ec49 100644 --- a/ipc/widgets.ts +++ b/ipc/widgets.ts @@ -57,6 +57,8 @@ export interface ItemCheckWidget extends Widget { export interface StopwatchWidget extends Widget { anchor: Anchor + toggleKey: string | null + resetKey: string | null } export interface StashSearchWidget extends Widget { diff --git a/main/src/shortcuts.ts b/main/src/shortcuts.ts index 032b3554..b298af76 100644 --- a/main/src/shortcuts.ts +++ b/main/src/shortcuts.ts @@ -8,8 +8,8 @@ import { config } from './config' import { PoeWindow } from './PoeWindow' import { logger } from './logger' import { toggleOverlayState, assertOverlayActive, assertPoEActive, overlayOnEvent, overlaySendEvent } from './overlay-window' -import * as ipc from '../../ipc/ipc-event' -import { StashSearchWidget } from '../../ipc/widgets' +import type * as ipc from '../../ipc/ipc-event' +import type * as widget from '../../ipc/widgets' import { typeInChat } from './game-chat' import { gameConfig } from './game-config' import { restoreClipboard } from './clipboard-saver' @@ -29,10 +29,12 @@ export interface ShortcutAction { 'price-check-locked' ) focusOverlay?: boolean - } | { + } | ({ type: 'trigger-event' - eventName: ipc.IpcToggleDelveGrid['name'] - } | { + } & ( + ShortcutActionTriggerEvent | + ShortcutActionTriggerEvent + )) | { type: 'stash-search' text: string } | { @@ -46,6 +48,11 @@ export interface ShortcutAction { } } +interface ShortcutActionTriggerEvent { + eventName: Name + payload: ipc.IpcEventPayload +} + function shortcutsFromConfig () { let actions: ShortcutAction[] = [] @@ -89,7 +96,7 @@ function shortcutsFromConfig () { if (config.get('delveGridKey')) { actions.push({ shortcut: config.get('delveGridKey')!, - action: { type: 'trigger-event', eventName: 'MAIN->OVERLAY::delve-grid' }, + action: { type: 'trigger-event', eventName: 'MAIN->OVERLAY::delve-grid', payload: undefined }, keepModKeys: true }) } @@ -110,7 +117,7 @@ function shortcutsFromConfig () { } for (const widget of config.get('widgets')) { if (widget.wmType === 'stash-search') { - const stashSearch = widget as StashSearchWidget + const stashSearch = widget as widget.StashSearchWidget for (const entry of stashSearch.entries) { if (entry.hotkey) { actions.push({ @@ -119,6 +126,30 @@ function shortcutsFromConfig () { }) } } + } else if (widget.wmType === 'timer') { + const stopwatch = widget as widget.StopwatchWidget + if (stopwatch.toggleKey) { + actions.push({ + shortcut: stopwatch.toggleKey, + keepModKeys: true, + action: { + type: 'trigger-event', + eventName: 'MAIN->OVERLAY::stopwatch', + payload: { wmId: widget.wmId, type: 'start-stop' } + } + }) + } + if (stopwatch.resetKey) { + actions.push({ + shortcut: stopwatch.resetKey, + keepModKeys: true, + action: { + type: 'trigger-event', + eventName: 'MAIN->OVERLAY::stopwatch', + payload: { wmId: widget.wmId, type: 'reset' } + } + }) + } } } @@ -172,7 +203,7 @@ function registerGlobal () { } else if (entry.action.type === 'paste-in-chat') { typeInChat(entry.action.text, entry.action.send) } else if (entry.action.type === 'trigger-event') { - overlaySendEvent({ name: entry.action.eventName, payload: undefined }) + overlaySendEvent({ name: entry.action.eventName, payload: entry.action.payload } as ipc.IpcEvent) } else if (entry.action.type === 'stash-search') { stashSearch(entry.action.text) } else if (entry.action.type === 'copy-item') { diff --git a/renderer/src/web/background/IPC.ts b/renderer/src/web/background/IPC.ts index 1f054d5b..568500a8 100644 --- a/renderer/src/web/background/IPC.ts +++ b/renderer/src/web/background/IPC.ts @@ -33,10 +33,12 @@ class MainProcessBinding { onEvent ( name: Name, cb: (payload: IpcEventPayload) => void - ) { + ): AbortController { + const controller = new AbortController() this.evBus.addEventListener(name, (e) => { cb((e as CustomEvent>).detail) - }) + }, { signal: controller.signal }) + return controller } closeOverlay () { diff --git a/renderer/src/web/overlay/WidgetTimer.vue b/renderer/src/web/overlay/WidgetTimer.vue index 02cef3ab..946fc609 100644 --- a/renderer/src/web/overlay/WidgetTimer.vue +++ b/renderer/src/web/overlay/WidgetTimer.vue @@ -1,5 +1,5 @@