diff --git a/gulpfile.js b/gulpfile.js index 5a9dc99fc..b467ecb79 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -98,6 +98,7 @@ const refactoredSrc = [ "./src/js/sound.js", "./src/js/custom-text.js", "./src/js/shift-tracker.js", + "./src/js/test-stats.js", ]; //legacy files diff --git a/src/js/commandline.js b/src/js/commandline.js index 54c884a6a..14d2ed8e2 100644 --- a/src/js/commandline.js +++ b/src/js/commandline.js @@ -682,7 +682,7 @@ let commands = { initPractiseMissedWords(); }, available: () => { - return resultVisible && Object.keys(missedWords).length > 0; + return resultVisible && Object.keys(TestStats.missedWords).length > 0; }, }, { diff --git a/src/js/global-dependencies.js b/src/js/global-dependencies.js index abe417c25..9e2f1f553 100644 --- a/src/js/global-dependencies.js +++ b/src/js/global-dependencies.js @@ -31,3 +31,4 @@ import * as Leaderboards from "./leaderboards"; import * as Sound from "./sound"; import * as CustomText from "./custom-text"; import * as ShiftTracker from "./shift-tracker"; +import * as TestStats from "./test-stats"; diff --git a/src/js/script.js b/src/js/script.js index 2a5546bce..212fe51a4 100644 --- a/src/js/script.js +++ b/src/js/script.js @@ -1,10 +1,10 @@ //test logic let wordsList = []; let currentWordIndex = 0; -let inputHistory = []; -let correctedHistory = []; -let currentCorrected = ""; let currentInput = ""; +let inputHistory = []; +let currentCorrected = ""; +let correctedHistory = []; let sameWordset = false; let textHasTab = false; let randomQuote = null; @@ -35,41 +35,6 @@ let memoryFunboxInterval = null; //pace caret let paceCaret = null; -//test stats -let testInvalid = false; -let testStart, testEnd; -let wpmHistory = []; -let rawHistory = []; -let restartCount = 0; -let incompleteTestSeconds = 0; -let keypressPerSecond = []; -let currentKeypress = { - count: 0, - mod: 0, - words: [], -}; -let errorsPerSecond = []; -let currentError = { - count: 0, - words: [], -}; -let lastSecondNotRound = false; -let missedWords = []; -let accuracyStats = { - correct: 0, - incorrect: 0, -}; -let keypressStats = { - spacing: { - current: -1, - array: [], - }, - duration: { - current: -1, - array: [], - }, -}; - //ui let pageTransition = false; let focusState = false; @@ -331,13 +296,13 @@ async function initWords() { wordsList = []; currentWordIndex = 0; currentWordElementIndex = 0; - accuracyStats = { - correct: 0, - incorrect: 0, - }; + // accuracy = { + // correct: 0, + // incorrect: 0, + // }; inputHistory = []; - correctedHistory = []; - currentCorrected = ""; + // correctedHistory = []; + // currentCorrected = ""; currentInput = ""; let language = await Misc.getLanguage(config.language); @@ -1658,7 +1623,7 @@ function countChars() { correctWordChars: correctWordChars, allCorrectChars: correctChars, incorrectChars: - config.mode == "zen" ? accuracyStats.incorrect : incorrectChars, + config.mode == "zen" ? TestStats.accuracy.incorrect : incorrectChars, extraChars: extraChars, missedChars: missedChars, correctSpaces: correctspaces, @@ -1666,7 +1631,7 @@ function countChars() { } function calculateStats() { - let testSeconds = (testEnd - testStart) / 1000; + let testSeconds = TestStats.calculateTestSeconds(); let chars = countChars(); let wpm = Misc.roundTo2( ((chars.correctWordChars + chars.correctSpaces) * (60 / testSeconds)) / 5 @@ -1679,11 +1644,7 @@ function calculateStats() { (60 / testSeconds)) / 5 ); - let acc = Misc.roundTo2( - (accuracyStats.correct / - (accuracyStats.correct + accuracyStats.incorrect)) * - 100 - ); + let acc = Misc.roundTo2(TestStats.calculateAccuracy()); return { wpm: isNaN(wpm) ? 0 : wpm, wpmRaw: isNaN(wpmraw) ? 0 : wpmraw, @@ -1723,14 +1684,12 @@ function showCrown() { function failTest() { inputHistory.push(currentInput); correctedHistory.push(currentCorrected); - lastSecondNotRound = true; + TestStats.setLastSecondNotRound(); showResult(true); - let testNow = performance.now(); - let testSeconds = Misc.roundTo2((testNow - testStart) / 1000); - let afkseconds = keypressPerSecond.filter((x) => x.count == 0 && x.mod == 0) - .length; - incompleteTestSeconds += testSeconds - afkseconds; - restartCount++; + let testSeconds = TestStats.calculateTestSeconds(performance.now()); + let afkseconds = TestStats.calculateAfkSeconds(); + TestStats.incrementIncompleteSeconds(testSeconds - afkseconds); + TestStats.incrementRestartCount(); } let resultCalculating = false; @@ -1743,7 +1702,7 @@ function showResult(difficultyFailed = false) { resultCalculating = true; resultVisible = true; - testEnd = performance.now(); + TestStats.setEnd(performance.now()); testActive = false; setFocus(false); hideCaret(); @@ -1751,7 +1710,6 @@ function showResult(difficultyFailed = false) { hideLiveAcc(); hideTimer(); hideKeymap(); - testInvalid = false; let stats = calculateStats(); if (stats === undefined) { stats = { @@ -1773,8 +1731,7 @@ function showResult(difficultyFailed = false) { } clearTimeout(timer); let testtime = stats.time; - let afkseconds = keypressPerSecond.filter((x) => x.count == 0 && x.mod == 0) - .length; + let afkseconds = TestStats.calculateAfkSeconds(); let afkSecondsPercent = Misc.roundTo2((afkseconds / testtime) * 100); wpmOverTimeChart.options.annotation.annotations = []; @@ -1907,26 +1864,21 @@ function showResult(difficultyFailed = false) { mode2 = "zen"; } - if (lastSecondNotRound) { + if (TestStats.lastSecondNotRound) { let wpmAndRaw = liveWpmAndRaw(); - wpmHistory.push(wpmAndRaw.wpm); - rawHistory.push(wpmAndRaw.raw); - keypressPerSecond.push(currentKeypress); - currentKeypress = { - mod: 0, - count: 0, - words: [], - }; - errorsPerSecond.push(currentError); - currentError = { - count: 0, - words: [], - }; + TestStats.pushToWpmHistory(wpmAndRaw.wpm); + TestStats.pushToRawHistory(wpmAndRaw.raw); + TestStats.pushKeypressesToHistory(); + // errorsPerSecond.push(currentError); + // currentError = { + // count: 0, + // words: [], + // }; } let labels = []; - for (let i = 1; i <= wpmHistory.length; i++) { - if (lastSecondNotRound && i === wpmHistory.length) { + for (let i = 1; i <= TestStats.wpmHistory.length; i++) { + if (TestStats.lastSecondNotRound && i === TestStats.wpmHistory.length) { labels.push(Misc.roundTo2(testtime).toString()); } else { labels.push(i.toString()); @@ -1952,7 +1904,7 @@ function showResult(difficultyFailed = false) { wpmOverTimeChart.data.labels = labels; - let rawWpmPerSecondRaw = keypressPerSecond.map((f) => + let rawWpmPerSecondRaw = TestStats.keypressPerSecond.map((f) => Math.round((f.count / 5) * 60) ); @@ -1964,8 +1916,8 @@ function showResult(difficultyFailed = false) { let consistency = Misc.roundTo2(Misc.kogasa(stddev / avg)); let keyConsistency = Misc.roundTo2( Misc.kogasa( - Misc.stdDev(keypressStats.spacing.array) / - Misc.mean(keypressStats.spacing.array) + Misc.stdDev(TestStats.keypressTimings.spacing.array) / + Misc.mean(TestStats.keypressTimings.spacing.array) ) ); @@ -1993,20 +1945,20 @@ function showResult(difficultyFailed = false) { wpmOverTimeChart.data.datasets[0].borderColor = themeColors.main; wpmOverTimeChart.data.datasets[0].pointBackgroundColor = themeColors.main; - wpmOverTimeChart.data.datasets[0].data = wpmHistory; + wpmOverTimeChart.data.datasets[0].data = TestStats.wpmHistory; wpmOverTimeChart.data.datasets[1].borderColor = themeColors.sub; wpmOverTimeChart.data.datasets[1].pointBackgroundColor = themeColors.sub; wpmOverTimeChart.data.datasets[1].data = rawWpmPerSecond; let maxChartVal = Math.max( - ...[Math.max(...rawWpmPerSecond), Math.max(...wpmHistory)] + ...[Math.max(...rawWpmPerSecond), Math.max(...TestStats.wpmHistory)] ); if (!config.startGraphsAtZero) { wpmOverTimeChart.options.scales.yAxes[0].ticks.min = Math.min( - ...wpmHistory + ...TestStats.wpmHistory ); wpmOverTimeChart.options.scales.yAxes[1].ticks.min = Math.min( - ...wpmHistory + ...TestStats.wpmHistory ); } else { wpmOverTimeChart.options.scales.yAxes[0].ticks.min = 0; @@ -2023,13 +1975,15 @@ function showResult(difficultyFailed = false) { // } let errorsArray = []; - for (let i = 0; i < errorsPerSecond.length; i++) { - errorsArray.push(errorsPerSecond[i].count); + for (let i = 0; i < TestStats.keypressPerSecond.length; i++) { + errorsArray.push(TestStats.keypressPerSecond[i].errors); } wpmOverTimeChart.data.datasets[2].data = errorsArray; - let kps = keypressPerSecond.slice(Math.max(keypressPerSecond.length - 5, 0)); + let kps = TestStats.keypressPerSecond.slice( + Math.max(TestStats.keypressPerSecond.length - 5, 0) + ); kps = kps.map((a) => a.count); @@ -2080,15 +2034,14 @@ function showResult(difficultyFailed = false) { } catch (e) {} let chartData = { - wpm: wpmHistory, + wpm: TestStats.wpmHistory, raw: rawWpmPerSecond, err: errorsArray, }; if (testtime > 122) { chartData = "toolong"; - keypressStats.spacing.array = "toolong"; - keypressStats.duration.array = "toolong"; + TestStats.setKeypressTimingsTooLong(); } let lang = config.language; @@ -2128,16 +2081,16 @@ function showResult(difficultyFailed = false) { numbers: config.numbers, timestamp: Date.now(), language: lang, - restartCount: restartCount, - incompleteTestSeconds: incompleteTestSeconds, + restartCount: TestStats.restartCount, + incompleteTestSeconds: TestStats.incompleteSeconds, difficulty: config.difficulty, testDuration: testtime, afkDuration: afkseconds, blindMode: config.blindMode, theme: config.theme, tags: activeTagsIds, - keySpacing: keypressStats.spacing.array, - keyDuration: keypressStats.duration.array, + keySpacing: TestStats.keypressTimings.spacing.array, + keyDuration: TestStats.keypressTimings.duration.array, consistency: consistency, keyConsistency: keyConsistency, funbox: activeFunBox, @@ -2155,8 +2108,9 @@ function showResult(difficultyFailed = false) { ((config.difficulty == "master" || config.difficulty == "expert") && !difficultyFailed) ) { - restartCount = 0; - incompleteTestSeconds = 0; + // restartCount = 0; + // incompleteTestSeconds = 0; + TestStats.resetIncomplete(); } if ( stats.wpm > 0 && @@ -2379,9 +2333,11 @@ function showResult(difficultyFailed = false) { afkseconds; } if (db_getSnapshot().globalStats.started == undefined) { - db_getSnapshot().globalStats.started = restartCount + 1; + db_getSnapshot().globalStats.started = + TestStats.restartCount + 1; } else { - db_getSnapshot().globalStats.started += restartCount + 1; + db_getSnapshot().globalStats.started += + TestStats.restartCount + 1; } if (db_getSnapshot().globalStats.completed == undefined) { db_getSnapshot().globalStats.completed = 1; @@ -2610,7 +2566,7 @@ function showResult(difficultyFailed = false) { } } else { Notifications.add("Test invalid", 0); - testInvalid = true; + TestStats.setInvalid(); try { firebase.analytics().logEvent("testCompletedInvalid", completedEvent); } catch (e) { @@ -2685,7 +2641,7 @@ function showResult(difficultyFailed = false) { if (afkDetected) { otherText += "
afk detected"; } - if (testInvalid) { + if (TestStats.invalid) { otherText += "
invalid"; } if (sameWordset) { @@ -2751,7 +2707,7 @@ function startTest() { console.log("Analytics unavailable"); } testActive = true; - testStart = performance.now(); + TestStats.setStart(performance.now()); restartTimer(); showTimer(); $("#liveWpm").text("0"); @@ -2759,16 +2715,6 @@ function startTest() { showLiveAcc(); updateTimer(); clearTimeout(timer); - keypressStats = { - spacing: { - current: -1, - array: [], - }, - duration: { - current: -1, - array: [], - }, - }; if (activeFunBox === "memory") { memoryFunboxInterval = clearInterval(memoryFunboxInterval); @@ -2795,15 +2741,11 @@ function startTest() { } let wpmAndRaw = liveWpmAndRaw(); updateLiveWpm(wpmAndRaw.wpm, wpmAndRaw.raw); - wpmHistory.push(wpmAndRaw.wpm); - rawHistory.push(wpmAndRaw.raw); + TestStats.pushToWpmHistory(wpmAndRaw.wpm); + TestStats.pushToRawHistory(wpmAndRaw.raw); Monkey.updateFastOpacity(wpmAndRaw.wpm); - let acc = Misc.roundTo2( - (accuracyStats.correct / - (accuracyStats.correct + accuracyStats.incorrect)) * - 100 - ); + let acc = Misc.roundTo2(TestStats.calculateAccuracy()); if (activeFunBox === "layoutfluid" && config.mode === "time") { const layouts = ["qwerty", "dvorak", "colemak"]; @@ -2838,17 +2780,7 @@ function startTest() { settingsGroups.layout.updateButton(); } - keypressPerSecond.push(currentKeypress); - currentKeypress = { - mod: 0, - count: 0, - words: [], - }; - errorsPerSecond.push(currentError); - currentError = { - count: 0, - words: [], - }; + TestStats.pushKeypressesToHistory(); if ( (config.minWpm === "custom" && wpmAndRaw.wpm < parseInt(config.minWpmCustomSpeed) && @@ -2882,7 +2814,7 @@ function startTest() { } loop(expectedStepEnd + stepIntervalMS); }, delay); - })(testStart + stepIntervalMS); + })(TestStats.start + stepIntervalMS); return true; } @@ -2952,12 +2884,12 @@ function restartTest(withSameWordset = false, nosave = false, event) { } if (testActive) { - let testNow = performance.now(); - let testSeconds = Misc.roundTo2((testNow - testStart) / 1000); - let afkseconds = keypressPerSecond.filter((x) => x.count == 0 && x.mod == 0) - .length; - incompleteTestSeconds += testSeconds - afkseconds; - restartCount++; + let testSeconds = TestStats.calculateTestSeconds(performance.now()); + let afkseconds = TestStats.calculateAfkSeconds(); + // incompleteTestSeconds += ; + TestStats.incrementIncompleteSeconds(testSeconds - afkseconds); + TestStats.incrementRestartCount(); + // restartCount++; } if (config.mode == "zen") { @@ -2977,11 +2909,9 @@ function restartTest(withSameWordset = false, nosave = false, event) { manualRestart = false; clearTimeout(timer); time = 0; - wpmHistory = []; - rawHistory = []; - missedWords = {}; - correctedHistory = []; + TestStats.restart(); currentCorrected = ""; + correctedHistory = []; ShiftTracker.reset(); setFocus(false); hideCaret(); @@ -2994,30 +2924,10 @@ function restartTest(withSameWordset = false, nosave = false, event) { if (paceCaret !== null) clearTimeout(paceCaret.timeout); $("#showWordHistoryButton").removeClass("loaded"); focusWords(); - keypressPerSecond = []; - lastSecondNotRound = false; - currentKeypress = { - mod: 0, - count: 0, - words: [], - }; - errorsPerSecond = []; - currentError = { - count: 0, - words: [], - }; + currentTestLine = 0; activeWordJumped = false; - keypressStats = { - spacing: { - current: -1, - array: [], - }, - duration: { - current: -1, - array: [], - }, - }; + $("#timerNumber").css("opacity", 0); let el = null; if (resultVisible) { @@ -3058,10 +2968,6 @@ function restartTest(withSameWordset = false, nosave = false, event) { testActive = false; currentWordIndex = 0; currentWordElementIndex = 0; - accuracyStats = { - correct: 0, - incorrect: 0, - }; inputHistory = []; currentInput = ""; initPaceCaret(); @@ -3181,8 +3087,9 @@ function changePage(page) { }); showTestConfig(); hideSignOutButton(); - restartCount = 0; - incompleteTestSeconds = 0; + // restartCount = 0; + // incompleteTestSeconds = 0; + TestStats.resetIncomplete(); manualRestart = true; restartTest(); } else if (page == "about") { @@ -3337,8 +3244,7 @@ function liveWpmAndRaw() { spaces = 0; } chars += currentInput.length; - let testNow = performance.now(); - let testSeconds = (testNow - testStart) / 1000; + let testSeconds = TestStats.calculateTestSeconds(performance.now()); let wpm = Math.round(((correctWordChars + spaces) * (60 / testSeconds)) / 5); let raw = Math.round(((chars + spaces) * (60 / testSeconds)) / 5); return { @@ -4706,6 +4612,10 @@ $(document.body).on("click", "#restartTestButton", () => { }); function initPractiseMissedWords() { + if (Object.keys(TestStats.missedWords).length == 0) { + Notifications.add("You haven't missed any words.", 0); + return; + } let mode = modeBeforePractise === null ? config.mode : modeBeforePractise; let punctuation = punctuationBeforePractise === null @@ -4715,8 +4625,8 @@ function initPractiseMissedWords() { numbersBeforePractise === null ? config.numbers : numbersBeforePractise; setMode("custom"); let newCustomText = []; - Object.keys(missedWords).forEach((missedWord) => { - for (let i = 0; i < missedWords[missedWord]; i++) { + Object.keys(TestStats.missedWords).forEach((missedWord) => { + for (let i = 0; i < TestStats.missedWords[missedWord]; i++) { newCustomText.push(missedWord); } }); @@ -4735,20 +4645,12 @@ function initPractiseMissedWords() { $(document).on("keypress", "#practiseMissedWordsButton", (event) => { if (event.keyCode == 13) { - if (Object.keys(missedWords).length > 0) { - initPractiseMissedWords(); - } else { - Notifications.add("You haven't missed any words.", 0); - } + initPractiseMissedWords(); } }); $(document.body).on("click", "#practiseMissedWordsButton", () => { - if (Object.keys(missedWords).length > 0) { - initPractiseMissedWords(); - } else { - Notifications.add("You haven't missed any words.", 0); - } + initPractiseMissedWords(); }); $(document).on("keypress", "#nextTestButton", (event) => { @@ -4920,11 +4822,13 @@ $(document).keyup((event) => { if (resultVisible) return; let now = performance.now(); - let diff = Math.abs(keypressStats.duration.current - now); - if (keypressStats.duration.current !== -1) { - keypressStats.duration.array.push(diff); + let diff = Math.abs(TestStats.keypressTimings.duration.current - now); + if (TestStats.keypressTimings.duration.current !== -1) { + TestStats.pushKeypressDuration(diff); + // keypressStats.duration.array.push(diff); } - keypressStats.duration.current = now; + TestStats.setKeypressDuration(now); + // keypressStats.duration.current = now; Monkey.stop(); }); @@ -4933,11 +4837,13 @@ $(document).keydown(function (event) { if (!resultVisible) { let now = performance.now(); - let diff = Math.abs(keypressStats.spacing.current - now); - if (keypressStats.spacing.current !== -1) { - keypressStats.spacing.array.push(diff); + let diff = Math.abs(TestStats.keypressTimings.spacing.current - now); + if (TestStats.keypressTimings.spacing.current !== -1) { + TestStats.pushKeypressSpacing(diff); + // keypressStats.spacing.array.push(diff); } - keypressStats.spacing.current = now; + TestStats.setKeypressSpacing(now); + // keypressStats.spacing.current = now; } Monkey.type(); @@ -4983,7 +4889,8 @@ $(document).keydown(function (event) { } } - keypressStats.duration.current = performance.now(); + // keypressStats.duration.current = performance.now(); + TestStats.setKeypressDuration(performance.now()); try { if ( !config.capsLockBackspace && @@ -5020,11 +4927,7 @@ $(document).keydown(function (event) { handleAlpha(event); } - let acc = Misc.roundTo2( - (accuracyStats.correct / - (accuracyStats.correct + accuracyStats.incorrect)) * - 100 - ); + let acc = Misc.roundTo2(TestStats.calculateAccuracy()); updateLiveAcc(acc); }); @@ -5254,15 +5157,17 @@ function handleSpace(event, isEnter) { paceCaret.wordsStatus[currentWordIndex] = undefined; paceCaret.correction -= currentWord.length + 1; } - accuracyStats.correct++; + TestStats.incrementAccuracy(true); inputHistory.push(currentInput); currentInput = ""; currentWordIndex++; currentWordElementIndex++; updateActiveElement(); updateCaretPosition(); - currentKeypress.count++; - currentKeypress.words.push(currentWordIndex); + TestStats.incrementKeypressCount(); + TestStats.pushKeypressWord(currentWordIndex); + // currentKeypress.count++; + // currentKeypress.words.push(currentWordIndex); if (activeFunBox !== "nospace") { Sound.playClick(config.playSoundOnClick); } @@ -5283,9 +5188,8 @@ function handleSpace(event, isEnter) { Sound.playError(config.playSoundOnError); } } - accuracyStats.incorrect++; - currentError.count++; - currentError.words.push(currentWordIndex); + TestStats.incrementAccuracy(false); + TestStats.incrementKeypressErrors(); let cil = currentInput.length; if (cil <= wordsList[currentWordIndex].length) { if (cil >= currentCorrected.length) { @@ -5318,14 +5222,16 @@ function handleSpace(event, isEnter) { currentWordElementIndex++; updateActiveElement(); updateCaretPosition(); - currentKeypress.count++; - currentKeypress.words.push(currentWordIndex); + // currentKeypress.count++; + // currentKeypress.words.push(currentWordIndex); + TestStats.incrementKeypressCount(); + TestStats.pushKeypressWord(currentWordIndex); if (config.difficulty == "expert" || config.difficulty == "master") { failTest(); return; } else if (currentWordIndex == wordsList.length) { //submitted last word that is incorrect - lastSecondNotRound = true; + TestStats.setLastSecondNotRound(); showResult(); return; } @@ -5426,7 +5332,8 @@ function handleAlpha(event) { undefined, ].includes(event.key) ) { - currentKeypress.mod++; + TestStats.incrementKeypressMod(); + // currentKeypress.mod++; return; } @@ -5573,17 +5480,14 @@ function handleAlpha(event) { } if (!thisCharCorrect) { - accuracyStats.incorrect++; - currentError.count++; - currentError.words.push(currentWordIndex); + TestStats.incrementAccuracy(false); + TestStats.incrementKeypressErrors(); + // currentError.count++; + // currentError.words.push(currentWordIndex); thisCharCorrect = false; - if (!Object.keys(missedWords).includes(wordsList[currentWordIndex])) { - missedWords[wordsList[currentWordIndex]] = 1; - } else { - missedWords[wordsList[currentWordIndex]]++; - } + TestStats.pushMissedWord(wordsList[currentWordIndex]); } else { - accuracyStats.correct++; + TestStats.incrementAccuracy(true); thisCharCorrect = true; if (config.mode == "zen") { //making the input visible to the user @@ -5623,9 +5527,10 @@ function handleAlpha(event) { currentCorrected.substring(cil + 1); } } - - currentKeypress.count++; - currentKeypress.words.push(currentWordIndex); + TestStats.incrementKeypressCount(); + TestStats.pushKeypressWord(currentWordIndex); + // currentKeypress.count++; + // currentKeypress.words.push(currentWordIndex); if (config.stopOnError == "letter" && !thisCharCorrect) { return; @@ -5675,7 +5580,7 @@ function handleAlpha(event) { currentInput = ""; correctedHistory.push(currentCorrected); currentCorrected = ""; - lastSecondNotRound = true; + TestStats.setLastSecondNotRound(); showResult(); } } @@ -6049,7 +5954,7 @@ let wpmOverTimeChart = new Chart(ctx, { $(".wordInputAfter").remove(); let wordsToHighlight = - keypressPerSecond[parseInt(ti.xLabel) - 1].words; + TestStats.keypressPerSecond[parseInt(ti.xLabel) - 1].words; let unique = [...new Set(wordsToHighlight)]; unique.forEach((wordIndex) => { diff --git a/src/js/test-stats.js b/src/js/test-stats.js new file mode 100644 index 000000000..13eca2dc7 --- /dev/null +++ b/src/js/test-stats.js @@ -0,0 +1,189 @@ +export let invalid = false; +export let start, end; +export let wpmHistory = []; +export let rawHistory = []; + +export let keypressPerSecond = []; +export let currentKeypress = { + count: 0, + mod: 0, + errors: 0, + words: [], +}; + +// export let errorsPerSecond = []; +// export let currentError = { +// count: 0, +// words: [], +// }; +export let lastSecondNotRound = false; +export let missedWords = {}; +export let accuracy = { + correct: 0, + incorrect: 0, +}; +export let keypressTimings = { + spacing: { + current: -1, + array: [], + }, + duration: { + current: -1, + array: [], + }, +}; + +export function restart() { + start = 0; + end = 0; + invalid = false; + wpmHistory = []; + rawHistory = []; + keypressPerSecond = []; + currentKeypress = { + count: 0, + mod: 0, + errors: 0, + words: [], + }; + // errorsPerSecond = []; + // currentError = { + // count: 0, + // words: [], + // }; + lastSecondNotRound = false; + missedWords = {}; + accuracy = { + correct: 0, + incorrect: 0, + }; + keypressTimings = { + spacing: { + current: -1, + array: [], + }, + duration: { + current: -1, + array: [], + }, + }; +} + +export let restartCount = 0; +export let incompleteSeconds = 0; + +export function incrementRestartCount() { + restartCount++; +} + +export function incrementIncompleteSeconds(val) { + incompleteSeconds += val; +} + +export function resetIncomplete() { + restartCount = 0; + incompleteSeconds = 0; +} + +export function setInvalid() { + invalid = true; +} + +export function calculateTestSeconds(now) { + if (now === undefined) { + return (end - start) / 1000; + } else { + return (now - start) / 1000; + } +} + +export function setEnd(e) { + end = e; +} + +export function setStart(s) { + start = s; +} + +export function pushToWpmHistory(word) { + wpmHistory.push(word); +} + +export function pushToRawHistory(word) { + rawHistory.push(word); +} + +export function incrementKeypressCount() { + currentKeypress.count++; +} + +export function incrementKeypressMod() { + currentKeypress.mod++; +} + +export function incrementKeypressErrors() { + currentKeypress.errors++; +} + +export function pushKeypressWord(word) { + currentKeypress.words.push(word); +} + +export function pushKeypressesToHistory() { + keypressPerSecond.push(currentKeypress); + currentKeypress = { + count: 0, + mod: 0, + errors: 0, + words: [], + }; +} + +export function calculateAfkSeconds() { + return keypressPerSecond.filter((x) => x.count == 0 && x.mod == 0).length; +} + +export function setLastSecondNotRound() { + lastSecondNotRound = true; +} + +export function calculateAccuracy() { + return (accuracy.correct / (accuracy.correct + accuracy.incorrect)) * 100; +} + +export function incrementAccuracy(correctincorrect) { + if (correctincorrect) { + accuracy.correct++; + } else { + accuracy.incorrect++; + } +} + +export function setKeypressTimingsTooLong() { + keypressTimings.spacing.array = "toolong"; + keypressTimings.duration.array = "toolong"; +} + +export function pushKeypressDuration(val) { + keypressTimings.duration.array.push(val); +} + +export function setKeypressDuration(val) { + keypressTimings.duration.current = val; +} + +export function pushKeypressSpacing(val) { + keypressTimings.spacing.array.push(val); +} + +export function setKeypressSpacing(val) { + keypressTimings.spacing.current = val; +} + +export function pushMissedWord(word) { + if (!Object.keys(missedWords).includes(word)) { + missedWords[word] = 1; + } else { + missedWords[word]++; + } +} diff --git a/src/js/userconfig.js b/src/js/userconfig.js index 11a733377..81e75b547 100644 --- a/src/js/userconfig.js +++ b/src/js/userconfig.js @@ -102,7 +102,7 @@ async function saveConfigToCookie(noDbCheck = false) { let save = config; delete save.resultFilters; Misc.setCookie("config", JSON.stringify(save), 365); - restartCount = 0; + // restartCount = 0; if (!noDbCheck) await saveConfigToDB(); }