Skip to content

Commit

Permalink
Make long press trigger a reset
Browse files Browse the repository at this point in the history
Fixes #250
  • Loading branch information
neilenns committed Aug 21, 2024
1 parent 4809f04 commit acc5b13
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 31 deletions.
19 changes: 16 additions & 3 deletions src/actions/atisLetter.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import {
action,
DidReceiveSettingsEvent,
KeyDownEvent,
KeyUpEvent,
SingletonAction,
WillAppearEvent,
WillDisappearEvent,
} from "@elgato/streamdeck";
import actionManager from "@managers/action";
import { LONG_PRESS_THRESHOLD } from "@utils/constants";

@action({ UUID: "com.neil-enns.trackaudio.atisletter" })
/**
* Represents the status of a TrackAudio station
*/
export class AtisLetter extends SingletonAction<AtisLetterSettings> {
private _keyDownStart = 0;

// When the action is added to a profile it gets saved in the ActionManager
// instance for use elsewhere in the code. The default title is also set
// to something useful.
Expand All @@ -35,8 +38,18 @@ export class AtisLetter extends SingletonAction<AtisLetterSettings> {
actionManager.updateAtisLetter(ev.action, ev.payload.settings);
}

onKeyDown(ev: KeyDownEvent<AtisLetterSettings>): Promise<void> | void {
actionManager.atisLetterKeyDown(ev.action);
onKeyDown(): Promise<void> | void {
this._keyDownStart = Date.now();
}

onKeyUp(ev: KeyUpEvent<AtisLetterSettings>): Promise<void> | void {
const pressLength = Date.now() - this._keyDownStart;

if (pressLength > LONG_PRESS_THRESHOLD) {
actionManager.atisLetterLongPress(ev.action.id);
} else {
actionManager.atisLetterShortPress(ev.action.id);
}
}
}

Expand Down
22 changes: 16 additions & 6 deletions src/actions/stationStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { ListenTo } from "@controllers/stationStatus";
import {
action,
DidReceiveSettingsEvent,
KeyDownEvent,
KeyUpEvent,
SingletonAction,
WillAppearEvent,
WillDisappearEvent,
} from "@elgato/streamdeck";
import actionManager from "@managers/action";
import { LONG_PRESS_THRESHOLD } from "@utils/constants";

@action({ UUID: "com.neil-enns.trackaudio.stationstatus" })
/**
* Represents the status of a TrackAudio station
*/
export class StationStatus extends SingletonAction<StationSettings> {
private _keyDownStart = 0;

// When the action is added to a profile it gets saved in the ActionManager
// instance for use elsewhere in the code. The default title is also set
// to something useful.
Expand All @@ -36,11 +39,18 @@ export class StationStatus extends SingletonAction<StationSettings> {
actionManager.updateStation(ev.action, ev.payload.settings);
}

// When the key is pressed send the request to toggle the current action to the ActionManager.
// That will take care of figuing out the frequency and listenTo value and sending
// the appropriate message to TrackAudio via a websocket.
onKeyDown(ev: KeyDownEvent<StationSettings>): void | Promise<void> {
actionManager.toggleFrequency(ev.action.id);
onKeyDown(): void | Promise<void> {
this._keyDownStart = Date.now();
}

onKeyUp(ev: KeyUpEvent<StationSettings>): Promise<void> | void {
const pressLength = Date.now() - this._keyDownStart;

if (pressLength > LONG_PRESS_THRESHOLD) {
actionManager.stationStatusLongPress(ev.action.id);
} else {
actionManager.stationStatusShortPress(ev.action.id);
}
}
}

Expand Down
17 changes: 14 additions & 3 deletions src/actions/trackAudioStatus.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import {
action,
DidReceiveSettingsEvent,
KeyDownEvent,
KeyUpEvent,
SingletonAction,
WillAppearEvent,
WillDisappearEvent,
} from "@elgato/streamdeck";
import actionManager from "@managers/action";
import { LONG_PRESS_THRESHOLD } from "@utils/constants";

@action({ UUID: "com.neil-enns.trackaudio.trackaudiostatus" })
/**
* Represents the status of the websocket connection to TrackAudio
*/
export class TrackAudioStatus extends SingletonAction<TrackAudioStatusSettings> {
private _keyDownStart = 0;

// When the action is added to a profile it gets saved in the ActionManager
// instance for use elsewhere in the code.
onWillAppear(
Expand All @@ -34,8 +37,16 @@ export class TrackAudioStatus extends SingletonAction<TrackAudioStatusSettings>
actionManager.updateTrackAudioStatus(ev.action, ev.payload.settings);
}

onKeyDown(ev: KeyDownEvent<TrackAudioStatusSettings>): Promise<void> | void {
actionManager.trackAudioStatusKeyDown(ev.action);
onKeyDown(): Promise<void> | void {
this._keyDownStart = Date.now();
}

onKeyUp(ev: KeyUpEvent<TrackAudioStatusSettings>): Promise<void> | void {
const pressLength = Date.now() - this._keyDownStart;

if (pressLength > LONG_PRESS_THRESHOLD) {
actionManager.trackAudioStatusLongPress(ev.action);
}
}
}

Expand Down
77 changes: 58 additions & 19 deletions src/managers/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,37 @@ class ActionManager extends EventEmitter {
this.emit("actionAdded", controller);
}

/**
* Called when a station status action has a long press. Resets the
* station status and refreshses its state.
* @param actionId The ID of the action that had the long press
*/
public stationStatusLongPress(actionId: string) {
const savedAction = this.getStationStatusControllers().find(
(entry) => entry.action.id === actionId
);

if (!savedAction) {
return;
}

savedAction.reset();
trackAudioManager.refreshStationState(savedAction.callsign);

savedAction.action.showOk().catch((error: unknown) => {
handleAsyncException(
"Unable to show OK on station status button:",
error
);
});
}

/**
* Called when a TrackAudio status action keydown event is triggered.
* Forces a refresh of the TrackAudio status.
* @param action The action
*/
public trackAudioStatusKeyDown(action: Action): void {
public trackAudioStatusLongPress(action: Action) {
this.resetAll();
trackAudioManager.refreshVoiceConnectedState(); // This also causes a refresh of the station states

Expand All @@ -151,30 +176,41 @@ class ActionManager extends EventEmitter {
}

/**
* Called when an ATIS letter action keydown event is triggered. If the
* action is in the isUpdated state then it clears the state. If the
* station is not in the isUpdated state then forces a VATSIM data refresh.
* @param action The action
* Called when an ATIS letter action has a short press. Clears the state.
* @param actionId The ID of the action that had the short press
*/
public atisLetterKeyDown(action: Action): void {
public atisLetterShortPress(actionId: string) {
const savedAction = this.getAtisLetterControllers().find(
(entry) => entry.action.id === action.id
(entry) => entry.action.id === actionId
);

if (!savedAction) {
return;
}

if (savedAction.isUpdated) {
savedAction.isUpdated = false;
} else {
savedAction.action.showOk().catch((error: unknown) => {
handleAsyncException("Unable to show OK on ATIS button:", error);
});
vatsimManager.refresh();
}
savedAction.isUpdated = false;
}

/**
* Called when an ATIS letter action has a long press. Refreshses the ATIS.
* @param actionId The ID of the action that had the long press
*/
public atisLetterLongPress(actionId: string) {
const savedAction = this.getAtisLetterControllers().find(
(entry) => entry.action.id === actionId
);

if (!savedAction) {
return;
}

savedAction.reset();
vatsimManager.refresh();

savedAction.action.showOk().catch((error: unknown) => {
handleAsyncException("Unable to show OK on ATIS button:", error);
});
}
/**
* Resets the ATIS letter on all ATIS letter actions to undefined.
*/
Expand Down Expand Up @@ -588,11 +624,14 @@ class ActionManager extends EventEmitter {
}

/**
* Toggles the tx, rx, xc, or spkr state of a frequency bound to a StreamDeck action.
* @param id The action id to toggle the state of
* Handles a short press of a station status action. Toggles the
* the tx, rx, xc, or spkr state of a frequency bound to a StreamDeck action.
* @param actionId The action id to toggle the state of
*/
public toggleFrequency(id: string): void {
const foundAction = this.actions.find((entry) => entry.action.id === id);
public stationStatusShortPress(actionId: string): void {
const foundAction = this.actions.find(
(entry) => entry.action.id === actionId
);

if (!foundAction || !isStationStatusController(foundAction)) {
return;
Expand Down
5 changes: 5 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* The length of time in ms that has to pass for an action press to
* count as a long press.
*/
export const LONG_PRESS_THRESHOLD = 500;

0 comments on commit acc5b13

Please sign in to comment.