41 lines
1.0 KiB
TypeScript
41 lines
1.0 KiB
TypeScript
/**
|
|||
|
|
* [Gitea #136] Elbow-on-the-keyboard guard for push-to-talk: a hold longer
|
||
|
|
* than `maxMs` is released as if the key came up. `arm()` on press, `disarm()`
|
||
|
|
* on release (a genuine release + re-press restarts the clock). Timers are
|
||
|
|
* injectable for tests.
|
||
|
|
*/
|
||
|
|
export const PTT_MAX_HOLD_MS = 5 * 60 * 1000;
|
||
|
|
|
||
|
|
type Timers = {
|
||
|
|
setTimeout: (fn: () => void, ms: number) => unknown;
|
||
|
|
clearTimeout: (handle: unknown) => void;
|
||
|
|
};
|
||
|
|
|
||
|
|
const realTimers: Timers = {
|
||
|
|
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
||
|
|
clearTimeout: (h) => clearTimeout(h as ReturnType<typeof setTimeout>),
|
||
|
|
};
|
||
|
|
|
||
|
|
export const createPttHoldWatchdog = (
|
||
|
|
onExpire: () => void,
|
||
|
|
maxMs = PTT_MAX_HOLD_MS,
|
||
|
|
timers: Timers = realTimers,
|
||
|
|
) => {
|
||
|
|
let handle: unknown;
|
||
|
|
const disarm = () => {
|
||
|
|
if (handle !== undefined) timers.clearTimeout(handle);
|
||
|
|
handle = undefined;
|
||
|
|
};
|
||
|
|
return {
|
||
|
|
arm: () => {
|
||
|
|
disarm();
|
||
|
|
handle = timers.setTimeout(() => {
|
||
|
|
handle = undefined;
|
||
|
|
onExpire();
|
||
|
|
}, maxMs);
|
||
|
|
},
|
||
|
|
disarm,
|
||
|
|
armed: () => handle !== undefined,
|
||
|
|
};
|
||
|
|
};
|