From aeb0b2fada200872a13da49565d08d5b65973e1b Mon Sep 17 00:00:00 2001 From: itsnobii <57056220+itsnobii@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:16:26 -0400 Subject: [PATCH 1/2] Add hotkey for agent select and send activation state to server --- angular/src/app/hotkeys/hotkeys.component.css | 43 +++++++++++++++++++ .../src/app/hotkeys/hotkeys.component.html | 41 ++++++++++++++++++ angular/src/app/hotkeys/hotkeys.component.ts | 41 ++++++++++++++++-- .../src/app/observer/observer.component.ts | 5 +++ src/main.ts | 1 + src/services/connectorService.ts | 2 + src/services/formattingService.ts | 1 + 7 files changed, 131 insertions(+), 3 deletions(-) diff --git a/angular/src/app/hotkeys/hotkeys.component.css b/angular/src/app/hotkeys/hotkeys.component.css index e69de29..81b0b60 100644 --- a/angular/src/app/hotkeys/hotkeys.component.css +++ b/angular/src/app/hotkeys/hotkeys.component.css @@ -0,0 +1,43 @@ +.agent-select-warning { + position: fixed; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: center; + padding-bottom: 1rem; + pointer-events: none; + z-index: 9999; + animation: toast-lifecycle 5s ease-in-out forwards; +} + +.agent-select-warning-inner { + background-color: var(--p-surface-800); + color: var(--p-surface-0); + font-size: 0.875rem; + padding: 0.625rem 1rem; + border-radius: 0.5rem; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + border: 1px solid var(--p-surface-600); + max-width: 28rem; + text-align: center; +} + +@keyframes toast-lifecycle { + 0% { + transform: translateY(150%); + opacity: 0; + } + 7% { + transform: translateY(0); + opacity: 1; + } + 88% { + transform: translateY(0); + opacity: 1; + } + 100% { + transform: translateY(150%); + opacity: 0; + } +} diff --git a/angular/src/app/hotkeys/hotkeys.component.html b/angular/src/app/hotkeys/hotkeys.component.html index 0cc63d4..18c61f6 100644 --- a/angular/src/app/hotkeys/hotkeys.component.html +++ b/angular/src/app/hotkeys/hotkeys.component.html @@ -202,4 +202,45 @@

Hotkeys

+ + + + + + + + + + + + +@if (showAgentSelectWarning) { +
+
+ Enabling the hotkey for agent select will stop it from displaying automatically. +
+
+} diff --git a/angular/src/app/hotkeys/hotkeys.component.ts b/angular/src/app/hotkeys/hotkeys.component.ts index 1350e2b..8fcee1d 100644 --- a/angular/src/app/hotkeys/hotkeys.component.ts +++ b/angular/src/app/hotkeys/hotkeys.component.ts @@ -4,6 +4,7 @@ import { EventEmitter, HostListener, Input, + OnDestroy, Output, ViewChild, } from "@angular/core"; @@ -37,7 +38,7 @@ import { ToggleSwitchModule } from "primeng/toggleswitch"; templateUrl: "./hotkeys.component.html", styleUrl: "./hotkeys.component.css", }) -export class HotkeysComponent implements Validatable, AfterContentInit { +export class HotkeysComponent implements Validatable, AfterContentInit, OnDestroy { @Input({ required: true }) data!: Hotkeys; @@ -48,11 +49,29 @@ export class HotkeysComponent implements Validatable, AfterContentInit { rightTimeout: false, switchKdaCredits: false, showToast: false, + toggleAgentSelect: false, }; @ViewChild("change_popover") changePopover!: Popover; + protected showAgentSelectWarning = false; + private warningTimer: ReturnType | null = null; + + onToggleAgentSelectChange(enabled: boolean) { + if (!enabled) return; + if (this.warningTimer !== null) clearTimeout(this.warningTimer); + this.showAgentSelectWarning = true; + this.warningTimer = setTimeout(() => { + this.showAgentSelectWarning = false; + this.warningTimer = null; + }, 5000); + } + + ngOnDestroy() { + if (this.warningTimer !== null) clearTimeout(this.warningTimer); + } + ngAfterContentInit(): void { this.runValidation(); } @@ -65,6 +84,7 @@ export class HotkeysComponent implements Validatable, AfterContentInit { | "spike" | "switchKdaCredits" | "showToast" + | "toggleAgentSelect" | "" = ""; @HostListener("window:keyup", ["$event"]) @@ -120,12 +140,23 @@ export class HotkeysComponent implements Validatable, AfterContentInit { break; case "showToast": this.data.showToast = keyString; + break; + case "toggleAgentSelect": + this.data.toggleAgentSelect = keyString; + break; } } changeKeybind( event: any, - hotkey: "timeLeft" | "timeRight" | "techPause" | "spike" | "switchKdaCredits" | "showToast", + hotkey: + | "timeLeft" + | "timeRight" + | "techPause" + | "spike" + | "switchKdaCredits" + | "showToast" + | "toggleAgentSelect", ) { this.isCapturing = true; this.capturingHotkey = hotkey; @@ -150,6 +181,9 @@ export class HotkeysComponent implements Validatable, AfterContentInit { !this.data.enabled.switchKdaCredits || this.data.switchKdaCredits.match(hotkeyRegex) != null; this.valid.showToast = !this.data.enabled.showToast || this.data.showToast.match(hotkeyRegex) != null; + this.valid.toggleAgentSelect = + !this.data.enabled.toggleAgentSelect || + this.data.toggleAgentSelect.match(hotkeyRegex) != null; valid = this.valid.spikePlanted && @@ -157,7 +191,8 @@ export class HotkeysComponent implements Validatable, AfterContentInit { this.valid.leftTimeout && this.valid.rightTimeout && this.valid.switchKdaCredits && - this.valid.showToast; + this.valid.showToast && + this.valid.toggleAgentSelect; this.validationChanged.emit(valid ? ValidationState.VALID : ValidationState.INVALID); } } diff --git a/angular/src/app/observer/observer.component.ts b/angular/src/app/observer/observer.component.ts index 0e2a965..2b16cca 100644 --- a/angular/src/app/observer/observer.component.ts +++ b/angular/src/app/observer/observer.component.ts @@ -259,6 +259,7 @@ export class ObserverComponent implements OnInit { rightTimeout: "P", switchKdaCredits: "I", showToast: "L", + toggleAgentSelect: "U", enabled: { spikePlanted: false, techPause: true, @@ -266,6 +267,7 @@ export class ObserverComponent implements OnInit { rightTimeout: true, switchKdaCredits: true, showToast: false, + toggleAgentSelect: false, }, }; @@ -347,6 +349,7 @@ export class ObserverComponent implements OnInit { rightTimeout: true, switchKdaCredits: true, showToast: true, + toggleAgentSelect: false, }; } // Hotkey migration for switch KDA/Credits @@ -959,6 +962,7 @@ export type Hotkeys = { rightTimeout: string; switchKdaCredits: string; showToast: string; + toggleAgentSelect: string; enabled: { spikePlanted: boolean; techPause: boolean; @@ -966,6 +970,7 @@ export type Hotkeys = { rightTimeout: boolean; switchKdaCredits: boolean; showToast: boolean; + toggleAgentSelect: boolean; }; }; diff --git a/src/main.ts b/src/main.ts index 96eac4c..1e06aa3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -557,6 +557,7 @@ function processInputs( playercamsInfo, timeoutInfo, roundWinBox, + hotkeys.enabled.toggleAgentSelect, win, ); } diff --git a/src/services/connectorService.ts b/src/services/connectorService.ts index aafcf36..1fc09a8 100644 --- a/src/services/connectorService.ts +++ b/src/services/connectorService.ts @@ -91,6 +91,7 @@ export class ConnectorService { playercamsInfo: PlayercamsInfo, timeoutInfo: ITimeoutInfo, roundWinBox: IRoundWinBox, + agentSelectHotkeyEnabled: boolean, win: Electron.Main.BrowserWindow, ) { if (RegExp("(http|https)://[^/]+:[0-9]+").test(ingestIp)) { @@ -204,6 +205,7 @@ export class ConnectorService { watermarkInfo: watermarkInfo, playercamsInfo: playercamsInfo, roundWinBox: roundWinBox, + agentSelectHotkeyEnabled: agentSelectHotkeyEnabled, }, }; this.ws.emit(SocketChannels.OBSERVER_LOGON, JSON.stringify(logonData)); diff --git a/src/services/formattingService.ts b/src/services/formattingService.ts index c0245e8..c5e170e 100644 --- a/src/services/formattingService.ts +++ b/src/services/formattingService.ts @@ -299,6 +299,7 @@ export interface IToolsData { watermarkInfo: WatermarkInfo; playercamsInfo: PlayercamsInfo; roundWinBox: IRoundWinBox; + agentSelectHotkeyEnabled?: boolean; } export type ISeriesInfo = { From c3dd6ade2ac1a403c402ebf7a54f426d17c58e8a Mon Sep 17 00:00:00 2001 From: itsnobii <57056220+itsnobii@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:28:49 -0400 Subject: [PATCH 2/2] Add agent select hotkey to appropriate services --- src/main.ts | 5 +++++ src/services/formattingService.ts | 1 + src/services/hotkeyService.ts | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/main.ts b/src/main.ts index 1e06aa3..5db7a51 100644 --- a/src/main.ts +++ b/src/main.ts @@ -526,6 +526,11 @@ function processInputs( hotkeys.showToast, hotkeys.enabled.showToast, ); + hotkeyService.setKeyForHotkey( + HotkeyType.TOGGLE_AGENT_SELECT, + hotkeys.toggleAgentSelect, + hotkeys.enabled.toggleAgentSelect, + ); } catch (error: any) { messageBox("Spectra Client - Error", error.message, messageBoxType.ERROR); return; diff --git a/src/services/formattingService.ts b/src/services/formattingService.ts index c5e170e..10f3d99 100644 --- a/src/services/formattingService.ts +++ b/src/services/formattingService.ts @@ -269,6 +269,7 @@ export enum DataTypes { LEFT_TIMEOUT = "left_timeout", RIGHT_TIMEOUT = "right_timeout", SWITCH_KDA_CREDITS = "switch_kda_credits", + TOGGLE_AGENT_SELECT = "toggle_agent_select", // Mid-match update type TOAST = "toast", SWAP_L_R = "swap_left_right", diff --git a/src/services/hotkeyService.ts b/src/services/hotkeyService.ts index 8c36469..316d224 100644 --- a/src/services/hotkeyService.ts +++ b/src/services/hotkeyService.ts @@ -49,6 +49,12 @@ export default class HotkeyService { type: HotkeyType.SHOW_TOAST, enabled: true, }; + this.hotkeys[HotkeyType.TOGGLE_AGENT_SELECT] = { + key: "", + action: this._toggleAgentSelectHotkeyAction.bind(this), + type: HotkeyType.TOGGLE_AGENT_SELECT, + enabled: false, + }; } public static getInstance(): HotkeyService { @@ -133,6 +139,11 @@ export default class HotkeyService { private _showToastHotkeyAction() { fireSendToast(); } + + private _toggleAgentSelectHotkeyAction() { + const toSend = { type: DataTypes.TOGGLE_AGENT_SELECT, data: true }; + ConnectorService.getInstance().sendToIngest(toSend); + } } export enum HotkeyType { SPIKE_PLANTED, @@ -141,6 +152,7 @@ export enum HotkeyType { RIGHT_TIMEOUT, SWITCH_KDA_CREDITS, SHOW_TOAST, + TOGGLE_AGENT_SELECT, } type Hotkey = { key: string;