From 239e3e61d650628c9c16fc0feedfc42a41ff7104 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 29 Mar 2021 00:19:17 +0100 Subject: [PATCH] lots of little code refactoring #495 relocated smaller functions and most events divided code into small modules (layout emulator, support popup, version popup) --- gulpfile.js | 3 + src/js/commandline.js | 5 + src/js/exports.js | 2 +- src/js/global-dependencies.js | 3 + src/js/layout-emulator.js | 105 ++++++++ src/js/misc.js | 6 + src/js/script.js | 490 +--------------------------------- src/js/support-popup.js | 35 +++ src/js/test/focus.js | 9 + src/js/test/keymap.js | 7 + src/js/test/test-logic.js | 40 +++ src/js/test/test-ui.js | 161 +++++++++++ src/js/ui.js | 104 +++++++- src/js/version-popup.js | 14 + 14 files changed, 505 insertions(+), 479 deletions(-) create mode 100644 src/js/layout-emulator.js create mode 100644 src/js/support-popup.js create mode 100644 src/js/version-popup.js diff --git a/gulpfile.js b/gulpfile.js index 6b28ce40e..dd1d40f88 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -136,6 +136,9 @@ const refactoredSrc = [ "./src/js/loader.js", "./src/js/mini-result-chart.js", "./src/js/sign-out-button.js", + "./src/js/layout-emulator.js", + "./src/js/version-popup.js", + "./src/js/support-popup.js", ]; //legacy files diff --git a/src/js/commandline.js b/src/js/commandline.js index 02e87c27a..ac2dca1f1 100644 --- a/src/js/commandline.js +++ b/src/js/commandline.js @@ -496,3 +496,8 @@ $(document).keydown((e) => { } } }); + +$(document).on("click", "#commandLineMobileButton", () => { + CommandlineLists.setCurrent(CommandlineLists.defaultCommands); + show(); +}); diff --git a/src/js/exports.js b/src/js/exports.js index c3dc504c0..6ab18a5af 100644 --- a/src/js/exports.js +++ b/src/js/exports.js @@ -3,7 +3,7 @@ //try to keep this list short because we need to eliminate it eventually global.simplePopups = simplePopups; global.sendVerificationEmail = Misc.sendVerificationEmail; -global.getuid = getuid; +global.getuid = Misc.getuid; //these exports are just for debugging in the browser global.snapshot = DB.getSnapshot; diff --git a/src/js/global-dependencies.js b/src/js/global-dependencies.js index 08e36cf28..2ac769495 100644 --- a/src/js/global-dependencies.js +++ b/src/js/global-dependencies.js @@ -50,3 +50,6 @@ import * as TestConfig from "./test-config"; import * as Loader from "./loader"; import * as MiniResultChart from "./mini-result-chart"; import * as SignOutButton from "./sign-out-button"; +import * as SupportPopup from "./support-popup"; +import * as VersionPopup from "./version-popup"; +import * as LayoutEmulator from "./layout-emulator"; diff --git a/src/js/layout-emulator.js b/src/js/layout-emulator.js new file mode 100644 index 000000000..4bd9d0be5 --- /dev/null +++ b/src/js/layout-emulator.js @@ -0,0 +1,105 @@ +import Config from "./config"; +import * as Misc from "./misc"; +import Layouts from "./layouts"; + +export function updateEvent(event) { + function emulatedLayoutShouldShiftKey(event, newKeyPreview) { + if (Config.capsLockBackspace) return event.shiftKey; + const isCapsLockHeld = event.originalEvent.getModifierState("CapsLock"); + if (isCapsLockHeld) + return Misc.isASCIILetter(newKeyPreview) !== event.shiftKey; + return event.shiftKey; + } + + function replaceEventKey(event, keyCode) { + const newKey = String.fromCharCode(keyCode); + event.keyCode = keyCode; + event.charCode = keyCode; + event.which = keyCode; + event.key = newKey; + event.code = "Key" + newKey.toUpperCase(); + } + + let newEvent = event; + + try { + if (Config.layout === "default") { + //override the caps lock modifier for the default layout if needed + if (Config.capsLockBackspace && Misc.isASCIILetter(newEvent.key)) { + replaceEventKey( + newEvent, + newEvent.shiftKey + ? newEvent.key.toUpperCase().charCodeAt(0) + : newEvent.key.toLowerCase().charCodeAt(0) + ); + } + return newEvent; + } + const keyEventCodes = [ + "Backquote", + "Digit1", + "Digit2", + "Digit3", + "Digit4", + "Digit5", + "Digit6", + "Digit7", + "Digit8", + "Digit9", + "Digit0", + "Minus", + "Equal", + "KeyQ", + "KeyW", + "KeyE", + "KeyR", + "KeyT", + "KeyY", + "KeyU", + "KeyI", + "KeyO", + "KeyP", + "BracketLeft", + "BracketRight", + "Backslash", + "KeyA", + "KeyS", + "KeyD", + "KeyF", + "KeyG", + "KeyH", + "KeyJ", + "KeyK", + "KeyL", + "Semicolon", + "Quote", + "IntlBackslash", + "KeyZ", + "KeyX", + "KeyC", + "KeyV", + "KeyB", + "KeyN", + "KeyM", + "Comma", + "Period", + "Slash", + "Space", + ]; + const layoutMap = Layouts[Config.layout].keys; + + let mapIndex; + for (let i = 0; i < keyEventCodes.length; i++) { + if (newEvent.code == keyEventCodes[i]) { + mapIndex = i; + } + } + const newKeyPreview = layoutMap[mapIndex][0]; + const shift = emulatedLayoutShouldShiftKey(newEvent, newKeyPreview) ? 1 : 0; + const newKey = layoutMap[mapIndex][shift]; + replaceEventKey(newEvent, newKey.charCodeAt(0)); + } catch (e) { + return event; + } + return newEvent; +} diff --git a/src/js/misc.js b/src/js/misc.js index 4a78bdbda..e72a9d9c7 100644 --- a/src/js/misc.js +++ b/src/js/misc.js @@ -1,5 +1,11 @@ import * as Loader from "./loader"; +export function getuid() { + console.error("Only share this uid with Miodec and nobody else!"); + console.log(firebase.auth().currentUser.uid); + console.error("Only share this uid with Miodec and nobody else!"); +} + function hexToHSL(H) { // Convert hex to RGB first let r = 0, diff --git a/src/js/script.js b/src/js/script.js index e69e786ed..c781dfae9 100644 --- a/src/js/script.js +++ b/src/js/script.js @@ -9,114 +9,6 @@ let verifyUserWhenLoggedIn = null; // let CustomText.isWordRandom = false; // let CustomText.word = 1; -function getuid() { - console.error("Only share this uid with Miodec and nobody else!"); - console.log(firebase.auth().currentUser.uid); - console.error("Only share this uid with Miodec and nobody else!"); -} - -function emulateLayout(event) { - function emulatedLayoutShouldShiftKey(event, newKeyPreview) { - if (Config.capsLockBackspace) return event.shiftKey; - const isCapsLockHeld = event.originalEvent.getModifierState("CapsLock"); - if (isCapsLockHeld) - return Misc.isASCIILetter(newKeyPreview) !== event.shiftKey; - return event.shiftKey; - } - - function replaceEventKey(event, keyCode) { - const newKey = String.fromCharCode(keyCode); - event.keyCode = keyCode; - event.charCode = keyCode; - event.which = keyCode; - event.key = newKey; - event.code = "Key" + newKey.toUpperCase(); - } - - let newEvent = event; - - try { - if (Config.layout === "default") { - //override the caps lock modifier for the default layout if needed - if (Config.capsLockBackspace && Misc.isASCIILetter(newEvent.key)) { - replaceEventKey( - newEvent, - newEvent.shiftKey - ? newEvent.key.toUpperCase().charCodeAt(0) - : newEvent.key.toLowerCase().charCodeAt(0) - ); - } - return newEvent; - } - const keyEventCodes = [ - "Backquote", - "Digit1", - "Digit2", - "Digit3", - "Digit4", - "Digit5", - "Digit6", - "Digit7", - "Digit8", - "Digit9", - "Digit0", - "Minus", - "Equal", - "KeyQ", - "KeyW", - "KeyE", - "KeyR", - "KeyT", - "KeyY", - "KeyU", - "KeyI", - "KeyO", - "KeyP", - "BracketLeft", - "BracketRight", - "Backslash", - "KeyA", - "KeyS", - "KeyD", - "KeyF", - "KeyG", - "KeyH", - "KeyJ", - "KeyK", - "KeyL", - "Semicolon", - "Quote", - "IntlBackslash", - "KeyZ", - "KeyX", - "KeyC", - "KeyV", - "KeyB", - "KeyN", - "KeyM", - "Comma", - "Period", - "Slash", - "Space", - ]; - const layoutMap = layouts[Config.layout].keys; - - let mapIndex; - for (let i = 0; i < keyEventCodes.length; i++) { - if (newEvent.code == keyEventCodes[i]) { - mapIndex = i; - } - } - const newKeyPreview = layoutMap[mapIndex][0]; - const shift = emulatedLayoutShouldShiftKey(newEvent, newKeyPreview) ? 1 : 0; - const newKey = layoutMap[mapIndex][shift]; - replaceEventKey(newEvent, newKey.charCodeAt(0)); - } catch (e) { - return event; - } - return newEvent; -} - (function (history) { var pushState = history.pushState; history.pushState = function (state) { @@ -127,51 +19,6 @@ function emulateLayout(event) { }; })(window.history); -function highlightBadWord(index, showError) { - if (!showError) return; - $($("#words .word")[index]).addClass("error"); -} - -function startTest() { - if (UI.pageTransition) { - return false; - } - if (!Config.dbConfigLoaded) { - UpdateConfig.setChangedBeforeDb(true); - } - try { - if (firebase.auth().currentUser != null) { - firebase.analytics().logEvent("testStarted"); - } else { - firebase.analytics().logEvent("testStartedNoLogin"); - } - } catch (e) { - console.log("Analytics unavailable"); - } - TestLogic.setActive(true); - TestStats.resetKeypressTimings(); - TimerProgress.restart(); - TimerProgress.show(); - $("#liveWpm").text("0"); - LiveWpm.show(); - LiveAcc.show(); - TimerProgress.update(TestTimer.time); - TestTimer.clear(); - - if (Funbox.active === "memory") { - Funbox.resetMemoryTimer(); - $("#wordsWrapper").addClass("hidden"); - } - - try { - if (Config.paceCaret !== "off") PaceCaret.start(); - } catch (e) {} - //use a recursive self-adjusting timer to avoid time drift - TestStats.setStart(performance.now()); - TestTimer.start(); - return true; -} - function changePage(page) { if (UI.pageTransition) { return; @@ -407,25 +254,6 @@ function tagsEdit() { } } -$(document).on("click", "#top .logo", (e) => { - changePage("test"); -}); - -$("#wordsWrapper").on("click", () => { - TestUI.focusWords(); -}); - -$(document).on("click", "#top #menu .icon-button", (e) => { - if ($(e.currentTarget).hasClass("discord")) return; - if ($(e.currentTarget).hasClass("leaderboards")) { - Leaderboards.show(); - } else { - const href = $(e.currentTarget).attr("href"); - ManualRestart.set(); - changePage(href.replace("/", "")); - } -}); - $(window).on("popstate", (e) => { let state = e.originalEvent.state; if (state == "" || state == "/") { @@ -443,190 +271,10 @@ $(window).on("popstate", (e) => { } }); -$(document).on("keypress", "#restartTestButton", (event) => { - if (event.keyCode == 13) { - if ( - TestLogic.active && - Config.repeatQuotes === "typing" && - Config.mode === "quote" - ) { - TestLogic.restart(true); - } else { - TestLogic.restart(); - } - } -}); - -$(document.body).on("click", "#restartTestButton", () => { - ManualRestart.set(); - if (TestUI.resultCalculating) return; - if ( - TestLogic.active && - Config.repeatQuotes === "typing" && - Config.mode === "quote" - ) { - TestLogic.restart(true); - } else { - TestLogic.restart(); - } -}); - -$(document).on("keypress", "#practiseMissedWordsButton", (event) => { - if (event.keyCode == 13) { - PractiseMissed.init(); - } -}); - -$(document.body).on("click", "#practiseMissedWordsButton", () => { - PractiseMissed.init(); -}); - -$(document).on("keypress", "#nextTestButton", (event) => { - if (event.keyCode == 13) { - TestLogic.restart(); - } -}); - -$(document.body).on("click", "#nextTestButton", () => { - ManualRestart.set(); - TestLogic.restart(); -}); - -$(document).on("keypress", "#showWordHistoryButton", (event) => { - if (event.keyCode == 13) { - TestUI.toggleResultWords(); - } -}); - -$(document.body).on("click", "#showWordHistoryButton", () => { - TestUI.toggleResultWords(); -}); - -$(document.body).on("click", "#restartTestButtonWithSameWordset", () => { - if (Config.mode == "zen") { - Notifications.add("Repeat test disabled in zen mode"); - return; - } - ManualRestart.set(); - TestLogic.restart(true); -}); - -$(document).on("keypress", "#restartTestButtonWithSameWordset", (event) => { - if (Config.mode == "zen") { - Notifications.add("Repeat test disabled in zen mode"); - return; - } - if (event.keyCode == 13) { - TestLogic.restart(true); - } -}); - -$(document.body).on("click", ".version", () => { - $("#versionHistoryWrapper") - .css("opacity", 0) - .removeClass("hidden") - .animate({ opacity: 1 }, 125); -}); - -$(document.body).on("click", "#versionHistoryWrapper", () => { - $("#versionHistoryWrapper") - .css("opacity", 1) - .animate({ opacity: 0 }, 125, () => { - $("#versionHistoryWrapper").addClass("hidden"); - }); -}); - -$(document.body).on("click", "#supportMeButton", () => { - $("#supportMeWrapper") - .css("opacity", 0) - .removeClass("hidden") - .animate({ opacity: 1 }, 125); -}); - -$(document.body).on("click", "#supportMeWrapper", () => { - $("#supportMeWrapper") - .css("opacity", 1) - .animate({ opacity: 0 }, 125, () => { - $("#supportMeWrapper").addClass("hidden"); - }); -}); - -$(document.body).on("click", "#supportMeWrapper .button.ads", () => { - CommandlineLists.pushCurrent(CommandlineLists.commandsEnableAds); - Commandline.show(); - $("#supportMeWrapper") - .css("opacity", 1) - .animate({ opacity: 0 }, 125, () => { - $("#supportMeWrapper").addClass("hidden"); - }); -}); - -$(document.body).on("click", "#supportMeWrapper a.button", () => { - $("#supportMeWrapper") - .css("opacity", 1) - .animate({ opacity: 0 }, 125, () => { - $("#supportMeWrapper").addClass("hidden"); - }); -}); - -$(document.body).on("click", ".pageAbout .aboutEnableAds", () => { - CommandlineLists.pushCurrent(CommandlineLists.commandsEnableAds); - Commandline.show(); -}); - $("#wordsInput").keypress((event) => { event.preventDefault(); }); -$("#wordsInput").on("focus", () => { - if (!TestUI.resultVisible && Config.showOutOfFocusWarning) { - OutOfFocus.hide(); - } - Caret.show(TestLogic.input.current); -}); - -$("#wordsInput").on("focusout", () => { - if (!TestUI.resultVisible && Config.showOutOfFocusWarning) { - OutOfFocus.show(); - } - Caret.hide(); -}); - -$(window).resize(() => { - Caret.updatePosition(); -}); - -$(document).mousemove(function (event) { - if ( - $("#top").hasClass("focus") && - (event.originalEvent.movementX > 0 || event.originalEvent.movementY > 0) - ) { - Focus.set(false); - } -}); - -$(document).on("click", "#testModesNotice .text-button", (event) => { - // console.log("CommandlineLists."+$(event.currentTarget).attr("commands")); - let commands = CommandlineLists.getList( - $(event.currentTarget).attr("commands") - ); - let func = $(event.currentTarget).attr("function"); - if (commands !== undefined) { - if ($(event.currentTarget).attr("commands") === "commandsTags") { - CommandlineLists.updateTagCommands(); - } - CommandlineLists.pushCurrent(commands); - Commandline.show(); - } else if (func != undefined) { - eval(func); - } -}); - -$(document).on("click", "#commandLineMobileButton", () => { - CommandlineLists.setCurrent(CommandlineLists.defaultCommands); - Commandline.show(); -}); - let dontInsertSpace = false; $(document).keyup((event) => { @@ -1030,7 +678,7 @@ function handleSpace(event, isEnter) { } if (Config.blindMode) $("#words .word.active letter").addClass("correct"); TestLogic.input.pushHistory(); - highlightBadWord(TestUI.currentWordElementIndex, !Config.blindMode); + TestUI.highlightBadWord(TestUI.currentWordElementIndex, !Config.blindMode); TestLogic.words.increaseCurrentIndex(); TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1); TestUI.updateActiveElement(); @@ -1214,7 +862,7 @@ function handleAlpha(event) { let originalEvent = event; - event = emulateLayout(event); + event = LayoutEmulator.updateEvent(event); //start the test if ( @@ -1222,7 +870,7 @@ function handleAlpha(event) { TestLogic.input.history.length == 0 && !TestLogic.active ) { - if (!startTest()) return; + if (!TestLogic.startTest()) return; } else { if (!TestLogic.active) return; } @@ -1463,52 +1111,6 @@ function handleAlpha(event) { Caret.updatePosition(); } -window.addEventListener("beforeunload", (event) => { - // Cancel the event as stated by the standard. - if ( - (Config.mode === "words" && Config.words < 1000) || - (Config.mode === "time" && Config.time < 3600) || - Config.mode === "quote" || - (Config.mode === "custom" && - CustomText.isWordRandom && - CustomText.word < 1000) || - (Config.mode === "custom" && - CustomText.isTimeRandom && - CustomText.time < 1000) || - (Config.mode === "custom" && - !CustomText.isWordRandom && - CustomText.text.length < 1000) - ) { - //ignore - } else { - if (TestLogic.active) { - event.preventDefault(); - // Chrome requires returnValue to be set. - event.returnValue = ""; - } - } -}); - -if (firebase.app().options.projectId === "monkey-type-dev-67af4") { - $("#top .logo .bottom").text("monkey-dev"); - $("head title").text("Monkey Dev"); - $("body").append( - `
DEV
DEV
` - ); -} - -if (window.location.hostname === "localhost") { - window.onerror = function (error) { - Notifications.add(error, -1); - }; - $("#top .logo .top").text("localhost"); - $("head title").text($("head title").text() + " (localhost)"); - firebase.functions().useFunctionsEmulator("http://localhost:5001"); - $("body").append( - `
local
local
` - ); -} - ManualRestart.set(); let configLoadDone; @@ -1520,43 +1122,6 @@ configLoadDone(); Misc.getReleasesFromGitHub(); // getPatreonNames(); -$(document).on("mouseenter", "#resultWordsHistory .words .word", (e) => { - if (TestUI.resultVisible) { - let input = $(e.currentTarget).attr("input"); - if (input != undefined) - $(e.currentTarget).append( - `
${input - .replace(/\t/g, "_") - .replace(/\n/g, "_")}
` - ); - } -}); - -$(document).on("click", "#bottom .leftright .right .current-theme", (e) => { - if (e.shiftKey) { - UpdateConfig.toggleCustomTheme(); - } else { - // if (Config.customTheme) { - // toggleCustomTheme(); - // } - CommandlineLists.setCurrent(CommandlineLists.themeCommands); - Commandline.show(); - } -}); - -$(document).on("click", ".keymap .r5 #KeySpace", (e) => { - CommandlineLists.setCurrent(CommandlineLists.commandsKeymapLayouts); - Commandline.show(); -}); - -$(document).on("mouseleave", "#resultWordsHistory .words .word", (e) => { - $(".wordInputAfter").remove(); -}); - -$("#wpmChart").on("mouseleave", (e) => { - $(".wordInputAfter").remove(); -}); - let mappedRoutes = { "/": "pageTest", "/login": "pageLogin", @@ -1616,46 +1181,17 @@ $(document).ready(() => { settingsFillPromise.then(updateSettingsPage); }); -$(".scrollToTopButton").click((event) => { - window.scrollTo(0, 0); +//TODO move after account is a module +$(document).on("click", "#top .logo", (e) => { + changePage("test"); }); -$(".merchBanner a").click((event) => { - $(".merchBanner").remove(); - Misc.setCookie("merchbannerclosed", true, 365); -}); - -$(".merchBanner .fas").click((event) => { - $(".merchBanner").remove(); - Misc.setCookie("merchbannerclosed", true, 365); - Notifications.add( - "Won't remind you anymore. Thanks for continued support <3", - 0, - 5 - ); -}); - -$(".pageTest #copyWordsListButton").click(async (event) => { - try { - let words; - if (Config.mode == "zen") { - words = TestLogic.input.history.join(" "); - } else { - words = TestLogic.words - .get() - .slice(0, TestLogic.input.history.length) - .join(" "); - } - await navigator.clipboard.writeText(words); - Notifications.add("Copied to clipboard", 0, 2); - } catch (e) { - Notifications.add("Could not copy to clipboard: " + e, -1); - } -}); - -//stop space scrolling -window.addEventListener("keydown", function (e) { - if (e.keyCode == 32 && e.target == document.body) { - e.preventDefault(); +$(document).on("click", "#top #menu .icon-button", (e) => { + if ($(e.currentTarget).hasClass("leaderboards")) { + Leaderboards.show(); + } else { + const href = $(e.currentTarget).attr("href"); + ManualRestart.set(); + changePage(href.replace("/", "")); } }); diff --git a/src/js/support-popup.js b/src/js/support-popup.js new file mode 100644 index 000000000..518ba1d62 --- /dev/null +++ b/src/js/support-popup.js @@ -0,0 +1,35 @@ +import * as Commandline from "./commandline"; +import * as CommandlineLists from "./commandline-lists"; + +$(document.body).on("click", "#supportMeButton", () => { + $("#supportMeWrapper") + .css("opacity", 0) + .removeClass("hidden") + .animate({ opacity: 1 }, 125); +}); + +$(document.body).on("click", "#supportMeWrapper", () => { + $("#supportMeWrapper") + .css("opacity", 1) + .animate({ opacity: 0 }, 125, () => { + $("#supportMeWrapper").addClass("hidden"); + }); +}); + +$(document.body).on("click", "#supportMeWrapper .button.ads", () => { + CommandlineLists.pushCurrent(CommandlineLists.commandsEnableAds); + Commandline.show(); + $("#supportMeWrapper") + .css("opacity", 1) + .animate({ opacity: 0 }, 125, () => { + $("#supportMeWrapper").addClass("hidden"); + }); +}); + +$(document.body).on("click", "#supportMeWrapper a.button", () => { + $("#supportMeWrapper") + .css("opacity", 1) + .animate({ opacity: 0 }, 125, () => { + $("#supportMeWrapper").addClass("hidden"); + }); +}); diff --git a/src/js/test/focus.js b/src/js/test/focus.js index 9502f7c4c..b7dc4f1bb 100644 --- a/src/js/test/focus.js +++ b/src/js/test/focus.js @@ -19,3 +19,12 @@ export function set(foc) { $("#middle").removeClass("focus"); } } + +$(document).mousemove(function (event) { + if ( + $("#top").hasClass("focus") && + (event.originalEvent.movementX > 0 || event.originalEvent.movementY > 0) + ) { + set(false); + } +}); diff --git a/src/js/test/keymap.js b/src/js/test/keymap.js index 94036e40e..0cad08015 100644 --- a/src/js/test/keymap.js +++ b/src/js/test/keymap.js @@ -1,6 +1,8 @@ import Config, * as UpdateConfig from "./config"; import * as ThemeColors from "./theme-colors"; import layouts from "./layouts"; +import * as CommandlineLists from "./commandline-lists"; +import * as Commandline from "./commandline"; export function highlightKey(currentKey) { if (Config.mode === "zen") return; @@ -242,3 +244,8 @@ export function refreshKeys(layout) { UpdateConfig.setKeymapLayout("qwerty", true); } } + +$(document).on("click", ".keymap .r5 #KeySpace", (e) => { + CommandlineLists.setCurrent(CommandlineLists.commandsKeymapLayouts); + Commandline.show(); +}); diff --git a/src/js/test/test-logic.js b/src/js/test/test-logic.js index 44a4ea1cc..db915a3cc 100644 --- a/src/js/test/test-logic.js +++ b/src/js/test/test-logic.js @@ -288,6 +288,46 @@ export function punctuateWord(previousWord, currentWord, index, maxindex) { return word; } +export function startTest() { + if (UI.pageTransition) { + return false; + } + if (!Config.dbConfigLoaded) { + UpdateConfig.setChangedBeforeDb(true); + } + try { + if (firebase.auth().currentUser != null) { + firebase.analytics().logEvent("testStarted"); + } else { + firebase.analytics().logEvent("testStartedNoLogin"); + } + } catch (e) { + console.log("Analytics unavailable"); + } + setActive(true); + TestStats.resetKeypressTimings(); + TimerProgress.restart(); + TimerProgress.show(); + $("#liveWpm").text("0"); + LiveWpm.show(); + LiveAcc.show(); + TimerProgress.update(TestTimer.time); + TestTimer.clear(); + + if (Funbox.active === "memory") { + Funbox.resetMemoryTimer(); + $("#wordsWrapper").addClass("hidden"); + } + + try { + if (Config.paceCaret !== "off") PaceCaret.start(); + } catch (e) {} + //use a recursive self-adjusting timer to avoid time drift + TestStats.setStart(performance.now()); + TestTimer.start(); + return true; +} + export async function init() { setActive(false); words.reset(); diff --git a/src/js/test/test-ui.js b/src/js/test/test-ui.js index b2a04dbe7..e844294c5 100644 --- a/src/js/test/test-ui.js +++ b/src/js/test/test-ui.js @@ -8,6 +8,11 @@ import * as PaceCaret from "./pace-caret"; import * as CustomText from "./custom-text"; import * as Keymap from "./keymap"; import * as Caret from "./caret"; +import * as CommandlineLists from "./commandline-lists"; +import * as Commandline from "./commandline"; +import * as OutOfFocus from "./out-of-focus"; +import * as ManualRestart from "./manual-restart-tracker"; +import * as PractiseMissed from "./practise-missed"; export let currentWordElementIndex = 0; export let resultVisible = false; @@ -747,6 +752,11 @@ export function toggleResultWords() { } } +export function highlightBadWord(index, showError) { + if (!showError) return; + $($("#words .word")[index]).addClass("error"); +} + $(document.body).on("click", "#copyResultToClipboardButton", () => { screenshot(); }); @@ -758,3 +768,154 @@ $(document).on("click", "#testModesNotice .text-button.restart", (event) => { $(document).on("click", "#testModesNotice .text-button.blind", (event) => { UpdateConfig.toggleBlindMode(); }); + +$(".pageTest #copyWordsListButton").click(async (event) => { + try { + let words; + if (Config.mode == "zen") { + words = TestLogic.input.history.join(" "); + } else { + words = TestLogic.words + .get() + .slice(0, TestLogic.input.history.length) + .join(" "); + } + await navigator.clipboard.writeText(words); + Notifications.add("Copied to clipboard", 0, 2); + } catch (e) { + Notifications.add("Could not copy to clipboard: " + e, -1); + } +}); + +$(document).on("mouseleave", "#resultWordsHistory .words .word", (e) => { + $(".wordInputAfter").remove(); +}); + +$("#wpmChart").on("mouseleave", (e) => { + $(".wordInputAfter").remove(); +}); + +$(document).on("mouseenter", "#resultWordsHistory .words .word", (e) => { + if (resultVisible) { + let input = $(e.currentTarget).attr("input"); + if (input != undefined) + $(e.currentTarget).append( + `
${input + .replace(/\t/g, "_") + .replace(/\n/g, "_")}
` + ); + } +}); + +$(document).on("click", "#testModesNotice .text-button", (event) => { + // console.log("CommandlineLists."+$(event.currentTarget).attr("commands")); + let commands = CommandlineLists.getList( + $(event.currentTarget).attr("commands") + ); + let func = $(event.currentTarget).attr("function"); + if (commands !== undefined) { + if ($(event.currentTarget).attr("commands") === "commandsTags") { + CommandlineLists.updateTagCommands(); + } + CommandlineLists.pushCurrent(commands); + Commandline.show(); + } else if (func != undefined) { + eval(func); + } +}); + +$("#wordsInput").on("focus", () => { + if (!resultVisible && Config.showOutOfFocusWarning) { + OutOfFocus.hide(); + } + Caret.show(TestLogic.input.current); +}); + +$("#wordsInput").on("focusout", () => { + if (!resultVisible && Config.showOutOfFocusWarning) { + OutOfFocus.show(); + } + Caret.hide(); +}); + +$(document).on("keypress", "#restartTestButton", (event) => { + if (event.keyCode == 13) { + if ( + TestLogic.active && + Config.repeatQuotes === "typing" && + Config.mode === "quote" + ) { + TestLogic.restart(true); + } else { + TestLogic.restart(); + } + } +}); + +$(document.body).on("click", "#restartTestButton", () => { + ManualRestart.set(); + if (resultCalculating) return; + if ( + TestLogic.active && + Config.repeatQuotes === "typing" && + Config.mode === "quote" + ) { + TestLogic.restart(true); + } else { + TestLogic.restart(); + } +}); + +$(document).on("keypress", "#practiseMissedWordsButton", (event) => { + if (event.keyCode == 13) { + PractiseMissed.init(); + } +}); + +$(document.body).on("click", "#practiseMissedWordsButton", () => { + PractiseMissed.init(); +}); + +$(document).on("keypress", "#nextTestButton", (event) => { + if (event.keyCode == 13) { + TestLogic.restart(); + } +}); + +$(document.body).on("click", "#nextTestButton", () => { + ManualRestart.set(); + TestLogic.restart(); +}); + +$(document).on("keypress", "#showWordHistoryButton", (event) => { + if (event.keyCode == 13) { + toggleResultWords(); + } +}); + +$(document.body).on("click", "#showWordHistoryButton", () => { + toggleResultWords(); +}); + +$(document.body).on("click", "#restartTestButtonWithSameWordset", () => { + if (Config.mode == "zen") { + Notifications.add("Repeat test disabled in zen mode"); + return; + } + ManualRestart.set(); + TestLogic.restart(true); +}); + +$(document).on("keypress", "#restartTestButtonWithSameWordset", (event) => { + if (Config.mode == "zen") { + Notifications.add("Repeat test disabled in zen mode"); + return; + } + if (event.keyCode == 13) { + TestLogic.restart(true); + } +}); + +$("#wordsWrapper").on("click", () => { + focusWords(); +}); diff --git a/src/js/ui.js b/src/js/ui.js index 22c487d6c..eae44a44e 100644 --- a/src/js/ui.js +++ b/src/js/ui.js @@ -1,4 +1,13 @@ -import Config from "./config"; +import Config, * as UpdateConfig from "./config"; +import * as Notifications from "./notification-center"; +import * as Leaderboards from "./leaderboards"; +import * as ManualRestart from "./manual-restart-tracker"; +import * as Misc from "./misc"; +import * as Caret from "./caret"; +import * as TestLogic from "./test-logic"; +import * as CustomText from "./custom-text"; +import * as CommandlineLists from "./commandline-lists"; +import * as Commandline from "./commandline"; export let pageTransition = false; @@ -91,3 +100,96 @@ export function swapElements( callback(); } } + +if (firebase.app().options.projectId === "monkey-type-dev-67af4") { + $("#top .logo .bottom").text("monkey-dev"); + $("head title").text("Monkey Dev"); + $("body").append( + `
DEV
DEV
` + ); +} + +if (window.location.hostname === "localhost") { + window.onerror = function (error) { + Notifications.add(error, -1); + }; + $("#top .logo .top").text("localhost"); + $("head title").text($("head title").text() + " (localhost)"); + firebase.functions().useFunctionsEmulator("http://localhost:5001"); + $("body").append( + `
local
local
` + ); +} + +//stop space scrolling +window.addEventListener("keydown", function (e) { + if (e.keyCode == 32 && e.target == document.body) { + e.preventDefault(); + } +}); + +$(".merchBanner a").click((event) => { + $(".merchBanner").remove(); + Misc.setCookie("merchbannerclosed", true, 365); +}); + +$(".merchBanner .fas").click((event) => { + $(".merchBanner").remove(); + Misc.setCookie("merchbannerclosed", true, 365); + Notifications.add( + "Won't remind you anymore. Thanks for continued support <3", + 0, + 5 + ); +}); + +$(".scrollToTopButton").click((event) => { + window.scrollTo(0, 0); +}); + +$(document).on("click", "#bottom .leftright .right .current-theme", (e) => { + if (e.shiftKey) { + UpdateConfig.toggleCustomTheme(); + } else { + // if (Config.customTheme) { + // toggleCustomTheme(); + // } + CommandlineLists.setCurrent(CommandlineLists.themeCommands); + Commandline.show(); + } +}); + +$(document.body).on("click", ".pageAbout .aboutEnableAds", () => { + CommandlineLists.pushCurrent(CommandlineLists.commandsEnableAds); + Commandline.show(); +}); + +window.addEventListener("beforeunload", (event) => { + // Cancel the event as stated by the standard. + if ( + (Config.mode === "words" && Config.words < 1000) || + (Config.mode === "time" && Config.time < 3600) || + Config.mode === "quote" || + (Config.mode === "custom" && + CustomText.isWordRandom && + CustomText.word < 1000) || + (Config.mode === "custom" && + CustomText.isTimeRandom && + CustomText.time < 1000) || + (Config.mode === "custom" && + !CustomText.isWordRandom && + CustomText.text.length < 1000) + ) { + //ignore + } else { + if (TestLogic.active) { + event.preventDefault(); + // Chrome requires returnValue to be set. + event.returnValue = ""; + } + } +}); + +$(window).resize(() => { + Caret.updatePosition(); +}); diff --git a/src/js/version-popup.js b/src/js/version-popup.js new file mode 100644 index 000000000..9508d103d --- /dev/null +++ b/src/js/version-popup.js @@ -0,0 +1,14 @@ +$(document.body).on("click", ".version", () => { + $("#versionHistoryWrapper") + .css("opacity", 0) + .removeClass("hidden") + .animate({ opacity: 1 }, 125); +}); + +$(document.body).on("click", "#versionHistoryWrapper", () => { + $("#versionHistoryWrapper") + .css("opacity", 1) + .animate({ opacity: 0 }, 125, () => { + $("#versionHistoryWrapper").addClass("hidden"); + }); +});