All files / src time-spent-timer.ts

94.44% Statements 34/36
71.43% Branches 5/7
83.33% Functions 10/12
94.29% Lines 33/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 1061x 1x     1x                   14x 14x 14x 14x 14x                   2x 2x 2x           2x   2x 2x 2x 2x   2x   2x                 2x 2x   2x           1x 1x           2x     2x 2x               3x   3x 3x   3x           5x         7x         4x    
import { Timer } from './timer';
import { EventManager } from './event-manager';
import { ITimeSpentConfig } from './interfaces/timespentconfig-interface';
 
export default class TimeSpentTimer {
 
    private idleTimer: Timer;
    private timeTimer: Timer;
    private idleThreshold: number;
    private idleCallback: (() => any) | undefined;
    private eventManager: EventManager;
 
    constructor(config: ITimeSpentConfig = {}) {
 
        this.idleTimer = new Timer(1000, this.userIdle.bind(this));
        this.timeTimer = new Timer(config.interval, config.onTick);
        this.idleThreshold = config.idleThreshold || 5000;
        this.idleCallback = config.onIdle;
        this.eventManager = new EventManager();
    }
 
    public get TimeSpent(): number {
 
        return this.timeTimer.Elapsed;
    }
 
    public init(): void {
 
        this.bindEvents();
        this.start(this.timeTimer);
        this.start(this.idleTimer);
    }
 
    private bindEvents(): void {
 
        //start events
        this.eventManager.onFocus(this.userReturned.bind(this));
        //reset events
        this.eventManager.onMouseMove(this.userActive.bind(this));
        this.eventManager.onKeyUp(this.userActive.bind(this));
        this.eventManager.onTouchStart(this.userActive.bind(this));
        this.eventManager.onScroll(this.userActive.bind(this));
        //pause events
        this.eventManager.onBlur(this.userLeft.bind(this));
        //Minimize 
        this.eventManager.onVisibilityChange(isHidden => {
 
            isHidden ? this.userLeft() : this.userReturned();
        });
    }
 
    private userLeft(): void {
 
        //Pauze both timers
        this.pause(this.timeTimer);
        this.pause(this.idleTimer);
        //Reset the idle timer
        this.reset(this.idleTimer);
    }
 
    private userReturned(): void {
 
        //Resume both timers
        this.start(this.timeTimer);
        this.start(this.idleTimer);
    }
 
    private userActive(): void {
 
        //Resume the timer
        this.start(this.timeTimer);
 
        //Reset and resume the idle timer
        this.reset(this.idleTimer);
        this.start(this.idleTimer);
 
    }
 
    private userIdle(): void {
 
        if (this.idleTimer.Elapsed >= this.idleThreshold) {
 
            if (this.idleCallback) this.idleCallback();
            //Pause both timers
            this.pause(this.timeTimer);
            this.pause(this.idleTimer);
            //Reset the idle timer
            this.reset(this.idleTimer);
        }
    }
 
    public start(timer: Timer): void {
 
        timer.start();
    }
 
    public pause(timer: Timer): void {
 
        timer.pause();
    }
 
    public reset(timer: Timer): void {
 
        timer.reset();
    }
}