├── .gitignore ├── .travis.yml ├── README.md ├── package.json ├── index.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .vscode 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4 4 | - 5 5 | - "node" 6 | before_script: 7 | - export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # idle-timer 2 | Checks if a user is idle for a configurable amount of time and fires a callback 3 | 4 | [![Build Status](https://travis-ci.org/micnews/idle-timer.svg)](https://travis-ci.org/micnews/idle-timer) 5 | 6 | 7 | ### Usage 8 | ```js 9 | var timer = idleTimer({ 10 | // function to fire after idle 11 | callback: callbackFn, 12 | // function to fire when active 13 | activeCallback: activeCallbackFn, 14 | // Amount of time in milliseconds before becoming idle. default 60000 15 | idleTime: 5000 16 | }) 17 | function callbackFn () { 18 | console.log("You're idle!"); 19 | } 20 | 21 | // when no longer needed, destroy() will remove 22 | // all of the event listeners and clear the timeouts 23 | timer.destroy(); 24 | ``` 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "idle-timer", 3 | "version": "1.2.0", 4 | "description": "Checks if a user is idle for a configurable amount of time and fires a callback", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "browserify test.js | testron | faucet" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/micnews/idle-timer.git" 12 | }, 13 | "keywords": [ 14 | "idle", 15 | "timer" 16 | ], 17 | "author": "mic.com", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/micnews/idle-timer/issues" 21 | }, 22 | "homepage": "https://github.com/micnews/idle-timer#readme", 23 | "devDependencies": { 24 | "browserify": "^13.0.0", 25 | "electron-prebuilt": "^0.36.7", 26 | "faucet": "0.0.1", 27 | "tape": "^4.4.0", 28 | "testron": "^1.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * idleTimer 3 | * 4 | * If user is idle for idleTime fire callback 5 | * 6 | * @param {object} options 7 | * - {function} callback - fired when user is idle 8 | * - {function} activeCallback - fired when user is active 9 | * - {Number} idleTime - time in milliseconds 10 | */ 11 | 12 | module.exports = idleTimer; 13 | 14 | function idleTimer(options) { 15 | options = options || {}; 16 | var callback = options.callback || function() {}; 17 | var activeCallback = options.activeCallback || function() {}; 18 | var idleTime = options.idleTime || 60000; 19 | var isActive = true; 20 | var timer; 21 | 22 | addOrRemoveEvents('addEventListener'); 23 | activate(); 24 | 25 | function addOrRemoveEvents(addOrRemove) { 26 | window[addOrRemove]('load', activate); 27 | document[addOrRemove]('mousemove', activate); 28 | document[addOrRemove]('scroll', activate); 29 | document[addOrRemove]('keypress', activate); 30 | } 31 | 32 | function activate() { 33 | if (!isActive) { 34 | isActive = true; 35 | activeCallback(); 36 | } 37 | clearTimeout(timer); 38 | timer = setTimeout(idle, idleTime); 39 | } 40 | 41 | function idle() { 42 | if (!isActive) return; 43 | isActive = false; 44 | callback(); 45 | } 46 | 47 | function destroy() { 48 | clearTimeout(timer); 49 | addOrRemoveEvents('removeEventListener'); 50 | } 51 | 52 | return { 53 | activate: activate, 54 | destroy: destroy, 55 | idle: idle 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var test = require("tape").test; 2 | var idleTimer = require("./index"); 3 | 4 | test('idleTimer is a function', function (t) { 5 | t.equal(typeof idleTimer , "function"); 6 | t.end(); 7 | }); 8 | 9 | test('idleTimer.destroy removes the listeners', function (t) { 10 | var foo = 'nothing happened'; 11 | t.plan(1); 12 | idleTimer({ 13 | callback: function() { 14 | foo = 'beep'; 15 | }, 16 | idleTime: 10 17 | }).destroy(); 18 | setTimeout(function() { 19 | t.equal(foo, 'nothing happened'); 20 | }, 11); 21 | }); 22 | 23 | test('idleTimer.idle explicitly stops the timer and reports idle', function (t) { 24 | var foo = 0; 25 | t.plan(2); 26 | var timer = idleTimer({ 27 | callback: function() { 28 | foo++; 29 | }, 30 | idleTime: 10 31 | }); 32 | timer.idle(); 33 | setTimeout(function() { 34 | t.equal(foo, 1); 35 | }, 9); 36 | setTimeout(function() { 37 | t.equal(foo, 1); 38 | }, 11); 39 | }); 40 | 41 | test('idleTimer.active explicitly resets the timer', function (t) { 42 | var foo = 0; 43 | t.plan(2); 44 | var timer = idleTimer({ 45 | callback: function() { 46 | foo++; 47 | }, 48 | idleTime: 10 49 | }); 50 | setTimeout(function() { 51 | timer.activate(); 52 | setTimeout(function() { 53 | t.equal(foo, 1); 54 | }, 11); 55 | }, 5); 56 | setTimeout(function() { 57 | t.equal(foo, 0); 58 | }, 11); 59 | }); 60 | 61 | test('idleTimer callback gets called after being idle', function (t) { 62 | var foo; 63 | t.plan(2); 64 | t.equal(foo, undefined); 65 | idleTimer({ 66 | callback: function() { 67 | foo = 'beep'; 68 | }, 69 | idleTime: 10 70 | }); 71 | setTimeout(function() { 72 | t.equal(foo, "beep"); 73 | }, 11); 74 | }); 75 | 76 | test('idleTimer activeCallback gets called after user activity', function (t) { 77 | var activeCalls = 0; 78 | var idleCalls = 0; 79 | t.plan(10); 80 | idleTimer({ 81 | activeCallback: function() { 82 | activeCalls++; 83 | }, 84 | callback: function() { 85 | idleCalls++; 86 | }, 87 | idleTime: 10 88 | }); 89 | setTimeout(function() { 90 | t.equal(activeCalls, 0, 'active initial'); 91 | t.equal(idleCalls, 0, 'idle initial'); 92 | }, 9); 93 | setTimeout(function() { 94 | t.equal(activeCalls, 0, 'active afrter first sleep'); 95 | t.equal(idleCalls, 1, 'idle after first sleep'); 96 | }, 11); 97 | setTimeout(function() { 98 | dispatchEvent(new Event('load')); 99 | setTimeout(function() { 100 | t.equal(activeCalls, 1, 'active after first activity'); 101 | t.equal(idleCalls, 1, 'idle after first activity'); 102 | }, 1); 103 | setTimeout(function() { 104 | t.equal(activeCalls, 1, 'active right before second sleep'); 105 | t.equal(idleCalls, 1, 'idle right before second sleep'); 106 | }, 9); 107 | setTimeout(function() { 108 | t.equal(activeCalls, 1, 'active after second sleep'); 109 | t.equal(idleCalls, 2, 'idle after second sleep'); 110 | }, 11); 111 | }, 12); 112 | }); 113 | 114 | test('idleTimer activeCallback does not get called before first callback', function (t) { 115 | var activeCalls = 0; 116 | var idleCalls = 0; 117 | t.plan(2); 118 | idleTimer({ 119 | activeCallback: function() { 120 | activeCalls++; 121 | }, 122 | callback: function() { 123 | idleCalls++; 124 | }, 125 | idleTime: 10 126 | }); 127 | dispatchEvent(new Event('load')); 128 | setTimeout(function() { 129 | t.equal(activeCalls, 0); 130 | t.equal(idleCalls, 0); 131 | }, 5); 132 | }); 133 | --------------------------------------------------------------------------------