Skip to content

Instantly share code, notes, and snippets.

@neilzheng
Created September 20, 2024 13:00
Show Gist options
  • Save neilzheng/d7fbf267f6eb96158db7966a25e07497 to your computer and use it in GitHub Desktop.
Save neilzheng/d7fbf267f6eb96158db7966a25e07497 to your computer and use it in GitHub Desktop.
const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
// tick timer for schedule jobs
// idle timer autoremove it self after stop
export class IdleTickTimer {
private idleCount: number = 0;
private stopIdleCount: number = 0;
private idleTickCallback: { (tick: number, final: boolean): void };
private intervalID: number;
private activityCallback: { (): void } | null;
private static instance: IdleTickTimer | null;
private constructor(
interval: number,
stopIdleCount: number,
tickCallback: { (idleCount: number, final: boolean): void },
) {
this.idleCount = 0;
this.stopIdleCount = stopIdleCount;
this.idleTickCallback = tickCallback;
this.intervalID = 0;
this.activityCallback = null;
// activity listener
events.forEach((e) => {
window.addEventListener(e, this);
});
this.intervalID = window.setInterval(
() => this.onTimeout(),
interval * 1000,
);
}
// reset idle timer on activity
public handleEvent() {
this.idleCount = 0;
if (this.activityCallback) this.activityCallback();
}
private onTimeout() {
++this.idleCount;
const final = this.idleCount >= this.stopIdleCount;
if (final) IdleTickTimer.stop();
this.idleTickCallback(this.idleCount, final);
}
// interval (seconds)
static start(
interval: number,
stopIdleCount: number,
tickCallback: { (idleCount: number, final: boolean): void },
): void {
// already started
if (this.instance) return;
this.instance = new IdleTickTimer(interval, stopIdleCount, tickCallback);
}
static stop() {
if (!this.instance) return;
this.instance.instanceStop();
this.instance = null;
}
// stop timer and clear
private instanceStop() {
events.forEach((e) => {
window.removeEventListener(e, this);
});
window.clearInterval(this.intervalID);
}
static setActivityCallback(cb: { (): void } | null) {
if (this.instance) this.instance.activityCallback = cb;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment