mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-03-13 15:36:42 +08:00
Merge branch 'master' of https://github.com/Miodec/monkeytype
This commit is contained in:
commit
8fcf467f7b
16 changed files with 1191 additions and 17 deletions
5
.firebaserc_example
Normal file
5
.firebaserc_example
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"projects": {
|
||||
"default": "your-firebase-project-id"
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ Montydrei for the name suggestion
|
|||
|
||||
Everyone who provided valuable feedback on the original reddit post for the prototype of this website
|
||||
|
||||
Contributors that have helped with implementing various features, adding themes and more.
|
||||
Contributors that have helped with implementing various features, adding themes and more
|
||||
|
||||
# support
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ function getAccountDataAndInit() {
|
|||
} else {
|
||||
accountIconLoading(false);
|
||||
}
|
||||
if (config.paceCaret === "pb") {
|
||||
if (config.paceCaret === "pb" || config.paceCaret === "average") {
|
||||
if (!testActive) {
|
||||
initPaceCaret(true);
|
||||
}
|
||||
|
@ -2433,4 +2433,3 @@ $(".pageLogin #forgotPasswordButton").click((e) => {
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1001,6 +1001,13 @@ let commandsPaceCaret = {
|
|||
setPaceCaret("pb");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "setPaceCaretAverage",
|
||||
display: "average",
|
||||
exec: () => {
|
||||
setPaceCaret("average");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "setPaceCaretCustom",
|
||||
display: "custom...",
|
||||
|
|
47
src/js/db.js
47
src/js/db.js
|
@ -31,6 +31,11 @@ export async function db_getUserSnapshot() {
|
|||
daily: null,
|
||||
},
|
||||
},
|
||||
globalStats: {
|
||||
time: 0,
|
||||
started: 0,
|
||||
completed: 0,
|
||||
},
|
||||
};
|
||||
try {
|
||||
await db
|
||||
|
@ -157,6 +162,48 @@ export async function db_getUserHighestWpm(
|
|||
return retval;
|
||||
}
|
||||
|
||||
export async function db_getUserAverageWpm10(
|
||||
mode,
|
||||
mode2,
|
||||
punctuation,
|
||||
language,
|
||||
difficulty
|
||||
) {
|
||||
function cont() {
|
||||
let wpmSum = 0;
|
||||
let count = 0;
|
||||
let i = 0;
|
||||
// You have to use every so you can break out of the loop
|
||||
dbSnapshot.results.every((result) => {
|
||||
if (
|
||||
result.mode == mode &&
|
||||
result.mode2 == mode2 &&
|
||||
result.punctuation == punctuation &&
|
||||
result.language == language &&
|
||||
result.difficulty == difficulty
|
||||
) {
|
||||
wpmSum += result.wpm;
|
||||
count++;
|
||||
if (count >= 10) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return Math.round(wpmSum / count);
|
||||
}
|
||||
|
||||
let retval = 0;
|
||||
|
||||
if (dbSnapshot == null) return retval;
|
||||
var dbSnapshotValid = await db_getUserResults();
|
||||
if (dbSnapshotValid === false) {
|
||||
return retval;
|
||||
}
|
||||
retval = cont();
|
||||
return retval;
|
||||
}
|
||||
|
||||
export async function db_getLocalPB(
|
||||
mode,
|
||||
mode2,
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
db_getUserResults,
|
||||
db_getUserHighestWpm,
|
||||
db_getLocalPB,
|
||||
db_getUserAverageWpm10,
|
||||
db_saveLocalPB,
|
||||
db_getLocalTagPB,
|
||||
db_saveLocalTagPB,
|
||||
|
|
|
@ -321,7 +321,11 @@ export function getReleasesFromGitHub() {
|
|||
// }
|
||||
|
||||
export function getLastChar(word) {
|
||||
return word.charAt(word.length - 1);
|
||||
try {
|
||||
return word.charAt(word.length - 1);
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export function capitalizeFirstLetter(str) {
|
||||
|
|
|
@ -45,6 +45,8 @@ let paceCaret = null;
|
|||
let missedWords = [];
|
||||
let verifyUserWhenLoggedIn = null;
|
||||
let modeBeforePractise = null;
|
||||
let punctuationBeforePractise = null;
|
||||
let numbersBeforePractise = null;
|
||||
let memoryFunboxTimer = null;
|
||||
let memoryFunboxInterval = null;
|
||||
|
||||
|
@ -2687,6 +2689,7 @@ function startTest() {
|
|||
const delay = expectedStepEnd - performance.now();
|
||||
timer = setTimeout(function () {
|
||||
time++;
|
||||
$(".pageTest #premidSecondsLeft").text(config.time - time);
|
||||
if (config.mode === "time") {
|
||||
updateTimer();
|
||||
}
|
||||
|
@ -2801,7 +2804,11 @@ function restartTest(withSameWordset = false, nosave = false) {
|
|||
if (modeBeforePractise !== null && !withSameWordset) {
|
||||
Misc.showNotification("Reverting to previous settings.", 1500);
|
||||
setMode(modeBeforePractise);
|
||||
setPunctuation(punctuationBeforePractise);
|
||||
setNumbers(numbersBeforePractise);
|
||||
modeBeforePractise = null;
|
||||
punctuationBeforePractise = null;
|
||||
numbersBeforePractise = null;
|
||||
}
|
||||
|
||||
manualRestart = false;
|
||||
|
@ -2902,6 +2909,25 @@ function restartTest(withSameWordset = false, nosave = false) {
|
|||
document.querySelector("#liveWpm").innerHTML = "0";
|
||||
document.querySelector("#liveAcc").innerHTML = "100%";
|
||||
|
||||
let mode2 = "";
|
||||
if (config.mode === "time") {
|
||||
mode2 = config.time;
|
||||
} else if (config.mode === "words") {
|
||||
mode2 = config.words;
|
||||
} else if (config.mode === "custom") {
|
||||
mode2 = "custom";
|
||||
} else if (config.mode === "quote") {
|
||||
mode2 = randomQuote.id;
|
||||
}
|
||||
let fbtext = "";
|
||||
if (activeFunBox !== "none") {
|
||||
fbtext = " " + activeFunBox;
|
||||
}
|
||||
$(".pageTest #premidTestMode").text(
|
||||
`${config.mode} ${mode2} ${config.language}${fbtext}`
|
||||
);
|
||||
$(".pageTest #premidSecondsLeft").text(config.time);
|
||||
|
||||
if (activeFunBox === "layoutfluid") {
|
||||
setLayout("qwerty");
|
||||
settingsGroups.layout.updateButton();
|
||||
|
@ -3599,10 +3625,18 @@ function updateTestModesNotice() {
|
|||
}
|
||||
|
||||
if (config.paceCaret !== "off") {
|
||||
let speed = "";
|
||||
try {
|
||||
speed = ` (${Math.round(paceCaret.wpm)} wpm)`;
|
||||
} catch {}
|
||||
$(".pageTest #testModesNotice").append(
|
||||
`<div class="text-button" commands="commandsPaceCaret"><i class="fas fa-tachometer-alt"></i>${
|
||||
config.paceCaret === "pb" ? "pb" : config.paceCaretCustomSpeed + " wpm"
|
||||
} pace</div>`
|
||||
config.paceCaret === "average"
|
||||
? "average"
|
||||
: config.paceCaret === "pb"
|
||||
? "pb"
|
||||
: "custom"
|
||||
} pace${speed}</div>`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3947,6 +3981,25 @@ async function initPaceCaret() {
|
|||
config.language,
|
||||
config.difficulty
|
||||
);
|
||||
} else if (config.paceCaret === "average") {
|
||||
let mode2 = "";
|
||||
if (config.mode === "time") {
|
||||
mode2 = config.time;
|
||||
} else if (config.mode === "words") {
|
||||
mode2 = config.words;
|
||||
} else if (config.mode === "custom") {
|
||||
mode2 = "custom";
|
||||
} else if (config.mode === "quote") {
|
||||
mode2 = randomQuote.id;
|
||||
}
|
||||
wpm = await db_getUserAverageWpm10(
|
||||
config.mode,
|
||||
mode2,
|
||||
config.punctuation,
|
||||
config.language,
|
||||
config.difficulty
|
||||
);
|
||||
console.log("avg pace " + wpm);
|
||||
} else if (config.paceCaret === "custom") {
|
||||
wpm = config.paceCaretCustomSpeed;
|
||||
}
|
||||
|
@ -3960,9 +4013,8 @@ async function initPaceCaret() {
|
|||
let cps = characters / 60; //characters per step
|
||||
let spc = 60 / characters; //seconds per character
|
||||
|
||||
updateTestModesNotice();
|
||||
|
||||
paceCaret = {
|
||||
wpm: wpm,
|
||||
cps: cps,
|
||||
spc: spc,
|
||||
correction: 0,
|
||||
|
@ -3971,6 +4023,8 @@ async function initPaceCaret() {
|
|||
wordsStatus: {},
|
||||
timeout: null,
|
||||
};
|
||||
|
||||
updateTestModesNotice();
|
||||
}
|
||||
|
||||
function movePaceCaret(expectedStepEnd) {
|
||||
|
@ -4331,7 +4385,13 @@ $(document.body).on("click", "#restartTestButton", () => {
|
|||
});
|
||||
|
||||
function initPractiseMissedWords() {
|
||||
let currentMode = config.mode;
|
||||
let mode = modeBeforePractise === null ? config.mode : modeBeforePractise;
|
||||
let punctuation =
|
||||
punctuationBeforePractise === null
|
||||
? config.punctuation
|
||||
: punctuationBeforePractise;
|
||||
let numbers =
|
||||
numbersBeforePractise === null ? config.numbers : numbersBeforePractise;
|
||||
setMode("custom");
|
||||
let newCustomText = [];
|
||||
Object.keys(missedWords).forEach((missedWord) => {
|
||||
|
@ -4342,10 +4402,14 @@ function initPractiseMissedWords() {
|
|||
customText = newCustomText;
|
||||
customTextIsRandom = true;
|
||||
customTextWordCount = 50;
|
||||
let mode = modeBeforePractise === null ? currentMode : modeBeforePractise;
|
||||
|
||||
modeBeforePractise = null;
|
||||
punctuationBeforePractise = null;
|
||||
numbersBeforePractise = null;
|
||||
restartTest();
|
||||
modeBeforePractise = mode;
|
||||
punctuationBeforePractise = punctuation;
|
||||
numbersBeforePractise = numbers;
|
||||
}
|
||||
|
||||
$(document).on("keypress", "#practiseMissedWordsButton", (event) => {
|
||||
|
@ -5004,7 +5068,11 @@ function handleAlpha(event) {
|
|||
if (/F\d+/.test(event.key)) return;
|
||||
if (/Numpad/.test(event.key)) return;
|
||||
if (/Volume/.test(event.key)) return;
|
||||
if (event.ctrlKey && !event.altKey) return;
|
||||
if (
|
||||
event.ctrlKey != event.altKey &&
|
||||
(event.ctrlKey || /Linux/.test(window.navigator.platform))
|
||||
)
|
||||
return;
|
||||
if (event.metaKey) return;
|
||||
event = emulateLayout(event);
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ function resetConfig() {
|
|||
config = {
|
||||
...defaultConfig,
|
||||
};
|
||||
applyConfig();
|
||||
applyConfig(config);
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
||||
|
@ -1615,4 +1615,3 @@ function applyConfig(configObj) {
|
|||
}
|
||||
updateTestModesNotice();
|
||||
}
|
||||
|
||||
|
|
|
@ -733,6 +733,11 @@ a:hover {
|
|||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.subtext {
|
||||
color: var(--sub-color);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
|
|
|
@ -806,6 +806,10 @@
|
|||
<div class="text">Buy Merch</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="subtext">
|
||||
FYI: Ads can be broken sometimes because Google keeps disabling them.
|
||||
:|
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="commandLineWrapper" class="hidden">
|
||||
|
@ -1216,6 +1220,8 @@
|
|||
<div class="right hidden"></div>
|
||||
<div class="both hidden"></div>
|
||||
</div>
|
||||
<div id="premidTestMode" class="hidden"></div>
|
||||
<div id="premidSecondsLeft" class="hidden"></div>
|
||||
</div>
|
||||
<div id="result" class="hidden">
|
||||
<div class="stats">
|
||||
|
@ -1642,7 +1648,7 @@
|
|||
<div class="buttons">
|
||||
<a
|
||||
class="button"
|
||||
href="https://discord.com/api/oauth2/authorize?client_id=757704816532258856&redirect_uri=https%3A%2F%2Fmonkeytype.com%2Fverify&response_type=token&scope=identify"
|
||||
href="https://discord.com/api/oauth2/authorize?client_id=798272335035498557&redirect_uri=https%3A%2F%2Fmonkeytype.com%2Fverify&response_type=token&scope=identify"
|
||||
style="text-decoration: none"
|
||||
>
|
||||
Verify with Discord
|
||||
|
@ -2211,6 +2217,14 @@
|
|||
>
|
||||
off
|
||||
</div>
|
||||
<div
|
||||
class="button"
|
||||
paceCaret="average"
|
||||
tabindex="0"
|
||||
onclick="this.blur();"
|
||||
>
|
||||
average
|
||||
</div>
|
||||
<div
|
||||
class="button"
|
||||
paceCaret="pb"
|
||||
|
|
1007
static/languages/code_javascript_1k.json
Normal file
1007
static/languages/code_javascript_1k.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -60,6 +60,7 @@
|
|||
,"code_csharp"
|
||||
,"code_c++"
|
||||
,"code_javascript"
|
||||
,"code_javascript_1k"
|
||||
,"code_html"
|
||||
,"code_java"
|
||||
,"code_go"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
--sub-color: #616161;
|
||||
--text-color: #f5e6c8;
|
||||
--error-color: #e72d2d;
|
||||
--colorful-error-color: #b62828;
|
||||
--colorful-error-color: #a5e72d;
|
||||
--colorful-error-extra-color: #74a120;
|
||||
--error-extra-color: #7e2a33;
|
||||
--colorful-error-color: #e72d2d;
|
||||
--colorful-error-extra-color: #7e2a33;
|
||||
}
|
||||
|
|
|
@ -473,5 +473,10 @@
|
|||
"name": "rudy",
|
||||
"bgColor": "#1a2b3e",
|
||||
"textColor": "#af8f5c"
|
||||
},
|
||||
{
|
||||
"name": "stealth",
|
||||
"bgColor": "#010203",
|
||||
"textColor": "#383e42"
|
||||
}
|
||||
]
|
||||
|
|
12
static/themes/stealth.css
Normal file
12
static/themes/stealth.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
:root{
|
||||
--bg-color: #010203;
|
||||
--main-color: #383e42;
|
||||
--caret-color: #e25303;
|
||||
--sub-color: #5e676e;
|
||||
--text-color: #383e42;
|
||||
--error-color: #e25303;
|
||||
--error-extra-color: #73280c;
|
||||
--colorful-error-color: #e25303;
|
||||
--colorful-error-extra-color: #73280c;
|
||||
}
|
||||
#menu .icon-button:nth-child(4){color:#e25303}
|
Loading…
Reference in a new issue