mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-05 21:15:26 +08:00
Merge branch 'master' into dracula
This commit is contained in:
commit
a283c5ce4d
24 changed files with 177 additions and 288 deletions
|
@ -645,7 +645,7 @@ key {
|
|||
margin: 5px 5px;
|
||||
color: var(--sub-color);
|
||||
display: flex;
|
||||
transition: 0.25s;
|
||||
// transition: 0.25s;
|
||||
/* margin-bottom: 1px; */
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
|
@ -663,7 +663,7 @@ key {
|
|||
}
|
||||
|
||||
.word.active {
|
||||
color: var(--active-word-color);
|
||||
color: var(--sub-color);
|
||||
}
|
||||
|
||||
.word letter {
|
||||
|
@ -795,11 +795,11 @@ key {
|
|||
width: min-content;
|
||||
width: -moz-min-content;
|
||||
}
|
||||
.themes{
|
||||
.themes, .languages{
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
// gap: 1rem;
|
||||
.theme{
|
||||
.theme, .language{
|
||||
// padding: 1rem 2rem;
|
||||
text-align: center;
|
||||
color: var(--sub-color);
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Monkey Type</title>
|
||||
<link rel="stylesheet" href="css/fa.css">
|
||||
<link rel="stylesheet" href="themes/dark.css" id="currentTheme">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="stylesheet" href="themes/dark.css" id="currentTheme">
|
||||
<link rel="shortcut icon" href="favicon.png">
|
||||
|
||||
</head>
|
||||
|
@ -89,7 +89,7 @@
|
|||
<div class="group punctuationMode">
|
||||
<!-- <div class="title">time</div> -->
|
||||
<div class="buttons">
|
||||
<div class="button toggleButton active" tabindex="2">punctuation</div>
|
||||
<div class="button toggleButton" tabindex="2">punctuation</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group mode">
|
||||
|
@ -193,11 +193,6 @@
|
|||
<p><a href="https://www.reddit.com/r/MechanicalKeyboards/comments/gc6wx3/experimenting_with_a_completely_new_type_of/">everyone</a> who provided
|
||||
valuable feedback on the original reddit post for the prototype of this website</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1>support</h1>
|
||||
<p>If yo are feeling extra awesome and wish to support further development, you can do so <a href="https://www.paypal.me/jackbartnik">here</a>.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="page pageSettings hidden">
|
||||
<div class="tip" style="grid-column: 1/3;">tip: You can also change all these settings quickly using the command line (<key>esc</key>)</div>
|
||||
|
@ -221,16 +216,14 @@
|
|||
<div class="text">Shows the keybind tips at the bottom of the page.</div>
|
||||
<div class="buttons"><div class="button on" tabindex="0">show</div><div class="button off" tabindex="0">hide</div></div>
|
||||
</div>
|
||||
<div class="section" style="grid-column: 1/3;">
|
||||
<h1>languages</h1>
|
||||
<div class="languages">
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" style="grid-column: 1/3;">
|
||||
<h1>theme</h1>
|
||||
<div class="themes">
|
||||
<div class="theme">light</div>
|
||||
<div class="theme active">dark</div>
|
||||
<div class="theme">light</div>
|
||||
<div class="theme">light</div>
|
||||
<div class="theme">light</div>
|
||||
<div class="theme">light</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -335,12 +328,11 @@
|
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-trendline@0.1.3/src/chartjs-plugin-trendline.min.js"></script>
|
||||
|
||||
<script src="js/words.js"></script>
|
||||
<script src="js/db.js"></script>
|
||||
<script src="js/commandline.js"></script>
|
||||
<script src="js/settings.js"></script>
|
||||
<script src="js/userconfig.js"></script>
|
||||
<script src="js/words.js"></script>
|
||||
<script src="js/script.js"></script>
|
||||
<script src="js/account.js"></script>
|
||||
|
||||
|
|
|
@ -289,7 +289,8 @@ var resultHistoryChart = new Chart($(".pageAccount #resultHistoryChart"), {
|
|||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
fontFamily: "Roboto Mono"
|
||||
fontFamily: "Roboto Mono",
|
||||
beginAtZero: true
|
||||
},
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
|
|
|
@ -51,6 +51,15 @@ let commands = {
|
|||
showCommandLine();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeLanguage",
|
||||
display: "Change language...",
|
||||
subgroup: true,
|
||||
exec: () => {
|
||||
currentCommands = commandsLanguages;
|
||||
showCommandLine();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "changeMode",
|
||||
display: "Change mode...",
|
||||
|
@ -237,7 +246,7 @@ let themesList;
|
|||
|
||||
$.getJSON("themes/list.json", function(data) {
|
||||
commandsThemes.list = [];
|
||||
themesList = data;
|
||||
themesList = data.sort();
|
||||
data.forEach(theme => {
|
||||
commandsThemes.list.push({
|
||||
id: "changeTheme" + capitalizeFirstLetter(theme),
|
||||
|
@ -263,6 +272,31 @@ let commandsThemes = {
|
|||
]
|
||||
};
|
||||
|
||||
let commandsLanguages = {
|
||||
title: "Change language...",
|
||||
list: [
|
||||
{
|
||||
id: "couldnotload",
|
||||
display: "Could not load the languages list :("
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
if (Object.keys(words).length > 0) {
|
||||
commandsLanguages.list = [];
|
||||
Object.keys(words).forEach(language => {
|
||||
commandsLanguages.list.push({
|
||||
id: "changeLanguage" + capitalizeFirstLetter(language),
|
||||
display: language.replace('_', ' '),
|
||||
exec: () => {
|
||||
changeLanguage(language);
|
||||
restartTest();
|
||||
saveConfigToCookie();
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
$("#commandLine input").keyup((e) => {
|
||||
if (e.keyCode == 38 || e.keyCode == 40) return;
|
||||
updateSuggestedCommands();
|
||||
|
|
|
@ -78,18 +78,28 @@ function initWords() {
|
|||
inputHistory = [];
|
||||
currentInput = "";
|
||||
|
||||
let language = words[config.language];
|
||||
|
||||
if (language == undefined || language == []) {
|
||||
config.language = "english";
|
||||
language = words[config.language];
|
||||
}
|
||||
|
||||
if (config.mode == "time" || config.mode == "words") {
|
||||
|
||||
let wordsBound = config.mode == "time" ? 50 : config.words;
|
||||
let randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
wordsList.push(randomWord);
|
||||
let randomWord = language[Math.floor(Math.random() * language.length)];
|
||||
while (randomWord.indexOf(' ') > -1) {
|
||||
randomWord = language[Math.floor(Math.random() * language.length)];
|
||||
}
|
||||
wordsList.push(randomWord.toLowerCase());
|
||||
for (let i = 1; i < wordsBound; i++) {
|
||||
randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
randomWord = language[Math.floor(Math.random() * language.length)];
|
||||
previousWord = wordsList[i - 1];
|
||||
while (randomWord == previousWord && (!config.punctuation && "I")) {
|
||||
randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
while (randomWord == previousWord || (!config.punctuation && randomWord == "I") || randomWord.indexOf(' ') > -1) {
|
||||
randomWord = language[Math.floor(Math.random() * language.length)];
|
||||
}
|
||||
wordsList.push(randomWord);
|
||||
wordsList.push(randomWord.toLowerCase());
|
||||
}
|
||||
|
||||
} else if (config.mode == "custom") {
|
||||
|
@ -98,7 +108,7 @@ function initWords() {
|
|||
wordsList.push(w[i]);
|
||||
}
|
||||
}
|
||||
if (config.punctuation) {
|
||||
if (config.punctuation && config.mode != "custom") {
|
||||
wordsList = buildSentences(wordsList);
|
||||
}
|
||||
showWords();
|
||||
|
@ -108,13 +118,20 @@ function buildSentences() {
|
|||
let returnList = [];
|
||||
$.each(wordsList, (index, word) => {
|
||||
let previousWord = returnList[index - 1];
|
||||
if (index == 0 || getLastChar(previousWord) == ".") {
|
||||
if (index == 0 || getLastChar(previousWord) == "." || getLastChar(previousWord) == "?" || getLastChar(previousWord) == "!") {
|
||||
//always capitalise the first word or if there was a dot
|
||||
word = capitalizeFirstLetter(word);
|
||||
} else if (
|
||||
//10% chance to add a dot or if its a last word
|
||||
//10% chance to end a sentence
|
||||
(Math.random() < 0.1 && getLastChar(previousWord) != "." && index != wordsList.length - 2) || index == wordsList.length - 1) {
|
||||
word += ".";
|
||||
let rand = Math.random();
|
||||
if (rand <= 0.8) {
|
||||
word += ".";
|
||||
} else if (rand > .8 && rand < .9){
|
||||
word += "?";
|
||||
} else {
|
||||
word += "!";
|
||||
}
|
||||
} else if (Math.random() < 0.01 &&
|
||||
getLastChar(previousWord) != "," &&
|
||||
getLastChar(previousWord) != ".") {
|
||||
|
@ -144,7 +161,11 @@ function buildSentences() {
|
|||
}
|
||||
|
||||
function addWord() {
|
||||
let randomWord = words[Math.floor(Math.random() * words.length)];
|
||||
let language = words[config.language]
|
||||
let randomWord = language[Math.floor(Math.random() * language.length)];
|
||||
while (randomWord.indexOf(' ') > -1) {
|
||||
randomWord = language[Math.floor(Math.random() * language.length)];
|
||||
}
|
||||
wordsList.push(randomWord);
|
||||
let w = "<div class='word'>";
|
||||
for (let c = 0; c < randomWord.length; c++) {
|
||||
|
@ -378,7 +399,7 @@ function calculateStats() {
|
|||
let testNow = Date.now();
|
||||
let testSeconds = (testNow - testStart) / 1000;
|
||||
let wpm = Math.round((chars.correctWordChars * (60 / testSeconds)) / 5);
|
||||
let acc = Math.round((accuracyStats.correct / (accuracyStats.correct + accuracyStats.incorrect)) * 100);
|
||||
let acc = Math.floor((accuracyStats.correct / (accuracyStats.correct + accuracyStats.incorrect)) * 100);
|
||||
return { wpm: wpm, acc: acc, correctChars: chars.allCorrectChars, incorrectChars: chars.incorrectChars + chars.extraChars + chars.missedChars };
|
||||
}
|
||||
|
||||
|
@ -416,7 +437,8 @@ function showResult() {
|
|||
mode: config.mode,
|
||||
mode2: mode2,
|
||||
punctuation: config.punctuation,
|
||||
timestamp: Date.now()
|
||||
timestamp: Date.now(),
|
||||
language: config.language
|
||||
};
|
||||
if (stats.wpm > 0 && stats.wpm < 250 && stats.acc > 50 && stats.acc <= 100) {
|
||||
if (firebase.auth().currentUser != null) {
|
||||
|
@ -445,15 +467,17 @@ function showResult() {
|
|||
|
||||
|
||||
let infoText = "";
|
||||
infoText = config.mode;
|
||||
|
||||
|
||||
infoText += config.mode;
|
||||
if (config.mode == "time") {
|
||||
infoText += " " + config.time
|
||||
} else if (config.mode == "words") {
|
||||
infoText += " " + config.words
|
||||
}
|
||||
infoText += "<br>" + config.language.replace('_', ' ') ;
|
||||
if (config.punctuation) {
|
||||
infoText += " with punctuation"
|
||||
infoText += "<br>with punctuation"
|
||||
}
|
||||
|
||||
$("#result .stats .info .bottom").html(infoText);
|
||||
|
@ -829,6 +853,7 @@ $(document).keypress(function(event) {
|
|||
if (!$("#wordsInput").is(":focus")) return;
|
||||
if (event["keyCode"] == 13) return;
|
||||
if (event["keyCode"] == 32) return;
|
||||
if (event["keyCode"] == 27) return;
|
||||
//start the test
|
||||
if (currentInput == "" && inputHistory.length == 0) {
|
||||
if (firebase.auth().currentUser != null) {
|
||||
|
@ -1030,7 +1055,8 @@ let wpmOverTimeChart = new Chart(ctx, {
|
|||
labelString: 'Words per Minute'
|
||||
},
|
||||
ticks: {
|
||||
fontFamily: 'Roboto Mono'
|
||||
fontFamily: 'Roboto Mono',
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
|
|
@ -2,20 +2,22 @@ function updateSettingsPage(){
|
|||
|
||||
let themesEl = $(".pageSettings .section .themes").empty();
|
||||
themesList.forEach(theme => {
|
||||
if (config.theme == 'theme') {
|
||||
themesEl.append(`<div class="theme active" theme='${theme}'>${theme.replace('_', ' ')}</div>`);
|
||||
} else {
|
||||
themesEl.append(`<div class="theme" theme='${theme}'>${theme.replace('_', ' ')}</div>`);
|
||||
}
|
||||
themesEl.append(`<div class="theme" theme='${theme}'>${theme.replace('_', ' ')}</div>`);
|
||||
})
|
||||
|
||||
|
||||
let langEl = $(".pageSettings .section .languages").empty();
|
||||
Object.keys(words).forEach(language => {
|
||||
langEl.append(`<div class="language" language='${language}'>${language.replace('_', ' ')}</div>`);
|
||||
})
|
||||
|
||||
setSettingsButton('smoothCaret', config.smoothCaret);
|
||||
setSettingsButton('quickTab', config.quickTab);
|
||||
setSettingsButton('liveWpm', config.showLiveWpm);
|
||||
setSettingsButton('keyTips', config.showKeyTips);
|
||||
|
||||
setActiveThemeButton();
|
||||
setActiveLanguageButton();
|
||||
|
||||
if (config.showKeyTips) {
|
||||
$(".pageSettings .tip").removeClass('hidden');
|
||||
} else {
|
||||
|
@ -25,6 +27,16 @@ function updateSettingsPage(){
|
|||
|
||||
}
|
||||
|
||||
function setActiveThemeButton() {
|
||||
$(`.pageSettings .section .themes .theme`).removeClass('active');
|
||||
$(`.pageSettings .section .themes .theme[theme=${config.theme}]`).addClass('active');
|
||||
}
|
||||
|
||||
function setActiveLanguageButton() {
|
||||
$(`.pageSettings .section .languages .language`).removeClass('active');
|
||||
$(`.pageSettings .section .languages .language[language=${config.language}]`).addClass('active');
|
||||
}
|
||||
|
||||
function setSettingsButton(buttonSection,tf) {
|
||||
if (tf) {
|
||||
$(".pageSettings .section."+buttonSection+" .buttons .button.on").addClass('active');
|
||||
|
@ -94,6 +106,7 @@ $(".pageSettings .section.keyTips .buttons .button.off").click(e => {
|
|||
}
|
||||
})
|
||||
|
||||
//themes
|
||||
$(document).on("mouseover",".pageSettings .section .themes .theme", (e) => {
|
||||
let theme = $(e.currentTarget).attr('theme');
|
||||
previewTheme(theme);
|
||||
|
@ -102,8 +115,17 @@ $(document).on("mouseover",".pageSettings .section .themes .theme", (e) => {
|
|||
$(document).on("click",".pageSettings .section .themes .theme", (e) => {
|
||||
let theme = $(e.currentTarget).attr('theme');
|
||||
setTheme(theme);
|
||||
setActiveThemeButton();
|
||||
})
|
||||
|
||||
$(document).on("mouseleave",".pageSettings .section .themes", (e) => {
|
||||
setTheme(config.theme);
|
||||
})
|
||||
|
||||
//languages
|
||||
$(document).on("click",".pageSettings .section .languages .language", (e) => {
|
||||
let language = $(e.currentTarget).attr('language');
|
||||
changeLanguage(language);
|
||||
restartTest();
|
||||
setActiveLanguageButton();
|
||||
})
|
|
@ -7,7 +7,8 @@ let config = {
|
|||
punctuation: false,
|
||||
words: 50,
|
||||
time: 30,
|
||||
mode: "words"
|
||||
mode: "words",
|
||||
language: "english"
|
||||
}
|
||||
|
||||
//cookies
|
||||
|
@ -28,6 +29,7 @@ function loadConfigFromCookie() {
|
|||
changeTimeConfig(newConfig.time);
|
||||
changeWordCount(newConfig.words);
|
||||
changeMode(newConfig.mode);
|
||||
changeLanguage(newConfig.language);
|
||||
config = newConfig;
|
||||
restartTest();
|
||||
}
|
||||
|
@ -136,5 +138,18 @@ function previewTheme(name) {
|
|||
function setTheme(name) {
|
||||
config.theme = name;
|
||||
$("#currentTheme").attr("href", `themes/${name}.css`);
|
||||
firebase.analytics().logEvent('changedTheme', name);
|
||||
firebase.analytics().logEvent('changedTheme', {
|
||||
theme: name
|
||||
});
|
||||
}
|
||||
|
||||
function changeLanguage(language) {
|
||||
if (language == null || language == undefined) {
|
||||
language = "english";
|
||||
}
|
||||
config.language = language;
|
||||
firebase.analytics().logEvent('changedLanguage', {
|
||||
language: language
|
||||
});
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,6 @@
|
|||
/* Dark Blue: #3c4756
|
||||
Light Blue: #a2aebd
|
||||
Pink: #f44c7f */
|
||||
|
||||
:root {
|
||||
--bg-color: #3c4756;
|
||||
--main-color: #f44c7f;
|
||||
--caret-color: #f44c7f;
|
||||
--sub-color: #a2aebd;
|
||||
--active-word-color: #a2aebd;
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
/* yellow #e2b714
|
||||
dark #323437
|
||||
light #d1d0c5 */
|
||||
|
||||
:root {
|
||||
--bg-color: #414755;
|
||||
--main-color: #ec4c56;
|
||||
--caret-color: #ec4c56;
|
||||
--sub-color: #ebeaef;
|
||||
--active-word-color: #ebeaef;
|
||||
}
|
||||
.word letter.incorrect{
|
||||
color: #ebe04c;
|
||||
}
|
||||
.word.error{
|
||||
border-bottom: 2px solid #ebe04c;
|
||||
}
|
||||
.word letter.incorrect.extra {
|
||||
color: #797717;
|
||||
}
|
|
@ -3,5 +3,4 @@
|
|||
--main-color: #ed6b21;
|
||||
--caret-color: #ed6b21;
|
||||
--sub-color: #e3d9c6;
|
||||
--active-word-color: #e3d9c6;
|
||||
}
|
|
@ -3,5 +3,4 @@
|
|||
--main-color: #eee;
|
||||
--caret-color: #eee;
|
||||
--sub-color: #444;
|
||||
--active-word-color: #444;
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
--caret-color: #fff;
|
||||
--main-color: #fff;
|
||||
--sub-color: #7f88ab;
|
||||
--active-word-color: #7f88ab;
|
||||
}
|
||||
|
||||
#menu{
|
||||
|
|
|
@ -3,5 +3,4 @@
|
|||
--main-color: #009eaf;
|
||||
--caret-color: #009eaf;
|
||||
--sub-color: #b82356;
|
||||
--active-word-color: #b82356;
|
||||
}
|
||||
|
|
|
@ -3,5 +3,4 @@
|
|||
--main-color: #111;
|
||||
--caret-color: #111;
|
||||
--sub-color: #ccc;
|
||||
--active-word-color: #ccc;
|
||||
}
|
|
@ -13,5 +13,6 @@
|
|||
"oblivion",
|
||||
"laser",
|
||||
"retro",
|
||||
"dracula"
|
||||
]
|
||||
"dracula",
|
||||
"nord"
|
||||
]
|
||||
|
|
|
@ -3,5 +3,4 @@
|
|||
--main-color: #eab622;
|
||||
--caret-color: #eab622;
|
||||
--sub-color: #1db8a8;
|
||||
--active-word-color: #1db8a8;
|
||||
}
|
18
public/themes/nord.css
Normal file
18
public/themes/nord.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
:root {
|
||||
--bg-color: #242933;
|
||||
--caret-color: #d8dee9;
|
||||
--main-color: #d8dee9;
|
||||
--sub-color: #617b94;
|
||||
}
|
||||
|
||||
.word letter.incorrect {
|
||||
color: #bf616a;
|
||||
}
|
||||
|
||||
.word letter.incorrect.extra {
|
||||
color: #793e44;
|
||||
}
|
||||
|
||||
.word.error {
|
||||
border-bottom: 2px solid #bf616a;
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
--main-color: #a5a096;
|
||||
--caret-color: #a5a096;
|
||||
--sub-color: #5d6263;
|
||||
--active-word-color: #5d6263;
|
||||
}
|
||||
|
||||
#menu .button:nth-child(1){
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
/* :root{
|
||||
--bg-color: #17171b;
|
||||
--main-color: #c79e6e;
|
||||
--caret-color: #c79e6e;
|
||||
--sub-color: #b43a49;
|
||||
--active-word-color: #b43a49;
|
||||
} */
|
||||
|
||||
:root{
|
||||
--bg-color: #84202c;
|
||||
--main-color: #17171b;
|
||||
--caret-color: #17171b;
|
||||
--sub-color: #c79e6e;
|
||||
--active-word-color: #c79e6e;
|
||||
}
|
|
@ -3,5 +3,4 @@
|
|||
--main-color: #1d181a;
|
||||
--caret-color: #1d181a;
|
||||
--sub-color: #ccc;
|
||||
--active-word-color: #ccc;
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
--main-color: #eee;
|
||||
--caret-color: #eee;
|
||||
--sub-color: #444;
|
||||
--active-word-color: #444;
|
||||
}
|
||||
|
||||
@keyframes rgb{
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
/* yellow #e2b714
|
||||
dark #323437
|
||||
light #d1d0c5 */
|
||||
|
||||
:root {
|
||||
--bg-color: #e2b714;
|
||||
--main-color: #323437;
|
||||
--caret-color: #323437;
|
||||
--sub-color: #d1d0c5;
|
||||
--active-word-color: #d1d0c5;
|
||||
}
|
|
@ -1,11 +1,6 @@
|
|||
/* yellow #e2b714
|
||||
dark #323437
|
||||
light #d1d0c5 */
|
||||
|
||||
:root {
|
||||
--bg-color: #323437;
|
||||
--main-color: #e2b714;
|
||||
--caret-color: #e2b714;
|
||||
--sub-color: #d1d0c5;
|
||||
--active-word-color: #d1d0c5;
|
||||
}
|
Loading…
Add table
Reference in a new issue