react-typing-test
Version:
A react component typing test, user input and wpm calculations.
96 lines (95 loc) • 5.08 kB
JavaScript
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import React, { useState, useRef, useCallback, useMemo, useEffect, } from "react";
import { getRandomWordList, } from "./util/wordListGenerator";
import { BottomBar, ColoredSpan, GlobalStyle } from "./components/style";
import { StyledThemeProvider } from "./themes/ThemeProvider";
import { RedoButton } from "./components/RedoButton";
import { MainContainer } from "./components/MainContainer";
import { Input } from "./components/Input";
import { Word } from "./components/Word";
export var TypingTest = function (_a) {
var _b = _a.wordLimit, wordLimit = _b === void 0 ? 50 : _b, _c = _a.language, language = _c === void 0 ? "english" : _c, _d = _a.theme, theme = _d === void 0 ? "Purpleish" : _d, onSetWPM = _a.onSetWPM, customWordList = _a.customWordList, customTheme = _a.customTheme;
var inputRef = useRef(null);
var _e = useState(""), currentWord = _e[0], setCurrentWord = _e[1];
var _f = useState(0), wordIndex = _f[0], setWordIndex = _f[1];
var _g = useState(null), startTime = _g[0], setStartTime = _g[1];
console.log(customWordList);
var _h = useState(getRandomWordList({ wordLimit: wordLimit, language: language, customList: customWordList })), wordsToType = _h[0], setWordsToType = _h[1];
var _j = useState(0), wpm = _j[0], setWpm = _j[1];
var _k = useState(false), hasError = _k[0], setHasError = _k[1];
var _l = useState([]), typedWords = _l[0], setTypedWords = _l[1];
var targetWord = useMemo(function () { return wordsToType[wordIndex]; }, [wordsToType, wordIndex]);
var handleOnChange = function (e) {
var value = e.target.value;
var len = value.length;
if (!startTime) {
setStartTime(new Date());
}
if (value.charAt(len - 1) === " " ||
(targetWord === wordsToType[wordsToType.length - 1] &&
len === targetWord.length &&
value.charAt(len - 1) === targetWord.charAt(len - 1) &&
typedWords.length === wordsToType.length - 1)) {
var nextTypedWords_1 = __spreadArray(__spreadArray([], typedWords, true), [value.replace(" ", "")], false);
if (wordIndex + 1 === wordsToType.length) {
var endTime = Date.now();
var timeDiffInMinutes = (endTime - startTime.getTime()) / 60000;
var correctChars_1 = 0;
wordsToType.forEach(function (word, i) {
if (nextTypedWords_1[i]) {
nextTypedWords_1[i].split("").forEach(function (ntw, j) {
if (word[j] === ntw) {
correctChars_1 += 1;
}
});
}
});
setWpm(Math.floor(correctChars_1 / 5 / timeDiffInMinutes));
}
setCurrentWord("");
setTypedWords(nextTypedWords_1);
setWordIndex(wordIndex + 1);
}
else {
setCurrentWord(value);
}
if (value.charAt(len - 1) !== " ") {
setHasError(value.charAt(len - 1) !== targetWord.charAt(len - 1));
}
};
useEffect(function () {
if (onSetWPM) {
onSetWPM(wpm);
}
}, [wpm, onSetWPM]);
var reset = useCallback(function () {
var _a;
setWordIndex(0);
setTypedWords([]);
setStartTime(null);
setWpm(0);
setCurrentWord("");
setWordsToType(getRandomWordList({ wordLimit: wordLimit, language: language, customList: customWordList }));
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
}, [inputRef]);
return (React.createElement(StyledThemeProvider, { themeName: theme, customTheme: customTheme },
React.createElement(MainContainer, null,
React.createElement(GlobalStyle, null),
React.createElement("div", null, wordsToType.map(function (randWord, i) { return (React.createElement(Word, { word: randWord, wordIndex: wordIndex, index: i, targetWord: targetWord, currentWord: currentWord, typedWords: typedWords })); })),
React.createElement(BottomBar, null,
React.createElement(Input, { ref: inputRef, type: "text", spellCheck: "false", value: currentWord, onChange: handleOnChange, autoComplete: "off", hasError: hasError, autoFocus: true }),
React.createElement(RedoButton, { onClick: reset }, "Redo")),
React.createElement(ColoredSpan, null,
"WPM: ",
wpm,
" "))));
};
export default TypingTest;