-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
142 lines (116 loc) · 4.04 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const display = document.getElementById("display");
const question = document.getElementById("question");
const startBtn = document.getElementById("starts");
const countdownOverlay = document.getElementById("countdown");
const resultModal = document.getElementById("result");
const modalBackground = document.getElementById("modal-background");
// variables
let userText = "";
let errorCount = 0;
let startTime = 0;
let questionText = "";
// Load and display question
fetch("./texts.json")
.then((res) => res.json())
.then((data) => {
questionText = data[Math.floor(Math.random() * data.length)];
question.innerHTML = questionText;
});
// checks the user typed character and displays accordingly
const typeController = (e) => {
const newLetter = e.key;
// Handle backspace press
if(newLetter == "Backspace") {
userText = userText.slice(0, userText.length - 1);
return display.removeChild(display.lastChild);
}
// these are the valid character we are allowing to type
const validLetters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890!@#$%^&*()_+-={}[]'\".,?";
// if it is not a valid character like Control/Alt then skip displaying anything
if(!validLetters.includes(newLetter)) {
return;
}
userText += newLetter;
const newLetterCorrect = validate(newLetter);
if(newLetterCorrect) {
display.innerHTML += `<span class="green">${newLetter === " " ? "▪" : newLetter}</span>`;
} else {
display.innerHTML += `<span class="red">${newLetter === " " ? "▪" : newLetter}</span>`;
errorCount++;
}
// check if given question text is equal to user typed text
if(questionText === userText) {
gameOver();
}
};
const validate = (key) => {
if(key === questionText[userText.length - 1]) {
return true;
}
return false;
};
// FINISHED TYPING
const gameOver = () => {
document.removeEventListener("keydown", typeController);
// the current time is the finish time
// so total time taken is current time - start time
const finishTime = new Date().getTime();
const timeTaken = (finishTime - startTime) / 1000;
const fixed = Math.round(timeTaken);
// show result modal
resultModal.innerHTML = "";
resultModal.classList.toggle("hidden");
modalBackground.classList.toggle("hidden");
// clear user text
display.innerHTML = "";
// make it inactive
display.classList.add("inactive");
// show result
resultModal.innerHTML += `
<h1>Finished!</h1>
<p>You took: <span class="bold">${fixed}</span> seconds</p>
<p>You made <span class="bold red">${errorCount}</span> mistakes</p>
<button onclick="closeModal()">Close</button>
`;
addHistory(questionText, fixed, errorCount);
// restart everything
startTime = null;
errorCount = 0;
userText = "";
display.classList.add("inactive");
};
const closeModal = () => {
modalBackground.classList.toggle("hidden");
resultModal.classList.toggle("hidden");
};
const start = (startBtn) => {
// If already started, do not start again
if(startTime) return;
let count = 3;
countdownOverlay.style.display = "flex";
const startCountdown = setInterval(() => {
countdownOverlay.innerHTML = `<h1>${count}</h1>`;
// finished timer
if(count === 0) {
// -------------- START TYPING -----------------
document.addEventListener("keydown", typeController);
countdownOverlay.style.display = "none";
countdownOverlay.classList.add("countdown");
clearInterval(startCountdown);
startTime = new Date().getTime();
}
count--;
}, 1000);
};
// START Countdown
startBtn.addEventListener("click", start);
// If history exists, show itt
displayHistory();
// Show typing time spent
setInterval(() => {
const currentTime = new Date().getTime();
const timeSpent = (currentTime - startTime) / 1000;
const timeRounded = Math.round(timeSpent);
document.getElementById("show-time").innerText = `${startTime ? timeRounded : 0} seconds`;
}, 1000);