Author: jruchaud Date: 2015-05-22 09:56:32 +0000 (Fri, 22 May 2015) New Revision: 1426 Url: http://forge.nuiton.org/projects/sandbox/repository/revisions/1426 Log: Setup eslint Added: wit/.eslintrc Modified: wit/activityChange.html wit/css/style.less wit/css/timeline.less wit/css/userActivity.less wit/idle.html wit/index.html wit/js/components/ActionsBar.js wit/js/components/FilterBar.js wit/js/components/FilterLogs.js wit/js/components/InputTag.js wit/js/components/LogsTable.js wit/js/components/Tags.js wit/js/components/Time.js wit/js/components/Timeline.js wit/js/gui.js wit/js/main.js wit/js/pages/EditionLogs.js wit/js/pages/Options.js wit/js/pages/Rapport.js wit/js/pages/Timer.js wit/js/pages/UserActivity.js wit/js/services/ConfigurationService.js wit/js/services/TimerService.js wit/js/services/UserActivityService.js wit/js/services/database.js Added: wit/.eslintrc =================================================================== --- wit/.eslintrc (rev 0) +++ wit/.eslintrc 2015-05-22 09:56:32 UTC (rev 1426) @@ -0,0 +1,247 @@ +{ + "ecmaFeatures": { + "jsx": true + }, + "globals": { + "console": false, + "React": false + }, + "env": { + "browser": true, + "node": true, + "es6": true + }, + "rules": { + "comma-dangle": [ + 2, + "never" + ], + "no-comma-dangle": 0, + "no-cond-assign": 2, + "no-console": 2, + "no-constant-condition": 2, + "no-control-regex": 2, + "no-debugger": 2, + "no-dupe-keys": 2, + "no-empty": 2, + "no-empty-class": 2, + "no-ex-assign": 2, + "no-extra-boolean-cast": 2, + "no-extra-parens": 2, + "no-extra-semi": 2, + "no-func-assign": 2, + "no-inner-declarations": [ + 0, + "both" + ], + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-negated-in-lhs": 2, + "no-obj-calls": 2, + "no-regex-spaces": 2, + "no-reserved-keys": 2, + "no-sparse-arrays": 2, + "no-unreachable": 2, + "use-isnan": 2, + "valid-jsdoc": 0, + "valid-typeof": 2, + "block-scoped-var": 0, + "complexity": 0, + "consistent-return": 2, + "curly": [ + 2, + "all" + ], + "default-case": 2, + "dot-notation": 2, + "eqeqeq": [ + 2, + "smart" + ], + "guard-for-in": 2, + "no-alert": 2, + "no-caller": 2, + "no-div-regex": 2, + "no-else-return": 2, + "no-empty-label": 2, + "no-eq-null": 0, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-implied-eval": 2, + "no-iterator": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-spaces": 1, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-octal": 2, + "no-octal-escape": 2, + "no-process-env": 1, + "no-proto": 2, + "no-redeclare": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-throw-literal": 2, + "no-unused-expressions": 2, + "no-void": 2, + "no-warning-comments": 0, + "no-with": 2, + "radix": 2, + "vars-on-top": 0, + "wrap-iife": 2, + "yoda": 2, + "global-strict": 0, + "no-extra-strict": 0, + "strict": [ + 2, + "global" + ], + "no-catch-shadow": 2, + "no-delete-var": 2, + "no-label-var": 2, + "no-shadow": 2, + "no-shadow-restricted-names": 2, + "no-undef": 2, + "no-undef-init": 2, + "no-undefined": 0, + "no-unused-vars": 2, + "no-use-before-define": 2, + "indent": [ + 1, + 4 + ], + "brace-style": [ + 1, + "1tbs", + { + "allowSingleLine": true + } + ], + "camelcase": 1, + "comma-spacing": [ + 1, + { + "before": false, + "after": true + } + ], + "comma-style": [ + 1, + "last" + ], + "consistent-this": [ + 2, + "_this" + ], + "eol-last": 1, + "func-names": 0, + "func-style": 0, + "key-spacing": [ + 1, + { + "beforeColon": false, + "afterColon": true + } + ], + "max-nested-callbacks": [ + 2, + 5 + ], + "new-cap": 2, + "new-parens": 2, + "no-array-constructor": 2, + "no-inline-comments": 0, + "no-lonely-if": 2, + "no-mixed-spaces-and-tabs": 1, + "no-multiple-empty-lines": 1, + "no-nested-ternary": 2, + "no-new-object": 2, + "no-space-before-semi": 0, + "no-spaced-func": 1, + "no-ternary": 0, + "no-trailing-spaces": 1, + "no-underscore-dangle": 0, + "no-wrap-func": 2, + "one-var": 0, + "operator-assignment": 0, + "padded-blocks": 0, + "quote-props": [ + 2, + "as-needed" + ], + "quotes": [ + 1, + "double" + ], + "semi": [ + 2, + "always" + ], + "semi-spacing": [ + 1, + { + "before": false, + "after": true + } + ], + "sort-vars": 0, + "space-after-function-name": 0, + "space-after-keywords": [ + 1, + "always" + ], + "space-before-blocks": [ + 1, + "always" + ], + "space-before-function-paren": [ + 1, + "never" + ], + "space-in-brackets": [ + 1, + "never" + ], + "space-in-parens": [ + 1, + "never" + ], + "space-infix-ops": 1, + "space-return-throw-case": 2, + "space-unary-ops": 2, + "spaced-line-comment": 0, + "wrap-regex": 0, + "no-var": 0, + "generator-star": [ + 2, + "start" + ], + "max-depth": [ + 2, + 10 + ], + "max-len": [ + 1, + 180 + ], + "max-params": [ + 2, + 10 + ], + "max-statements": [ + 1, + 100 + ], + "no-bitwise": 2, + "no-plusplus": 0 + } +} Modified: wit/activityChange.html =================================================================== --- wit/activityChange.html 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/activityChange.html 2015-05-22 09:56:32 UTC (rev 1426) @@ -2,19 +2,19 @@ <head> <title>WIT activity</title> <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css"> - + <style> h1 { text-align: center; } </style> - + <script> var gui = require('nw.gui'); var window = gui.Window.get(); var timer = global.timer; var user = global.user; - + var keepTiming = function() { user.resumeActivityDetection(); window.close(); @@ -27,16 +27,16 @@ timer.reassignTimeFrom(user.getActivityChangeDetectedDate()); window.close(); }; - + timer.subscribeIdle(window.close.bind(window)); </script> </head> - + <body> <div class="container-fluid"> <h1>Activity change detected</h1> <div class="alert alert-danger" role="alert"> Are you still working on the same activity ?</div> - + <button type="button" class="btn btn-primary btn-lg btn-block" onclick="keepTiming()"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Yes ! Please keep timing current activity Modified: wit/css/style.less =================================================================== --- wit/css/style.less 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/css/style.less 2015-05-22 09:56:32 UTC (rev 1426) @@ -28,7 +28,7 @@ .editInput { margin: 20px 0 15px 0; - + input { font-family: Digital; } Modified: wit/css/timeline.less =================================================================== --- wit/css/timeline.less 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/css/timeline.less 2015-05-22 09:56:32 UTC (rev 1426) @@ -2,15 +2,15 @@ @timelineDefaultHeight: 30px; .timeline { - + margin: 10px 0; - + .sessions { display: flex; width: @timelineDefaultWidth; - height: @timelineDefaultHeight; - + height: @timelineDefaultHeight; + background: red; .slice { @@ -22,9 +22,9 @@ text-overflow: ellipsis; cursor: pointer; - + color:white; - + &:hover{ box-shadow: 0px 0px 5px 2px #656565; } Modified: wit/css/userActivity.less =================================================================== --- wit/css/userActivity.less 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/css/userActivity.less 2015-05-22 09:56:32 UTC (rev 1426) @@ -2,13 +2,13 @@ display: flex; flex-direction: column; justify-content: center; - + height: 350px; width: 100%; - + h1 { position: absolute; top: 50px; color: black; } -} \ No newline at end of file +} Modified: wit/idle.html =================================================================== --- wit/idle.html 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/idle.html 2015-05-22 09:56:32 UTC (rev 1426) @@ -2,18 +2,18 @@ <head> <title>WIT idle</title> <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css"> - + <style> h1 { text-align: center; } </style> - + <script> var gui = require('nw.gui'); var window = gui.Window.get(); var timer = global.timer; - + var keepIdle = function() { timer.keepIdle(); window.close(); @@ -28,12 +28,12 @@ }; </script> </head> - + <body> <div class="container-fluid"> <h1>Idle detected</h1> <div class="alert alert-danger" role="alert">Idle detcted, please select your option:</div> - + <button type="button" class="btn btn-primary btn-lg btn-block" onclick="keepIdle()"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Keep idle for current time Modified: wit/index.html =================================================================== --- wit/index.html 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/index.html 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,11 +1,11 @@ <html> <head> <title>WIT</title> - + <!-- For React --> <script type="text/javascript" src="node_modules/react/dist/react-with-addons.js"></script> <script type="text/javascript" src="node_modules/react/dist/JSXTransformer.js"></script> - + <script type="text/jsx" src="js/components/InputTag.js"></script> <script type="text/jsx" src="js/components/Tags.js"></script> <script type="text/jsx" src="js/components/Time.js"></script> @@ -21,19 +21,19 @@ <script type="text/jsx" src="js/pages/EditionLogs.js"></script> <script type="text/jsx" src="js/main.js"></script> <script type="application/javascript" src="js/gui.js"></script> - + <!-- For Bootstrap --> <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css"> - + <!-- For Less --> <link rel="stylesheet/less" type="text/css" href="css/style.less" /> <link rel="stylesheet/less" type="text/css" href="css/timeline.less" /> <link rel="stylesheet/less" type="text/css" href="css/userActivity.less" /> - + <script type="text/javascript" src="node_modules/less/dist/less.min.js"></script> </head> - + <body></body> </html> Modified: wit/js/components/ActionsBar.js =================================================================== --- wit/js/components/ActionsBar.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/ActionsBar.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,28 +1,27 @@ -/** @jsx React.DOM */ +"use strict"; var ActionsBar = React.createClass({ - + onPlay: function() { timer.start(); }, - + onStop: function() { timer.stop(true); }, - + prevHistory: function() { timer.stop(); timer.prevHistory(); }, - + nextHistory: function() { timer.stop(); timer.nextHistory(); }, - + render: function() { - return ( - <div className="text-center"> + return <div className="text-center"> <div ref="actions" className="btn-group" role="group"> <button type="button" className="btn btn-primary btn-lg" onClick={this.prevHistory}> <span className="glyphicon glyphicon-step-backward" aria-hidden="true"></span> @@ -37,7 +36,6 @@ <span className="glyphicon glyphicon-step-forward" aria-hidden="true"></span> </button> </div> - </div> - ); + </div>; } }); Modified: wit/js/components/FilterBar.js =================================================================== --- wit/js/components/FilterBar.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/FilterBar.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,49 +1,47 @@ -/** @jsx React.DOM */ +"use strict"; var FilterBar = React.createClass({ - + componentDidMount: function() { - var moment = require('moment'); - + var moment = require("moment"); + var now = moment(); - now.add(1, 'days'); + now.add(1, "days"); var endDefaultDate = now.format("YYYY-MM-DDThh:mm"); - now.subtract(7, 'days'); - var startDefaultDate = now.format("YYYY-MM-DDThh:mm"); - + now.subtract(7, "days"); + var startDefaultDate = now.format("YYYY-MM-DDThh:mm"); + this.refs.beginDate.getDOMNode().value = startDefaultDate; this.refs.endDate.getDOMNode().value = endDefaultDate; }, - + search: function() { - var moment = require('moment'); + var moment = require("moment"); var db = require("./js/services/database.js"); - + this.startDate = moment(this.refs.beginDate.getDOMNode().value); this.endDate = moment(this.refs.endDate.getDOMNode().value); return db.searchLogs(null, this.startDate, this.endDate, true); }, - + onSearch: function() { - var self = this; - + var startDate = this.startDate; + var endDate = this.endDate; + this.search() .then(function(result) { - self.props.onSearchResult(result, self.startDate, self.endDate); + self.props.onSearchResult(result, startDate, endDate); // console.log(result); }); }, - + render: function() { - - return ( - <div> + return <div> <input ref="beginDate" type="datetime-local" className="form-control" required></input> <input ref="endDate" type="datetime-local" className="form-control" required></input> <button onClick={this.onSearch} className="btn btn-primary btn-block">Search</button> - </div> - ); + </div>; } }); Modified: wit/js/components/FilterLogs.js =================================================================== --- wit/js/components/FilterLogs.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/FilterLogs.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,126 +1,127 @@ -/** @jsx React.DOM */ -var nonce = require('nonce')(); +"use strict"; var FilterLogs = React.createClass({ - + getCSV: function() { var result = ""; - + var nodes = document.querySelectorAll("tr"); for (var r = 0, lr = nodes.length; r < lr; r++) { var row = nodes[r].children; - + for (var c = 0, lc = row.length; c < lc; c++) { var col = row[c]; result += col.textContent + ";"; } result += "\n"; - }; - + } + return result; }, - + getTXT: function() { var result = ""; - + var dates = Object.keys(this.state.data); for (var date of dates) { - result += date + "\n--------\n" + result += date + "\n--------\n"; result += "\n" + this.getTXTRow(date, [], this.state.data[date]) + "\n"; } - + return result; }, - + getTXTRow: function(date, tags, tagObject) { var r = ""; - + if (tagObject.duration) { - var self = this; + var state = this.state; var filterTags = tags.filter(function(tag) { - return self.state.tags[tag]; + return state.tags[tag]; }); - + if (filterTags.length) { - r += tagObject.duration + " - " + filterTags.join(', ') + "\n"; + r += tagObject.duration + " - " + filterTags.join(", ") + "\n"; } } - + var keys = Object.keys(tagObject); for (var k of keys) { - if (k != "diff" && k != "duration") { + if (k !== "diff" && k !== "duration") { r += this.getTXTRow(date, tags.concat(k), tagObject[k]); } } - + return r; }, - + onClipboardCSV: function() { var content = this.getCSV(); this.clipboard(content); }, - + onClipboardTXT: function() { var content = this.getTXT(); this.clipboard(content); }, - + clipboard: function(content) { - var gui = require('nw.gui'); + var gui = require("nw.gui"); var clipboard = gui.Clipboard.get(); - clipboard.set(content, 'text'); + clipboard.set(content, "text"); }, - - onMailCSV: function(content) { + + onMailCSV: function() { var content = this.getCSV(); this.mail(content); }, - - onMailTXT: function(content) { + + onMailTXT: function() { var content = this.getTXT(); this.mail(content); }, - - onShowSummary: function () { + + onShowSummary: function() { this.refs.summary.getDOMNode().classList.toggle("hidden"); }, - - onLogDetails: function (e) { + + onLogDetails: function(e) { var nodeId = e.target.dataset.id; - nodeId && this.refs[nodeId].getDOMNode().classList.toggle("hidden"); + if (nodeId) { + this.refs[nodeId].getDOMNode().classList.toggle("hidden"); + } }, - + mail: function(content) { content = content.replace(/\n/g, "%0A").replace(/;/g, "%3B").replace(/-/g, "%2D"); var link = "mailto:?body=" + content; window.location.href = link; }, - + onToggleFilterTag: function() { this.refs.filterTags.getDOMNode().classList.toggle("hidden"); }, - + getInitialState: function() { return {data: null, tags: {}}; }, - + componentWillReceiveProps: function(nextProps) { this.createTree(nextProps); }, - + toggleTagChecked: function(e) { Object.keys(this.state.tags).forEach(function(tag) { this.state.tags[tag] = e.target.checked; }, this); - + this.createTree({ data: this.props.data, tags: this.state.tags }); e.stopPropagation(); }, - + filterTag: function(e) { this.state.tags[e.target.name] = e.target.checked; this.createTree({ @@ -128,26 +129,26 @@ tags: this.state.tags }); }, - + createTree: function(currentState) { var data = {}, tags = {}; - + currentState.data.result.forEach(function(log) { - + var moment = require("moment"); var date = moment(log.startDate).format("MM/DD/YY"); var diff = moment(moment(log.endDate).diff(log.startDate)).utcOffset(0); - + var current = data[date] = data[date] || {}; log.tags.forEach(function(tag) { - + if (!currentState.tags || currentState.tags[tag]) { current = current[tag] = current[tag] || {}; } - + tags[tag] = true; }); - + if (current.diff) { current.diff.add(diff); } else { @@ -157,31 +158,32 @@ current.duration = current.diff.format("HH:mm:ss"); current.endDate = log.endDate; }); - + this.setState({ - data: data, tags: currentState.tags || tags, - startDate: currentState.data.startDate, + data: data, tags: currentState.tags || tags, + startDate: currentState.data.startDate, endDate: currentState.data.endDate }); }, - + renderTd: function(date, tags, tagObject) { + var nonce = require("nonce")(); var r = []; - + if (tagObject.duration) { - var self = this; + var state = this.state; var filterTags = tags.filter(function(tag) { - return self.state.tags[tag]; + return state.tags[tag]; }); - + var key = date + nonce(); - + if (filterTags.length) { r.push( <tr> <td>{date}</td> <td>{tagObject.duration}</td> - <td>{filterTags.join(', ')}</td> + <td>{filterTags.join(", ")}</td> <td> <button type="button" className="btn btn-default" data-id={key}> <span data-id={key} className="glyphicon glyphicon-option-horizontal" aria-hidden="false"></span> @@ -196,24 +198,24 @@ ); } } - + var keys = Object.keys(tagObject); for (var k of keys) { - if (k != "diff" && k != "duration") { + if (k !== "diff" && k !== "duration") { r = r.concat(this.renderTd(date, tags.concat(k), tagObject[k])); } } - + return r; }, - + render: function() { var items = []; - + var classString = ""; if (!this.state.data) { classString = "hidden"; - + } else { var dates = Object.keys(this.state.data); for (var date of dates) { @@ -221,7 +223,7 @@ items = items.concat(r); } } - + var tags = []; for (var tag of Object.keys(this.state.tags)) { tags.push( @@ -233,9 +235,8 @@ </div> ); } - - return ( - <div className={classString}> + + return <div className={classString}> <h2>Result</h2> <div ref="actions" className="btn-group" role="group"> @@ -269,7 +270,7 @@ </div> {tags} </div> - + <div ref="summary" className="hidden"> <Timeline key={nonce()} data={this.state}/> </div> @@ -287,11 +288,10 @@ {items} </tbody> </table> - + <h3 className={items.length ? "hidden" : "text-center"}> No result ! </h3> - </div> - ); + </div>; } }); Modified: wit/js/components/InputTag.js =================================================================== --- wit/js/components/InputTag.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/InputTag.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,63 +1,61 @@ -/** @jsx React.DOM */ +"use strict"; var InputTag = React.createClass({ - + getInitialState: function() { return {options: [], value: ""}; }, - + getTags: function() { - var self = this; + var setState = self.setState; timer.getLastTags().then(function(tags) { - self.setState({options: tags, value: ""}); + setState({options: tags, value: ""}); }); }, - + onKey: function(e) { var target = e.target; var value = target.value; - - if (e.keyCode == 13 && value != "") { // On enter + + if (e.keyCode === 13 && value !== "") { // On enter this.setState({options: this.state.options, value: ""}); timer.stop(); timer.addTag(value); } }, - + onChange: function(e) { this.setState({options: this.state.options, value: e.target.value}); }, - + render: function() { var options = []; - + if (this.state.value) { - + for (var i = 0, l = this.state.options.length; i < l; i++) { var item = this.state.options[i]; - if (options.length < 3 && item.indexOf(this.state.value) == 0) { + if (options.length < 3 && item.indexOf(this.state.value) === 0) { var element = <option>{item}</option>; options.push(element); } } } - - return ( - <div> - <input id="search"className="form-control" + + return <div> + <input id="search"className="form-control" onKeyDown={this.onKey} onFocus={this.getTags} - onChange={this.onChange} placeholder="enter tag" + onChange={this.onChange} placeholder="enter tag" tabIndex="-1" autoComplete="off" autoCorrect="off" value={this.state.value} - autoCapitalize="off" spellCheck="false" role="textbox" + autoCapitalize="off" spellCheck="false" role="textbox" type="text" list="searchresults" /> - + <datalist id="searchresults"> {options} </datalist> - </div> - ); + </div>; } - + }); Modified: wit/js/components/LogsTable.js =================================================================== --- wit/js/components/LogsTable.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/LogsTable.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,32 +1,33 @@ -/** @jsx React.DOM */ +"use strict"; var LogsTable = React.createClass({ - + onDelete: function(e) { var logId = e.target.dataset.id; if (logId) { timer.deleteLog(logId); - - var index = parseInt(e.target.dataset.index); + + var index = parseInt(e.target.dataset.index, 10); this.props.data.splice(index, 1); this.forceUpdate(); } }, - + render: function() { + var moment = require("moment"); var items = []; - + var classString = ""; if (!this.props.data) { classString = "hidden"; - + } else { this.props.data.forEach(function(log, index) { items.push( <tr> <td>{moment(log.startDate).format()}</td> <td>{moment(log.endDate).format()}</td> - <td>{log.tags.join(', ')}</td> + <td>{log.tags.join(", ")}</td> <td> <div ref="actions" className="btn-group" role="group"> <button type="button" className="btn btn-primary btn-lg" data-index={index} data-id={log._id}> @@ -38,9 +39,8 @@ ); }, this); } - - return ( - <div className={classString}> + + return <div className={classString}> <h2>Result</h2> <table className="table"> @@ -56,11 +56,10 @@ {items} </tbody> </table> - + <h3 className={items.length ? "hidden" : "text-center"}> No result ! </h3> - </div> - ); + </div>; } }); Modified: wit/js/components/Tags.js =================================================================== --- wit/js/components/Tags.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/Tags.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,55 +1,53 @@ -/** @jsx React.DOM */ +"use strict"; var Tags = React.createClass({ - - getInitialState : function() { - return timer; + + getInitialState: function() { + return timer; }, - + componentDidMount: function() { - this.forceUpdate_bound = this.forceUpdate.bind(this); - timer.subscribeTagsChanged(this.forceUpdate_bound); + this.forceUpdateBound = this.forceUpdate.bind(this); + timer.subscribeTagsChanged(this.forceUpdateBound); }, - + componentWillUnmount: function() { - timer.unsubscribeTagsChanged(this.forceUpdate_bound); + timer.unsubscribeTagsChanged(this.forceUpdateBound); }, - + onRemove: function(e) { var target = e.target; var index = target.dataset.index; - + timer.stop(); timer.removeTag(index); }, - + render: function() { - var self = this; - + var onRemove = this.onRemove; + var tags = timer.getTags(); - + var rows = []; - for (var i=0; i < 5; i++) { + for (var i = 0; i < 5; i++) { var tag = tags[i]; - + rows.push(<li className="list-group-item"> <button type="button" className="close" aria-label="Close"> - <span aria-hidden="true" onClick={self.onRemove} data-index={i}>×</span> + <span aria-hidden="true" onClick={onRemove} data-index={i}>×</span> </button> - + {tag ? tag : "empty"} </li> ); } - - return ( - <ul className="list-group"> + + return <ul className="list-group"> {rows} - + <li className="list-group-item"> <InputTag /> - </li> - </ul> - ); + </li> + </ul>; } }); Modified: wit/js/components/Time.js =================================================================== --- wit/js/components/Time.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/Time.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,65 +1,63 @@ -/** @jsx React.DOM */ +"use strict"; var Time = React.createClass({ - + getInitialState: function() { return timer; }, - + componentDidMount: function() { - this.forceUpdate_bound = this.forceUpdate.bind(this); - timer.subscribeTimeChanged(this.forceUpdate_bound); + this.forceUpdateBound = this.forceUpdate.bind(this); + timer.subscribeTimeChanged(this.forceUpdateBound); }, - + componentWillUnmount: function() { timer.unsubscribeTimeChanged(this.forceUpdate_bound); }, - - onEdit: function(e) { + + onEdit: function() { this.refs.editButton.getDOMNode().classList.toggle("hidden"); this.refs.editInput.getDOMNode().classList.toggle("hidden"); this.refs.timeValue.getDOMNode().classList.toggle("hidden"); - + var time = timer.getTime() || "00:00:00"; var editInputTime = this.refs.editInputTime.getDOMNode(); editInputTime.value = time; editInputTime.max = time; }, - - onSaveTime: function(e) { + + onSaveTime: function() { this.refs.editButton.getDOMNode().classList.toggle("hidden"); this.refs.editInput.getDOMNode().classList.toggle("hidden"); this.refs.timeValue.getDOMNode().classList.toggle("hidden"); - + var editInputTime = this.refs.editInputTime.getDOMNode(); timer.editTime(editInputTime.value); }, - + render: function() { - return ( - <div> + return <div> <button ref="editButton" type="button" className="btn btn-primary btn-small editButton" onClick={this.onEdit}> <span className="glyphicon glyphicon-pencil" aria-hidden="true"></span> </button> - + <div ref="editInput" className="input-group editInput hidden"> - - <input ref="editInputTime" type="time" className="form-control" + + <input ref="editInputTime" type="time" className="form-control" min="00:00:00" step="1"/> - + <span className="input-group-btn"> <button className="btn btn-primary" type="button" onClick={this.onSaveTime}>Save</button> </span> </div> - + <h1 ref="timeValue" className="digit"> - {this.state.getTime() ? this.state.getTime() : "00:00:00"} + {this.state.getTime() ? this.state.getTime() : "00:00:00"} </h1> - + <h5 className="digit"> - {this.state.getDayTime() ? this.state.getDayTime() : "00:00:00"} + {this.state.getDayTime() ? this.state.getDayTime() : "00:00:00"} </h5> - </div> - ); + </div>; } }); Modified: wit/js/components/Timeline.js =================================================================== --- wit/js/components/Timeline.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/components/Timeline.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,86 +1,102 @@ -var moment = require('moment'); -var nonce = require('nonce')(); +"use strict"; var Timeline = React.createClass({ - + getInitialState: function() { return { sessions: [] }; }, - - componentDidMount: function () { - var startDate = this.props.data.startDate && moment(this.props.data.startDate); - var endDate = this.props.data.endDate && moment(this.props.data.endDate); - + + componentDidMount: function() { + var moment = require("moment"); + + var startDate; + if (this.props.data.startDate) { + startDate = moment(this.props.data.startDate); + } + + var endDate; + if (this.props.data.endDate) { + endDate = moment(this.props.data.endDate); + } + if (startDate && endDate) { - var self = this; + var setState = this.setState; user.getSessions(startDate, endDate, true) - .then(function (sessions) { - self.setState({ + .then(function(sessions) { + setState({ sessions: sessions }); }); } }, - + render: function() { var sessions = this.state.sessions; - + var items = []; - + // Create a wrapper for each window session - - var startDate = this.props.data.startDate && moment(this.props.data.startDate); - var endDate = this.props.data.endDate && moment(this.props.data.endDate); - var self = this, - timeRange = endDate && endDate.diff(startDate); - + var moment = require("moment"); + + var startDate; + if (this.props.data.startDate) { + startDate = moment(this.props.data.startDate); + } + + var endDate; + if (this.props.data.endDate) { + endDate = moment(this.props.data.endDate); + } + + var _normalize = this._normalize, + timeRange = endDate && endDate.diff(startDate), + nonce = require("nonce")(); + items = items.concat( sessions.map(function(session) { - var rst = ""; - - var ns = self._normalize(session, startDate, endDate); // normalize session according to timeline boundaries - + var ns = _normalize(session, startDate, endDate); // normalize session according to timeline boundaries + var data = { title: ns.name, color: ns.color, width: (ns.duration / timeRange * 100 || 0) + "%" }; - + var key = nonce(); - - return <TimelineSession key={key} data={data} /> + + return <TimelineSession key={key} data={data} />; }) ); - return ( - <div className="timeline"> + return <div className="timeline"> <div className="sessions"> {items} </div> - </div> - ); + </div>; }, - + /* * Normalize session dates and duration according to the given dates * If the given session starts before the given startDate or end after the given endDate, * this function will remove the session part outside the scope */ - _normalize: function (session, startDate, endDate) { + _normalize: function(session, startDate, endDate) { + var moment = require("moment"); + session.startDate = moment(session.startDate); session.endDate = moment(session.endDate); - + if (session.startDate.isBefore(startDate)) { session.startDate = startDate; } if (session.endDate.isAfter(endDate)) { session.endDate = endDate; } - + session.duration = session.endDate.diff(session.startDate); return session; @@ -88,7 +104,7 @@ }); var TimelineSession = React.createClass({ - render: function () { + render: function() { var data = this.props.data; var title = data.title || ""; @@ -96,8 +112,6 @@ background: data.color, width: data.width }; - return ( - <div className="slice" style={style} title={title}>{title}</div> - ); + return <div className="slice" style={style} title={title}>{title}</div>; } }); Modified: wit/js/gui.js =================================================================== --- wit/js/gui.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/gui.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,27 +1,29 @@ +"use strict"; + // Load library -var gui = require('nw.gui'); +var gui = require("nw.gui"); // Reference to window and tray var win = gui.Window.get(); -win.removeAllListeners('minimize'); +win.removeAllListeners("minimize"); var tray; // Get the minimize event -win.on('minimize', function() { +win.on("minimize", function() { // Hide window this.hide(); // Show tray - tray = new gui.Tray({ icon: 'img/stopwatch-34108_640.png' }); + tray = new gui.Tray({icon: "img/stopwatch-34108_640.png"}); var menu = new gui.Menu(); - menu.append(new gui.MenuItem({ label: 'play' })); - menu.append(new gui.MenuItem({ label: 'stop' })); + menu.append(new gui.MenuItem({label: "play"})); + menu.append(new gui.MenuItem({label: "stop"})); tray.menu = menu; // Show window and remove tray when clicked - tray.on('click', function() { + tray.on("click", function() { win.show(); this.remove(); tray = null; Modified: wit/js/main.js =================================================================== --- wit/js/main.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/main.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,6 +1,6 @@ -/** @jsx React.DOM */ +"use strict"; -// Popup Idle +// Popup Idle // Options with idle time + nb tags + Configuration week day // Route // Dropdown rapport week/day/month @@ -11,16 +11,16 @@ global.navigator = window.navigator; global.localStorage = window.localStorage; -var timer = require('./js/services/TimerService.js'); +var timer = require("./js/services/TimerService.js"); global.timer = timer; -var user = require('./js/services/UserActivityService.js'); +var user = require("./js/services/UserActivityService.js"); global.user = user; -var config = require('./js/services/ConfigurationService.js'); +var config = require("./js/services/ConfigurationService.js"); -var React = require('react'); -var Router = require('react-router'); +var React = require("react"); +var Router = require("react-router"); var DefaultRoute = Router.DefaultRoute; var Link = Router.Link; @@ -28,26 +28,25 @@ var RouteHandler = Router.RouteHandler; var App = React.createClass({ - - openRapport: function(e) { + + openRapport: function() { this.refs.rapportDropdown.getDOMNode().classList.toggle("open"); this.refs.editionDropdown.getDOMNode().classList.remove("open"); }, - - openEdition: function(e) { + + openEdition: function() { this.refs.editionDropdown.getDOMNode().classList.toggle("open"); this.refs.rapportDropdown.getDOMNode().classList.remove("open"); }, - - closeAll: function(e) { + + closeAll: function() { this.refs.editionDropdown.getDOMNode().classList.remove("open"); this.refs.rapportDropdown.getDOMNode().classList.remove("open"); }, - + render: function() { - return ( - <div className="container-fluid"> - + return <div className="container-fluid"> + <div className="navbar navbar-default"> <div className="navbar-header pull-left"> <a className="navbar-brand" href="#">WIT</a> @@ -56,7 +55,7 @@ <div className="nav navbar-header pull-right"> <ul className="nav pull-right"> <li className="pull-left"><Link onClick={this.closeAll} to="app">Timer</Link></li> - + <li ref="rapportDropdown" className="dropdown pull-left"> <a className="dropdown-toggle" onClick={this.openRapport}> Rapport <span className="caret"></span> @@ -68,7 +67,7 @@ <li><a href="#">By Year</a></li> </ul> </li> - + <li ref="editionDropdown" className="dropdown pull-left"> <a className="dropdown-toggle" onClick={this.openEdition}> Edition <span className="caret"></span> @@ -79,64 +78,61 @@ <li><a href="#">Activities</a></li> </ul> </li> - + <li className="pull-left"><Link onClick={this.closeAll} to="options">Options</Link></li> </ul> </div> </div> <RouteHandler/> - </div> - ); + </div>; } }); -var routes = ( - <Route name="app" path="/" handler={App}> - <Route name="rapport" handler={Rapport}/> - <Route name="activity" handler={UserActivity}/> - <Route name="options" handler={Options}/> - <Route name="editionLogs" handler={EditionLogs}/> - <DefaultRoute handler={Timer}/> - </Route> -); +var routes = <Route name="app" path="/" handler={App}> + <Route name="rapport" handler={Rapport}/> + <Route name="activity" handler={UserActivity}/> + <Route name="options" handler={Options}/> + <Route name="editionLogs" handler={EditionLogs}/> + <DefaultRoute handler={Timer}/> + </Route>; -Router.run(routes, function (Handler) { - React.render(<Handler/>, document.body); +Router.run(routes, function(Handler) { + React.render(<Handler/>, document.body); }); var popups = []; -var openWindow = function (file) { +var openWindow = function(file) { var gui = global.window.nwDispatcher.requireNwGui(); - + var current = gui.Window.get(); current.hide(); - + user.suspendActivityDetection(); - + var window = gui.Window.open(file, { - "position": "center", - "focus": true, - "toolbar": false, - "frame": true, - "width": 480, - "height": 300, + position: "center", + focus: true, + toolbar: false, + frame: true, + width: 480, + height: 300 }); - + popups.push(window); - - window.on('close', function() { + + window.on("close", function() { this.hide(); // Pretend to be closed already // this.close(true); - + popups.splice(popups.indexOf(window), 1); - + if (!popups.length) { current.show(); } - }); + }); }; // Subscriptions to services -timer.subscribeIdle(openWindow.bind(null, "idle.html")) +timer.subscribeIdle(openWindow.bind(null, "idle.html")); user.subscribeActivityChange(openWindow.bind(null, "activityChange.html")); Modified: wit/js/pages/EditionLogs.js =================================================================== --- wit/js/pages/EditionLogs.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/pages/EditionLogs.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,16 +1,16 @@ -/** @jsx React.DOM */ +"use strict"; var EditionLogs = React.createClass({ - - getInitialState : function() { - var moment = require("moment"); - return { + + getInitialState: function() { + var moment = require("moment"); + return { startDate: moment().subtract(1, "h"), endDate: moment(), result: null }; }, - + handleSearchResult: function(result, startDate, endDate) { this.setState({ startDate: startDate, @@ -18,25 +18,24 @@ result: result }); }, - + onAdd: function() { - var moment = require('moment'); + var moment = require("moment"); var db = require("./js/services/database.js"); - + var tags = this.refs.tags.getDOMNode().value.split(","); var startDate = moment(this.refs.beginDate.getDOMNode().value); var endDate = moment(this.refs.endDate.getDOMNode().value); return db.insertLog(tags, startDate, endDate); }, - + render: function() { - return ( - <div> + return <div> <h1>Search log</h1> <FilterBar onSearchResult={this.handleSearchResult}/> <LogsTable data={this.state.result}/> - + <div> <h1>Add log</h1> <input ref="beginDate" type="datetime-local" className="form-control" required></input> @@ -44,7 +43,6 @@ <input ref="tags" type="text" className="form-control" required placeholder="Enter tags with comma"></input> <button onClick={this.onAdd} className="btn btn-primary btn-block">Add</button> </div> - </div> - ); + </div>; } }); Modified: wit/js/pages/Options.js =================================================================== --- wit/js/pages/Options.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/pages/Options.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,46 +1,45 @@ -/** @jsx React.DOM */ +"use strict"; var Options = React.createClass({ - + setIdleTime: function(e) { config.setIdleTime(e.target.value); }, - + setActivityTime: function(e) { config.setActivityTime(e.target.value); }, - + setWeekDay: function(e) { config.setWeekDay(e.target.value); }, - + render: function() { var idleTime = config.getIdleTime(); var activityTime = config.getActivityTime(); var weekDay = config.getWeekDay(); - - return ( - <div className="form-horizontal"> - + + return <div className="form-horizontal"> + <div className="form-group"> <label for="idleTime" className="col-sm-2 control-label">Idle time (minutes)</label> <div className="col-sm-10"> <input type="number" className="form-control" defaultValue={idleTime} min="0" step="1" onChange={this.setIdleTime}/> </div> </div> - + <div className="form-group"> <label for="idleTime" className="col-sm-2 control-label">Activity time (minutes)</label> <div className="col-sm-10"> <input type="number" className="form-control" id="activityTime" defaultValue={activityTime} min="0" step="1" onChange={this.setActivityTime}/> </div> </div> - + <div className="form-group"> <label for="idleTime" className="col-sm-2 control-label">Week day</label> <div className="col-sm-10"> <select name="select" className="form-control" id="weekDay" defaultValue={weekDay} onChange={this.setWeekDay}> - <option value="0">monday</option> + <option value="0">monday</option> <option value="1">tuesday</option> <option value="2">wednesday</option> <option value="3">thursday</option> @@ -50,7 +49,6 @@ </select> </div> </div> - </div> - ); + </div>; } }); Modified: wit/js/pages/Rapport.js =================================================================== --- wit/js/pages/Rapport.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/pages/Rapport.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,16 +1,16 @@ -/** @jsx React.DOM */ +"use strict"; var Rapport = React.createClass({ - - getInitialState : function() { - var moment = require("moment"); - return { + + getInitialState: function() { + var moment = require("moment"); + return { startDate: moment().subtract(1, "h"), endDate: moment(), result: [] }; }, - + handleSearchResult: function(result, startDate, endDate) { this.setState({ startDate: startDate, @@ -18,14 +18,12 @@ result: result }); }, - + render: function() { - return ( - <div> + return <div> <h1>Search by date</h1> <FilterBar onSearchResult={this.handleSearchResult}/> <FilterLogs data={this.state}/> - </div> - ); + </div>; } }); Modified: wit/js/pages/Timer.js =================================================================== --- wit/js/pages/Timer.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/pages/Timer.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,13 +1,11 @@ -/** @jsx React.DOM */ +"use strict"; var Timer = React.createClass({ render: function() { - return ( - <div> + return <div> <Time /> <Tags /> <ActionsBar /> - </div> - ); + </div>; } }); Modified: wit/js/pages/UserActivity.js =================================================================== --- wit/js/pages/UserActivity.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/pages/UserActivity.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,18 +1,18 @@ -/** @jsx React.DOM */ +"use strict"; -var moment = require("moment"); var UserActivity = React.createClass({ - + render: function() { + var moment = require("moment"); + var data = { - startDate : moment().subtract(1, "m").valueOf(), - endDate : moment().valueOf() - } - return ( - <div className="userActivity"> + startDate: moment().subtract(1, "m").valueOf(), + endDate: moment().valueOf() + }; + + return <div className="userActivity"> <h1> What the hell did i do today ? </h1> <Timeline data={data}/> - </div> - ); + </div>; } -}); \ No newline at end of file +}); Modified: wit/js/services/ConfigurationService.js =================================================================== --- wit/js/services/ConfigurationService.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/services/ConfigurationService.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,3 +1,5 @@ +"use strict"; + // Base on localStorage var storage = localStorage; @@ -12,7 +14,7 @@ }; exports.getIdleTime = function() { - return parseInt(storage.idleTime || DEFAULT_IDLE_TIME); + return parseInt(storage.idleTime || DEFAULT_IDLE_TIME, 10); }; // time as minutes @@ -21,7 +23,7 @@ }; exports.getActivityTime = function() { - return parseInt(storage.activityTime || DEFAULT_ACTIVITY_TIME); + return parseInt(storage.activityTime || DEFAULT_ACTIVITY_TIME, 10); }; // 0 -> Monday @@ -30,5 +32,5 @@ }; exports.getWeekDay = function() { - return parseInt(storage.weekDay || DEFAULT_WEEK_DAY); + return parseInt(storage.weekDay || DEFAULT_WEEK_DAY, 10); }; Modified: wit/js/services/TimerService.js =================================================================== --- wit/js/services/TimerService.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/services/TimerService.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,9 +1,11 @@ -var moment = require('moment'); +"use strict"; + +var moment = require("moment"); var db = require("./database.js"); var config = require("./ConfigurationService.js"); -var x11 = require('x11'); +var x11 = require("x11"); -var events = require('events'); +var events = require("events"); var eventEmitter = new events.EventEmitter(); var tags = ["wit", "js", "dev"]; @@ -20,30 +22,30 @@ } var X = display.client; - X.require('screen-saver', function(err, SS) { - + X.require("screen-saver", function(err, SS) { + var queryIdle = function() { SS.QueryInfo(display.screen[0].root, function(err, info) { // console.log('Idle time ' + info.idle + "ms"); if (time) { var configIdleTime = config.getIdleTime(); - var durationIdleTime = moment.duration(configIdleTime, 'm'); + var durationIdleTime = moment.duration(configIdleTime, "m"); if (info.idle >= durationIdleTime.asMilliseconds() && !idleTime) { idleTime = new Date(); - eventEmitter.emit('onIdle'); + eventEmitter.emit("onIdle"); } } - + setTimeout(queryIdle, 1000); }); }; - + queryIdle(); }); - - X.on('error', console.error); + + X.on("error", console.error); }); var insertLog = function(tags, start, end) { @@ -52,7 +54,7 @@ }; exports.start = function() { - + // Come from to keep idle if (time) { var diff = moment(idleTime).diff(moment(time)); @@ -60,23 +62,23 @@ } else { time = new Date(); } - + idleTime = null; historyIndex = -1; - + timeChange(); - + user.resumeActivityDetection(); }; exports.stop = function(force) { - + if (idleTime && force) { time = null; idleTime = null; timeChange(); } - + if (time && !idleTime) { insertLog(tags, time, new Date()); time = null; @@ -98,7 +100,7 @@ exports.addTag = function(tag) { tags.push(tag); - eventEmitter.emit('onTagsChanged'); + eventEmitter.emit("onTagsChanged"); }; exports.removeTag = function(index) { @@ -110,7 +112,7 @@ var timeChange = function() { clearTimeout(timeChangeTimer); - + eventEmitter.emit('onTimeChanged'); if (time) { timeChangeTimer = setTimeout(timeChange.bind(), 1000); @@ -150,9 +152,9 @@ insertLog(tags, time, idleTime); time = null; idleTime = null; - + timeChange(); - + exports.start(); }; @@ -172,16 +174,16 @@ insertLog(tags, time, newStartTime); time = newStartTime; idleTime = new Date(); - + clearTimeout(timeChangeTimer); eventEmitter.emit('onTimeChanged'); }; var setTagsFromHistory = function() { - + db.getHistory(historyIndex) .then(function(logs) { - + if (logs && logs.length) { var log = logs[0]; tags = log.tags.slice(0); @@ -194,7 +196,7 @@ exports.prevHistory = function() { historyIndex++; - + setTagsFromHistory(); }; @@ -202,9 +204,9 @@ if (historyIndex == -1) { return; } - + historyIndex--; - + setTagsFromHistory(); }; @@ -218,7 +220,7 @@ var now = moment(); diff += now.diff(time); } - + var value = moment(diff).utcOffset(0); return value.format("HH:mm:ss"); }; Modified: wit/js/services/UserActivityService.js =================================================================== --- wit/js/services/UserActivityService.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/services/UserActivityService.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -21,9 +21,9 @@ exports.getSessions = function (startDate, endDate, withEmptySession) { var rst; if (!startDate || !endDate) { - + console.error("[UserActivityService] getSessions : parameter missing !"); - + } else { var d1 = moment(startDate), d2 = moment(endDate); @@ -36,9 +36,9 @@ }) .then(function (sessions) { var result = JSON.parse(JSON.stringify(sessions)); - + // Convert results - + var lastSessionEnd = d1, s; for (var i = 0; i < result.length; i++) { @@ -57,15 +57,15 @@ } lastSessionEnd = s.endDate; } - + if (withEmptySession && lastSessionEnd.isBefore(d2)) { result.push(createFakeSession(lastSessionEnd, d2)); } - + return result; }); } - + return rst; }; @@ -89,27 +89,27 @@ disableActivityDetection = false; }; -/* +/* * Listen to active window change and window title change - * Some part of the code has derived from : + * Some part of the code has derived from : * http://stackoverflow.com/questions/19840459/linux-get-notification-on-focuse... - * + * */ x11.createClient(function(err, display) { var X = display.client; - X.ChangeWindowAttributes(display.screen[0].root, { - eventMask: x11.eventMask.PropertyChange + X.ChangeWindowAttributes(display.screen[0].root, { + eventMask: x11.eventMask.PropertyChange }); // Init windows session with the currently active window // addWindowSession(X, display.screen[0].root); - + // Listen to client display events to identify when the currently active window has change X.on('event', onActiveWindowChange.bind(null, X)); }); -/** +/** * Subscriber to timer change : * If timer change occured while activity change detection is on going, * stop activity change detection process (means the user has handled it) @@ -125,18 +125,18 @@ var onActiveWindowChange = function (X, ev) { if(ev.name == 'PropertyNotify') { - + X.GetAtomName(ev.atom, function(err, name) { // if the property change refers to the currently active window, retrieve new active window name - - if (name == '_NET_ACTIVE_WINDOW') { + if (name == '_NET_ACTIVE_WINDOW') { + registerWindowEvents(X, ev); addWindowSession(X, ev); } else if (name == '_NET_WM_NAME') { - + updateWindowSession(X, ev); } }); @@ -146,8 +146,8 @@ var registerWindowEvents = function (X, ev) { getActiveWindowId(X, ev) .then(function (wid) { - X.ChangeWindowAttributes(wid, { - eventMask:x11.eventMask.PropertyChange + X.ChangeWindowAttributes(wid, { + eventMask:x11.eventMask.PropertyChange }); }); }; @@ -157,7 +157,7 @@ */ var addWindowSession = function (X, ev) { var crt = crtSession; - + return getActiveWindowId(X, ev) .then(getWindowName) .then(createNewSession) @@ -166,28 +166,28 @@ /** * Current active window is still the same - * but it's title has changed. + * but it's title has changed. * Trace it by creating a new session with the same shape attributes than the previous one */ var updateWindowSession = function (X, ev) { return getWindowName(ev.wid) .then(function (windowName) { - - // Let's create a new seesion but with same color attributes than the last one, + + // Let's create a new seesion but with same color attributes than the last one, // since the active window has not really changed, only some of its attibutes - + if (currentSession.name != windowName) { createNewSession(windowName, last.color); } - + }); }; var getActiveWindowId = function (X, ev) { return new Promise(function (resolve, reject) { - + if (!ev.wid) return reject(); - + X.GetProperty(0, ev.wid, ev.atom, X.atoms.WINDOW, 0, 4, function(err, prop) { if (err || !prop.data.length) { console.log("Couldn't retrieve active window property"); @@ -195,10 +195,10 @@ } else { var wid = prop.data.readUInt32LE(0); - + if (wid) { resolve(wid); - + } else { console.log("Couldn't retrieve active window property"); reject(); @@ -210,9 +210,9 @@ var getWindowName = function (windowId) { return new Promise(function (resolve, reject) { - + if (!windowId) return reject(); - + xprop({prop:'_NET_WM_NAME', id:windowId}, function(err, properties) { if (err) { @@ -228,21 +228,21 @@ var createNewSession = function (windowName, color, startDate) { var now = moment(); - + // Stop current session - + if (crtSession) { crtSession.endDate = now.valueOf(); db.insertSession(crtSession); } - + // Check if a session corresponding to the given name already exists, // so that we can retrieve some properties - + var prev = db.getSessionByName(windowName); - + // Create new session - + crtSession = { name: windowName, color: color || prev && prev.color || "#" + (Math.floor(Math.random() * (999 - 100 + 1)) + 100), @@ -252,7 +252,7 @@ var createFakeSession = function (startDate, endDate) { var d1 = moment(startDate), d2 = moment(endDate); - + return { name: "", color: "transparent", @@ -263,16 +263,16 @@ var setupActivityDetection = function (session) { if (disableActivityDetection || !session || !timer.getTime()) { - + clearTimeout(activityChangeTimer); // stop activity detection - + } else { - + now = moment(); if (now.diff(session.startDate, "m") >= config.getActivityTime()) { // The user has stayed more than "config.getActivityTime()" minutes on a window - // and now has just switched to another window. + // and now has just switched to another window. // If it stays at list as long as he did on the previous one, let's notify it to him activityChangeTimer = setTimeout( @@ -290,4 +290,4 @@ clearTimeout(activityChangeTimer); } } -}; \ No newline at end of file +}; Modified: wit/js/services/database.js =================================================================== --- wit/js/services/database.js 2015-05-21 16:07:11 UTC (rev 1425) +++ wit/js/services/database.js 2015-05-22 09:56:32 UTC (rev 1426) @@ -1,24 +1,41 @@ -var moment = require('moment'); -var pjson = require('../../package.json'); +"use strict"; + +var moment = require("moment"); +var pjson = require("../../package.json"); var dbFileNamePrefix = pjson.dbFileNamePrefix; var path = (process.env.HOME || process.env.USERPROFILE) + "/.wit/"; -var Datastore = require('nedb'); +var Datastore = require("nedb"); var db = { - logs: new Datastore({filename : path + dbFileNamePrefix + "logs.json", autoload: true}), - sessions: new Datastore({filename : path + dbFileNamePrefix + "sessions.json", autoload: true}) + logs: new Datastore({filename: path + dbFileNamePrefix + "logs.json", autoload: true}), + sessions: new Datastore({filename: path + dbFileNamePrefix + "sessions.json", autoload: true}) }; +/************ + * Utilities + ************/ +var _normalize = function(period, tstmpStart, tstmpEnd) { + if (period.startDate < tstmpStart) { + period.startDate = tstmpStart; + } + + if (period.endDate > tstmpEnd) { + period.endDate = tstmpEnd; + } + + return period; +}; + /******************** - * Logs db management + * Logs db management *********************/ exports.insertLog = function(tags, startDate, endDate) { var m1 = startDate && moment(startDate), m2 = endDate && moment(endDate); - - return new Promise(function(resolve, reject) { + + return new Promise(function(resolve, reject) { db.logs.insert({ tags: tags.sort(), // keep the key in same order to be able to create a tree startDate: m1.valueOf(), @@ -32,31 +49,31 @@ }); }); }; - + /** * Search for logs in the database - */ + */ exports.searchLogs = function(tags, startDate, endDate, truncate) { var query = {}; var t1 = startDate && moment(startDate).valueOf(), t2 = endDate && moment(endDate).valueOf(); - if (tags) { query.tags = { $in: tags }; } - if (t1) { query.endDate = { $gte : t1 }; } - if (t2) { query.startDate = { $lte: t2 }; } - + if (tags) { query.tags = {$in: tags}; } + if (t1) { query.endDate = {$gte: t1}; } + if (t2) { query.startDate = {$lte: t2}; } + return new Promise(function(resolve, reject) { - db.logs.find(query).sort({ startDate: -1 }).exec(function(err, docs) { + db.logs.find(query).sort({startDate: -1}).exec(function(err, docs) { if (!err) { - + // - tuncate periods to fit search dates params if required - + if (truncate) { - docs.forEach(function (d) { + docs.forEach(function(d) { _normalize(d, t1, t2); }); } - + resolve(docs); } else { reject(err); @@ -66,9 +83,9 @@ }; exports.getHistory = function(index) { - + return new Promise(function(resolve, reject) { - db.logs.find({}).sort({ startDate: -1 }).skip(index).limit(1).exec(function (err, docs) { + db.logs.find({}).sort({startDate: -1}).skip(index).limit(1).exec(function(err, docs) { if (!err) { resolve(docs); } else { @@ -79,9 +96,9 @@ }; exports.getLastTags = function() { - + return new Promise(function(resolve, reject) { - db.logs.find({}).sort({startDate: -1 }).limit(100).exec(function (err, docs) { + db.logs.find({}).sort({startDate: -1}).limit(100).exec(function(err, docs) { if (!err) { var map = {}; docs.forEach(function(log) { @@ -89,7 +106,7 @@ map[tag] = true; }); }); - + resolve(Object.keys(map)); } else { reject(err); @@ -101,7 +118,7 @@ exports.deleteLog = function(id) { return new Promise(function(resolve, reject) { - db.logs.remove({_id: id}, {}, function (err, numRemoved) { + db.logs.remove({_id: id}, {}, function(err) { if (!err) { resolve(); } else { @@ -111,13 +128,13 @@ }); }; -/******************************** - * Window sessions db management +/******************************** + * Window sessions db management ********************************/ -exports.insertSession = function (session) { - return new Promise(function(resolve, reject) { - db.sessions.insert(session, +exports.insertSession = function(session) { + return new Promise(function(resolve, reject) { + db.sessions.insert(session, function(err, newDocs) { if (!err) { resolve(newDocs); @@ -128,7 +145,7 @@ }); }; -exports.getSessionByName = function (name) { +exports.getSessionByName = function(name) { return new Promise(function(resolve, reject) { db.sessions.findOne({ name: name @@ -142,14 +159,14 @@ }); }; -exports.getSessions = function (startDate, endDate) { +exports.getSessions = function(startDate, endDate) { var query = {}; - - if (endDate) { query.startDate = { $lte: endDate.getTime() }; } - if (startDate) { query.endDate = { $gte : startDate.getTime() }; } + if (endDate) { query.startDate = {$lte: endDate.getTime()}; } + if (startDate) { query.endDate = {$gte: startDate.getTime()}; } + return new Promise(function(resolve, reject) { - db.sessions.find(query).sort({ startDate: 1 }).exec(function(err, docs) { + db.sessions.find(query).sort({startDate: 1}).exec(function(err, docs) { if (!err) { resolve(docs); } else { @@ -158,19 +175,3 @@ }); }); }; - - -/************ - * Utilities - ************/ -var _normalize = function (period, tstmpStart, tstmpEnd) { - if (period.startDate < tstmpStart) { - period.startDate = tstmpStart; - } - - if (period.endDate > tstmpEnd) { - period.endDate = tstmpEnd; - } - - return period; -};