diff --git a/gulpfile.js b/gulpfile.js index 2a34268d1..b6bc131cd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -108,7 +108,6 @@ const refactoredSrc = [ "./src/js/manual-restart-tracker.js", "./src/js/config.js", "./src/js/config-set.js", - "./src/js/test/pace-caret.js", ]; //legacy files diff --git a/src/js/account.js b/src/js/account.js index e0fc1d282..60828668f 100644 --- a/src/js/account.js +++ b/src/js/account.js @@ -416,7 +416,7 @@ function getAccountDataAndInit() { } if (Config.paceCaret === "pb" || Config.paceCaret === "average") { if (!testActive) { - PaceCaret.init(); + initPaceCaret(true); } } // try { diff --git a/src/js/commandline.js b/src/js/commandline.js index 7c0e2cf23..f5a70c10d 100644 --- a/src/js/commandline.js +++ b/src/js/commandline.js @@ -1537,7 +1537,7 @@ function updateCommandsTagsList() { DB.getSnapshot().tags.forEach((tag) => { tag.active = false; }); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); saveActiveTagsToCookie(); }, }); @@ -1557,7 +1557,12 @@ function updateCommandsTagsList() { sticky: true, exec: () => { toggleTag(tag.id); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice( + sameWordset, + textHasTab, + paceCaret, + activeFunbox + ); let txt = tag.name; if (tag.active === true) { diff --git a/src/js/dom-util.js b/src/js/dom-util.js index d510632c6..303373897 100644 --- a/src/js/dom-util.js +++ b/src/js/dom-util.js @@ -1,6 +1,5 @@ import * as DB from "./db"; import Config from "./config"; -import * as PaceCaret from "./pace-caret"; export function showBackgroundLoader() { $("#backgroundLoader").stop(true, true).fadeIn(125); @@ -82,7 +81,12 @@ export function swapElements( } } -export function updateTestModesNotice(sameWordset, textHasTab, activeFunbox) { +export function updateTestModesNotice( + sameWordset, + textHasTab, + paceCaret, + activeFunbox +) { let anim = false; if ($(".pageTest #testModesNotice").text() === "") anim = true; @@ -136,7 +140,7 @@ export function updateTestModesNotice(sameWordset, textHasTab, activeFunbox) { if (Config.paceCaret !== "off") { let speed = ""; try { - speed = ` (${Math.round(PaceCaret.caret.wpm)} wpm)`; + speed = ` (${Math.round(paceCaret.wpm)} wpm)`; } catch {} $(".pageTest #testModesNotice").append( `
${ diff --git a/src/js/global-dependencies.js b/src/js/global-dependencies.js index b892d1a97..4887816e8 100644 --- a/src/js/global-dependencies.js +++ b/src/js/global-dependencies.js @@ -36,4 +36,3 @@ import * as CustomTextPopup from "./custom-text-popup"; import * as ManualRestart from "./manual-restart-tracker"; import Config from "./config"; import * as ConfigSet from "./config-set"; -import * as PaceCaret from "./test/pace-caret"; diff --git a/src/js/script.js b/src/js/script.js index c5114407a..5e8e0b0e2 100644 --- a/src/js/script.js +++ b/src/js/script.js @@ -30,6 +30,9 @@ let activeFunbox = "none"; let memoryFunboxTimer = null; let memoryFunboxInterval = null; +//pace caret +let paceCaret = null; + //ui let pageTransition = false; let focusState = false; @@ -210,7 +213,7 @@ async function activateFunbox(funbox, mode) { settingsGroups.layout.updateButton(); } } - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); return true; } @@ -2556,8 +2559,7 @@ function startTest() { try { if (Config.paceCaret !== "off") - PaceCaret.updatePosition(performance.now() + PaceCaret.caret.spc * 1000); - // movePaceCaret(); + movePaceCaret(performance.now() + paceCaret.spc * 1000); } catch (e) {} //use a recursive self-adjusting timer to avoid time drift const stepIntervalMS = 1000; @@ -2755,7 +2757,8 @@ function restartTest(withSameWordset = false, nosave = false, event) { hideLiveAcc(); hideTimer(); bailout = false; - PaceCaret.reset(); + paceCaret = null; + if (paceCaret !== null) clearTimeout(paceCaret.timeout); $("#showWordHistoryButton").removeClass("loaded"); focusWords(); @@ -2796,7 +2799,7 @@ function restartTest(withSameWordset = false, nosave = false, event) { sameWordset = false; textHasTab = false; await initWords(); - PaceCaret.init(); + initPaceCaret(nosave); } else { sameWordset = true; testActive = false; @@ -2804,7 +2807,7 @@ function restartTest(withSameWordset = false, nosave = false, event) { currentWordElementIndex = 0; inputHistory = []; currentInput = ""; - PaceCaret.init(); + initPaceCaret(); showWords(); } if (Config.mode === "quote") { @@ -2873,6 +2876,7 @@ function restartTest(withSameWordset = false, nosave = false, event) { $("#testModesNotice").removeClass("hidden").css({ opacity: 1, }); + resetPaceCaret(); $("#typingTest") .css("opacity", 0) .removeClass("hidden") @@ -2884,12 +2888,17 @@ function restartTest(withSameWordset = false, nosave = false, event) { 125, () => { testRestarting = false; - PaceCaret.resetPosition(); + resetPaceCaret(); hideCrown(); clearTimeout(timer); if ($("#commandLineWrapper").hasClass("hidden")) focusWords(); ChartController.result.update(); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice( + sameWordset, + textHasTab, + paceCaret, + activeFunbox + ); pageTransition = false; // console.log(TestStats.incompleteSeconds); // console.log(TestStats.restartCount); @@ -3015,7 +3024,7 @@ function setMode(mode, nosave) { activeFunbox === "ascii" ) { activeFunbox = "none"; - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); } $("#top .config .wordCount").addClass("hidden"); $("#top .config .time").addClass("hidden"); @@ -3678,6 +3687,220 @@ 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 = 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 = 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, + }; + + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); +} + +function movePaceCaret(expectedStepEnd) { + if (paceCaret === null || !testActive || resultVisible) { + return; + } + if ($("#paceCaret").hasClass("hidden")) { + $("#paceCaret").removeClass("hidden"); + } + if ($("#paceCaret").hasClass("off")) { + return; + } + try { + paceCaret.currentLetterIndex++; + if ( + paceCaret.currentLetterIndex >= + wordsList[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 = + wordsList[paceCaret.currentWordIndex - 1].length - 1; + paceCaret.currentWordIndex--; + } + paceCaret.correction++; + } + } else if (paceCaret.correction > 0) { + while (paceCaret.correction > 0) { + paceCaret.currentLetterIndex++; + if ( + paceCaret.currentLetterIndex >= + wordsList[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 - + (currentWordIndex - 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(); @@ -4530,12 +4753,12 @@ function handleSpace(event, isEnter) { if (currentWord == currentInput || Config.mode == "zen") { //correct word or in zen mode if ( - PaceCaret.caret !== null && - PaceCaret.caret.wordsStatus[currentWordIndex] === true && + paceCaret !== null && + paceCaret.wordsStatus[currentWordIndex] === true && !Config.blindMode ) { - PaceCaret.caret.wordsStatus[currentWordIndex] = undefined; - PaceCaret.caret.correction -= currentWord.length + 1; + paceCaret.wordsStatus[currentWordIndex] = undefined; + paceCaret.correction -= currentWord.length + 1; } TestStats.incrementAccuracy(true); inputHistory.push(currentInput); @@ -4554,12 +4777,12 @@ function handleSpace(event, isEnter) { } else { //incorrect word if ( - PaceCaret.caret !== null && - PaceCaret.caret.wordsStatus[currentWordIndex] === undefined && + paceCaret !== null && + paceCaret.wordsStatus[currentWordIndex] === undefined && !Config.blindMode ) { - PaceCaret.caret.wordsStatus[currentWordIndex] = true; - PaceCaret.caret.correction += currentWord.length + 1; + paceCaret.wordsStatus[currentWordIndex] = true; + paceCaret.correction += currentWord.length + 1; } if (activeFunbox !== "nospace") { if (!Config.playSoundOnError || Config.blindMode) { diff --git a/src/js/settings.js b/src/js/settings.js index 0b59f9f5c..df828e131 100644 --- a/src/js/settings.js +++ b/src/js/settings.js @@ -757,7 +757,7 @@ function toggleTag(tagid, nosave = false) { } } }); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveActiveTagsToCookie(); } diff --git a/src/js/test/pace-caret.js b/src/js/test/pace-caret.js deleted file mode 100644 index 57bc24cf9..000000000 --- a/src/js/test/pace-caret.js +++ /dev/null @@ -1,223 +0,0 @@ -import Config from "./config"; -import * as DB from "./db"; -import { updateTestModesNotice } from "./dom-util"; - -export let caret = null; - -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 = 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 = 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)) { - caret = null; - return; - } - - let characters = wpm * 5; - let cps = characters / 60; //characters per step - let spc = 60 / characters; //seconds per character - - caret = { - wpm: wpm, - cps: cps, - spc: spc, - correction: 0, - currentWordIndex: 0, - currentLetterIndex: -1, - wordsStatus: {}, - timeout: null, - }; - - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); -} - -export function updatePosition(expectedStepEnd) { - if (caret === null || !testActive || resultVisible) { - return; - } - if ($("#paceCaret").hasClass("hidden")) { - $("#paceCaret").removeClass("hidden"); - } - if ($("#paceCaret").hasClass("off")) { - return; - } - try { - caret.currentLetterIndex++; - if (caret.currentLetterIndex >= wordsList[caret.currentWordIndex].length) { - //go to the next word - caret.currentLetterIndex = -1; - caret.currentWordIndex++; - } - if (!Config.blindMode) { - if (caret.correction < 0) { - while (caret.correction < 0) { - caret.currentLetterIndex--; - if (caret.currentLetterIndex <= -2) { - //go to the previous word - caret.currentLetterIndex = - wordsList[caret.currentWordIndex - 1].length - 1; - caret.currentWordIndex--; - } - caret.correction++; - } - } else if (caret.correction > 0) { - while (caret.correction > 0) { - caret.currentLetterIndex++; - if ( - caret.currentLetterIndex >= wordsList[caret.currentWordIndex].length - ) { - //go to the next word - caret.currentLetterIndex = -1; - caret.currentWordIndex++; - } - caret.correction--; - } - } - } - } catch (e) { - //out of words - caret = null; - $("#paceCaret").addClass("hidden"); - return; - } - - try { - let caretEl = $("#paceCaret"); - let currentLetter; - let newTop; - let newLeft; - try { - let newIndex = - caret.currentWordIndex - (currentWordIndex - currentWordElementIndex); - if (caret.currentLetterIndex === -1) { - currentLetter = document - .querySelectorAll("#words .word") - [newIndex].querySelectorAll("letter")[0]; - } else { - currentLetter = document - .querySelectorAll("#words .word") - [newIndex].querySelectorAll("letter")[caret.currentLetterIndex]; - } - newTop = currentLetter.offsetTop - $(currentLetter).height() / 20; - newLeft; - if (caret.currentLetterIndex === -1) { - newLeft = currentLetter.offsetLeft; - } else { - newLeft = - currentLetter.offsetLeft + - $(currentLetter).width() - - caretEl.width() / 2; - } - caretEl.removeClass("hidden"); - } catch (e) { - caretEl.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) { - caretEl.stop(true, true).animate( - { - left: newLeft, - }, - duration, - "linear" - ); - } else { - caretEl.stop(true, true).animate( - { - left: newLeft, - }, - 0, - "linear" - ); - } - caret.timeout = setTimeout(() => { - try { - updatePosition(expectedStepEnd + caret.spc * 1000); - } catch (e) { - caret = null; - } - }, duration); - } catch (e) { - console.error(e); - $("#paceCaret").addClass("hidden"); - } -} - -export function reset() { - resetPosition(); - caret = null; - if (caret !== null) clearTimeout(caret.timeout); -} - -export function resetPosition() { - if (Config.paceCaret === "off") return; - if (!$("#paceCaret").hasClass("hidden")) { - $("#paceCaret").addClass("hidden"); - } - if (Config.mode === "zen") return; - - let caretEl = $("#paceCaret"); - let firstLetter = document - .querySelector("#words .word") - .querySelector("letter"); - - caretEl.stop(true, true).animate( - { - top: firstLetter.offsetTop - $(firstLetter).height() / 4, - left: firstLetter.offsetLeft, - }, - 0, - "linear" - ); - - caret = null; - if (caret !== null) clearTimeout(caret.timeout); -} diff --git a/src/js/test/test-logic.js b/src/js/test/test-logic.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/js/userconfig.js b/src/js/userconfig.js index 223bbcbba..2a2d4bdc3 100644 --- a/src/js/userconfig.js +++ b/src/js/userconfig.js @@ -140,7 +140,7 @@ function setDifficulty(diff, nosave) { } ConfigSet.difficulty(diff); if (!nosave) restartTest(false, nosave); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveConfigToCookie(); } @@ -160,7 +160,7 @@ function toggleBlindMode() { blind = false; } ConfigSet.blindMode(blind); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); saveConfigToCookie(); } @@ -169,7 +169,7 @@ function setBlindMode(blind, nosave) { blind = false; } ConfigSet.blindMode(blind); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveConfigToCookie(); } @@ -237,7 +237,7 @@ function setStopOnError(soe, nosave) { if (Config.stopOnError !== "off") { ConfigSet.confidenceMode("off"); } - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveConfigToCookie(); } @@ -314,8 +314,8 @@ function setPaceCaret(val, nosave) { // val = "off"; // } ConfigSet.paceCaret(val); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); - PaceCaret.init(); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); + initPaceCaret(nosave); if (!nosave) saveConfigToCookie(); } @@ -333,7 +333,7 @@ function setMinWpm(minwpm, nosave) { minwpm = "off"; } ConfigSet.minWpm(minwpm); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveConfigToCookie(); } @@ -351,7 +351,7 @@ function setMinAcc(min, nosave) { min = "off"; } ConfigSet.minAcc(min); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveConfigToCookie(); } @@ -953,7 +953,7 @@ function setConfidenceMode(cm, nosave) { ConfigSet.stopOnError("off"); } - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (!nosave) saveConfigToCookie(); } @@ -1085,7 +1085,7 @@ function setLayout(layout, nosave) { layout = "qwerty"; } ConfigSet.layout(layout); - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); if (Config.keymapLayout === "overrideSync") { refreshKeymapKeys(Config.keymapLayout); } @@ -1529,5 +1529,5 @@ function applyConfig(configObj) { $("#nitropay_ad_about").remove(); } } - updateTestModesNotice(sameWordset, textHasTab, activeFunbox); + updateTestModesNotice(sameWordset, textHasTab, paceCaret, activeFunbox); }