diff --git a/functions/index.js b/functions/index.js index f99a4685c..3f2b14472 100644 --- a/functions/index.js +++ b/functions/index.js @@ -828,7 +828,7 @@ exports.testCompleted = functions request.obj.name = name; //check keyspacing and duration here - if (obj.mode === "time" && obj.wpm > 130) { + if (obj.mode === "time" && obj.wpm > 130 && obj.testDuration < 122) { if (verified === false || verified === undefined) { if (keySpacing !== null && keyDuration !== null) { if ( diff --git a/public/css/style.scss b/public/css/style.scss index e677348df..d9b114419 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -474,12 +474,17 @@ a:hover { padding: 2rem; display: grid; gap: 1rem; - width: 300px; + width: 400px; .title { font-size: 1.5rem; color: var(--sub-color); } + + .tip{ + font-size: .75rem; + color: var(--sub-color); + } } } @@ -797,7 +802,7 @@ a:hover { #centerContent { max-width: 1000px; - min-width: 500px; + // min-width: 500px; margin: 0 auto; display: grid; grid-auto-flow: row; @@ -2699,7 +2704,7 @@ key { } } -@media only screen and (max-width: 1000px) { +@media only screen and (max-width: 1050px) { #centerContent { .pageSettings .section.themes .buttons, .pageSettings .section.language .buttons, @@ -2710,9 +2715,15 @@ key { .pageSettings .section.keymapStyle .buttons { grid-template-columns: 1fr 1fr 1fr; } + + #result .morestats { + gap: 1rem; + grid-template-rows: 1fr 1fr; + } } } + @media only screen and (max-width: 800px) { #centerContent { #top { @@ -2724,11 +2735,6 @@ key { } } - #result .morestats { - gap: 1rem; - grid-template-rows: 1fr 1fr; - } - #menu { gap: 0.5rem; font-size: 0.8rem; @@ -2777,6 +2783,48 @@ key { } } +@media only screen and (max-width: 600px) { +#middle{ + #result{ + grid-template-areas: + "stats stats" + "chart chart" + "morestats morestats"; + .stats{ + grid-template-areas: "wpm acc"; + gap: 4rem; + } + .stats.morestats{ + grid-template-rows: 1fr 1fr 1fr; + gap: 1rem; + } + } +} +} + +@media only screen and (max-width: 500px) { + #top{ + .logo{ + .bottom{ + font-size: 1.75rem; + line-height: 1.75rem; + margin-top: .5rem; + } + .top{ + display: none; + } + } + #menu{ + .icon-button{ + padding: 0; + } + } + } + #centerContent{ + padding: 1rem; + } +} + .keymap { display: grid; grid-template-rows: 1fr 1fr 1fr; diff --git a/public/index.html b/public/index.html index 67f7f1485..ccbc11a80 100644 --- a/public/index.html +++ b/public/index.html @@ -90,6 +90,7 @@
Test length
+
You can start an infinite test by inputting 0. Then, to stop the test, use the Bail Out feature (esc > Bail Out)
ok
@@ -936,7 +937,7 @@
60
-
+ @@ -1146,7 +1147,7 @@
-
+
diff --git a/public/js/commandline.js b/public/js/commandline.js index b8e57da32..a40a8b9af 100644 --- a/public/js/commandline.js +++ b/public/js/commandline.js @@ -519,8 +519,8 @@ let commands = { (config.mode === "custom" && !customTextIsRandom && customText.length >= 5000) || - (config.mode === "words" && config.words >= 5000) || - (config.mode === "time" && config.time >= 3600) + (config.mode === "words" && config.words >= 5000 || config.words === 0) || + (config.mode === "time" && (config.time >= 3600 || config.time === 0)) ) { bailout = true; showResult(); @@ -1042,6 +1042,14 @@ let commandsWordCount = { let commandsQuoteLengthConfig = { title: "Change quote length...", list: [ + { + id: "changeQuoteLengthAll", + display: "all", + exec: () => { + changeQuoteLength(-1); + restartTest(); + }, + }, { id: "changeQuoteLengthShort", display: "short", @@ -1261,6 +1269,19 @@ let commandsTags = { function updateCommandsTagsList() { if (dbSnapshot.tags.length > 0) { commandsTags.list = []; + + commandsTags.list.push({ + id: "clearTags", + display: 'Clear tags', + exec: () => { + dbSnapshot.tags.forEach((tag) => { + tag.active = false; + }); + updateTestModesNotice(); + saveActiveTagsToCookie(); + }, + }); + dbSnapshot.tags.forEach((tag) => { let dis = tag.name; @@ -1284,9 +1305,16 @@ function updateCommandsTagsList() { } else { txt = '' + txt; } - $( - `#commandLine .suggestions .entry[command='toggleTag${tag.id}']` - ).html(txt); + if (isSingleListCommandLineActive()) { + $( + `#commandLine .suggestions .entry[command='toggleTag${tag.id}']` + ).html('Change tags > ' + txt); + } else { + $( + `#commandLine .suggestions .entry[command='toggleTag${tag.id}']` + ).html(txt); + } + }, }); }); @@ -1482,7 +1510,7 @@ $(document).ready((e) => { } setFontFamily(config.fontFamily, true); if (config.customTheme === true) { - setCustomTheme(); + applyCustomThemeColors(); } else { setTheme(config.theme); @@ -1542,8 +1570,12 @@ $("#commandLineWrapper #commandLine .suggestions").click((e) => { $("#commandLineWrapper").click((e) => { if ($(e.target).attr("id") === "commandLineWrapper") { hideCommandLine(); - setTheme(config.theme, true); setFontFamily(config.fontFamily, true); + if (config.customTheme === true) { + applyCustomThemeColors(); + } else { + setTheme(config.theme, true); + } } }); @@ -1711,8 +1743,17 @@ function showCommandInput(command, placeholder) { } function updateSuggestedCommands() { - let inputVal = $("#commandLine input").val().toLowerCase().split(" ").filter((s,i) => s||i==0); //remove empty entries after first + let inputVal = $("#commandLine input").val().toLowerCase().split(" ").filter((s, i) => s || i == 0); //remove empty entries after first let list = currentCommands[currentCommands.length - 1]; + if (inputVal[0] === "" + && config.singleListCommandLine === "on" + && currentCommands.length === 1) { + $.each(list.list, (index, obj) => { + obj.found = false; + }); + displayFoundCommands(); + return; + } //ignore the preceeding ">"s in the command line input if (inputVal[0] && inputVal[0][0] == ">") inputVal[0] = inputVal[0].replace(/^>+/,''); if (inputVal[0] == "" && inputVal.length == 1) { diff --git a/public/js/script.js b/public/js/script.js index 9df2e2678..c175cac25 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -247,6 +247,7 @@ function copyResultToClipboard() { var sourceWidth = src.width(); /*clientWidth/offsetWidth from div#target*/ var sourceHeight = src.height(); /*clientHeight/offsetHeight from div#target*/ $(".notification").addClass("hidden"); + $('.pageTest .loginTip').addClass('hidden'); try { html2canvas(document.body, { backgroundColor: themeColors.bg, @@ -271,12 +272,14 @@ function copyResultToClipboard() { showNotification("Copied to clipboard", 1000); $(".pageTest .ssWatermark").addClass("hidden"); $(".pageTest .buttons").removeClass("hidden"); + $('.pageTest .loginTip').removeClass('hidden'); }) .catch((f) => { $(".notification").removeClass("hidden"); showNotification("Error saving image to clipboard", 2000); $(".pageTest .ssWatermark").addClass("hidden"); $(".pageTest .buttons").removeClass("hidden"); + $('.pageTest .loginTip').removeClass('hidden'); }); }); }); @@ -285,6 +288,7 @@ function copyResultToClipboard() { showNotification("Error creating image", 2000); $(".pageTest .ssWatermark").addClass("hidden"); $(".pageTest .buttons").removeClass("hidden"); + $('.pageTest .loginTip').removeClass('hidden'); } } } @@ -467,6 +471,9 @@ function initWords() { wordsBound = customText.length; } } + if (config.mode === "words" && config.words === 0) { + wordsBound = 100; + } if (activeFunBox === "plus_one") { wordsBound = 2; } @@ -719,14 +726,14 @@ function addWord() { let bound = 100; if (activeFunBox === "plus_one") bound = 1; if ( - (wordsList.length - inputHistory.length > bound || - (config.mode === "words" && wordsList.length >= config.words) || + wordsList.length - inputHistory.length > bound || + (config.mode === "words" && wordsList.length >= config.words && config.words > 0) || (config.mode === "custom" && customTextIsRandom && wordsList.length >= customTextWordCount) || (config.mode === "custom" && !customTextIsRandom && - wordsList.length >= customText.length)) + wordsList.length >= customText.length) ) return; const language = @@ -833,11 +840,6 @@ function showWords() { $(".outOfFocusWarning").css("line-height", wordHeight * 3 + "px"); } - var currentKey = wordsList[currentWordIndex] - .substring(currentInput.length, currentInput.length + 1) - .toString() - .toUpperCase(); - if (config.keymapMode === "next") { updateHighlightedKeymapKey(); } @@ -1131,10 +1133,16 @@ function updateTimer() { // } // } let displayTime = secondsToString(config.time - time); + if (config.time === 0) { + displayTime = secondsToString(time); + } $("#timerNumber").html("
" + displayTime + "
"); // $("#timerNumber").html(config.time - time); } else if (config.timerStyle === "mini") { let displayTime = secondsToString(config.time - time); + if (config.time === 0) { + displayTime = secondsToString(time); + } $("#miniTimerAndLiveWpm .time").html(displayTime); } } else if ( @@ -1175,9 +1183,15 @@ function updateTimer() { outof = customText.length; } } - $("#timerNumber").html( - "
" + `${inputHistory.length}/${outof}` + "
" - ); + if (config.words === 0) { + $("#timerNumber").html( + "
" + `${inputHistory.length}` + "
" + ); + } else { + $("#timerNumber").html( + "
" + `${inputHistory.length}/${outof}` + "
" + ); + } // $("#timerNumber").html(config.time - time); } else if (config.timerStyle === "mini") { let outof = wordsList.length; @@ -1191,7 +1205,11 @@ function updateTimer() { outof = customText.length; } } - $("#miniTimerAndLiveWpm .time").html(`${inputHistory.length}/${outof}`); + if (config.words === 0) { + $("#miniTimerAndLiveWpm .time").html(`${inputHistory.length}`); + } else { + $("#miniTimerAndLiveWpm .time").html(`${inputHistory.length}/${outof}`); + } } } } @@ -2553,7 +2571,7 @@ function startTest() { // afkDetected = true; // } if (config.mode == "time") { - if (time >= config.time) { + if (time >= config.time && config.time !== 0) { //times up clearTimeout(timer); hideCaret(); @@ -2573,8 +2591,8 @@ function startTest() { function restartTest(withSameWordset = false, nosave = false) { if (!manualRestart) { if ( - (config.mode === "words" && config.words < 1000) || - (config.mode === "time" && config.time < 3600) || + (config.mode === "words" && config.words < 1000 && config.words > 0) || + (config.mode === "time" && config.time < 3600 && config.time > 0) || config.mode === "quote" || (config.mode === "custom" && customTextIsRandom && @@ -2592,7 +2610,7 @@ function restartTest(withSameWordset = false, nosave = false) { } } - if (modeBeforePractise !== null) { + if (modeBeforePractise !== null && !withSameWordset) { showNotification("Reverting to previous settings.", 1500); changeMode(modeBeforePractise); modeBeforePractise = null; @@ -2900,6 +2918,8 @@ function changeMode(mode, nosave) { $("#top .config .punctuationMode").addClass("hidden"); $("#top .config .numbersMode").addClass("hidden"); $("#top .config .quoteLength").addClass("hidden"); + setPunctuation(false, true); + setNumbers(false, true); } else if (config.mode == "quote") { setToggleSettings(false, nosave); $("#top .config .wordCount").addClass("hidden"); @@ -4025,23 +4045,27 @@ function applyMode2Popup() { let val = $("#customMode2Popup input").val(); if (mode == "time") { - if (val !== null && !isNaN(val) && val > 0) { + if (val !== null && !isNaN(val) && val >= 0) { changeTimeConfig(val); manualRestart = true; restartTest(); if (val >= 1800) { showNotification("Stay safe and take breaks!", 3000); + } else if (val == 0) { + showNotification("Infinite time! Make sure to use Bail Out from the command line to save your result.", 5000); } } else { showNotification("Custom time must be at least 1", 3000); } } else if (mode == "words") { - if (val !== null && !isNaN(val) && val > 0) { + if (val !== null && !isNaN(val) && val >= 0) { changeWordCount(val); manualRestart = true; restartTest(); if (val > 2000) { showNotification("Stay safe and take breaks!", 3000); + } else if (val == 0) { + showNotification("Infinite words! Make sure to use Bail Out from the command line to save your result.", 5000); } } else { showNotification("Custom word amount must be at least 1", 3000); @@ -4478,6 +4502,7 @@ $(document).keydown((event) => { }); $(document).keyup((event) => { + if (resultVisible) return; let now = performance.now(); let diff = Math.abs(keypressStats.duration.current - now); if (keypressStats.duration.current !== -1) { @@ -4510,6 +4535,7 @@ window.addEventListener("beforeunload", (event) => { //handle keyboard events $(document).keydown((event) => { + if (resultVisible) return; let now = performance.now(); let diff = Math.abs(keypressStats.spacing.current - now); if (keypressStats.spacing.current !== -1) { @@ -4896,7 +4922,7 @@ $(document).on("click", "#bottom .leftright .right .current-theme", (e) => { if (config.customTheme) { togglePresetCustomTheme(); } - currentCommands = [commandsThemes]; + currentCommands.push(commandsThemes); showCommandLine(); }); @@ -4973,6 +4999,13 @@ $(".pageTest #copyWordsListButton").click(async (event) => { } }); +//stop space scrolling +window.addEventListener('keydown', function(e) { + if(e.keyCode == 32 && e.target == document.body) { + e.preventDefault(); + } +}); + let ctx = $("#wpmChart"); let wpmOverTimeChart = new Chart(ctx, { type: "line", diff --git a/public/js/userconfig.js b/public/js/userconfig.js index 1883e3db1..133d8285e 100644 --- a/public/js/userconfig.js +++ b/public/js/userconfig.js @@ -683,7 +683,7 @@ function toggleKeyTips() { //mode function changeTimeConfig(time, nosave) { - if (time !== null && !isNaN(time) && time > 0) { + if (time !== null && !isNaN(time) && time >= 0) { } else { time = 15; } @@ -717,7 +717,7 @@ function changeQuoteLength(len, nosave) { } function changeWordCount(wordCount, nosave) { - if (wordCount !== null && !isNaN(wordCount) && wordCount > 0) { + if (wordCount !== null && !isNaN(wordCount) && wordCount >= 0) { } else { wordCount = 10; } @@ -955,6 +955,8 @@ function setTheme(name, nosave) { } catch (e) { console.log("Analytics unavailable"); } + setCustomTheme(false, true); + applyCustomThemeColors(); setTimeout(() => { $(".keymap-key").attr("style", ""); refreshThemeColorObject(); diff --git a/public/themes/alduin.css b/public/themes/alduin.css new file mode 100644 index 000000000..5bec62562 --- /dev/null +++ b/public/themes/alduin.css @@ -0,0 +1,11 @@ +:root { + --bg-color: #1c1c1c; + --main-color: #dfd7af; + --caret-color: #e3e3e3; + --sub-color: #444444; + --text-color: #f5f3ed; + --error-color: #af5f5f; + --error-extra-color: #4d2113; + --colorful-error-color: #af5f5f; + --colorful-error-extra-color: #4d2113; +} diff --git a/public/themes/light.css b/public/themes/light.css deleted file mode 100644 index cd7045541..000000000 --- a/public/themes/light.css +++ /dev/null @@ -1,11 +0,0 @@ -:root { - --bg-color: #fff; - --main-color: #111; - --caret-color: #111; - --sub-color: #ccc; - --text-color: #111; - --error-color: #da3333; - --error-extra-color: #791717; - --colorful-error-color: #da3333; - --colorful-error-extra-color: #791717; -} diff --git a/public/themes/list.json b/public/themes/list.json index 752552592..d43ed32f4 100644 --- a/public/themes/list.json +++ b/public/themes/list.json @@ -1,9 +1,4 @@ [ - { - "name": "light", - "bgColor": "#fff", - "textColor": "#111" - }, { "name": "dark", "bgColor": "#111", @@ -398,5 +393,15 @@ "name": "pastel", "bgColor": "#ffd1dc", "textColor": "#b39eb5" + }, + { + "name": "alduin", + "bgColor": "#1c1c1c", + "textColor": "#dfd7af" + }, + { + "name": "paper", + "bgColor": "#eeeeee", + "textColor": "#444444" } ] diff --git a/public/themes/mashu.css b/public/themes/mashu.css index 3d0720504..67fd40b87 100644 --- a/public/themes/mashu.css +++ b/public/themes/mashu.css @@ -3,9 +3,9 @@ --main-color: #76689a; --caret-color: #76689a; --sub-color: #d8a0a6; - --text-color: #d8a0a6; - --error-color: #d8a0a6; - --error-extra-color: #e9e0d2; - --colorful-error-color: #e9e0d2; - --colorful-error-extra-color: #e9e0d2; + --text-color: #f1e2e4; + --error-color: #d44729; + --error-extra-color: #8f2f19; + --colorful-error-color: #d44729; + --colorful-error-extra-color: #8f2f19; } diff --git a/public/themes/paper.css b/public/themes/paper.css new file mode 100644 index 000000000..83b167650 --- /dev/null +++ b/public/themes/paper.css @@ -0,0 +1,11 @@ +:root { + --bg-color: #eeeeee; + --main-color: #444444; + --caret-color: #444444; + --sub-color: #b2b2b2; + --text-color: #444444; + --error-color: #d70000; + --error-extra-color: #d70000; + --colorful-error-color: #d70000; + --colorful-error-extra-color: #d70000; +} diff --git a/public/themes/solarized_light.css b/public/themes/solarized_light.css index 4f2a5a851..cae62cfb9 100644 --- a/public/themes/solarized_light.css +++ b/public/themes/solarized_light.css @@ -3,7 +3,7 @@ --main-color: #859900; --caret-color: #dc322f; --sub-color: #2aa198; - --text-color: #268bd2; + --text-color: #181819; --error-color: #d33682; --error-extra-color: #9b225c; --colorful-error-color: #d33682;