From 31ed2ff4ee7fb8afa44f37cfbcd4b139ab457080 Mon Sep 17 00:00:00 2001 From: niclas Date: Wed, 7 Apr 2021 10:42:44 +0200 Subject: [PATCH] added carrot and added unit mode --- components/input/Input.jsx | 41 ++++++++++++------- pages/config/index.js | 5 ++- public/carrot.png | Bin 0 -> 5053 bytes styles/components/Input.module.css | 12 +++++- styles/components/config/Checkbox.module.css | 2 +- util/config.js | 20 ++++++--- util/logic/type-logic.js | 12 ++++-- 7 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 public/carrot.png diff --git a/components/input/Input.jsx b/components/input/Input.jsx index 0f85ca8..7a7b7f1 100644 --- a/components/input/Input.jsx +++ b/components/input/Input.jsx @@ -17,7 +17,7 @@ export class Input extends React.Component { author: this.props.author, errorCount: 0, validLetters: - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZöüäß.?!;:,'\" ", + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZöüäß.?!;-:,'\" ", time: 0.0, start: 0.0, wpm: 0.0, @@ -25,6 +25,7 @@ export class Input extends React.Component { clickSounds: [], errorSound: undefined, words: [], + unit: undefined }; this.state.fullText.split(" ").forEach((element) => { @@ -63,6 +64,10 @@ export class Input extends React.Component { ? localStorage.getItem("language") : "english"; + this.state.unit = localStorage.getItem("unit") + ? localStorage.getItem("unit") + : "WPM" + if ( localStorage.getItem("mode") ? localStorage.getItem("mode") == "Quotes" @@ -94,7 +99,10 @@ export class Input extends React.Component { }); this.setState({ index: (this.state.index -= 1) }); this.setState({ - typedText: this.state.typedText.substring(0, this.state.typedText.length - 1), + typedText: this.state.typedText.substring( + 0, + this.state.typedText.length - 1 + ), }); } @@ -104,11 +112,11 @@ export class Input extends React.Component { if (localStorage.getItem("click_sounds") === "true") playSound("click_sounds"); - if (event.key !== this.state.fullText[this.state.index]) { - this.setState({ errorCount: this.state.errorCount + 1 }); - if (localStorage.getItem("error_sounds") === "true") - playSound("error_sounds"); - } + if (event.key !== this.state.fullText[this.state.index]) { + this.setState({ errorCount: this.state.errorCount + 1 }); + if (localStorage.getItem("error_sounds") === "true") + playSound("error_sounds"); + } this.state.typedText += event.key; this.state.remainingText = this.state.remainingText.slice( @@ -135,13 +143,20 @@ export class Input extends React.Component { ); let typed = []; + let remaining = []; + + for (let i = 0; i < this.state.fullText.length; i++) + remaining.push({this.state.remainingText[i]}); for (let i = 0; i < this.state.typedText.length; i++) { let value = this.state.typedText[i]; if (value !== this.state.fullText[i]) typed.push({this.state.fullText[i]}); - else typed.push({value}); + else { + typed.push({value}); + } } + typed.push(); return (
@@ -149,20 +164,16 @@ export class Input extends React.Component {

Errors: {this.state.errorCount}

Letters: {this.state.typedText.length}

- Time elapsed:{" "} - - {Math.round((this.state.time / 1000) * 1) / 1} - {" "} - seconds + Time elapsed: {Math.round((this.state.time / 1000) * 1) / 1}s

-

WPM: {calculated.wpm}

+

{this.state.unit}: {this.state.unit == "wpm" ? calculated.wpm : calculated.cpm}

Raw: {calculated.raw}

Accuracy: {calculated.accuracy}%

{typed} - {this.state.remainingText} + {remaining}

~ {this.state.author}

diff --git a/pages/config/index.js b/pages/config/index.js index 59449f4..0b0a559 100644 --- a/pages/config/index.js +++ b/pages/config/index.js @@ -4,9 +4,10 @@ import { Mode } from "../../components/config/Mode.jsx" export default function Home() { return ( <> - - + + + ) diff --git a/public/carrot.png b/public/carrot.png new file mode 100644 index 0000000000000000000000000000000000000000..751ea31db2f797e71299ce6a08dd08a35ab50d02 GIT binary patch literal 5053 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 T^rEtl00000NkvXXu0mjf%BXmd literal 0 HcmV?d00001 diff --git a/styles/components/Input.module.css b/styles/components/Input.module.css index e6627de..a0ff048 100644 --- a/styles/components/Input.module.css +++ b/styles/components/Input.module.css @@ -3,8 +3,8 @@ } .wrong { - color: #ef4f4f; -} + background-color: rgb(240, 84, 84, 1); +} .text { max-width: 300px; @@ -18,6 +18,7 @@ -ms-user-select: none; user-select: none; cursor: default; + font-size: 20px; } .text:focus { @@ -31,6 +32,11 @@ margin-top: 0; } +.carrot { + height: 20px; + width: 0.28rem; +} + .information { max-width: 500px; overflow: hidden; @@ -43,6 +49,8 @@ font-size: 0.9rem; font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace; + font-size: 17px; + display: flex; } .timeElapsed { diff --git a/styles/components/config/Checkbox.module.css b/styles/components/config/Checkbox.module.css index dd1c15d..d164597 100644 --- a/styles/components/config/Checkbox.module.css +++ b/styles/components/config/Checkbox.module.css @@ -12,7 +12,7 @@ height: auto; display: flex; align-items: center; - margin: 30px; + margin: 10px; } .content .box { diff --git a/util/config.js b/util/config.js index b1ca43a..6adec41 100644 --- a/util/config.js +++ b/util/config.js @@ -1,6 +1,16 @@ -class Config { - mode = "quotes"; - language = "english"; - click_sound = false; - error_sound = false; +let currentConfig = { + mode: "", + language: "", + clickSounds: false, + errorSounds: false +} + +export function load() { + if (localStorage.getItem("config")) + this.currentConfig = JSON.parse(localStorage.getItem("config")) + else this.save() +} + +export function save() { + localStorage.setItem("config", currentConfig) } \ No newline at end of file diff --git a/util/logic/type-logic.js b/util/logic/type-logic.js index a1e0c5d..b3898ce 100644 --- a/util/logic/type-logic.js +++ b/util/logic/type-logic.js @@ -10,8 +10,9 @@ */ export function calculate(time, typedText, errors, words) { const mins = Math.round((time / 1000) * 1) / 1 - let wpm = Math.round(((typedText.length - errors + (words.length - 2)) * (60 / mins)) / 5) + let wpm = Math.round((((typedText.length - errors) + (words.length - 2)) * (60 / mins)) / 5) let raw = Math.round((typedText.length * (60 / mins)) / 5); + let cpm = Math.round(((typedText.length - errors) * (60 / mins))); const rawAccuracy = (((typedText.length - errors) / typedText.length) * 100) let accuracy = Math.round(rawAccuracy) @@ -19,17 +20,20 @@ export function calculate(time, typedText, errors, words) { if (isNaN(accuracy) || accuracy.toString().includes("-Infinity")) accuracy = 100 - if (isNaN(wpm) || wpm.toString().includes("-Infinity")) + if (isNaN(wpm) || wpm.toString().includes("-Infinity") || wpm < 0) wpm = 0 - if (isNaN(raw) || raw.toString().includes("-Infinity")) + if (isNaN(raw) || raw.toString().includes("-Infinity") || raw < 0) raw = 0 + if (isNaN(cpm) || cpm.toString().includes("-Infinity") || cpm < 0) + cpm = 0 + if (typedText.length < errors) { wpm = 0 accuracy = 0 raw = 0 } - return { wpm, accuracy, raw } + return { wpm, accuracy, raw, cpm } } \ No newline at end of file