From 3b47f0172a7806155dfdba665053356335ff48eb Mon Sep 17 00:00:00 2001 From: Miodec Date: Wed, 24 Mar 2021 19:44:32 +0000 Subject: [PATCH] moved pace caret to a module. part of #495 --- gulpfile.js | 1 + src/js/account.js | 2 +- src/js/commandline.js | 4 +- src/js/global-dependencies.js | 1 + src/js/script.js | 255 ++-------------------------------- src/js/settings.js | 2 +- src/js/test/pace-caret.js | 252 +++++++++++++++++++++++++++++++++ src/js/test/test-ui.js | 5 +- src/js/userconfig.js | 22 +-- 9 files changed, 283 insertions(+), 261 deletions(-) create mode 100644 src/js/test/pace-caret.js diff --git a/gulpfile.js b/gulpfile.js index 29e4823c8..024a011da 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -120,6 +120,7 @@ const refactoredSrc = [ "./src/js/test/timer-progress.js", "./src/js/test/test-logic.js", "./src/js/test/funbox.js", + "./src/js/test/pace-caret.js", ]; //legacy files diff --git a/src/js/account.js b/src/js/account.js index d13bd802a..94f6cc063 100644 --- a/src/js/account.js +++ b/src/js/account.js @@ -417,7 +417,7 @@ function getAccountDataAndInit() { } if (Config.paceCaret === "pb" || Config.paceCaret === "average") { if (!TestLogic.active) { - initPaceCaret(true); + PaceCaret.init(true); } } // try { diff --git a/src/js/commandline.js b/src/js/commandline.js index 21879a3fc..613c7fe3e 100644 --- a/src/js/commandline.js +++ b/src/js/commandline.js @@ -1544,7 +1544,7 @@ function updateCommandsTagsList() { DB.getSnapshot().tags.forEach((tag) => { tag.active = false; }); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); saveActiveTagsToCookie(); }, }); @@ -1564,7 +1564,7 @@ function updateCommandsTagsList() { sticky: true, exec: () => { toggleTag(tag.id); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); let txt = tag.name; if (tag.active === true) { diff --git a/src/js/global-dependencies.js b/src/js/global-dependencies.js index ac36843cd..cda8a2d74 100644 --- a/src/js/global-dependencies.js +++ b/src/js/global-dependencies.js @@ -49,3 +49,4 @@ import * as TestLeaderboards from "./test-leaderboards"; import * as TimerProgress from "./timer-progress"; import * as TestLogic from "./test-logic"; import * as Funbox from "./funbox"; +import * as PaceCaret from "./pace-caret"; diff --git a/src/js/script.js b/src/js/script.js index e16e83b8a..c1f6a525f 100644 --- a/src/js/script.js +++ b/src/js/script.js @@ -2,9 +2,6 @@ let time = 0; let timer = null; -//pace caret -let paceCaret = null; - //ui let pageTransition = false; let notSignedInLastResult = null; @@ -108,7 +105,7 @@ async function activateFunbox(funbox, mode) { settingsGroups.layout.updateButton(); } } - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); return true; } @@ -1910,8 +1907,7 @@ function startTest() { } try { - if (Config.paceCaret !== "off") - movePaceCaret(performance.now() + paceCaret.spc * 1000); + if (Config.paceCaret !== "off") PaceCaret.start(); } catch (e) {} //use a recursive self-adjusting timer to avoid time drift const stepIntervalMS = 1000; @@ -2113,8 +2109,7 @@ function restartTest(withSameWordset = false, nosave = false, event) { LiveAcc.hide(); TimerProgress.hide(); TestLogic.setBailout(false); - paceCaret = null; - if (paceCaret !== null) clearTimeout(paceCaret.timeout); + PaceCaret.reset(); $("#showWordHistoryButton").removeClass("loaded"); focusWords(); Funbox.resetMemoryTimer(); @@ -2155,13 +2150,13 @@ function restartTest(withSameWordset = false, nosave = false, event) { TestLogic.setRepeated(false); TestLogic.setHasTab(false); await initWords(); - initPaceCaret(nosave); + PaceCaret.init(nosave); } else { TestLogic.setRepeated(true); TestLogic.setActive(false); TestLogic.words.resetCurrentIndex(); TestLogic.input.reset(); - initPaceCaret(); + PaceCaret.init(); showWords(); } if (Config.mode === "quote") { @@ -2224,7 +2219,7 @@ function restartTest(withSameWordset = false, nosave = false, event) { $("#testModesNotice").removeClass("hidden").css({ opacity: 1, }); - resetPaceCaret(); + // resetPaceCaret(); $("#typingTest") .css("opacity", 0) .removeClass("hidden") @@ -2236,12 +2231,12 @@ function restartTest(withSameWordset = false, nosave = false, event) { 125, () => { TestUI.setTestRestarting(false); - resetPaceCaret(); + // resetPaceCaret(); hideCrown(); clearTimeout(timer); if ($("#commandLineWrapper").hasClass("hidden")) focusWords(); ChartController.result.update(); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); pageTransition = false; // console.log(TestStats.incompleteSeconds); // console.log(TestStats.restartCount); @@ -2361,7 +2356,7 @@ function setMode(mode, nosave) { Funbox.active === "ascii" ) { Funbox.setAcitve("none"); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); } $("#top .config .wordCount").addClass("hidden"); $("#top .config .time").addClass("hidden"); @@ -2872,220 +2867,6 @@ function hideQuoteSearchPopup() { } } -async function initPaceCaret() { - let mode2 = ""; - if (Config.mode === "time") { - mode2 = Config.time; - } else if (Config.mode === "words") { - mode2 = Config.words; - } else if (Config.mode === "custom") { - mode2 = "custom"; - } else if (Config.mode === "quote") { - mode2 = TestLogic.randomQuote.id; - } - let wpm; - if (Config.paceCaret === "pb") { - wpm = await DB.getLocalPB( - Config.mode, - mode2, - Config.punctuation, - Config.language, - Config.difficulty - ); - } else if (Config.paceCaret === "average") { - let mode2 = ""; - if (Config.mode === "time") { - mode2 = Config.time; - } else if (Config.mode === "words") { - mode2 = Config.words; - } else if (Config.mode === "custom") { - mode2 = "custom"; - } else if (Config.mode === "quote") { - mode2 = TestLogic.randomQuote.id; - } - wpm = await DB.getUserAverageWpm10( - Config.mode, - mode2, - Config.punctuation, - Config.language, - Config.difficulty - ); - console.log("avg pace " + wpm); - } else if (Config.paceCaret === "custom") { - wpm = Config.paceCaretCustomSpeed; - } - - if (wpm < 1 || wpm == false || wpm == undefined || Number.isNaN(wpm)) { - paceCaret = null; - return; - } - - let characters = wpm * 5; - let cps = characters / 60; //characters per step - let spc = 60 / characters; //seconds per character - - paceCaret = { - wpm: wpm, - cps: cps, - spc: spc, - correction: 0, - currentWordIndex: 0, - currentLetterIndex: -1, - wordsStatus: {}, - timeout: null, - }; - - TestUI.updateModesNotice(paceCaret); -} - -function movePaceCaret(expectedStepEnd) { - if (paceCaret === null || !TestLogic.active || TestUI.resultVisible) { - return; - } - if ($("#paceCaret").hasClass("hidden")) { - $("#paceCaret").removeClass("hidden"); - } - if ($("#paceCaret").hasClass("off")) { - return; - } - try { - paceCaret.currentLetterIndex++; - if ( - paceCaret.currentLetterIndex >= - TestLogic.words.get(paceCaret.currentWordIndex).length - ) { - //go to the next word - paceCaret.currentLetterIndex = -1; - paceCaret.currentWordIndex++; - } - if (!Config.blindMode) { - if (paceCaret.correction < 0) { - while (paceCaret.correction < 0) { - paceCaret.currentLetterIndex--; - if (paceCaret.currentLetterIndex <= -2) { - //go to the previous word - paceCaret.currentLetterIndex = - TestLogic.words.get(paceCaret.currentWordIndex - 1).length - 1; - paceCaret.currentWordIndex--; - } - paceCaret.correction++; - } - } else if (paceCaret.correction > 0) { - while (paceCaret.correction > 0) { - paceCaret.currentLetterIndex++; - if ( - paceCaret.currentLetterIndex >= - TestLogic.words.get(paceCaret.currentWordIndex).length - ) { - //go to the next word - paceCaret.currentLetterIndex = -1; - paceCaret.currentWordIndex++; - } - paceCaret.correction--; - } - } - } - } catch (e) { - //out of words - paceCaret = null; - $("#paceCaret").addClass("hidden"); - return; - } - - try { - let caret = $("#paceCaret"); - let currentLetter; - let newTop; - let newLeft; - try { - let newIndex = - paceCaret.currentWordIndex - - (TestLogic.words.currentIndex - TestUI.currentWordElementIndex); - if (paceCaret.currentLetterIndex === -1) { - currentLetter = document - .querySelectorAll("#words .word") - [newIndex].querySelectorAll("letter")[0]; - } else { - currentLetter = document - .querySelectorAll("#words .word") - [newIndex].querySelectorAll("letter")[paceCaret.currentLetterIndex]; - } - newTop = currentLetter.offsetTop - $(currentLetter).height() / 20; - newLeft; - if (paceCaret.currentLetterIndex === -1) { - newLeft = currentLetter.offsetLeft; - } else { - newLeft = - currentLetter.offsetLeft + - $(currentLetter).width() - - caret.width() / 2; - } - caret.removeClass("hidden"); - } catch (e) { - caret.addClass("hidden"); - } - - let smoothlinescroll = $("#words .smoothScroller").height(); - if (smoothlinescroll === undefined) smoothlinescroll = 0; - - $("#paceCaret").css({ - top: newTop - smoothlinescroll, - }); - - let duration = expectedStepEnd - performance.now(); - - if (Config.smoothCaret) { - caret.stop(true, true).animate( - { - left: newLeft, - }, - duration, - "linear" - ); - } else { - caret.stop(true, true).animate( - { - left: newLeft, - }, - 0, - "linear" - ); - } - paceCaret.timeout = setTimeout(() => { - try { - movePaceCaret(expectedStepEnd + paceCaret.spc * 1000); - } catch (e) { - paceCaret = null; - } - }, duration); - } catch (e) { - console.error(e); - $("#paceCaret").addClass("hidden"); - } -} - -function resetPaceCaret() { - if (Config.paceCaret === "off") return; - if (!$("#paceCaret").hasClass("hidden")) { - $("#paceCaret").addClass("hidden"); - } - if (Config.mode === "zen") return; - - let caret = $("#paceCaret"); - let firstLetter = document - .querySelector("#words .word") - .querySelector("letter"); - - caret.stop(true, true).animate( - { - top: firstLetter.offsetTop - $(firstLetter).height() / 4, - left: firstLetter.offsetLeft, - }, - 0, - "linear" - ); -} - $("#customMode2PopupWrapper").click((e) => { if ($(e.target).attr("id") === "customMode2PopupWrapper") { hideCustomMode2Popup(); @@ -3832,14 +3613,7 @@ function handleSpace(event, isEnter) { dontInsertSpace = true; if (currentWord == TestLogic.input.current || Config.mode == "zen") { //correct word or in zen mode - if ( - paceCaret !== null && - paceCaret.wordsStatus[TestLogic.words.currentIndex] === true && - !Config.blindMode - ) { - paceCaret.wordsStatus[TestLogic.words.currentIndex] = undefined; - paceCaret.correction -= currentWord.length + 1; - } + PaceCaret.handleSpace(true, currentWord); TestStats.incrementAccuracy(true); TestLogic.input.pushHistory(); TestLogic.words.increaseCurrentIndex(); @@ -3856,14 +3630,7 @@ function handleSpace(event, isEnter) { } } else { //incorrect word - if ( - paceCaret !== null && - paceCaret.wordsStatus[TestLogic.words.currentIndex] === undefined && - !Config.blindMode - ) { - paceCaret.wordsStatus[TestLogic.words.currentIndex] = true; - paceCaret.correction += currentWord.length + 1; - } + PaceCaret.handleSpace(false, currentWord); if (Funbox.active !== "nospace") { if (!Config.playSoundOnError || Config.blindMode) { Sound.playClick(Config.playSoundOnClick); diff --git a/src/js/settings.js b/src/js/settings.js index 0e150b676..1619e206e 100644 --- a/src/js/settings.js +++ b/src/js/settings.js @@ -757,7 +757,7 @@ function toggleTag(tagid, nosave = false) { } } }); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveActiveTagsToCookie(); } diff --git a/src/js/test/pace-caret.js b/src/js/test/pace-caret.js new file mode 100644 index 000000000..627e572fa --- /dev/null +++ b/src/js/test/pace-caret.js @@ -0,0 +1,252 @@ +import * as TestLogic from "./test-logic"; +import * as TestUI from "./test-ui"; +import Config from "./config"; +import * as DB from "./db"; + +export let settings = null; + +export function start() { + update(performance.now() + settings.spc * 1000); +} + +export async function init() { + let mode2 = ""; + if (Config.mode === "time") { + mode2 = Config.time; + } else if (Config.mode === "words") { + mode2 = Config.words; + } else if (Config.mode === "custom") { + mode2 = "custom"; + } else if (Config.mode === "quote") { + mode2 = TestLogic.randomQuote.id; + } + let wpm; + if (Config.paceCaret === "pb") { + wpm = await DB.getLocalPB( + Config.mode, + mode2, + Config.punctuation, + Config.language, + Config.difficulty + ); + } else if (Config.paceCaret === "average") { + let mode2 = ""; + if (Config.mode === "time") { + mode2 = Config.time; + } else if (Config.mode === "words") { + mode2 = Config.words; + } else if (Config.mode === "custom") { + mode2 = "custom"; + } else if (Config.mode === "quote") { + mode2 = TestLogic.randomQuote.id; + } + wpm = await DB.getUserAverageWpm10( + Config.mode, + mode2, + Config.punctuation, + Config.language, + Config.difficulty + ); + console.log("avg pace " + wpm); + } else if (Config.paceCaret === "custom") { + wpm = Config.paceCaretCustomSpeed; + } + + if (wpm < 1 || wpm == false || wpm == undefined || Number.isNaN(wpm)) { + settings = null; + return; + } + + let characters = wpm * 5; + let cps = characters / 60; //characters per step + let spc = 60 / characters; //seconds per character + + settings = { + wpm: wpm, + cps: cps, + spc: spc, + correction: 0, + currentWordIndex: 0, + currentLetterIndex: -1, + wordsStatus: {}, + timeout: null, + }; + + resetCaretPosition(); + TestUI.updateModesNotice(); +} + +export function update(expectedStepEnd) { + if (settings === null || !TestLogic.active || TestUI.resultVisible) { + return; + } + if ($("#paceCaret").hasClass("hidden")) { + $("#paceCaret").removeClass("hidden"); + } + if ($("#paceCaret").hasClass("off")) { + return; + } + try { + settings.currentLetterIndex++; + if ( + settings.currentLetterIndex >= + TestLogic.words.get(settings.currentWordIndex).length + ) { + //go to the next word + settings.currentLetterIndex = -1; + settings.currentWordIndex++; + } + if (!Config.blindMode) { + if (settings.correction < 0) { + while (settings.correction < 0) { + settings.currentLetterIndex--; + if (settings.currentLetterIndex <= -2) { + //go to the previous word + settings.currentLetterIndex = + TestLogic.words.get(settings.currentWordIndex - 1).length - 1; + settings.currentWordIndex--; + } + settings.correction++; + } + } else if (settings.correction > 0) { + while (settings.correction > 0) { + settings.currentLetterIndex++; + if ( + settings.currentLetterIndex >= + TestLogic.words.get(settings.currentWordIndex).length + ) { + //go to the next word + settings.currentLetterIndex = -1; + settings.currentWordIndex++; + } + settings.correction--; + } + } + } + } catch (e) { + //out of words + settings = null; + $("#paceCaret").addClass("hidden"); + return; + } + + try { + let caret = $("#paceCaret"); + let currentLetter; + let newTop; + let newLeft; + try { + let newIndex = + settings.currentWordIndex - + (TestLogic.words.currentIndex - TestUI.currentWordElementIndex); + if (settings.currentLetterIndex === -1) { + currentLetter = document + .querySelectorAll("#words .word") + [newIndex].querySelectorAll("letter")[0]; + } else { + currentLetter = document + .querySelectorAll("#words .word") + [newIndex].querySelectorAll("letter")[settings.currentLetterIndex]; + } + newTop = currentLetter.offsetTop - $(currentLetter).height() / 20; + newLeft; + if (settings.currentLetterIndex === -1) { + newLeft = currentLetter.offsetLeft; + } else { + newLeft = + currentLetter.offsetLeft + + $(currentLetter).width() - + caret.width() / 2; + } + caret.removeClass("hidden"); + } catch (e) { + caret.addClass("hidden"); + } + + let smoothlinescroll = $("#words .smoothScroller").height(); + if (smoothlinescroll === undefined) smoothlinescroll = 0; + + $("#paceCaret").css({ + top: newTop - smoothlinescroll, + }); + + let duration = expectedStepEnd - performance.now(); + + if (Config.smoothCaret) { + caret.stop(true, true).animate( + { + left: newLeft, + }, + duration, + "linear" + ); + } else { + caret.stop(true, true).animate( + { + left: newLeft, + }, + 0, + "linear" + ); + } + settings.timeout = setTimeout(() => { + try { + update(expectedStepEnd + settings.spc * 1000); + } catch (e) { + settings = null; + } + }, duration); + } catch (e) { + console.error(e); + $("#paceCaret").addClass("hidden"); + } +} + +function resetCaretPosition() { + if (Config.paceCaret === "off") return; + if (!$("#paceCaret").hasClass("hidden")) { + $("#paceCaret").addClass("hidden"); + } + if (Config.mode === "zen") return; + + let caret = $("#paceCaret"); + let firstLetter = document + .querySelector("#words .word") + .querySelector("letter"); + + caret.stop(true, true).animate( + { + top: firstLetter.offsetTop - $(firstLetter).height() / 4, + left: firstLetter.offsetLeft, + }, + 0, + "linear" + ); +} + +export function reset() { + settings = null; + if (settings !== null) clearTimeout(settings.timeout); +} + +export function handleSpace(correct, currentWord) { + if (correct) { + if ( + settings !== null && + settings.wordsStatus[TestLogic.words.currentIndex] === true && + !Config.blindMode + ) { + settings.wordsStatus[TestLogic.words.currentIndex] = undefined; + settings.correction -= currentWord.length + 1; + } + } else { + if ( + settings !== null && + settings.wordsStatus[TestLogic.words.currentIndex] === undefined && + !Config.blindMode + ) { + settings.wordsStatus[TestLogic.words.currentIndex] = true; + settings.correction += currentWord.length + 1; + } + } +} diff --git a/src/js/test/test-ui.js b/src/js/test/test-ui.js index 37a7aa864..cbdca36cd 100644 --- a/src/js/test/test-ui.js +++ b/src/js/test/test-ui.js @@ -4,6 +4,7 @@ import Config from "./config"; import * as DB from "./db"; import * as TestLogic from "./test-logic"; import * as Funbox from "./funbox"; +import * as PaceCaret from "./pace-caret"; export let currentWordElementIndex = 0; export let resultVisible = false; @@ -215,7 +216,7 @@ export function lineJump(currentTop) { currentTestLine++; } -export function updateModesNotice(paceCaret) { +export function updateModesNotice() { let anim = false; if ($(".pageTest #testModesNotice").text() === "") anim = true; @@ -269,7 +270,7 @@ export function updateModesNotice(paceCaret) { if (Config.paceCaret !== "off") { let speed = ""; try { - speed = ` (${Math.round(paceCaret.wpm)} wpm)`; + speed = ` (${Math.round(PaceCaret.settings.wpm)} wpm)`; } catch {} $(".pageTest #testModesNotice").append( `
${ diff --git a/src/js/userconfig.js b/src/js/userconfig.js index bc745cebc..aee196758 100644 --- a/src/js/userconfig.js +++ b/src/js/userconfig.js @@ -146,7 +146,7 @@ function setDifficulty(diff, nosave) { } ConfigSet.difficulty(diff); if (!nosave) restartTest(false, nosave); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveConfigToCookie(); } @@ -166,7 +166,7 @@ function toggleBlindMode() { blind = false; } ConfigSet.blindMode(blind); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); saveConfigToCookie(); } @@ -175,7 +175,7 @@ function setBlindMode(blind, nosave) { blind = false; } ConfigSet.blindMode(blind); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveConfigToCookie(); } @@ -243,7 +243,7 @@ function setStopOnError(soe, nosave) { if (Config.stopOnError !== "off") { ConfigSet.confidenceMode("off"); } - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveConfigToCookie(); } @@ -320,8 +320,8 @@ function setPaceCaret(val, nosave) { // val = "off"; // } ConfigSet.paceCaret(val); - TestUI.updateModesNotice(paceCaret); - initPaceCaret(nosave); + TestUI.updateModesNotice(); + PaceCaret.init(nosave); if (!nosave) saveConfigToCookie(); } @@ -339,7 +339,7 @@ function setMinWpm(minwpm, nosave) { minwpm = "off"; } ConfigSet.minWpm(minwpm); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveConfigToCookie(); } @@ -357,7 +357,7 @@ function setMinAcc(min, nosave) { min = "off"; } ConfigSet.minAcc(min); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveConfigToCookie(); } @@ -1014,7 +1014,7 @@ function setConfidenceMode(cm, nosave) { ConfigSet.stopOnError("off"); } - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (!nosave) saveConfigToCookie(); } @@ -1146,7 +1146,7 @@ function setLayout(layout, nosave) { layout = "qwerty"; } ConfigSet.layout(layout); - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); if (Config.keymapLayout === "overrideSync") { Keymap.refreshKeys(Config.keymapLayout, setKeymapLayout); } @@ -1497,5 +1497,5 @@ function applyConfig(configObj) { $("#nitropay_ad_about").remove(); } } - TestUI.updateModesNotice(paceCaret); + TestUI.updateModesNotice(); }