WPM tracking

This commit is contained in:
Shadowfacts 2016-10-02 18:01:26 -04:00
parent 3d780753c4
commit 59999d084f
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
3 changed files with 83 additions and 3 deletions

View File

@ -33,10 +33,23 @@
height: 20px;
}
#toolbar > #info {
float: right;
margin-right: 14px;
}
#toolbar > #info > #paused {
font-weight: bold;
}
#content {
margin-top: 33px;
}
#content.paused > .CodeMirror {
opacity: 0.5;
}
/* Index */
.prev-list {
padding: 0px;

View File

@ -4,6 +4,9 @@ var incompleteMark;
var focused = false;
let invalids = [];
var fileLines;
// WPM tracking
var lastStartTime;
var elapsedTime;
let hash = window.location.hash.substring(1);
let hashBits = hash.split("/");
@ -114,7 +117,7 @@ function setup(data, mime) {
className: "incomplete"
});
focused = true;
resume();
editor.on("focus", handleFocus);
editor.on("blur", handleBlur);
@ -130,11 +133,11 @@ function setup(data, mime) {
}
function handleFocus() {
focused = true;
resume();
}
function handleBlur() {
focused = false;
pause();
}
function handleMouseDown(instance, event) {
@ -168,6 +171,14 @@ function handleKeyDown(event) {
} else if (event.keyCode == 9) { // tab
event.preventDefault();
handleTab(event);
} else if (event.keyCode == 27) { // escape
event.preventDefault();
pause();
}
} else {
if (event.keyCode == 27) {
event.preventDefault();
resume();
}
}
}
@ -221,6 +232,7 @@ function handleEnter(event) {
}
}
updateIncompleteMark();
updateWPM();
save();
} else {
goToNextChunk();
@ -437,6 +449,7 @@ function load() {
let chunk = val[filePath].chunks[val[filePath].chunk];
loadInvalids(chunk);
loadCursor(chunk);
loadElapsedTime(chunk);
} else {
save();
}
@ -458,6 +471,7 @@ function save() {
let chunk = file.chunks[file.chunk];
saveInvalids(chunk);
saveCursor(chunk);
saveElapsedTime(chunk);
localforage.setItem(repo, val)
.catch((e) => {
@ -515,6 +529,14 @@ function saveCursor(obj) {
obj.cursor = editor.getCursor();
}
function loadElapsedTime(obj) {
elapsedTime = obj.elapsedTime;
}
function saveElapsedTime(obj) {
obj.elapsedTime = elapsedTime;
}
function setTheme(theme) {
if (theme != "default") {
$("head").append(`<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.19.0/theme/${theme}.min.css">`);
@ -532,6 +554,47 @@ function setCursor(pos) {
}
}
function updateWPM() {
if (focused) {
// update elapsed time
if (!elapsedTime || isNaN(elapsedTime)) {
elapsedTime = Date.now() - lastStartTime;
} else {
elapsedTime += Date.now() - lastStartTime;
}
lastStartTime = Date.now();
}
// calculate words typed
let typed = editor.doc.getRange({ line: 0, ch: 0 }, editor.getCursor());
let words = typed.split(/[\s,\.]+/).length;
let seconds = elapsedTime / 1000;
if (seconds >= 60) {
// update real WPM
let minutes = seconds / 60;
$("#wpm").text(Math.round(words / minutes));
} else {
// extrapolate forwards
let scaledWords = words / (seconds / 60);
$("#wpm").text(Math.round(scaledWords));
}
}
function pause() {
focused = false;
elapsedTime += Date.now() - lastStartTime;
$("#paused").text("Paused");
$("#content").addClass("paused");
}
function resume() {
focused = true;
lastStartTime = Date.now();
$("#paused").text("");
$("#content").removeClass("paused");
}
String.prototype.hasOnlyWhiteSpaceBeforeIndex = function(index) {
return this.substring(index) == this.trim();
};

View File

@ -70,6 +70,10 @@
<option value="yeti">Yeti</option>
<option value="zenburn">Zenburn</option>
</select>
<div id="info">
WPM: <span id="wpm">Unknown</span>
<span id="paused"></span>
</div>
</div>
<div id="content">