mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 07:16:17 +08:00
added db connection,
new highscore display
This commit is contained in:
parent
f2e5a2b5fa
commit
99ce95dfac
|
@ -9,12 +9,11 @@
|
|||
"**/.*",
|
||||
"**/node_modules/**"
|
||||
],
|
||||
"redirects": [{
|
||||
"source": "/",
|
||||
"destination": "/app",
|
||||
"type": 301
|
||||
}],
|
||||
"rewrites": [{
|
||||
"source": "/app",
|
||||
"destination": "/"
|
||||
},
|
||||
{
|
||||
"source": "/**",
|
||||
"destination": "/app"
|
||||
}],
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
<div class="page pageAbout hidden">
|
||||
this is the about page
|
||||
</div>
|
||||
<div class="page pageAccount hidden">
|
||||
<div class="page pageLogin hidden">
|
||||
<div class="register">
|
||||
register
|
||||
<input type="text" placeholder="name">
|
||||
|
@ -182,7 +182,12 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div class="page pageAccount hidden">
|
||||
account page
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bottom">
|
||||
<key>tab</key> and <key>enter</key> / <key>space</key> - restart test<br>
|
||||
<key>esc</key> - command line
|
||||
|
@ -199,15 +204,20 @@
|
|||
https://firebase.google.com/docs/web/setup#available-libraries -->
|
||||
<script src="/__/firebase/7.14.3/firebase-analytics.js"></script>
|
||||
<script src="/__/firebase/7.14.3/firebase-auth.js"></script>
|
||||
<script src="/__/firebase/7.14.2/firebase-firestore.js"></script>
|
||||
|
||||
|
||||
<!-- Initialize Firebase -->
|
||||
<script src="/__/firebase/init.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
|
||||
<script src="js/db.js"></script>
|
||||
<script src="js/commandline.js"></script>
|
||||
<script src="js/words.js"></script>
|
||||
<script src="js/script.js"></script>
|
||||
<script src="js/account.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ a:hover {
|
|||
font-size: 1rem;
|
||||
font-family: "Roboto Mono";
|
||||
width: 100%;
|
||||
border-radius: var(--roundness);
|
||||
}
|
||||
|
||||
#commandLineWrapper #commandLine .separator {
|
||||
|
@ -218,6 +219,7 @@ a:hover {
|
|||
-webkit-animation-duration: 1s;
|
||||
animation-duration: 1s;
|
||||
position: absolute;
|
||||
border-radius: var(--roundness);
|
||||
}
|
||||
|
||||
@-webkit-keyframes caretFlash {
|
||||
|
@ -579,6 +581,25 @@ key {
|
|||
#result .stats .wpm .top {
|
||||
font-size: 3rem;
|
||||
line-height: 3rem;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#result .stats .wpm .top .crown {
|
||||
font-size: .7rem;
|
||||
line-height: 1.7rem;
|
||||
background: var(--sub-color);
|
||||
color: var(--main-color);
|
||||
border-radius: .6rem;
|
||||
text-align: center;
|
||||
-ms-flex-item-align: center;
|
||||
-ms-grid-row-align: center;
|
||||
align-self: center;
|
||||
margin-left: .5rem;
|
||||
width: 1.7rem;
|
||||
height: 1.7rem;
|
||||
margin-top: .6rem;
|
||||
}
|
||||
|
||||
#result .stats .wpm .bottom {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -59,6 +59,7 @@ a:hover {
|
|||
font-size: 1rem;
|
||||
font-family: "Roboto Mono";
|
||||
width: 100%;
|
||||
border-radius: var(--roundness);
|
||||
}
|
||||
.separator {
|
||||
background: black;
|
||||
|
@ -195,6 +196,7 @@ a:hover {
|
|||
animation-iteration-count: infinite;
|
||||
animation-duration: 1s;
|
||||
position: absolute;
|
||||
border-radius: var(--roundness);
|
||||
// transition: 0.05s;
|
||||
}
|
||||
|
||||
|
@ -485,6 +487,20 @@ key {
|
|||
.top{
|
||||
font-size: 3rem;
|
||||
line-height: 3rem;
|
||||
display: flex;
|
||||
.crown{
|
||||
font-size: .7rem;
|
||||
line-height: 1.7rem;
|
||||
background: var(--sub-color);
|
||||
color: var(--main-color);
|
||||
border-radius: .6rem;
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
margin-left: .5rem;
|
||||
width: 1.7rem;
|
||||
height: 1.7rem;
|
||||
margin-top: .6rem;
|
||||
}
|
||||
}
|
||||
.bottom{
|
||||
font-size: 4rem;
|
||||
|
|
|
@ -34,6 +34,30 @@ $(".pageAccount .register input").keyup(e => {
|
|||
}
|
||||
})
|
||||
|
||||
$(".pageLogin .login input").keyup(e => {
|
||||
if (e.key == "Enter") {
|
||||
|
||||
let email = $(".pageLogin .login input")[0].value;
|
||||
let password = $(".pageLogin .login input")[1].value;
|
||||
|
||||
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
|
||||
alert(error.message);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
function signOut() {
|
||||
firebase.auth().signOut().then(function() {
|
||||
alert('signed out');
|
||||
}).catch(function(error) {
|
||||
alert(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
firebase.auth().onAuthStateChanged(function(user) {
|
||||
if (user) {
|
||||
// User is signed in.
|
||||
|
|
307
public/js/commandline.js
Normal file
307
public/js/commandline.js
Normal file
|
@ -0,0 +1,307 @@
|
|||
let commands = {
|
||||
title: "",
|
||||
list: [
|
||||
{
|
||||
id: "togglePunctuation",
|
||||
display: "Toggle punctuation",
|
||||
exec: () => {
|
||||
togglePunctuation();
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "toggleSmoothCaret",
|
||||
display: "Toggle smooth caret",
|
||||
exec: () => {
|
||||
toggleSmoothCaret();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "toggleQuickTab",
|
||||
display: "Toggle quick tab mode",
|
||||
exec: () => {
|
||||
toggleQuickTabMode();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeMode",
|
||||
display: "Change mode...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsMode;
|
||||
showCommandLine();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig",
|
||||
display: "Change time config...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsTimeConfig;
|
||||
showCommandLine();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount",
|
||||
display: "Change word count...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsWordCount;
|
||||
showCommandLine();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let commandsWordCount = {
|
||||
title: "Change word count...",
|
||||
list: [
|
||||
{
|
||||
id: "changeWordCount10",
|
||||
display: "10",
|
||||
exec: () => {
|
||||
changeWordCount("10");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount25",
|
||||
display: "25",
|
||||
exec: () => {
|
||||
changeWordCount("25");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount50",
|
||||
display: "50",
|
||||
exec: () => {
|
||||
changeWordCount("50");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount100",
|
||||
display: "100",
|
||||
exec: () => {
|
||||
changeWordCount("100");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount200",
|
||||
display: "200",
|
||||
exec: () => {
|
||||
changeWordCount("200");
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
let commandsMode = {
|
||||
title: "Change mode...",
|
||||
list: [
|
||||
{
|
||||
id: "changeModeTime",
|
||||
display: "time",
|
||||
exec: () => {
|
||||
changeMode("time");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeModeWords",
|
||||
display: "words",
|
||||
exec: () => {
|
||||
changeMode("words");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeModeCustom",
|
||||
display: "custom",
|
||||
exec: () => {
|
||||
changeMode("custom");
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
let commandsTimeConfig = {
|
||||
title: "Change time config...",
|
||||
list: [
|
||||
{
|
||||
id: "changeTimeConfig15",
|
||||
display: "15",
|
||||
exec: () => {
|
||||
changeTimeConfig("15");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig30",
|
||||
display: "30",
|
||||
exec: () => {
|
||||
changeTimeConfig("30");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig60",
|
||||
display: "60",
|
||||
exec: () => {
|
||||
changeTimeConfig("60");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig120",
|
||||
display: "120",
|
||||
exec: () => {
|
||||
changeTimeConfig("120");
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
$("#commandLine input").keyup((e) => {
|
||||
if (e.keyCode == 38 || e.keyCode == 40) return;
|
||||
updateSuggestedCommands();
|
||||
});
|
||||
|
||||
|
||||
$("#commandLine input").keydown((e) => {
|
||||
if (e.keyCode == 13) {
|
||||
//enter
|
||||
e.preventDefault();
|
||||
let command = $(".suggestions .entry.active").attr("command");
|
||||
let subgroup = false;
|
||||
$.each(currentCommands.list, (i, obj) => {
|
||||
if (obj.id == command) {
|
||||
obj.exec();
|
||||
subgroup = obj.subgroup;
|
||||
}
|
||||
});
|
||||
if (!subgroup) hideCommandLine();
|
||||
return;
|
||||
}
|
||||
if (e.keyCode == 38 || e.keyCode == 40) {
|
||||
//up
|
||||
let entries = $(".suggestions .entry");
|
||||
let activenum = -1;
|
||||
$.each(entries, (index, obj) => {
|
||||
if ($(obj).hasClass("active")) activenum = index;
|
||||
});
|
||||
if (e.keyCode == 38) {
|
||||
entries.removeClass("active");
|
||||
if (activenum == 0) {
|
||||
$(entries[entries.length - 1]).addClass("active");
|
||||
} else {
|
||||
$(entries[--activenum]).addClass("active");
|
||||
}
|
||||
}
|
||||
if (e.keyCode == 40) {
|
||||
entries.removeClass("active");
|
||||
if (activenum + 1 == entries.length) {
|
||||
$(entries[0]).addClass("active");
|
||||
} else {
|
||||
$(entries[++activenum]).addClass("active");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
function hideCommandLine() {
|
||||
$("#commandLineWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 1)
|
||||
.animate(
|
||||
{
|
||||
opacity: 0
|
||||
},
|
||||
100,
|
||||
() => {
|
||||
$("#commandLineWrapper").addClass("hidden");
|
||||
}
|
||||
);
|
||||
focusWords();
|
||||
}
|
||||
|
||||
function showCommandLine() {
|
||||
if ($("#commandLineWrapper").hasClass("hidden")) {
|
||||
$("#commandLineWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 0)
|
||||
.removeClass("hidden")
|
||||
.animate(
|
||||
{
|
||||
opacity: 1
|
||||
},
|
||||
100
|
||||
);
|
||||
}
|
||||
$("#commandLine input").val("");
|
||||
updateSuggestedCommands();
|
||||
$("#commandLine input").focus();
|
||||
}
|
||||
|
||||
function updateSuggestedCommands() {
|
||||
let inputVal = $("#commandLine input").val().toLowerCase().split(" ");
|
||||
if (inputVal[0] == "") {
|
||||
$.each(currentCommands.list, (index, obj) => {
|
||||
obj.found = true;
|
||||
});
|
||||
} else {
|
||||
$.each(currentCommands.list, (index, obj) => {
|
||||
let foundcount = 0;
|
||||
$.each(inputVal, (index2, obj2) => {
|
||||
if (obj2 == "") return;
|
||||
let re = new RegExp(obj2, "g");
|
||||
let res = obj.display.toLowerCase().match(re);
|
||||
if (res != null && res.length > 0) {
|
||||
foundcount++;
|
||||
} else {
|
||||
foundcount--;
|
||||
}
|
||||
});
|
||||
if (foundcount > 0) {
|
||||
obj.found = true;
|
||||
} else {
|
||||
obj.found = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
displayFoundCommands();
|
||||
}
|
||||
|
||||
function displayFoundCommands() {
|
||||
$("#commandLine .suggestions").empty();
|
||||
$.each(currentCommands.list, (index, obj) => {
|
||||
if (obj.found) {
|
||||
$("#commandLine .suggestions").append(
|
||||
'<div class="entry" command="' + obj.id + '">' + obj.display + "</div>"
|
||||
);
|
||||
}
|
||||
});
|
||||
if ($("#commandLine .suggestions .entry").length == 0) {
|
||||
$("#commandLine .separator").css({ height: 0, margin: 0 });
|
||||
} else {
|
||||
$("#commandLine .separator").css({
|
||||
height: "1px",
|
||||
"margin-bottom": ".5rem"
|
||||
});
|
||||
}
|
||||
let entries = $("#commandLine .suggestions .entry");
|
||||
if (entries.length > 0) {
|
||||
$(entries[0]).addClass("active");
|
||||
}
|
||||
$("#commandLine .listTitle").remove();
|
||||
// if(currentCommands.title != ''){
|
||||
// $("#commandLine .suggestions").before("<div class='listTitle'>"+currentCommands.title+"</div>");
|
||||
// }
|
||||
}
|
55
public/js/db.js
Normal file
55
public/js/db.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
const db = firebase.firestore();
|
||||
|
||||
function db_testCompleted(wpm, correctChars, incorrectChars, acc, mode, mode2) {
|
||||
|
||||
if (wpm > 250 || acc < 50 || acc > 100) return false;
|
||||
|
||||
let uid = "";
|
||||
let user = firebase.auth().currentUser;
|
||||
if (user) {
|
||||
uid = user.uid;
|
||||
}
|
||||
db.collection('results').add({
|
||||
uid: uid,
|
||||
wpm: wpm,
|
||||
correctChars: correctChars,
|
||||
incorrectChars: incorrectChars,
|
||||
acc: acc,
|
||||
mode: mode,
|
||||
mode2: mode2,
|
||||
timestamp: Date.now()
|
||||
})
|
||||
}
|
||||
|
||||
async function db_getUserResults() {
|
||||
let user = firebase.auth().currentUser;
|
||||
if (user == null) return false;
|
||||
let ret = [];
|
||||
await db.collection('results').where('uid', '==', user.uid).get().then(data => {
|
||||
|
||||
data.docs.forEach(doc => {
|
||||
ret.push(doc.data());
|
||||
})
|
||||
})
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
async function db_getUserHighestWpm(mode, mode2) {
|
||||
let user = firebase.auth().currentUser;
|
||||
if (user == null) return false;
|
||||
let ret = {};
|
||||
await db.collection('results')
|
||||
.where('uid', '==', user.uid)
|
||||
.where('mode', '==', mode)
|
||||
.where('mode2', '==', mode2)
|
||||
.orderBy('wpm', "desc")
|
||||
.limit(1)
|
||||
.get().then(data => {
|
||||
ret = data.docs[0].data()
|
||||
}).catch(e => {
|
||||
ret = false;
|
||||
})
|
||||
return ret;
|
||||
|
||||
}
|
|
@ -2,19 +2,22 @@ let wordsList = [];
|
|||
let currentWordIndex = 0;
|
||||
let inputHistory = [];
|
||||
let currentInput = "";
|
||||
let wordsConfig = 100;
|
||||
let timeConfig = 30;
|
||||
let time = 0;
|
||||
let timer = null;
|
||||
let testActive = false;
|
||||
let testMode = "words";
|
||||
let testStart, testEnd;
|
||||
let missedChars = 0;
|
||||
let punctuationMode = true;
|
||||
let wpmHistory = [];
|
||||
let currentCommands = commands;
|
||||
|
||||
|
||||
let quickTabMode = true;
|
||||
let config = {
|
||||
smoothCaret: true,
|
||||
quickTab: true,
|
||||
punctuation: true,
|
||||
words: 100,
|
||||
time: 30,
|
||||
mode: "words"
|
||||
}
|
||||
|
||||
let customText = "The quick brown fox jumps over the lazy dog";
|
||||
|
||||
|
@ -55,9 +58,9 @@ function initWords() {
|
|||
missedChars = 0;
|
||||
inputHistory = [];
|
||||
currentInput = "";
|
||||
if (testMode == "time") {
|
||||
if (config.mode == "time") {
|
||||
let randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
if (punctuationMode) {
|
||||
if (config.punctuation) {
|
||||
wordsList.push(capitalizeFirstLetter(randomWord));
|
||||
} else {
|
||||
wordsList.push(randomWord);
|
||||
|
@ -75,13 +78,13 @@ function initWords() {
|
|||
) {
|
||||
randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
}
|
||||
if (punctuationMode) {
|
||||
if (config.punctuation) {
|
||||
if (previousWord.charAt(previousWord.length - 1) == ".") {
|
||||
randomWord = capitalizeFirstLetter(randomWord);
|
||||
} else if (
|
||||
(Math.random() < 0.1 &&
|
||||
previousWord.charAt(previousWord.length - 1) != ".") ||
|
||||
i == wordsConfig - 1
|
||||
i == config.words - 1
|
||||
) {
|
||||
randomWord += ".";
|
||||
} else if (Math.random() < 0.01) {
|
||||
|
@ -104,14 +107,14 @@ function initWords() {
|
|||
}
|
||||
wordsList.push(randomWord);
|
||||
}
|
||||
} else if (testMode == "words") {
|
||||
} else if (config.mode == "words") {
|
||||
let randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
if (punctuationMode) {
|
||||
if (config.punctuation) {
|
||||
wordsList.push(capitalizeFirstLetter(randomWord));
|
||||
} else {
|
||||
wordsList.push(randomWord);
|
||||
}
|
||||
for (let i = 1; i < wordsConfig; i++) {
|
||||
for (let i = 1; i < config.words; i++) {
|
||||
randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
previousWord = wordsList[i - 1];
|
||||
while (
|
||||
|
@ -124,13 +127,13 @@ function initWords() {
|
|||
) {
|
||||
randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
}
|
||||
if (punctuationMode) {
|
||||
if (config.punctuation) {
|
||||
if (previousWord.charAt(previousWord.length - 1) == ".") {
|
||||
randomWord = capitalizeFirstLetter(randomWord);
|
||||
} else if (
|
||||
(Math.random() < 0.1 &&
|
||||
previousWord.charAt(previousWord.length - 1) != ".") ||
|
||||
i == wordsConfig - 1
|
||||
i == config.words - 1
|
||||
) {
|
||||
randomWord += ".";
|
||||
} else if (Math.random() < 0.01) {
|
||||
|
@ -153,7 +156,7 @@ function initWords() {
|
|||
}
|
||||
wordsList.push(randomWord);
|
||||
}
|
||||
} else if (testMode == "custom") {
|
||||
} else if (config.mode == "custom") {
|
||||
let w = customText.split(" ");
|
||||
for (let i = 0; i < w.length; i++) {
|
||||
wordsList.push(w[i]);
|
||||
|
@ -175,7 +178,7 @@ function addWord() {
|
|||
|
||||
function showWords() {
|
||||
$("#words").empty();
|
||||
if (testMode == "words" || testMode == "custom") {
|
||||
if (config.mode == "words" || config.mode == "custom") {
|
||||
$("#words").css("height", "auto");
|
||||
for (let i = 0; i < wordsList.length; i++) {
|
||||
let w = "<div class='word'>";
|
||||
|
@ -185,7 +188,7 @@ function showWords() {
|
|||
w += "</div>";
|
||||
$("#words").append(w);
|
||||
}
|
||||
} else if (testMode == "time") {
|
||||
} else if (config.mode == "time") {
|
||||
$("#words").css("height", "78px").css("overflow", "hidden");
|
||||
for (let i = 0; i < wordsList.length; i++) {
|
||||
let w = "<div class='word'>";
|
||||
|
@ -295,12 +298,17 @@ function updateCaretPosition() {
|
|||
|
||||
let duration = 0;
|
||||
|
||||
if (true) {
|
||||
// if (config.smoothCaret && Math.round(caret.position().top) == Math.round(newTop)) {
|
||||
// duration = 100;
|
||||
// }
|
||||
|
||||
if (config.smoothCaret) {
|
||||
duration = 100;
|
||||
}
|
||||
|
||||
if (caret.position().top != newTop) {
|
||||
duration = 0;
|
||||
if (Math.round(caret.position().top) != Math.round(newTop)) {
|
||||
caret.css("top", newTop);
|
||||
duration = 10;
|
||||
}
|
||||
|
||||
caret.stop(true,true).animate({
|
||||
|
@ -310,8 +318,27 @@ function updateCaretPosition() {
|
|||
|
||||
}
|
||||
|
||||
function saveConfigToCookie() {
|
||||
let d = new Date();
|
||||
d.setFullYear(d.getFullYear() + 1)
|
||||
$.cookie("config",JSON.stringify(config),{expires:d})
|
||||
}
|
||||
|
||||
function loadConfigFromCookie() {
|
||||
let newConfig = $.cookie('config');
|
||||
if (newConfig) {
|
||||
newConfig = JSON.parse(newConfig);
|
||||
config = newConfig;
|
||||
setPunctuation(config.punctuation)
|
||||
changeTimeConfig(config.time);
|
||||
changeWordCount(config.words);
|
||||
changeMode(config.mode);
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
|
||||
function calculateStats() {
|
||||
if (testMode == "words") {
|
||||
if (config.mode == "words") {
|
||||
if (inputHistory.length != wordsList.length) return;
|
||||
}
|
||||
let correctWords = 0;
|
||||
|
@ -345,9 +372,8 @@ function calculateStats() {
|
|||
avgWordLen = 5;
|
||||
wpm = calculateWpm();
|
||||
// let acc = (correctChars / totalChars) * 100;
|
||||
let acc = ((totalChars - missedChars) / totalChars) * 100;
|
||||
let key = correctChars + "/" + (totalChars - correctChars);
|
||||
return { wpm: wpm, acc: acc, key: key };
|
||||
let acc = Math.round(((totalChars - missedChars) / totalChars) * 100);
|
||||
return { wpm: wpm, acc: acc, correctChars: correctChars, incorrectChars: (totalChars - correctChars) };
|
||||
}
|
||||
|
||||
function calculateWpm() {
|
||||
|
@ -391,13 +417,13 @@ function showResult() {
|
|||
$("#top .result .wpm .val").text(stats.wpm);
|
||||
$("#top .result .acc .val").text(Math.round(stats.acc) + "%");
|
||||
$("#top .result .key .val").text(stats.key);
|
||||
$("#top .result .testmode .mode1").text(testMode);
|
||||
if (testMode == "time") {
|
||||
$("#top .result .testmode .mode2").text(timeConfig);
|
||||
} else if (testMode == "words") {
|
||||
$("#top .result .testmode .mode2").text(wordsConfig);
|
||||
$("#top .result .testmode .mode1").text(config.mode);
|
||||
if (config.mode == "time") {
|
||||
$("#top .result .testmode .mode2").text(config.time);
|
||||
} else if (config.mode == "words") {
|
||||
$("#top .result .testmode .mode2").text(config.words);
|
||||
}
|
||||
if (punctuationMode) {
|
||||
if (config.punctuation) {
|
||||
$("#top .result .testmode .mode3").text("punc.");
|
||||
} else {
|
||||
$("#top .result .testmode .mode3").text("");
|
||||
|
@ -495,19 +521,40 @@ function showResult2() {
|
|||
clearInterval(timer);
|
||||
timer = null;
|
||||
$("#result .stats .wpm .bottom").text(stats.wpm);
|
||||
$("#result .stats .acc .bottom").text(Math.round(stats.acc) + "%");
|
||||
$("#result .stats .key .bottom").text(stats.key);
|
||||
$("#result .stats .acc .bottom").text(stats.acc + "%");
|
||||
$("#result .stats .key .bottom").text(stats.correctChars+"/"+stats.incorrectChars);
|
||||
|
||||
let mode2 = "";
|
||||
if (config.mode == "time") {
|
||||
mode2 = config.time;
|
||||
} else if (config.mode == "words") {
|
||||
mode2 = config.words;
|
||||
}
|
||||
$("#result .stats .wpm .top .crown").remove();
|
||||
|
||||
if (stats.wpm < 250 && stats.acc > 50 && stats.acc <= 100) {
|
||||
db_getUserHighestWpm(config.mode, mode2).then(data => {
|
||||
if (data.wpm < stats.wpm || data == false) {
|
||||
$("#result .stats .wpm .top").append('<div class="crown"><i class="fas fa-crown"></i></div>');
|
||||
}
|
||||
db_testCompleted(stats.wpm, stats.correctChars, stats.incorrectChars, stats.acc, config.mode, mode2);
|
||||
})
|
||||
} else {
|
||||
alert('test invalid');
|
||||
}
|
||||
|
||||
|
||||
|
||||
let infoText = "";
|
||||
|
||||
infoText = testMode;
|
||||
infoText = config.mode;
|
||||
|
||||
if (testMode == "time") {
|
||||
infoText += " " + timeConfig
|
||||
} else if (testMode == "words") {
|
||||
infoText += " " + wordsConfig
|
||||
if (config.mode == "time") {
|
||||
infoText += " " + config.time
|
||||
} else if (config.mode == "words") {
|
||||
infoText += " " + config.words
|
||||
}
|
||||
if (punctuationMode) {
|
||||
if (config.punctuation) {
|
||||
infoText += " with punctuation"
|
||||
}
|
||||
|
||||
|
@ -538,7 +585,7 @@ function showResult2() {
|
|||
}
|
||||
|
||||
function updateTimer() {
|
||||
let percent = ((time + 1) / timeConfig) * 100;
|
||||
let percent = ((time + 1) / config.time) * 100;
|
||||
$("#timer")
|
||||
.stop(true, true)
|
||||
.css("width", percent + "vw");
|
||||
|
@ -679,15 +726,16 @@ function compareInput() {
|
|||
}
|
||||
|
||||
$(document).ready(() => {
|
||||
loadConfigFromCookie();
|
||||
$("#centerContent").css("opacity", "0").removeClass("hidden");
|
||||
// initWords();
|
||||
$("#centerContent")
|
||||
.stop(true, true)
|
||||
.animate({ opacity: 1 }, 250, () => {
|
||||
updateCaretPosition();
|
||||
// updateCaretPosition();
|
||||
});
|
||||
restartTest();
|
||||
if (quickTabMode) {
|
||||
if (config.quickTab) {
|
||||
$("#restartTestButton").remove();
|
||||
}
|
||||
});
|
||||
|
@ -699,12 +747,13 @@ $(document).on("click", "#top .config .wordCount .button", (e) => {
|
|||
|
||||
function changeWordCount(wordCount) {
|
||||
changeMode("words");
|
||||
wordsConfig = parseInt(wordCount);
|
||||
config.words = parseInt(wordCount);
|
||||
$("#top .config .wordCount .button").removeClass("active");
|
||||
$("#top .config .wordCount .button[wordCount='" + wordCount + "']").addClass(
|
||||
"active"
|
||||
);
|
||||
restartTest();
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
$(document).on("click", "#top .config .time .button", (e) => {
|
||||
|
@ -714,10 +763,11 @@ $(document).on("click", "#top .config .time .button", (e) => {
|
|||
|
||||
function changeTimeConfig(time) {
|
||||
changeMode("time");
|
||||
timeConfig = time;
|
||||
config.time = time;
|
||||
$("#top .config .time .button").removeClass("active");
|
||||
$("#top .config .time .button[timeConfig='" + time + "']").addClass("active");
|
||||
restartTest();
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
$(document).on("click", "#top .config .customText .button", (e) => {
|
||||
|
@ -737,13 +787,40 @@ function focusWords() {
|
|||
$("#wordsInput").focus();
|
||||
}
|
||||
|
||||
function togglePunctuation() {
|
||||
if (punctuationMode) {
|
||||
function toggleSmoothCaret() {
|
||||
config.smoothCaret = !config.smoothCaret;
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
function toggleQuickTabMode() {
|
||||
config.quickTab = !config.quickTab;
|
||||
if (!config.quickTab) {
|
||||
$(".pageTest").append('<div id="restartTestButton" class="" tabindex="0"><i class="fas fa-redo-alt"></i></div>');
|
||||
$("#restartTestButton").css("opacity",1);
|
||||
} else {
|
||||
$("#restartTestButton").remove();
|
||||
}
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
function setPunctuation(punc) {
|
||||
config.punctuation = punc;
|
||||
if (!config.punctuation) {
|
||||
$("#top .config .punctuationMode .button").removeClass("active");
|
||||
} else {
|
||||
$("#top .config .punctuationMode .button").addClass("active");
|
||||
}
|
||||
punctuationMode = !punctuationMode;
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
function togglePunctuation() {
|
||||
if (config.punctuation) {
|
||||
$("#top .config .punctuationMode .button").removeClass("active");
|
||||
} else {
|
||||
$("#top .config .punctuationMode .button").addClass("active");
|
||||
}
|
||||
config.punctuation = !config.punctuation;
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
$(document).on("click", "#top .config .mode .button", (e) => {
|
||||
|
@ -755,7 +832,7 @@ $(document).on("click", "#top .config .mode .button", (e) => {
|
|||
|
||||
$(document).on("click", "#top #menu .button", (e) => {
|
||||
href = $(e.currentTarget).attr('href');
|
||||
history.pushState(href, null, href);
|
||||
// history.pushState(href, null, href);
|
||||
changePage(href.replace('/', ''));
|
||||
})
|
||||
|
||||
|
@ -767,7 +844,11 @@ $(window).on('popstate', (e) => {
|
|||
// show about
|
||||
changePage("about");
|
||||
} else if (e.originalEvent.state == "account") {
|
||||
changePage("account")
|
||||
if (firebase.auth().currentUser) {
|
||||
changePage("account");
|
||||
} else {
|
||||
changePage('login');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -782,30 +863,37 @@ function changePage(page) {
|
|||
} else if (page == "about") {
|
||||
$(".page.pageAbout").removeClass('hidden');
|
||||
} else if (page == "account") {
|
||||
$(".page.pageAccount").removeClass('hidden');
|
||||
if (!firebase.auth().currentUser) {
|
||||
changePage("login");
|
||||
} else {
|
||||
$(".page.pageAccount").removeClass('hidden');
|
||||
}
|
||||
} else if (page == "login") {
|
||||
$(".page.pageLogin").removeClass('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function changeMode(mode) {
|
||||
testMode = mode;
|
||||
config.mode = mode;
|
||||
$("#top .config .mode .button").removeClass("active");
|
||||
$("#top .config .mode .button[mode='" + mode + "']").addClass("active");
|
||||
if (testMode == "time") {
|
||||
if (config.mode == "time") {
|
||||
$("#top .config .wordCount").addClass("hidden");
|
||||
$("#top .config .time").removeClass("hidden");
|
||||
$("#top .config .customText").addClass("hidden");
|
||||
$("#top .config .punctuationMode").removeClass("hidden");
|
||||
} else if (testMode == "words") {
|
||||
} else if (config.mode == "words") {
|
||||
$("#top .config .wordCount").removeClass("hidden");
|
||||
$("#top .config .time").addClass("hidden");
|
||||
$("#top .config .customText").addClass("hidden");
|
||||
$("#top .config .punctuationMode").removeClass("hidden");
|
||||
} else if (testMode == "custom") {
|
||||
} else if (config.mode == "custom") {
|
||||
$("#top .config .wordCount").addClass("hidden");
|
||||
$("#top .config .time").addClass("hidden");
|
||||
$("#top .config .customText").removeClass("hidden");
|
||||
$("#top .config .punctuationMode").addClass("hidden");
|
||||
}
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
$("#restartTestButton").keypress((event) => {
|
||||
|
@ -842,7 +930,7 @@ $(document).keypress(function(event) {
|
|||
testActive = true;
|
||||
stopCaretAnimation();
|
||||
testStart = Date.now();
|
||||
if (testMode == "time") {
|
||||
if (config.mode == "time") {
|
||||
showTimer();
|
||||
}
|
||||
updateTimer();
|
||||
|
@ -851,8 +939,8 @@ $(document).keypress(function(event) {
|
|||
updateTimer();
|
||||
let wpm = calculateWpm();
|
||||
wpmHistory.push(wpm);
|
||||
if (testMode == "time") {
|
||||
if (time == timeConfig) {
|
||||
if (config.mode == "time") {
|
||||
if (time == config.time) {
|
||||
clearInterval(timer);
|
||||
timesUp();
|
||||
}
|
||||
|
@ -893,7 +981,7 @@ $(document).keydown((event) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (quickTabMode) {
|
||||
if (config.quickTab) {
|
||||
if (event["keyCode"] == 9) {
|
||||
event.preventDefault();
|
||||
restartTest();
|
||||
|
@ -941,7 +1029,7 @@ $(document).keydown((event) => {
|
|||
event.preventDefault();
|
||||
if (currentInput == "") return;
|
||||
let currentWord = wordsList[currentWordIndex];
|
||||
if (testMode == "time") {
|
||||
if (config.mode == "time") {
|
||||
let currentTop = $($("#words .word")[currentWordIndex]).position().top;
|
||||
let nextTop = $($("#words .word")[currentWordIndex + 1]).position().top;
|
||||
if (nextTop > currentTop) {
|
||||
|
@ -972,303 +1060,9 @@ $(document).keydown((event) => {
|
|||
updateActiveElement();
|
||||
updateCaretPosition();
|
||||
}
|
||||
if (testMode == "time") {
|
||||
if (config.mode == "time") {
|
||||
addWord();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let commands = {
|
||||
title: "",
|
||||
list: [
|
||||
{
|
||||
id: "togglePunctuation",
|
||||
display: "Toggle punctuation",
|
||||
exec: () => {
|
||||
togglePunctuation();
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeMode",
|
||||
display: "Change mode...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsMode;
|
||||
showCommandLine();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig",
|
||||
display: "Change time config...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsTimeConfig;
|
||||
showCommandLine();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount",
|
||||
display: "Change word count...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsWordCount;
|
||||
showCommandLine();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let commandsWordCount = {
|
||||
title: "Change word count...",
|
||||
list: [
|
||||
{
|
||||
id: "changeWordCount10",
|
||||
display: "10",
|
||||
exec: () => {
|
||||
changeWordCount("10");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount25",
|
||||
display: "25",
|
||||
exec: () => {
|
||||
changeWordCount("25");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount50",
|
||||
display: "50",
|
||||
exec: () => {
|
||||
changeWordCount("50");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount100",
|
||||
display: "100",
|
||||
exec: () => {
|
||||
changeWordCount("100");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeWordCount200",
|
||||
display: "200",
|
||||
exec: () => {
|
||||
changeWordCount("200");
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
let commandsMode = {
|
||||
title: "Change mode...",
|
||||
list: [
|
||||
{
|
||||
id: "changeModeTime",
|
||||
display: "time",
|
||||
exec: () => {
|
||||
changeMode("time");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeModeWords",
|
||||
display: "words",
|
||||
exec: () => {
|
||||
changeMode("words");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeModeCustom",
|
||||
display: "custom",
|
||||
exec: () => {
|
||||
changeMode("custom");
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
let commandsTimeConfig = {
|
||||
title: "Change time config...",
|
||||
list: [
|
||||
{
|
||||
id: "changeTimeConfig15",
|
||||
display: "15",
|
||||
exec: () => {
|
||||
changeTimeConfig("15");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig30",
|
||||
display: "30",
|
||||
exec: () => {
|
||||
changeTimeConfig("30");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig60",
|
||||
display: "60",
|
||||
exec: () => {
|
||||
changeTimeConfig("60");
|
||||
restartTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeTimeConfig120",
|
||||
display: "120",
|
||||
exec: () => {
|
||||
changeTimeConfig("120");
|
||||
restartTest();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let currentCommands = commands;
|
||||
|
||||
$("#commandLine input").keydown((e) => {
|
||||
if (e.keyCode == 13) {
|
||||
//enter
|
||||
e.preventDefault();
|
||||
let command = $(".suggestions .entry.active").attr("command");
|
||||
let subgroup = false;
|
||||
$.each(currentCommands.list, (i, obj) => {
|
||||
if (obj.id == command) {
|
||||
obj.exec();
|
||||
subgroup = obj.subgroup;
|
||||
}
|
||||
});
|
||||
if (!subgroup) hideCommandLine();
|
||||
return;
|
||||
}
|
||||
if (e.keyCode == 38 || e.keyCode == 40) {
|
||||
//up
|
||||
let entries = $(".suggestions .entry");
|
||||
let activenum = -1;
|
||||
$.each(entries, (index, obj) => {
|
||||
if ($(obj).hasClass("active")) activenum = index;
|
||||
});
|
||||
if (e.keyCode == 38) {
|
||||
entries.removeClass("active");
|
||||
if (activenum == 0) {
|
||||
$(entries[entries.length - 1]).addClass("active");
|
||||
} else {
|
||||
$(entries[--activenum]).addClass("active");
|
||||
}
|
||||
}
|
||||
if (e.keyCode == 40) {
|
||||
entries.removeClass("active");
|
||||
if (activenum + 1 == entries.length) {
|
||||
$(entries[0]).addClass("active");
|
||||
} else {
|
||||
$(entries[++activenum]).addClass("active");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$("#commandLine input").keyup((e) => {
|
||||
if (e.keyCode == 38 || e.keyCode == 40) return;
|
||||
updateSuggestedCommands();
|
||||
});
|
||||
|
||||
function hideCommandLine() {
|
||||
$("#commandLineWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 1)
|
||||
.animate(
|
||||
{
|
||||
opacity: 0
|
||||
},
|
||||
100,
|
||||
() => {
|
||||
$("#commandLineWrapper").addClass("hidden");
|
||||
}
|
||||
);
|
||||
focusWords();
|
||||
}
|
||||
|
||||
function showCommandLine() {
|
||||
if ($("#commandLineWrapper").hasClass("hidden")) {
|
||||
$("#commandLineWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 0)
|
||||
.removeClass("hidden")
|
||||
.animate(
|
||||
{
|
||||
opacity: 1
|
||||
},
|
||||
100
|
||||
);
|
||||
}
|
||||
$("#commandLine input").val("");
|
||||
updateSuggestedCommands();
|
||||
$("#commandLine input").focus();
|
||||
}
|
||||
|
||||
function updateSuggestedCommands() {
|
||||
let inputVal = $("#commandLine input").val().toLowerCase().split(" ");
|
||||
if (inputVal[0] == "") {
|
||||
$.each(currentCommands.list, (index, obj) => {
|
||||
obj.found = true;
|
||||
});
|
||||
} else {
|
||||
$.each(currentCommands.list, (index, obj) => {
|
||||
let foundcount = 0;
|
||||
$.each(inputVal, (index2, obj2) => {
|
||||
if (obj2 == "") return;
|
||||
let re = new RegExp(obj2, "g");
|
||||
let res = obj.display.toLowerCase().match(re);
|
||||
if (res != null && res.length > 0) {
|
||||
foundcount++;
|
||||
} else {
|
||||
foundcount--;
|
||||
}
|
||||
});
|
||||
if (foundcount > 0) {
|
||||
obj.found = true;
|
||||
} else {
|
||||
obj.found = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
displayFoundCommands();
|
||||
}
|
||||
|
||||
function displayFoundCommands() {
|
||||
$("#commandLine .suggestions").empty();
|
||||
$.each(currentCommands.list, (index, obj) => {
|
||||
if (obj.found) {
|
||||
$("#commandLine .suggestions").append(
|
||||
'<div class="entry" command="' + obj.id + '">' + obj.display + "</div>"
|
||||
);
|
||||
}
|
||||
});
|
||||
if ($("#commandLine .suggestions .entry").length == 0) {
|
||||
$("#commandLine .separator").css({ height: 0, margin: 0 });
|
||||
} else {
|
||||
$("#commandLine .separator").css({
|
||||
height: "1px",
|
||||
"margin-bottom": ".5rem"
|
||||
});
|
||||
}
|
||||
let entries = $("#commandLine .suggestions .entry");
|
||||
if (entries.length > 0) {
|
||||
$(entries[0]).addClass("active");
|
||||
}
|
||||
$("#commandLine .listTitle").remove();
|
||||
// if(currentCommands.title != ''){
|
||||
// $("#commandLine .suggestions").before("<div class='listTitle'>"+currentCommands.title+"</div>");
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue