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 @@
@@ -936,7 +937,7 @@
1:00
60
-
+
Click the words to focus
@@ -1146,7 +1147,7 @@
-
+
@@ -2673,6 +2674,15 @@
Sign In
+
Returning Chrome Users
Please read me
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;