Merge pull request #1 from Miodec/master

update forked repo
This commit is contained in:
Alexander Ushaev 2020-11-20 13:33:33 +07:00 committed by GitHub
commit f35d09b798
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 4726 additions and 1868 deletions

View file

@ -829,346 +829,347 @@ async function incrementTimeSpentTyping(uid, res, userData) {
}
}
exports.testCompleted = functions
.runWith({ timeoutSeconds: 540, memory: "2GB" })
.https.onRequest(async (request, response) => {
response.set("Access-Control-Allow-Origin", "*");
if (request.method === "OPTIONS") {
// Send response to OPTIONS requests
response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.set(
"Access-Control-Allow-Headers",
"Authorization,Content-Type"
);
response.set("Access-Control-Max-Age", "3600");
response.status(204).send("");
return;
}
request = request.body.data;
if (request === undefined) {
exports.testCompleted = functions.https.onRequest(async (request, response) => {
response.set("Access-Control-Allow-Origin", "*");
if (request.method === "OPTIONS") {
// Send response to OPTIONS requests
response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
response.set("Access-Control-Max-Age", "3600");
response.status(204).send("");
return;
}
request = request.body.data;
if (request === undefined) {
response.status(200).send({ data: { resultCode: -999 } });
return;
}
try {
if (request.uid === undefined || request.obj === undefined) {
console.error(`error saving result for - missing input`);
response.status(200).send({ data: { resultCode: -999 } });
return;
}
try {
if (request.uid === undefined || request.obj === undefined) {
console.error(`error saving result for - missing input`);
response.status(200).send({ data: { resultCode: -999 } });
return;
}
let obj = request.obj;
let obj = request.obj;
function verifyValue(val) {
let errCount = 0;
if (Array.isArray(val)) {
//array
val.forEach((val2) => {
errCount += verifyValue(val2);
});
} else if (typeof val === "object" && !Array.isArray(val)) {
//object
Object.keys(val).forEach((valkey) => {
errCount += verifyValue(val[valkey]);
});
} else {
if (!/^[0-9a-zA-Z._]+$/.test(val)) errCount++;
}
return errCount;
}
let errCount = verifyValue(obj);
// console.log(errCount);
if (errCount > 0) {
console.error(
`error saving result for ${
request.uid
} error count ${errCount} - bad input - ${JSON.stringify(
request.obj
)}`
);
response.status(200).send({ data: { resultCode: -1 } });
return;
}
if (obj.wpm <= 0 || obj.wpm > 350 || obj.acc < 50 || obj.acc > 100) {
response.status(200).send({ data: { resultCode: -1 } });
return;
}
if (!validateResult(obj)) {
if (
obj.bailedOut &&
((obj.mode === "time" && obj.mode2 >= 3600) ||
(obj.mode === "words" && obj.mode2 >= 5000) ||
obj.mode === "custom")
) {
//dont give an error
} else {
response.status(200).send({ data: { resultCode: -4 } });
return;
}
}
let keySpacing = null;
let keyDuration = null;
try {
keySpacing = {
average:
obj.keySpacing.reduce(
(previous, current) => (current += previous)
) / obj.keySpacing.length,
sd: stdDev(obj.keySpacing),
};
keyDuration = {
average:
obj.keyDuration.reduce(
(previous, current) => (current += previous)
) / obj.keyDuration.length,
sd: stdDev(obj.keyDuration),
};
} catch (e) {
console.error(
`cant verify key spacing or duration for user ${request.uid}! - ${e} - ${obj.keySpacing} ${obj.keyDuration}`
);
}
obj.keySpacingStats = keySpacing;
obj.keyDurationStats = keyDuration;
if (obj.mode == "time" && (obj.mode2 == 15 || obj.mode2 == 60)) {
function verifyValue(val) {
let errCount = 0;
if (Array.isArray(val)) {
//array
val.forEach((val2) => {
errCount += verifyValue(val2);
});
} else if (typeof val === "object" && !Array.isArray(val)) {
//object
Object.keys(val).forEach((valkey) => {
errCount += verifyValue(val[valkey]);
});
} else {
obj.keySpacing = "removed";
obj.keyDuration = "removed";
if (!/^[0-9a-zA-Z._]+$/.test(val)) errCount++;
}
return errCount;
}
emailVerified = await admin
.auth()
.getUser(request.uid)
.then((user) => {
return user.emailVerified;
});
return db
.collection("users")
.doc(request.uid)
.get()
.then((ret) => {
let userdata = ret.data();
let name = userdata.name === undefined ? false : userdata.name;
let banned = userdata.banned === undefined ? false : userdata.banned;
let verified = userdata.verified;
request.obj.name = name;
//check keyspacing and duration here
if (obj.mode === "time" && obj.wpm > 130 && obj.testDuration < 122) {
if (verified === false || verified === undefined) {
if (keySpacing !== null && keyDuration !== null) {
if (
keySpacing.sd <= 15 ||
keyDuration.sd <= 10 ||
keyDuration.average < 15 ||
(obj.wpm > 200 && obj.consistency < 70)
) {
console.error(
`possible bot detected by user (${obj.wpm} ${obj.rawWpm} ${
obj.acc
}) ${request.uid} ${name} - spacing ${JSON.stringify(
keySpacing
)} duration ${JSON.stringify(keyDuration)}`
);
response.status(200).send({ data: { resultCode: -2 } });
return;
}
if (
(keySpacing.sd > 15 && keySpacing.sd <= 25) ||
(keyDuration.sd > 10 && keyDuration.sd <= 15) ||
(keyDuration.average > 15 && keyDuration.average <= 20)
) {
console.error(
`very close to bot detected threshold by user (${obj.wpm} ${
obj.rawWpm
} ${obj.acc}) ${
request.uid
} ${name} - spacing ${JSON.stringify(
keySpacing
)} duration ${JSON.stringify(keyDuration)}`
);
}
} else {
response.status(200).send({ data: { resultCode: -3 } });
return;
}
}
}
return db
.collection(`users/${request.uid}/results`)
.add(obj)
.then((e) => {
let createdDocId = e.id;
return Promise.all([
checkLeaderboards(
request.obj,
"global",
banned,
name,
verified,
emailVerified
),
checkLeaderboards(
request.obj,
"daily",
banned,
name,
verified,
emailVerified
),
checkIfPB(request.uid, request.obj, userdata),
])
.then(async (values) => {
let globallb = values[0].insertedAt;
let dailylb = values[1].insertedAt;
let ispb = values[2];
// console.log(values);
if (obj.mode === "time" && String(obj.mode2) === "60") {
incrementT60Bananas(request.uid, obj, userdata);
}
incrementTestCounter(request.uid, userdata);
incrementStartedTestCounter(
request.uid,
obj.restartCount + 1,
userdata
);
incrementTimeSpentTyping(request.uid, obj, userdata);
let usr =
userdata.discordId !== undefined
? userdata.discordId
: userdata.name;
if (
globallb !== null &&
globallb.insertedAt >= 0 &&
globallb.insertedAt <= 9 &&
globallb.newBest
) {
let lbstring = `${obj.mode} ${obj.mode2} global`;
console.log(
`sending command to the bot to announce lb update ${
userdata.discordId
} ${globallb + 1} ${lbstring} ${obj.wpm}`
);
announceLbUpdate(
usr,
globallb.insertedAt + 1,
lbstring,
obj.wpm,
obj.rawWpm,
obj.acc
);
}
let returnobj = {
resultCode: null,
globalLeaderboard: globallb,
dailyLeaderboard: dailylb,
lbBanned: banned,
name: name,
createdId: createdDocId,
needsToVerify: values[0].needsToVerify,
needsToVerifyEmail: values[0].needsToVerifyEmail,
};
if (ispb) {
let logobj = request.obj;
logobj.keySpacing = "removed";
logobj.keyDuration = "removed";
console.log(
`saved result for ${
request.uid
} (new PB) - ${JSON.stringify(logobj)}`
);
await db
.collection(`users/${request.uid}/results/`)
.doc(createdDocId)
.update({ isPb: true });
if (
obj.mode === "time" &&
String(obj.mode2) === "60" &&
userdata.discordId !== null &&
userdata.discordId !== undefined
) {
if (verified !== false) {
console.log(
`sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}`
);
updateDiscordRole(
userdata.discordId,
Math.round(obj.wpm)
);
}
}
returnobj.resultCode = 2;
} else {
let logobj = request.obj;
logobj.keySpacing = "removed";
logobj.keyDuration = "removed";
console.log(
`saved result for ${request.uid} - ${JSON.stringify(
logobj
)}`
);
returnobj.resultCode = 1;
}
response.status(200).send({ data: returnobj });
return;
})
.catch((e) => {
console.error(
`error saving result when checking for PB / checking leaderboards for ${request.uid} - ${e.message}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
});
})
.catch((e) => {
console.error(
`error saving result when adding result to the db for ${request.uid} - ${e.message}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
});
})
.catch((e) => {
console.error(
`error saving result when getting user data for ${request.uid} - ${e.message}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
});
} catch (e) {
let errCount = verifyValue(obj);
// console.log(errCount);
if (errCount > 0) {
console.error(
`error saving result for ${request.uid} - ${JSON.stringify(
request.obj
)} - ${e}`
`error saving result for ${
request.uid
} error count ${errCount} - bad input - ${JSON.stringify(request.obj)}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
response.status(200).send({ data: { resultCode: -1 } });
return;
}
});
if (obj.wpm <= 0 || obj.wpm > 350 || obj.acc < 50 || obj.acc > 100) {
response.status(200).send({ data: { resultCode: -1 } });
return;
}
if (!validateResult(obj)) {
if (
obj.bailedOut &&
((obj.mode === "time" && obj.mode2 >= 3600) ||
(obj.mode === "words" && obj.mode2 >= 5000) ||
obj.mode === "custom")
) {
//dont give an error
} else {
response.status(200).send({ data: { resultCode: -4 } });
return;
}
}
let keySpacing = null;
let keyDuration = null;
try {
keySpacing = {
average:
obj.keySpacing.reduce((previous, current) => (current += previous)) /
obj.keySpacing.length,
sd: stdDev(obj.keySpacing),
};
keyDuration = {
average:
obj.keyDuration.reduce((previous, current) => (current += previous)) /
obj.keyDuration.length,
sd: stdDev(obj.keyDuration),
};
} catch (e) {
console.error(
`cant verify key spacing or duration for user ${request.uid}! - ${e} - ${obj.keySpacing} ${obj.keyDuration}`
);
}
obj.keySpacingStats = keySpacing;
obj.keyDurationStats = keyDuration;
if (obj.mode == "time" && (obj.mode2 == 15 || obj.mode2 == 60)) {
} else {
obj.keySpacing = "removed";
obj.keyDuration = "removed";
}
emailVerified = await admin
.auth()
.getUser(request.uid)
.then((user) => {
return user.emailVerified;
});
return db
.collection("users")
.doc(request.uid)
.get()
.then((ret) => {
let userdata = ret.data();
let name = userdata.name === undefined ? false : userdata.name;
let banned = userdata.banned === undefined ? false : userdata.banned;
let verified = userdata.verified;
request.obj.name = name;
//check keyspacing and duration here
if (obj.mode === "time" && obj.wpm > 130 && obj.testDuration < 122) {
if (verified === false || verified === undefined) {
if (keySpacing !== null && keyDuration !== null) {
if (
keySpacing.sd <= 15 ||
keyDuration.sd <= 10 ||
keyDuration.average < 15 ||
(obj.wpm > 200 && obj.consistency < 70)
) {
console.error(
`possible bot detected by user (${obj.wpm} ${obj.rawWpm} ${
obj.acc
}) ${request.uid} ${name} - spacing ${JSON.stringify(
keySpacing
)} duration ${JSON.stringify(keyDuration)}`
);
response.status(200).send({ data: { resultCode: -2 } });
return;
}
if (
(keySpacing.sd > 15 && keySpacing.sd <= 25) ||
(keyDuration.sd > 10 && keyDuration.sd <= 15) ||
(keyDuration.average > 15 && keyDuration.average <= 20)
) {
console.error(
`very close to bot detected threshold by user (${obj.wpm} ${
obj.rawWpm
} ${obj.acc}) ${
request.uid
} ${name} - spacing ${JSON.stringify(
keySpacing
)} duration ${JSON.stringify(keyDuration)}`
);
}
} else {
response.status(200).send({ data: { resultCode: -3 } });
return;
}
}
}
//yeet the key data
obj.keySpacing = null;
obj.keyDuration = null;
try {
obj.keyDurationStats.average = roundTo2(obj.keyDurationStats.average);
obj.keyDurationStats.sd = roundTo2(obj.keyDurationStats.sd);
obj.keySpacingStats.average = roundTo2(obj.keySpacingStats.average);
obj.keySpacingStats.sd = roundTo2(obj.keySpacingStats.sd);
} catch (e) {}
return db
.collection(`users/${request.uid}/results`)
.add(obj)
.then((e) => {
let createdDocId = e.id;
return Promise.all([
checkLeaderboards(
request.obj,
"global",
banned,
name,
verified,
emailVerified
),
checkLeaderboards(
request.obj,
"daily",
banned,
name,
verified,
emailVerified
),
checkIfPB(request.uid, request.obj, userdata),
])
.then(async (values) => {
let globallb = values[0].insertedAt;
let dailylb = values[1].insertedAt;
let ispb = values[2];
// console.log(values);
if (obj.mode === "time" && String(obj.mode2) === "60") {
incrementT60Bananas(request.uid, obj, userdata);
}
incrementTestCounter(request.uid, userdata);
incrementStartedTestCounter(
request.uid,
obj.restartCount + 1,
userdata
);
incrementTimeSpentTyping(request.uid, obj, userdata);
let usr =
userdata.discordId !== undefined
? userdata.discordId
: userdata.name;
if (
globallb !== null &&
globallb.insertedAt >= 0 &&
globallb.insertedAt <= 9 &&
globallb.newBest
) {
let lbstring = `${obj.mode} ${obj.mode2} global`;
console.log(
`sending command to the bot to announce lb update ${
userdata.discordId
} ${globallb + 1} ${lbstring} ${obj.wpm}`
);
announceLbUpdate(
usr,
globallb.insertedAt + 1,
lbstring,
obj.wpm,
obj.rawWpm,
obj.acc
);
}
let returnobj = {
resultCode: null,
globalLeaderboard: globallb,
dailyLeaderboard: dailylb,
lbBanned: banned,
name: name,
createdId: createdDocId,
needsToVerify: values[0].needsToVerify,
needsToVerifyEmail: values[0].needsToVerifyEmail,
};
if (ispb) {
let logobj = request.obj;
logobj.keySpacing = "removed";
logobj.keyDuration = "removed";
console.log(
`saved result for ${
request.uid
} (new PB) - ${JSON.stringify(logobj)}`
);
await db
.collection(`users/${request.uid}/results/`)
.doc(createdDocId)
.update({ isPb: true });
if (
obj.mode === "time" &&
String(obj.mode2) === "60" &&
userdata.discordId !== null &&
userdata.discordId !== undefined
) {
if (verified !== false) {
console.log(
`sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}`
);
updateDiscordRole(
userdata.discordId,
Math.round(obj.wpm)
);
}
}
returnobj.resultCode = 2;
} else {
let logobj = request.obj;
logobj.keySpacing = "removed";
logobj.keyDuration = "removed";
console.log(
`saved result for ${request.uid} - ${JSON.stringify(
logobj
)}`
);
returnobj.resultCode = 1;
}
response.status(200).send({ data: returnobj });
return;
})
.catch((e) => {
console.error(
`error saving result when checking for PB / checking leaderboards for ${request.uid} - ${e.message}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
});
})
.catch((e) => {
console.error(
`error saving result when adding result to the db for ${request.uid} - ${e.message}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
});
})
.catch((e) => {
console.error(
`error saving result when getting user data for ${request.uid} - ${e.message}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
});
} catch (e) {
console.error(
`error saving result for ${request.uid} - ${JSON.stringify(
request.obj
)} - ${e}`
);
response
.status(200)
.send({ data: { resultCode: -999, message: e.message } });
return;
}
});
exports.updateEmail = functions.https.onCall(async (request, response) => {
try {

View file

@ -84,9 +84,9 @@
}
},
"@google-cloud/common": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.4.1.tgz",
"integrity": "sha512-e5z0CwsM0RXky+PnyPtQ3QK46ksqm+kE7kX8pm8X+ddBwZJipHchKeazMM5fLlGCS+AALalzXb+uYmH72TRnpQ==",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz",
"integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==",
"optional": true,
"requires": {
"@google-cloud/projectify": "^2.0.0",
@ -101,14 +101,14 @@
}
},
"@google-cloud/firestore": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.5.0.tgz",
"integrity": "sha512-sExt4E+TlBqyv4l/av6kBZ4YGS99Cc3P5UvLRNj9z41mT9ekPGhIzptbj4K6O7h0KCyDIDOiJdi4gUPH9lip4g==",
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.7.1.tgz",
"integrity": "sha512-Qici+WKB6uRdDS1S3CaxGrIaCl4Bck70DYSzA5dZFkTU03Jj5DKXC4PYeUkfCAiB4haj7tzx+2ye7rhLxPclhQ==",
"optional": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"functional-red-black-tree": "^1.0.1",
"google-gax": "^2.2.0"
"google-gax": "^2.9.2"
}
},
"@google-cloud/paginator": {
@ -134,9 +134,9 @@
"optional": true
},
"@google-cloud/storage": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.3.0.tgz",
"integrity": "sha512-3t5UF3SZ14Bw2kcBHubCai6EIugU2GnQOstYWVSFuoO8IJ94RAaIOPq/dtexvQbUTpBTAGpd5smVR9WPL1mJVw==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.5.0.tgz",
"integrity": "sha512-Pat83kHNnKJpEHUirtQtCoAJ2K3OlEo2ZcSlPjierJnEKnhbIQPyJ6mAbs/ovm3K3QDQhouKJ9QSONkFPEwQuA==",
"optional": true,
"requires": {
"@google-cloud/common": "^3.3.0",
@ -144,12 +144,12 @@
"@google-cloud/promisify": "^2.0.0",
"arrify": "^2.0.0",
"compressible": "^2.0.12",
"concat-stream": "^2.0.0",
"date-and-time": "^0.14.0",
"duplexify": "^3.5.0",
"duplexify": "^4.0.0",
"extend": "^3.0.2",
"gaxios": "^3.0.0",
"gaxios": "^4.0.0",
"gcs-resumable-upload": "^3.1.0",
"get-stream": "^6.0.0",
"hash-stream-validation": "^0.2.2",
"mime": "^2.2.0",
"mime-types": "^2.0.8",
@ -161,31 +161,6 @@
"xdg-basedir": "^4.0.0"
},
"dependencies": {
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
"integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
"optional": true,
"requires": {
"end-of-stream": "^1.0.0",
"inherits": "^2.0.1",
"readable-stream": "^2.0.0",
"stream-shift": "^1.0.0"
}
},
"gaxios": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz",
"integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==",
"optional": true,
"requires": {
"abort-controller": "^3.0.0",
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
"is-stream": "^2.0.0",
"node-fetch": "^2.3.0"
}
},
"p-limit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
@ -194,36 +169,6 @@
"requires": {
"p-try": "^2.0.0"
}
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"optional": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"optional": true
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"optional": true,
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
@ -253,9 +198,9 @@
}
},
"@types/node": {
"version": "12.19.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.3.tgz",
"integrity": "sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg==",
"version": "12.19.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.4.tgz",
"integrity": "sha512-o3oj1bETk8kBwzz1WlO6JWL/AfAA3Vm6J1B3C9CsdxHYp7XgPiH7OEXPUbZTndHlRaIElrANkQfe6ZmfJb3H2w==",
"optional": true
}
}
@ -523,9 +468,9 @@
"dev": true
},
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"optional": true
},
"bignumber.js": {
@ -581,12 +526,6 @@
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"optional": true
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@ -717,18 +656,6 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"concat-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
"optional": true,
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.0.2",
"typedarray": "^0.0.6"
}
},
"configstore": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
@ -773,12 +700,6 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"optional": true
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
@ -1251,13 +1172,13 @@
}
},
"firebase-admin": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.3.0.tgz",
"integrity": "sha512-qMUITOp2QKLLc2o0/wSiDC2OO2knejjieZN/8Or9AzfFk8ftTcUKq5ALNlQXu+7aUzGe0IwSJq9TVnkIU0h1xw==",
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.4.1.tgz",
"integrity": "sha512-y9r2Mz2x1WTr60YrCDqz8Lw70DlwIvRIieVltP+UdRogkVpfnvyd+bi4D0KPlujW3teqcFPmxuzsXB+DP5vGfQ==",
"requires": {
"@firebase/database": "^0.6.10",
"@firebase/database-types": "^0.5.2",
"@google-cloud/firestore": "^4.0.0",
"@google-cloud/firestore": "^4.5.0",
"@google-cloud/storage": "^5.3.0",
"@types/node": "^10.10.0",
"dicer": "^0.3.0",
@ -1345,28 +1266,13 @@
}
},
"gcp-metadata": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.0.tgz",
"integrity": "sha512-vQZD57cQkqIA6YPGXM/zc+PIZfNRFdukWGsGZ5+LcJzesi5xp6Gn7a02wRJi4eXPyArNMIYpPET4QMxGqtlk6Q==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz",
"integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==",
"optional": true,
"requires": {
"gaxios": "^3.0.0",
"gaxios": "^4.0.0",
"json-bigint": "^1.0.0"
},
"dependencies": {
"gaxios": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz",
"integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==",
"optional": true,
"requires": {
"abort-controller": "^3.0.0",
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
"is-stream": "^2.0.0",
"node-fetch": "^2.3.0"
}
}
}
},
"gcs-resumable-upload": {
@ -1405,6 +1311,12 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"optional": true
},
"get-stream": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz",
"integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==",
"optional": true
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@ -1443,9 +1355,9 @@
}
},
"google-gax": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.9.1.tgz",
"integrity": "sha512-KQ7HiMTB/PAzKv3OU00x6tC1H7MHvSxQfon5BSyW5o+lkMgRA8xoqvlxZCBC1dlW1azOPGF8vScy8QgFmhaQ9Q==",
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.9.2.tgz",
"integrity": "sha512-Pve4osEzNKpBZqFXMfGKBbKCtgnHpUe5IQMh5Ou+Xtg8nLcba94L3gF0xgM5phMdGRRqJn0SMjcuEVmOYu7EBg==",
"optional": true,
"requires": {
"@grpc/grpc-js": "~1.1.1",
@ -1453,7 +1365,7 @@
"@types/long": "^4.0.0",
"abort-controller": "^3.0.0",
"duplexify": "^4.0.0",
"google-auth-library": "^6.0.0",
"google-auth-library": "^6.1.3",
"is-stream-ended": "^0.1.4",
"node-fetch": "^2.6.1",
"protobufjs": "^6.9.0",
@ -1661,12 +1573,6 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"optional": true
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"optional": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -2097,12 +2003,6 @@
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
"dev": true
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"optional": true
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@ -2594,12 +2494,6 @@
"mime-types": "~2.1.24"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"optional": true
},
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",

View file

@ -13,7 +13,7 @@
"node": "10"
},
"dependencies": {
"firebase-admin": "^9.3.0",
"firebase-admin": "^9.4.1",
"firebase-functions": "^3.11.0"
},
"devDependencies": {

View file

@ -1,25 +1,15 @@
const { task, src, dest, series, watch } = require("gulp");
const browserify = require("browserify");
const babelify = require("babelify");
const concat = require("gulp-concat");
const del = require("del");
const source = require("vinyl-source-stream");
const buffer = require("vinyl-buffer");
const vinylPaths = require("vinyl-paths");
const eslint = require("gulp-eslint");
var sass = require("gulp-sass");
sass.compiler = require("dart-sass");
//the order of files is important
const gulpSrc = [
"./src/js/misc.js",
"./src/js/words.js",
"./src/js/layouts.js",
"./src/js/db.js",
"./src/js/userconfig.js",
"./src/js/commandline.js",
"./src/js/leaderboards.js",
"./src/js/settings.js",
"./src/js/account.js",
"./src/js/script.js",
];
let eslintConfig = {
parser: "babel-eslint",
globals: [
@ -94,13 +84,34 @@ let eslintConfig = {
},
};
//refactored files, which should be es6 modules
//once all files are moved here, then can we use a bundler to its full potential
const refactoredSrc = ["./src/js/db.js"];
//legacy files
//the order of files is important
const globalSrc = [
"./src/js/global-dependencies.js",
"./src/js/misc.js",
"./src/js/words.js",
"./src/js/layouts.js",
"./src/js/userconfig.js",
"./src/js/commandline.js",
"./src/js/leaderboards.js",
"./src/js/settings.js",
"./src/js/account.js",
"./src/js/script.js",
"./src/js/exports.js",
];
//concatenates and lints legacy js files and writes the output to dist/gen/index.js
task("cat", function () {
return src(gulpSrc)
.pipe(concat("monkeytype.js"))
return src(globalSrc)
.pipe(concat("index.js"))
.pipe(eslint(eslintConfig))
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.pipe(dest("./dist/js"));
.pipe(dest("./dist/gen"));
});
task("sass", function () {
@ -113,11 +124,50 @@ task("static", function () {
return src("./static/**/*").pipe(dest("./dist/"));
});
//copies refactored js files to dist/gen so that they can be required by dist/gen/index.js
task("copy-modules", function () {
return src(refactoredSrc, { allowEmpty: true }).pipe(dest("./dist/gen"));
});
//bundles the refactored js files together with index.js (the concatenated legacy js files)
//it's odd that the entry point is generated, so we should seek a better way of doing this
task("browserify", function () {
const b = browserify({
//index.js is generated by task "cat"
entries: "./dist/gen/index.js",
//a source map isn't very useful right now because
//the source files are concatenated together
debug: false,
});
return b
.transform(
babelify.configure({
presets: ["@babel/preset-env"],
plugins: ["@babel/transform-runtime"],
})
)
.bundle()
.pipe(source("monkeytype.js"))
.pipe(buffer())
.pipe(dest("./dist/js"));
});
//lints only the refactored files
task("lint", function () {
return src(refactoredSrc)
.pipe(eslint(eslintConfig))
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
task("clean", function () {
return src("./dist/", { allowEmpty: true }).pipe(vinylPaths(del));
});
task("compile", series("static", "sass", "cat"));
task(
"compile",
series("lint", "cat", "copy-modules", "browserify", "static", "sass")
);
task("watch", function () {
watch(["./static/**/*", "./src/**/*"], series("compile"));

2473
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,12 @@
"node": "10"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"babel-eslint": "^10.1.0",
"babelify": "^10.0.0",
"browserify": "^17.0.0",
"concurrently": "^5.3.0",
"dart-sass": "^1.25.0",
"del": "^6.0.0",
@ -27,11 +32,16 @@
"husky": "^4.3.0",
"prettier": "2.1.2",
"pretty-quick": "^3.1.0",
"vinyl-paths": "^3.0.1"
"vinyl-buffer": "^1.0.1",
"vinyl-paths": "^3.0.1",
"vinyl-source-stream": "^2.0.0"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"dependencies": {
"@babel/runtime": "^7.12.5"
}
}

View file

@ -160,7 +160,7 @@ function signUp() {
console.log("Analytics unavailable");
}
$(".pageLogin .preloader").addClass("hidden");
dbSnapshot = {
db_setSnapshot({
results: [],
personalBests: {},
tags: [],
@ -169,14 +169,14 @@ function signUp() {
started: undefined,
completed: undefined,
},
};
});
if (notSignedInLastResult !== null) {
notSignedInLastResult.uid = usr.uid;
testCompleted({
uid: usr.uid,
obj: notSignedInLastResult,
});
dbSnapshot.results.push(notSignedInLastResult);
db_getSnapshot().results.push(notSignedInLastResult);
config.resultFilters = defaultAccountFilters;
}
changePage("account");
@ -225,7 +225,7 @@ function signOut() {
hideAccountSettingsSection();
updateAccountLoginButton();
changePage("login");
dbSnapshot = null;
db_setSnapshot(null);
})
.catch(function (error) {
showNotification(error.message, 5000);
@ -262,7 +262,6 @@ firebase.auth().onAuthStateChanged(function (user) {
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
// showNotification('Signed in', 1000);
$(".pageLogin .preloader").addClass("hidden");
$("#menu .icon-button.account .text").text(displayName);
@ -285,7 +284,7 @@ firebase.auth().onAuthStateChanged(function (user) {
verifyUser(verifyUserWhenLoggedIn).then((data) => {
showNotification(data.data.message, 3000);
if (data.data.status === 1) {
dbSnapshot.discordId = data.data.did;
db_getSnapshot().discordId = data.data.did;
updateDiscordSettingsSection();
}
});
@ -307,33 +306,24 @@ firebase.auth().onAuthStateChanged(function (user) {
setCustomTheme(true);
setCustomThemeInputs();
applyCustomThemeColors();
// let save = [];
// $.each(
// $(".pageSettings .section.customTheme [type='color']"),
// (index, element) => {
// save.push($(element).attr("value"));
// }
// );
// setCustomThemeColors(save);
}
});
function getAccountDataAndInit() {
db_getUserSnapshot()
.then((e) => {
if (dbSnapshot === null) {
if (db_getSnapshot() === null) {
throw "Missing db snapshot. Client likely could not connect to the backend.";
}
initPaceCaret(true);
if (!configChangedBeforeDb) {
if (cookieConfig === null) {
accountIconLoading(false);
applyConfig(dbSnapshot.config);
// showNotification('Applying db config',3000);
applyConfig(db_getSnapshot().config);
updateSettingsPage();
saveConfigToCookie(true);
restartTest(false, true);
} else if (dbSnapshot.config !== undefined) {
} else if (db_getSnapshot().config !== undefined) {
let configsDifferent = false;
Object.keys(config).forEach((key) => {
if (!configsDifferent) {
@ -341,18 +331,22 @@ function getAccountDataAndInit() {
if (key !== "resultFilters") {
if (Array.isArray(config[key])) {
config[key].forEach((arrval, index) => {
if (arrval != dbSnapshot.config[key][index]) {
if (arrval != db_getSnapshot().config[key][index]) {
configsDifferent = true;
console.log(
`.config is different: ${arrval} != ${dbSnapshot.config[key][index]}`
`.config is different: ${arrval} != ${
db_getSnapshot().config[key][index]
}`
);
}
});
} else {
if (config[key] != dbSnapshot.config[key]) {
if (config[key] != db_getSnapshot().config[key]) {
configsDifferent = true;
console.log(
`..config is different ${key}: ${config[key]} != ${dbSnapshot.config[key]}`
`..config is different ${key}: ${config[key]} != ${
db_getSnapshot().config[key]
}`
);
}
}
@ -367,7 +361,7 @@ function getAccountDataAndInit() {
if (configsDifferent) {
console.log("applying config from db");
accountIconLoading(false);
config = dbSnapshot.config;
config = db_getSnapshot().config;
applyConfig(config);
updateSettingsPage();
saveConfigToCookie(true);
@ -385,12 +379,12 @@ function getAccountDataAndInit() {
config.resultFilters.difficulty === undefined
) {
if (
dbSnapshot.config.resultFilters == null ||
dbSnapshot.config.resultFilters.difficulty === undefined
db_getSnapshot().config.resultFilters == null ||
db_getSnapshot().config.resultFilters.difficulty === undefined
) {
config.resultFilters = defaultAccountFilters;
} else {
config.resultFilters = dbSnapshot.config.resultFilters;
config.resultFilters = db_getSnapshot().config.resultFilters;
}
}
} catch (e) {
@ -431,11 +425,6 @@ var resultHistoryChart = new Chart($(".pageAccount #resultHistoryChart"), {
data: [],
borderColor: "#f44336",
borderWidth: 2,
// trendlineLinear: {
// style: "rgba(244,67,54,.25)",
// lineStyle: "solid",
// width: 1
// }
trendlineLinear: {
style: "rgba(255,105,180, .8)",
lineStyle: "dotted",
@ -528,10 +517,6 @@ var resultHistoryChart = new Chart($(".pageAccount #resultHistoryChart"), {
},
responsive: true,
maintainAspectRatio: false,
// tooltips: {
// mode: 'index',
// intersect: false,
// },
hover: {
mode: "nearest",
intersect: false,
@ -725,7 +710,6 @@ let hoverChart = new Chart($(".pageAccount #hoverChart"), {
{
label: "wpm",
data: [],
// backgroundColor: 'rgba(255, 255, 255, 0.25)',
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "wpm",
@ -735,7 +719,6 @@ let hoverChart = new Chart($(".pageAccount #hoverChart"), {
{
label: "raw",
data: [],
// backgroundColor: 'rgba(255, 255, 255, 0.25)',
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "raw",
@ -745,25 +728,23 @@ let hoverChart = new Chart($(".pageAccount #hoverChart"), {
{
label: "errors",
data: [],
// backgroundColor: 'rgba(255, 255, 255, 0.25)',
borderColor: "rgba(255, 125, 125, 1)",
pointBackgroundColor: "rgba(255, 125, 125, 1)",
borderWidth: 2,
order: 1,
yAxisID: "error",
// barPercentage: 0.1,
maxBarThickness: 10,
type: "scatter",
pointStyle: "crossRot",
radius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value.y <= 0 ? 0 : 3;
return value <= 0 ? 0 : 3;
},
pointHoverRadius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value.y <= 0 ? 0 : 5;
return value <= 0 ? 0 : 5;
},
},
],
@ -783,10 +764,6 @@ let hoverChart = new Chart($(".pageAccount #hoverChart"), {
},
responsive: true,
maintainAspectRatio: false,
// hover: {
// mode: 'x',
// intersect: false
// },
scales: {
xAxes: [
{
@ -987,10 +964,6 @@ $(document).on("click", ".pageAccount .hoverChartBg", (event) => {
hideHoverChart();
});
// $(document).on("mouseleave", ".pageAccount .hoverChartButton", (event) => {
// hideHoverChart();
// });
let defaultAccountFilters = {
difficulty: {
normal: true,
@ -1076,14 +1049,14 @@ function updateFilterTags() {
$(
".pageAccount .content .filterButtons .buttonsAndTitle.tags .buttons"
).empty();
if (dbSnapshot.tags.length > 0) {
if (db_getSnapshot().tags.length > 0) {
$(".pageAccount .content .filterButtons .buttonsAndTitle.tags").removeClass(
"hidden"
);
$(
".pageAccount .content .filterButtons .buttonsAndTitle.tags .buttons"
).append(`<div class="button" filter="none">no tag</div>`);
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
defaultAccountFilters.tags[tag.id] = true;
$(
".pageAccount .content .filterButtons .buttonsAndTitle.tags .buttons"
@ -1094,7 +1067,6 @@ function updateFilterTags() {
"hidden"
);
}
// showActiveFilters();
}
function toggleFilter(group, filter) {
@ -1110,117 +1082,7 @@ function setFilter(group, filter, set) {
config.resultFilters[group][filter] = set;
}
// function toggleFilterButton(filter) {
// const element = $(
// `.pageAccount .content .filterButtons .button[filter=${filter}]`
// );
// if (element.hasClass("active")) {
// //disable that filter
// if (filter == "all" || filter == "none") {
// return;
// } else if (filter == "mode_words") {
// // $.each($(`.pageAccount .content .filterButtons .buttons.wordsFilter .button`),(index,obj)=>{
// // let f = $(obj).attr('filter')
// // disableFilterButton(f)
// // })
// } else if (filter == "mode_time") {
// // $.each($(`.pageAccount .content .filterButtons .buttons.timeFilter .button`),(index,obj)=>{
// // let f = $(obj).attr('filter')
// // disableFilterButton(f)
// // })
// } else if (filter == "punc_off") {
// enableFilterButton("punc_on");
// } else if (filter == "punc_on") {
// enableFilterButton("punc_off");
// }
// disableFilterButton(filter);
// disableFilterButton("all");
// } else {
// //enable that filter
// disableFilterButton("none");
// if (filter == "all") {
// $.each(
// $(`.pageAccount .content .filterButtons .button`),
// (index, obj) => {
// let f = $(obj).attr("filter");
// if (
// f != "none" &&
// f != "date_month" &&
// f != "date_week" &&
// f != "date_day"
// ) {
// enableFilterButton(f);
// }
// }
// );
// } else if (filter == "none") {
// disableFilterButton("all");
// $.each(
// $(`.pageAccount .content .filterButtons .button`),
// (index, obj) => {
// let f = $(obj).attr("filter");
// if (f != "none") {
// disableFilterButton(f);
// }
// }
// );
// } else if (
// filter == "date_all" ||
// filter == "date_month" ||
// filter == "date_week" ||
// filter == "date_day"
// ) {
// disableFilterButton("date_all");
// disableFilterButton("date_month");
// disableFilterButton("date_week");
// disableFilterButton("date_day");
// enableFilterButton(filter);
// }
// // else if(filter == "mode_words"){
// // $.each($(`.pageAccount .content .filterButtons .buttons.wordsFilter .button`),(index,obj)=>{
// // let f = $(obj).attr('filter');
// // enableFilterButton(f);
// // })
// // }else if(filter == "mode_time"){
// // $.each($(`.pageAccount .content .filterButtons .buttons.timeFilter .button`),(index,obj)=>{
// // let f = $(obj).attr('filter');
// // enableFilterButton(f);
// // })
// // }else if(['10','25','50','100','200'].includes(filter)){
// // enableFilterButton('words');
// // }else if(['15','30','60','120'].includes(filter)){
// // enableFilterButton('time');
// // }
// enableFilterButton(filter);
// }
// showActiveFilters();
// }
// function disableFilterButton(filter) {
// const element = $(
// `.pageAccount .content .filterButtons .button[filter=${filter}]`
// );
// element.removeClass("active");
// }
// function enableFilterButton(filter) {
// const element = $(
// `.pageAccount .content .filterButtons .button[filter=${filter}]`
// );
// element.addClass("active");
// }
function showActiveFilters() {
// activeFilters = [];
// $.each($(".pageAccount .filterButtons .button"), (i, obj) => {
// if ($(obj).hasClass("active")) {
// activeFilters.push($(obj).attr("filter"));
// }
// });
let aboveChartDisplay = {};
Object.keys(config.resultFilters).forEach((group) => {
@ -1288,15 +1150,13 @@ function showActiveFilters() {
if (aboveChartDisplay[group].all) {
ret += "all";
} else {
//TODO: is this used?
//allall = false;
if (group === "tags") {
ret += aboveChartDisplay.tags.array
.map((id) => {
if (id == "none") return id;
let name = dbSnapshot.tags.filter((t) => t.id == id)[0];
let name = db_getSnapshot().tags.filter((t) => t.id == id)[0];
if (name !== undefined) {
return dbSnapshot.tags.filter((t) => t.id == id)[0].name;
return db_getSnapshot().tags.filter((t) => t.id == id)[0].name;
}
})
.join(", ");
@ -1352,77 +1212,6 @@ function showActiveFilters() {
//tags
chartString += addText("tags");
// chartString += `<div class="spacer"></div>`;
// let allall = true;
// let count = 0;
// Object.keys(aboveChartDisplay).forEach((group) => {
// count++;
// if (group === "time" && !aboveChartDisplay.mode.array.includes("time"))
// return;
// if (group === "words" && !aboveChartDisplay.mode.array.includes("words"))
// return;
// if (aboveChartDisplay[group].array.length > 0) {
// chartString += "<div class='group'>";
// if (group == "difficulty") {
// chartString += `<span aria-label="Difficulty" data-balloon-pos="up"><i class="fas fa-fw fa-star"></i>`;
// } else if (group == "mode") {
// chartString += `<span aria-label="Mode" data-balloon-pos="up"><i class="fas fa-fw fa-bars"></i>`;
// } else if (group == "punctuation") {
// chartString += `<span aria-label="Punctuation" data-balloon-pos="up"><span class="punc" style="font-weight: 900;
// width: 1.25rem;
// text-align: center;
// display: inline-block;
// letter-spacing: -.1rem;">!?</span>`;
// } else if (group == "numbers") {
// chartString += `<span aria-label="Numbers" data-balloon-pos="up"><span class="numbers" style="font-weight: 900;
// width: 1.25rem;
// text-align: center;
// margin-right: .1rem;
// display: inline-block;
// letter-spacing: -.1rem;">15</span>`;
// } else if (group == "words") {
// chartString += `<span aria-label="Words" data-balloon-pos="up"><i class="fas fa-fw fa-font"></i>`;
// } else if (group == "time") {
// chartString += `<span aria-label="Time" data-balloon-pos="up"><i class="fas fa-fw fa-clock"></i>`;
// } else if (group == "date") {
// chartString += `<span aria-label="Date" data-balloon-pos="up"><i class="fas fa-fw fa-calendar"></i>`;
// } else if (group == "tags") {
// chartString += `<span aria-label="Tags" data-balloon-pos="up"><i class="fas fa-fw fa-tags"></i>`;
// } else if (group == "language") {
// chartString += `<span aria-label="Language" data-balloon-pos="up"><i class="fas fa-fw fa-globe-americas"></i>`;
// } else if (group == "funbox") {
// chartString += `<span aria-label="Funbox" data-balloon-pos="up"><i class="fas fa-fw fa-gamepad"></i>`;
// }
// if (aboveChartDisplay[group].all) {
// chartString += "all";
// } else {
// allall = false;
// if (group === "tags") {
// chartString += aboveChartDisplay.tags.array
// .map((id) => {
// if (id == "none") return id;
// let name = dbSnapshot.tags.filter((t) => t.id == id)[0];
// if (name !== undefined) {
// return dbSnapshot.tags.filter((t) => t.id == id)[0].name;
// }
// })
// .join(", ");
// } else {
// chartString += aboveChartDisplay[group].array
// .join(", ")
// .replace(/_/g, " ");
// }
// }
// chartString += "</span></div>";
// if (Object.keys(aboveChartDisplay).length !== count)
// chartString += `<div class="spacer"></div>`;
// }
// });
// if (allall) chartString = `<i class="fas fa-fw fa-filter"></i>all`;
$(".pageAccount .group.chart .above").html(chartString);
@ -1486,10 +1275,14 @@ $(".pageAccount .topFilters .button.currentConfigFilter").click((e) => {
} else {
config.resultFilters.numbers.off = true;
}
config.resultFilters.language[config.language] = true;
if (config.mode === "quote" && /english.*/.test(config.language)) {
config.resultFilters.language["english"] = true;
} else {
config.resultFilters.language[config.language] = true;
}
config.resultFilters.funbox[activeFunBox] = true;
config.resultFilters.tags.none = true;
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
if (tag.active === true) {
config.resultFilters.tags.none = false;
config.resultFilters.tags[tag.id] = true;
@ -1514,7 +1307,6 @@ $(
).click(".button", (e) => {
const filter = $(e.target).attr("filter");
const group = $(e.target).parents(".buttons").attr("group");
// toggleFilterButton(filter);
if ($(e.target).hasClass("allFilters")) {
Object.keys(config.resultFilters).forEach((group) => {
Object.keys(config.resultFilters[group]).forEach((filter) => {
@ -1610,7 +1402,7 @@ function fillPbTables() {
</tr>
`);
const pb = dbSnapshot.personalBests;
const pb = db_getSnapshot().personalBests;
let pbData;
let text;
@ -1790,12 +1582,6 @@ function loadMoreLines() {
const result = filteredResults[i];
if (result == undefined) continue;
let withpunc = "";
// if (result.punctuation) {
// withpunc = '<br>punctuation';
// }
// if (result.blindMode) {
// withpunc = '<br>blind';
// }
let diff = result.difficulty;
if (diff == undefined) {
diff = "normal";
@ -1855,7 +1641,7 @@ function loadMoreLines() {
if (result.tags !== undefined && result.tags.length > 0) {
result.tags.forEach((tag) => {
dbSnapshot.tags.forEach((snaptag) => {
db_getSnapshot().tags.forEach((snaptag) => {
if (tag === snaptag.id) {
tagNames += snaptag.name + ", ";
}
@ -1864,10 +1650,6 @@ function loadMoreLines() {
tagNames = tagNames.substring(0, tagNames.length - 2);
}
// if(tagNames !== ""){
// icons += `<span aria-label="${tagNames}" data-balloon-pos="up"><i class="fas fa-fw fa-tag"></i></span>`;
// }
let restags;
if (result.tags === undefined) {
restags = "[]";
@ -1930,10 +1712,10 @@ function clearGlobalStats() {
}
function refreshGlobalStats() {
if (dbSnapshot.globalStats.time != undefined) {
let th = Math.floor(dbSnapshot.globalStats.time / 3600);
let tm = Math.floor((dbSnapshot.globalStats.time % 3600) / 60);
let ts = Math.floor((dbSnapshot.globalStats.time % 3600) % 60);
if (db_getSnapshot().globalStats.time != undefined) {
let th = Math.floor(db_getSnapshot().globalStats.time / 3600);
let tm = Math.floor((db_getSnapshot().globalStats.time % 3600) / 60);
let ts = Math.floor((db_getSnapshot().globalStats.time % 3600) % 60);
$(".pageAccount .globalTimeTyping .val").text(`
${th < 10 ? "0" + th : th}:${tm < 10 ? "0" + tm : tm}:${
@ -1941,14 +1723,14 @@ function refreshGlobalStats() {
}
`);
}
if (dbSnapshot.globalStats.started != undefined) {
if (db_getSnapshot().globalStats.started != undefined) {
$(".pageAccount .globalTestsStarted .val").text(
dbSnapshot.globalStats.started
db_getSnapshot().globalStats.started
);
}
if (dbSnapshot.globalStats.completed != undefined) {
if (db_getSnapshot().globalStats.completed != undefined) {
$(".pageAccount .globalTestsCompleted .val").text(
dbSnapshot.globalStats.completed
db_getSnapshot().globalStats.completed
);
}
}
@ -1963,8 +1745,6 @@ function refreshAccountPage() {
let chartData = [];
let wpmChartData = [];
//TODO: is this used?
//let rawChartData = [];
let accChartData = [];
visibleTableLines = 0;
@ -1995,13 +1775,11 @@ function refreshAccountPage() {
let totalCons10 = 0;
let consCount = 0;
//TODO: is this used?
//let dailyActivityDays = [];
let activityChartData = {};
filteredResults = [];
$(".pageAccount .history table tbody").empty();
dbSnapshot.results.forEach((result) => {
db_getSnapshot().results.forEach((result) => {
let tt = 0;
if (result.testDuration == undefined) {
//test finished before testDuration field was introduced - estimate
@ -2020,16 +1798,13 @@ function refreshAccountPage() {
}
totalSeconds += tt;
// console.log(result);
//apply filters
try {
let resdiff = result.difficulty;
if (resdiff == undefined) {
resdiff = "normal";
}
// if (!activeFilters.includes("difficulty_" + resdiff)) return;
if (!config.resultFilters.difficulty[resdiff]) return;
// if (!activeFilters.includes("mode_" + result.mode)) return;
if (!config.resultFilters.mode[result.mode]) return;
if (result.mode == "time") {
@ -2037,19 +1812,15 @@ function refreshAccountPage() {
if ([15, 30, 60, 120].includes(parseInt(result.mode2))) {
timefilter = result.mode2;
}
// if (!activeFilters.includes(timefilter)) return;
if (!config.resultFilters.time[timefilter]) return;
} else if (result.mode == "words") {
let wordfilter = "custom";
if ([10, 25, 50, 100, 200].includes(parseInt(result.mode2))) {
wordfilter = result.mode2;
}
// if (!activeFilters.includes(wordfilter)) return;
if (!config.resultFilters.words[wordfilter]) return;
}
// if (!activeFilters.includes("lang_" + result.language)) return;
let langFilter = config.resultFilters.language[result.language];
if (
@ -2065,7 +1836,6 @@ function refreshAccountPage() {
puncfilter = "on";
}
if (!config.resultFilters.punctuation[puncfilter]) return;
// if (!activeFilters.includes(puncfilter)) return;
let numfilter = "off";
if (result.numbers) {
@ -2074,10 +1844,8 @@ function refreshAccountPage() {
if (!config.resultFilters.numbers[numfilter]) return;
if (result.funbox === "none" || result.funbox === undefined) {
// if (!activeFilters.includes("funbox_none")) return;
if (!config.resultFilters.funbox.none) return;
} else {
// if (!activeFilters.includes("funbox_" + result.funbox)) return;
if (!config.resultFilters.funbox[result.funbox]) return;
}
@ -2085,22 +1853,20 @@ function refreshAccountPage() {
if (result.tags === undefined || result.tags.length === 0) {
//no tags, show when no tag is enabled
if (dbSnapshot.tags.length > 0) {
// if (activeFilters.includes("tag_notag")) tagHide = false;
if (db_getSnapshot().tags.length > 0) {
if (config.resultFilters.tags.none) tagHide = false;
} else {
tagHide = false;
}
} else {
//tags exist
let validTags = dbSnapshot.tags.map((t) => t.id);
let validTags = db_getSnapshot().tags.map((t) => t.id);
result.tags.forEach((tag) => {
//check if i even need to check tags anymore
if (!tagHide) return;
//check if tag is valid
if (validTags.includes(tag)) {
//tag valid, check if filter is on
// if (activeFilters.includes("tag_" + tag)) tagHide = false;
if (config.resultFilters.tags[tag]) tagHide = false;
} else {
//tag not found in valid tags, meaning probably deleted
@ -2115,15 +1881,6 @@ function refreshAccountPage() {
let datehide = true;
// if (
// activeFilters.includes("date_all") ||
// (activeFilters.includes("date_day") && timeSinceTest <= 86400) ||
// (activeFilters.includes("date_week") && timeSinceTest <= 604800) ||
// (activeFilters.includes("date_month") && timeSinceTest <= 18144000)
// ) {
// datehide = false;
// }
if (
config.resultFilters.date.all ||
(config.resultFilters.date.last_day && timeSinceTest <= 86400) ||
@ -2299,8 +2056,6 @@ function refreshAccountPage() {
lastTimestamp = date;
});
// console.log(activityChartData);
activityChart.options.scales.xAxes[0].ticks.minor.fontColor =
themeColors.sub;
activityChart.options.scales.yAxes[0].ticks.minor.fontColor =
@ -2320,7 +2075,6 @@ function refreshAccountPage() {
activityChart.options.scales.yAxes[1].scaleLabel.fontColor =
themeColors.sub;
activityChart.data.datasets[1].borderColor = themeColors.sub;
// activityChart.data.datasets[1].backgroundColor = themeColors.main;
activityChart.data.datasets[1].data = activityChartData_avgWpm;
activityChart.options.legend.labels.fontColor = themeColors.sub;
@ -2384,9 +2138,6 @@ function refreshAccountPage() {
$(".pageAccount .triplegroup.stats").removeClass("hidden");
}
// moment
// .utc(moment.duration(totalSeconds, "seconds").asMilliseconds())
// .format("HH:mm:ss")
let th = Math.floor(totalSeconds / 3600);
let tm = Math.floor((totalSeconds % 3600) / 60);
let ts = Math.floor((totalSeconds % 3600) % 60);
@ -2396,9 +2147,6 @@ function refreshAccountPage() {
ts < 10 ? "0" + ts : ts
}
`);
//moment
// .utc(moment.duration(totalSecondsFiltered, "seconds").asMilliseconds())
// .format("HH:mm:ss")
let tfh = Math.floor(totalSecondsFiltered / 3600);
let tfm = Math.floor((totalSecondsFiltered % 3600) / 60);
let tfs = Math.floor((totalSecondsFiltered % 3600) % 60);
@ -2431,9 +2179,6 @@ function refreshAccountPage() {
Math.round(totalAcc10 / last10) + "%"
);
// console.log(totalCons10);
// console.log(last10);
if (totalCons == 0 || totalCons == undefined) {
$(".pageAccount .avgCons .val").text("-");
$(".pageAccount .avgCons10 .val").text("-");
@ -2458,31 +2203,6 @@ function refreshAccountPage() {
(testRestarts / testCount).toFixed(1)
);
// if(testCount == 0){
// $('.pageAccount .group.chart').fadeOut(125);
// $('.pageAccount .triplegroup.stats').fadeOut(125);
// $('.pageAccount .group.history').fadeOut(125);
// }else{
// $('.pageAccount .group.chart').fadeIn(125);
// $('.pageAccount .triplegroup.stats').fadeIn(125);
// $('.pageAccount .group.history').fadeIn(125);
// }
// let favMode = testModes.words10;
// let favModeName = 'words10';
// $.each(testModes, (key, mode) => {
// if (mode.length > favMode.length) {
// favMode = mode;
// favModeName = key;
// }
// })
// if (favModeName == 'words10' && testModes.words10.length == 0) {
// //new user
// $(".pageAccount .favouriteTest .val").text(`-`);
// } else {
// $(".pageAccount .favouriteTest .val").text(`${favModeName} (${Math.floor((favMode.length/testCount) * 100)}%)`);
// }
if (resultHistoryChart.data.datasets[0].data.length > 0) {
resultHistoryChart.options.plugins.trendlineLinear = true;
} else {
@ -2503,7 +2223,6 @@ function refreshAccountPage() {
let wpmChangePerHour = wpmChange * (3600 / totalSecondsFiltered);
// let slope = calculateSlope(trend);
let plus = wpmChangePerHour > 0 ? "+" : "";
$(".pageAccount .group.chart .below .text").text(
@ -2517,19 +2236,17 @@ function refreshAccountPage() {
swapElements($(".pageAccount .preloader"), $(".pageAccount .content"), 250);
}
if (dbSnapshot === null) {
if (db_getSnapshot() === null) {
showNotification(`Missing account data. Please refresh.`, 5000);
$(".pageAccount .preloader").html("Missing account data. Please refresh.");
} else if (dbSnapshot.results === undefined) {
} else if (db_getSnapshot().results === undefined) {
db_getUserResults().then((d) => {
if (d) {
// cont();
showActiveFilters();
} else {
setTimeout(() => {
changePage("");
}, 500);
// console.log("something went wrong");
}
});
} else {
@ -2579,7 +2296,7 @@ $(".pageAccount .toggleChartStyle").click((params) => {
});
$(document).on("click", ".pageAccount .group.history #resultEditTags", (f) => {
if (dbSnapshot.tags.length > 0) {
if (db_getSnapshot().tags.length > 0) {
let resultid = $(f.target).parents("span").attr("resultid");
let tags = $(f.target).parents("span").attr("tags");
$("#resultEditTagsPanel").attr("resultid", resultid);
@ -2601,7 +2318,7 @@ $("#resultEditTagsPanelWrapper").click((e) => {
function updateResultEditTagsPanelButtons() {
$("#resultEditTagsPanel .buttons").empty();
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
$("#resultEditTagsPanel .buttons").append(
`<div class="button tag" tagid="${tag.id}">${tag.name}</div>`
);
@ -2617,13 +2334,6 @@ function updateActiveResultEditTagsPanelButtons(active) {
} else {
$(obj).removeClass("active");
}
// active.forEach(activetagid => {
// if(activetagid === tagid){
// $(obj).addClass('active');
// }else{
// $(obj).removeClass('active');
// }
// })
});
}
@ -2648,7 +2358,7 @@ $("#resultEditTagsPanel .confirmButton").click((f) => {
hideBackgroundLoader();
if (r.data.resultCode === 1) {
showNotification("Tags updated.", 3000);
dbSnapshot.results.forEach((result) => {
db_getSnapshot().results.forEach((result) => {
if (result.id === resultid) {
result.tags = newtags;
}
@ -2658,7 +2368,7 @@ $("#resultEditTagsPanel .confirmButton").click((f) => {
if (newtags.length > 0) {
newtags.forEach((tag) => {
dbSnapshot.tags.forEach((snaptag) => {
db_getSnapshot().tags.forEach((snaptag) => {
if (tag === snaptag.id) {
tagNames += snaptag.name + ", ";
}
@ -2697,8 +2407,6 @@ $("#resultEditTagsPanel .confirmButton").click((f) => {
"no tags"
);
}
// refreshAccountPage();
} else {
showNotification("Error updating tags", 3000);
}
@ -2706,5 +2414,5 @@ $("#resultEditTagsPanel .confirmButton").click((f) => {
});
function updateLbMemory(mode, mode2, type, value) {
dbSnapshot.lbMemory[mode + mode2][type] = value;
db_getSnapshot().lbMemory[mode + mode2][type] = value;
}

View file

@ -210,6 +210,13 @@ let commands = {
toggleBlindMode();
},
},
{
id: "toggleAlwaysShowWordsHistory",
display: "Toggle always show words history",
exec: () => {
toggleAlwaysShowWordsHistory();
},
},
{
id: "toggleIndicateTypos",
display: "Toggle indicate typos",
@ -224,13 +231,6 @@ let commands = {
toggleHideExtraLetters();
},
},
// {
// id: "toggleReadAheadMode",
// display: "Toggle read ahead mode",
// exec: () => {
// toggleReadAheadMode();
// },
// },
{
id: "toggleQuickEnd",
display: "Toggle quick end",
@ -575,37 +575,28 @@ let commands = {
exec: () => {
hideCommandLine();
},
available: () => {
return canBailOut();
},
},
{
id: "bailOutForSure",
display: "Yes, I am sure",
exec: () => {
if (
(config.mode === "custom" &&
customTextIsRandom &&
customTextWordCount >= 5000) ||
(config.mode === "custom" &&
!customTextIsRandom &&
customText.length >= 5000) ||
(config.mode === "words" && config.words >= 5000) ||
config.words === 0 ||
(config.mode === "time" &&
(config.time >= 3600 || config.time === 0))
) {
bailout = true;
showResult();
} else {
showNotification(
"You can only bailout out of test longer than 3600 seconds / 5000 words.",
5000
);
}
bailout = true;
showResult();
},
available: () => {
return canBailOut();
},
},
],
});
showCommandLine();
},
available: () => {
return canBailOut();
},
},
{
id: "joinDiscord",
@ -614,6 +605,57 @@ let commands = {
window.open("https://discord.gg/monkeytype");
},
},
{
id: "repeatTest",
display: "Repeat test",
exec: () => {
restartTest(true);
},
available: () => {
return resultVisible;
},
},
{
id: "practiceMissedWords",
display: "Practice missed words",
exec: () => {
initPractiseMissedWords();
},
available: () => {
return resultVisible && Object.keys(missedWords).length > 0;
},
},
{
id: "toggleWordHistory",
display: "Toggle word history",
exec: () => {
toggleResultWordsDisplay();
},
available: () => {
return resultVisible;
},
},
{
id: "saveScreenshot",
display: "Save screenshot",
exec: () => {
copyResultToClipboard();
},
available: () => {
return resultVisible;
},
},
{
id: "changeCustomModeText",
display: "Change custom text",
exec: () => {
showCustomTextPopup();
setTimeout(() => {
// Workaround to focus textarea since hideCommandLine() will focus test words
$("#customTextPopup textarea").focus();
}, 150);
},
},
],
};
@ -929,14 +971,6 @@ let commandsPaceCaret = {
setPaceCaret("custom");
},
},
// {
// id: "setPaceCaretCustomSpeed",
// display: "Set custom speed...",
// input: true,
// exec: (input) => {
// console.log(input);
// },
// },
],
};
@ -959,14 +993,6 @@ let commandsMinWpm = {
setMinWpm("custom");
},
},
// {
// id: "setPaceCaretCustomSpeed",
// display: "Set custom speed...",
// input: true,
// exec: (input) => {
// console.log(input);
// },
// },
],
};
@ -1430,14 +1456,14 @@ let commandsTags = {
};
function updateCommandsTagsList() {
if (dbSnapshot.tags.length > 0) {
if (db_getSnapshot().tags.length > 0) {
commandsTags.list = [];
commandsTags.list.push({
id: "clearTags",
display: "Clear tags",
exec: () => {
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
tag.active = false;
});
updateTestModesNotice();
@ -1445,7 +1471,7 @@ function updateCommandsTagsList() {
},
});
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
let dis = tag.name;
if (tag.active === true) {
@ -1596,11 +1622,9 @@ let commandsLanguages = {
],
};
// if (getLanguageList().length > 0) {
commandsLanguages.list = [];
getLanguageList().then((languages) => {
languages.forEach((language) => {
// if (language === "english_10k") return;
commandsLanguages.list.push({
id: "changeLanguage" + capitalizeFirstLetter(language),
display: language.replace(/_/g, " "),
@ -1611,19 +1635,7 @@ getLanguageList().then((languages) => {
},
});
});
// if (language === "english_expanded") {
// commandsLanguages.list.push({
// id: "changeLanguageEnglish10k",
// display: "english 10k",
// exec: () => {
// changeLanguage("english_10k");
// restartTest();
// saveConfigToCookie();
// },
// });
// }
});
// }
let commandsLayouts = {
title: "Change layout...",
@ -2013,7 +2025,7 @@ function displayFoundCommands() {
$("#commandLine .suggestions").empty();
let list = currentCommands[currentCommands.length - 1];
$.each(list.list, (index, obj) => {
if (obj.found) {
if (obj.found && (obj.available !== undefined ? obj.available() : true)) {
$("#commandLine .suggestions").append(
'<div class="entry" command="' + obj.id + '">' + obj.display + "</div>"
);
@ -2040,7 +2052,4 @@ function displayFoundCommands() {
} catch (e) {}
}
$("#commandLine .listTitle").remove();
// if(currentCommands.title != ''){
// $("#commandLine .suggestions").before("<div class='listTitle'>"+currentCommands.title+"</div>");
// }
}

View file

@ -3,7 +3,15 @@ db.settings({ experimentalForceLongPolling: true });
let dbSnapshot = null;
async function db_getUserSnapshot() {
export function db_getSnapshot() {
return dbSnapshot;
}
export function db_setSnapshot(newSnapshot) {
dbSnapshot = newSnapshot;
}
export async function db_getUserSnapshot() {
let user = firebase.auth().currentUser;
if (user == null) return false;
let snap = {
@ -22,37 +30,11 @@ async function db_getUserSnapshot() {
},
},
};
// await db.collection('results')
// .orderBy('timestamp', 'desc')
// .where('uid', '==', user.uid)
// .get()
// .then(data => {
// // console.log('getting data from db!');
// data.docs.forEach(doc => {
// ret.push(doc.data());
// })
// })
try {
// await db
// .collection(`users/${user.uid}/results/`)
// .orderBy("timestamp", "desc")
// .get()
// .then((data) => {
// // console.log('getting data from db!');
// data.docs.forEach((doc) => {
// let result = doc.data();
// result.id = doc.id;
// snap.results.push(result);
// });
// })
// .catch((e) => {
// throw e;
// });
await db
.collection(`users/${user.uid}/tags/`)
.get()
.then((data) => {
// console.log('getting data from db!');
data.docs.forEach((doc) => {
let tag = doc.data();
tag.id = doc.id;
@ -67,7 +49,6 @@ async function db_getUserSnapshot() {
.doc(user.uid)
.get()
.then((res) => {
// console.log('getting data from db!');
let data = res.data();
if (data === undefined) return;
if (data.personalBests !== undefined) {
@ -98,7 +79,7 @@ async function db_getUserSnapshot() {
return dbSnapshot;
}
async function db_getUserResults() {
export async function db_getUserResults() {
let user = firebase.auth().currentUser;
if (user == null) return false;
if (dbSnapshot === null) return false;
@ -130,7 +111,7 @@ async function db_getUserResults() {
}
}
async function db_getUserHighestWpm(
export async function db_getUserHighestWpm(
mode,
mode2,
punctuation,
@ -157,9 +138,6 @@ async function db_getUserHighestWpm(
let retval;
if (dbSnapshot == null || dbSnapshot.results === undefined) {
// await db_getUserResults().then(data => {
// retval = cont();
// });
retval = 0;
} else {
retval = cont();
@ -167,7 +145,13 @@ async function db_getUserHighestWpm(
return retval;
}
async function db_getLocalPB(mode, mode2, punctuation, language, difficulty) {
export async function db_getLocalPB(
mode,
mode2,
punctuation,
language,
difficulty
) {
function cont() {
let ret = 0;
try {
@ -188,16 +172,13 @@ async function db_getLocalPB(mode, mode2, punctuation, language, difficulty) {
let retval;
if (dbSnapshot == null) {
// await db_getUserResults().then(data => {
// retval = cont();
// });
} else {
retval = cont();
}
return retval;
}
async function db_saveLocalPB(
export async function db_saveLocalPB(
mode,
mode2,
punctuation,
@ -260,9 +241,6 @@ async function db_saveLocalPB(
}
if (dbSnapshot == null) {
// await db_getUserResults().then(data => {
// retval = cont();
// });
} else {
cont();
}

4
src/js/exports.js Normal file
View file

@ -0,0 +1,4 @@
//this file should be concatenated with the legacy js files
//these exports are just for debugging in the browser
global.snapshot = db_getSnapshot;

View file

@ -0,0 +1,11 @@
//this file should be concatenated at the top of the legacy js files
import {
db_getSnapshot,
db_setSnapshot,
db_getUserSnapshot,
db_getUserResults,
db_getUserHighestWpm,
db_getLocalPB,
db_saveLocalPB,
} from "./db";

View file

@ -82,6 +82,17 @@ const layouts = {
" "
],
},
qwertz: {
keymapShowTopRow: false,
iso: true,
keys: [
"^°", "1!", "2\"", "3§", "4$", "5%", "6&", "7/", "8(", "9)", "0=", "ß?", "´`",
"qQ", "wW", "eE", "rR", "tT", "zZ", "uU", "iI", "oO", "pP", "üÜ", "+*", "'#",
"aA", "sS", "dD", "fF", "gG", "hH", "jJ", "kK", "lL", "öÖ", "äÄ",
"<>", "yY", "xX", "cC", "vV", "bB", "nN", "mM", ",;", ".:", "-_",
" "
]
},
workman: {
keymapShowTopRow: false,
keys: [
@ -202,5 +213,26 @@ const layouts = {
"<>", "wW", "xX", "cC", "vV", "bB", "nN", ",?", ";.", ":/", "!§",
" "
]
}
},
bepo: {
keymapShowTopRow: false,
iso: true,
keys: [
"$#", "\"1", "«2", "»3", "(4", ")5", "@6", "+7", "-8", "/9", "*0", "=°", "%`",
"bB", "éÉ", "pP", "oO", "èÈ", "^!", "vV", "dD", "lL", "jJ", "zZ", "wW", "mM",
"aA", "uU", "iI", "eE", ",;", "cC", "tT", "sS", "rR", "sS", "nN",
"êÊ", "àÀ", "yY", "xX", ".:", "kK", "?", "qQ", "gG", "hH", "fF",
" "
]
},
alpha: {
keymapShowTopRow: false,
keys: [
"`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+",
"aA", "bB", "cC", "dD", "eE", "fF", "gG", "hH", "iI", "jJ", "[{", "]}", "\\|",
"kK", "lL", "mM", "nN", "oO", "pP", "qQ", "rR", "sS", ";:", "'\"",
"\\|", "tT", "uU", "vV", "wW", "xX", "yY", "zZ", ",<", ".>", "/?",
" "
]
},
}

View file

@ -40,37 +40,8 @@ function updateLeaderboards() {
`#leaderboardsWrapper .buttons .button[board=${currentLeaderboard}]`
).addClass("active");
// $(
// `#leaderboardsWrapper .leaderboardMode .button[mode=${currentLeaderboard.mode}]`
// ).addClass("active");
// $("#leaderboardsWrapper .leaderboardWords .button").removeClass("active");
// $(
// `#leaderboardsWrapper .leaderboardWords .button[words=${currentLeaderboard.words}]`
// ).addClass("active");
// $("#leaderboardsWrapper .leaderboardTime .button").removeClass("active");
// $(
// `#leaderboardsWrapper .leaderboardTime .button[time=${currentLeaderboard.time}]`
// ).addClass("active");
let boardinfo = currentLeaderboard.split("_");
// if (boardinfo[0] === "time") {
// $("#leaderboardsWrapper .leaderboardWords").addClass("hidden");
// $("#leaderboardsWrapper .leaderboardTime").removeClass("hidden");
// } else if (currentLeaderboard.mode === "words") {
// $("#leaderboardsWrapper .leaderboardWords").removeClass("hidden");
// $("#leaderboardsWrapper .leaderboardTime").addClass("hidden");
// }
// let mode2;
// if (currentLeaderboard.mode === "words") {
// mode2 = currentLeaderboard.words;
// } else if (currentLeaderboard.mode === "time") {
// mode2 = currentLeaderboard.time;
// }
let uid = null;
if (firebase.auth().currentUser !== null) {
uid = firebase.auth().currentUser.uid;
@ -260,13 +231,3 @@ $("#leaderboardsWrapper .buttons .button").click((e) => {
currentLeaderboard = $(e.target).attr("board");
updateLeaderboards();
});
// $("#leaderboardsWrapper .leaderboardWords .button").click((e) => {
// currentLeaderboard.words = $(e.target).attr("words");
// updateLeaderboards();
// });
// $("#leaderboardsWrapper .leaderboardTime .button").click((e) => {
// currentLeaderboard.time = $(e.target).attr("time");
// updateLeaderboards();
// });

View file

@ -105,6 +105,29 @@ async function getLanguage(lang) {
}
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function smooth(arr, windowSize, getter = (value) => value, setter) {
const get = getter;
const result = [];
@ -488,6 +511,20 @@ function toggleFullscreen(elem) {
}
}
function canBailOut() {
return (
(config.mode === "custom" &&
customTextIsRandom &&
customTextWordCount >= 5000) ||
(config.mode === "custom" &&
!customTextIsRandom &&
customText.length >= 5000) ||
(config.mode === "words" && config.words >= 5000) ||
config.words === 0 ||
(config.mode === "time" && (config.time >= 3600 || config.time === 0))
);
}
let simplePopups = {};
class SimplePopup {

File diff suppressed because it is too large Load diff

View file

@ -145,10 +145,6 @@ settingsGroups.hideExtraLetters = new SettingsGroup(
settingsGroups.blindMode = new SettingsGroup("blindMode", setBlindMode);
settingsGroups.quickEnd = new SettingsGroup("quickEnd", setQuickEnd);
settingsGroups.enableAds = new SettingsGroup("enableAds", setEnableAds);
// settingsGroups.readAheadMode = new SettingsGroup(
// "readAheadMode",
// setReadAheadMode
// );
settingsGroups.alwaysShowWordsHistory = new SettingsGroup(
"alwaysShowWordsHistory",
setAlwaysShowWordsHistory
@ -193,9 +189,7 @@ settingsGroups.playSoundOnClick = new SettingsGroup(
"playSoundOnClick",
setPlaySoundOnClick,
() => {
if (config.playSoundOnClick !== "off")
// clickSounds[config.playSoundOnClick][0].sounds[0].play();
playClickSound();
if (config.playSoundOnClick !== "off") playClickSound();
}
);
settingsGroups.showAllLines = new SettingsGroup(
@ -497,8 +491,6 @@ $("#customThemeShare .button").click((e) => {
});
$("#shareCustomThemeButton").click((e) => {
// showCustomThemeShare();
if (e.shiftKey) {
showCustomThemeShare();
} else {
@ -556,9 +548,9 @@ function hideAccountSettingsSection() {
}
function refreshTagsSettingsSection() {
if (firebase.auth().currentUser !== null && dbSnapshot !== null) {
if (firebase.auth().currentUser !== null && db_getSnapshot() !== null) {
let tagsEl = $(".pageSettings .section.tags .tagsList").empty();
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
if (tag.active === true) {
tagsEl.append(`
@ -626,7 +618,7 @@ function setCustomThemeInputs() {
}
function showActiveTags() {
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
if (tag.active === true) {
$(
`.pageSettings .section.tags .tagsList .tag[id='${tag.id}'] .active`
@ -640,7 +632,7 @@ function showActiveTags() {
}
function toggleTag(tagid, nosave = false) {
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
if (tag.id === tagid) {
if (tag.active === undefined) {
tag.active = true;
@ -658,10 +650,10 @@ function updateDiscordSettingsSection() {
if (firebase.auth().currentUser == null) {
$(".pageSettings .section.discordIntegration").addClass("hidden");
} else {
if (dbSnapshot == null) return;
if (db_getSnapshot() == null) return;
$(".pageSettings .section.discordIntegration").removeClass("hidden");
if (dbSnapshot.discordId == undefined) {
if (db_getSnapshot().discordId == undefined) {
//show button
$(".pageSettings .section.discordIntegration .buttons").removeClass(
"hidden"
@ -727,7 +719,7 @@ $(
.then((ret) => {
hideBackgroundLoader();
if (ret.data.status === 1 || ret.data.status === 2) {
dbSnapshot.pairingCode = ret.data.pairingCode;
db_getSnapshot().pairingCode = ret.data.pairingCode;
$(".pageSettings .section.discordIntegration .code .bottom").text(
ret.data.pairingCode
);
@ -751,7 +743,7 @@ $(".pageSettings .section.discordIntegration #unlinkDiscordButton").click(
hideBackgroundLoader();
console.log(ret);
if (ret.data.status === 1) {
dbSnapshot.discordId = null;
db_getSnapshot().discordId = null;
showNotification("Accounts unlinked", 2000);
updateDiscordSettingsSection();
} else {
@ -826,7 +818,7 @@ $(".pageSettings .section.themes .tabs .button").click((e) => {
$target.addClass("active");
setCustomThemeInputs();
if ($target.attr("tab") == "preset") {
setCustomTheme(false, true);
setCustomTheme(false);
applyCustomThemeColors();
swapElements(
$('.pageSettings .section.themes .tabContainer [tabContent="custom"]'),
@ -834,7 +826,7 @@ $(".pageSettings .section.themes .tabs .button").click((e) => {
250
);
} else {
setCustomTheme(true, true);
setCustomTheme(true);
applyCustomThemeColors();
swapElements(
$('.pageSettings .section.themes .tabContainer [tabContent="preset"]'),

View file

@ -31,7 +31,6 @@ let defaultConfig = {
difficulty: "normal",
blindMode: false,
quickEnd: false,
// readAheadMode: false,
caretStyle: "default",
paceCaretStyle: "default",
flipTestColors: false,
@ -86,31 +85,26 @@ let configChangedBeforeDb = false;
//cookies
async function saveConfigToCookie(noDbCheck = false) {
if (!dbConfigLoaded && !noDbCheck) {
// console.log('config changed before db loaded!');
configChangedBeforeDb = true;
}
// showNotification('saving to cookie',1000);
let d = new Date();
d.setFullYear(d.getFullYear() + 1);
// $.cookie("config", null);
$.cookie("config", JSON.stringify(config), {
expires: d,
path: "/",
});
// let d = new Date();
// d.setFullYear(d.getFullYear() + 1);
// $.cookie("config", JSON.stringify(config), {
// expires: d,
// path: "/",
// });
setCookie("config", JSON.stringify(config), 365);
restartCount = 0;
if (!noDbCheck) await saveConfigToDB();
}
async function saveConfigToDB() {
if (firebase.auth().currentUser !== null) {
// showNotification('saving to db',1000);
accountIconLoading(true);
saveConfig({ uid: firebase.auth().currentUser.uid, obj: config }).then(
(d) => {
// console.log(d.data);
accountIconLoading(false);
if (d.data.returnCode === 1) {
// showNotification('config saved to db',1000);
} else {
showNotification(
`Error saving config to DB! ${d.data.message}`,
@ -135,26 +129,32 @@ function saveActiveTagsToCookie() {
let tags = [];
try {
dbSnapshot.tags.forEach((tag) => {
db_getSnapshot().tags.forEach((tag) => {
if (tag.active === true) {
tags.push(tag.id);
}
});
let d = new Date();
d.setFullYear(d.getFullYear() + 1);
$.cookie("activeTags", null);
$.cookie("activeTags", JSON.stringify(tags), {
expires: d,
path: "/",
});
// let d = new Date();
// d.setFullYear(d.getFullYear() + 1);
// $.cookie("activeTags", null);
// $.cookie("activeTags", JSON.stringify(tags), {
// expires: d,
// path: "/",
// });
setCookie("activeTags", JSON.stringify(tags), 365);
} catch (e) {}
}
function loadConfigFromCookie() {
console.log("loading cookie config");
let newConfig = $.cookie("config");
if (newConfig !== undefined) {
newConfig = JSON.parse(newConfig);
// let newConfig = $.cookie("config");
let newConfig = getCookie("config");
if (newConfig !== undefined && newConfig !== "") {
try {
newConfig = JSON.parse(newConfig);
} catch (e) {
newConfig = {};
}
applyConfig(newConfig);
console.log("applying cookie config");
cookieConfig = newConfig;
@ -189,7 +189,6 @@ function applyConfig(configObj) {
setDifficulty(configObj.difficulty, true);
setBlindMode(configObj.blindMode, true);
setQuickEnd(configObj.quickEnd, true);
// setReadAheadMode(configObj.readAheadMode, true);
setFlipTestColors(configObj.flipTestColors, true);
setColorfulMode(configObj.colorfulMode, true);
setConfidenceMode(configObj.confidenceMode, true);
@ -229,14 +228,8 @@ function applyConfig(configObj) {
setAlwaysShowCPM(configObj.alwaysShowCPM, true);
setHideExtraLetters(configObj.hideExtraLetters, true);
setStartGraphsAtZero(configObj.startGraphsAtZero, true);
setStrictSpace(configObj.strictSpace, true);
setMode(configObj.mode, true);
// if (
// configObj.resultFilters !== null &&
// configObj.resultFilters !== undefined
// ) {
// accountFilters = configObj.resultFilters;
// }
// config = configObj;
try {
setEnableAds(configObj.enableAds, true);
@ -300,9 +293,14 @@ function applyConfig(configObj) {
}
function loadActiveTagsFromCookie() {
let newTags = $.cookie("activeTags");
if (newTags !== undefined) {
newTags = JSON.parse(newTags);
// let newTags = $.cookie("activeTags");
let newTags = getCookie("activeTags");
if (newTags !== undefined && newTags !== "") {
try {
newTags = JSON.parse(newTags);
} catch (e) {
newTags = {};
}
newTags.forEach((ntag) => {
toggleTag(ntag, true);
});
@ -441,35 +439,6 @@ function setChartStyle(chartStyle, nosave) {
if (!nosave) saveConfigToCookie();
}
//read ahead mode
// function toggleReadAheadMode() {
// config.readAheadMode = !config.readAheadMode;
// applyReadAheadMode(config.readAheadMode);
// updateTestModesNotice();
// saveConfigToCookie();
// }
// function setReadAheadMode(readAhead, nosave) {
// if (readAhead == undefined) {
// readAhead = false;
// }
// config.readAheadMode = readAhead;
// applyReadAheadMode(readAhead);
// updateTestModesNotice();
// if (!nosave) saveConfigToCookie();
// }
//stoponerror
// function toggleStopOnError() {
// soe = !config.stopOnError;
// if (soe == undefined) {
// soe = false;
// }
// config.stopOnError = soe;
// updateTestModesNotice();
// saveConfigToCookie();
// }
function setStopOnError(soe, nosave) {
if (soe == undefined || soe === true || soe === false) {
soe = "off";
@ -595,6 +564,15 @@ function setAlwaysShowWordsHistory(val, nosave) {
if (!nosave) saveConfigToCookie();
}
function toggleAlwaysShowWordsHistory() {
let val = !config.alwaysShowWordsHistory;
if (val == undefined) {
val = false;
}
config.alwaysShowWordsHistory = val;
saveConfigToCookie();
}
//single list command line
function setSingleListCommandLine(option, nosave) {
if (!option) option = "manual";
@ -780,17 +758,11 @@ function setShowLiveWpm(live, nosave) {
live = false;
}
config.showLiveWpm = live;
// if (config.keymapMode !== "off") {
// config.keymapMode = "off";
// }
if (!nosave) saveConfigToCookie();
}
function toggleShowLiveWpm() {
config.showLiveWpm = !config.showLiveWpm;
// if (config.keymapMode !== "off") {
// config.keymapMode = "off";
// }
saveConfigToCookie();
}
@ -812,9 +784,6 @@ function setHideExtraLetters(val, nosave) {
function toggleHideExtraLetters() {
config.hideExtraLetters = !config.hideExtraLetters;
// if (config.keymapMode !== "off") {
// config.keymapMode = "off";
// }
saveConfigToCookie();
}
@ -971,11 +940,6 @@ function setStartGraphsAtZero(mode, nosave) {
if (!nosave) saveConfigToCookie();
}
// function toggleSmoothCaret() {
// config.smoothCaret = !config.smoothCaret;
// saveConfigToCookie();
// }
//linescroll
function setSmoothLineScroll(mode, nosave) {
config.smoothLineScroll = mode;
@ -991,14 +955,12 @@ function toggleSmoothLineScroll() {
function setQuickTabMode(mode, nosave) {
config.quickTab = mode;
if (!config.quickTab) {
// $(".pageTest").append('<div id="restartTestButton" class="" tabindex="0"><i class="fas fa-redo-alt"></i></div>');
$("#restartTestButton").removeClass("hidden");
$("#restartTestButton").css("opacity", 1);
$("#bottom .keyTips")
.html(`<key>tab</key> and <key>enter</key> / <key>space</key> - restart test<br>
<key>esc</key> - command line`);
} else {
// $("#restartTestButton").remove();
$("#restartTestButton").addClass("hidden");
$("#bottom .keyTips").html(`<key>tab</key> - restart test<br>
<key>esc</key> - command line`);
@ -1009,14 +971,12 @@ function setQuickTabMode(mode, nosave) {
function toggleQuickTabMode() {
config.quickTab = !config.quickTab;
if (!config.quickTab) {
// $(".pageTest").append('<div id="restartTestButton" class="" tabindex="0"><i class="fas fa-redo-alt"></i></div>');
$("#restartTestButton").removeClass("hidden");
$("#restartTestButton").css("opacity", 1);
$("#bottom .keyTips")
.html(`<key>tab</key> and <key>enter</key> / <key>space</key> - restart test<br>
<key>esc</key> - command line`);
} else {
// $("#restartTestButton").remove();
$("#restartTestButton").addClass("hidden");
$("#bottom .keyTips").html(`<key>tab</key> - restart test<br>
<key>esc</key> - command line`);
@ -1071,7 +1031,6 @@ function previewFontFamily(font) {
font = "Roboto_Mono";
}
document.documentElement.style.setProperty("--font", font.replace(/_/g, " "));
// if (!nosave) saveConfigToCookie();
}
//font family
@ -1205,14 +1164,8 @@ function setRandomTheme(val, nosave) {
if (!nosave) saveConfigToCookie();
}
// function toggleRandomTheme() {
// config.randomTheme = !config.randomTheme;
// saveConfigToCookie();
// }
function setCustomTheme(boolean, nosave) {
if (boolean !== undefined) config.customTheme = boolean;
// setCustomThemeColors(config.customThemeColors, nosave);
if (!nosave) saveConfigToCookie();
}
@ -1251,8 +1204,6 @@ function togglePresetCustomTheme() {
if (config.customTheme) {
setCustomTheme(false);
applyCustomThemeColors();
// $('[tabContent="custom"]').removeClass("reveal");
// $('[tabContent="preset"]').addClass("reveal");
swapElements(
$('.pageSettings [tabContent="custom"]'),
$('.pageSettings [tabContent="preset"]'),
@ -1266,8 +1217,6 @@ function togglePresetCustomTheme() {
$('.pageSettings [tabContent="custom"]'),
250
);
// $('[tabContent="preset"]').removeClass("reveal");
// $('[tabContent="custom"]').addClass("reveal");
}
$(".keymap-key").attr("style", "");
}
@ -1308,7 +1257,6 @@ function updateFavicon(size, curveSize) {
ctx.textAlign = "center";
ctx.fillStyle = maincolor;
ctx.fillText("mt", size / 2 + size / 32, (size / 3) * 2.1);
// document.body.appendChild(canvas);
$("#favicon").attr("href", canvas.toDataURL("image/png"));
}
@ -1363,12 +1311,8 @@ function setKeymapMode(mode, nosave) {
if (mode == null || mode == undefined) {
mode = "off";
}
// if (mode === "react" ||) {
$(".active-key").removeClass("active-key");
// }
// if (mode === "next") {
$(".keymap-key").attr("style", "");
// }
config.keymapMode = mode;
if (!nosave) restartTest(false, nosave);
if (!nosave) saveConfigToCookie();
@ -1390,55 +1334,10 @@ function setKeymapStyle(style, nosave) {
} else if (style === "split_matrix") {
$(".keymap").addClass("split_matrix");
}
// if (style === "staggered") {
// $(".keymap .keymap-split-spacer").addClass("hidden");
// $(".keymap .r1, .r2, .r3, .r4").removeClass("matrix");
// $(".keymap .r5").removeClass("matrixSpace");
// $(".keymap #KeyLeftBracket").removeClass("hide-key");
// $(".keymap #KeyRightBracket").removeClass("hide-key");
// $(".keymap #KeyQuote").removeClass("hide-key");
// }
// if (style === "split") {
// $(".keymap .keymap-split-spacer").removeClass("hidden");
// $(".keymap .r1, .keymap .r2, .keymap .r3, .keymap .r4").removeClass(
// "matrix"
// );
// $(".keymap .r5").removeClass("splitSpace");
// $(".keymap #KeyLeftBracket").removeClass("hide-key");
// $(".keymap #KeyRightBracket").removeClass("hide-key");
// $(".keymap #KeyQuote").removeClass("hide-key");
// }
// if (style === "matrix") {
// $(".keymap .keymap-split-spacer").addClass("hidden");
// $(".keymap .r1, .keymap .r2, .keymap .r3, .keymap .r4").addClass("matrix");
// $(".keymap .r5").addClass("matrixSpace");
// $(".keymap #KeyLeftBracket").addClass("hide-key");
// $(".keymap #KeyRightBracket").addClass("hide-key");
// $(".keymap #KeyQuote").addClass("hide-key");
// }
config.keymapStyle = style;
if (!nosave) saveConfigToCookie();
}
// function toggleISOKeymap() {
// val = !config.isoKeymap;
// if (val == undefined) {
// val = false;
// }
// config.isoKeymap = val;
// updateKeymapBottomRow();
// saveConfigToCookie();
// }
// function setISOKeymap(val, nosave) {
// if (val == undefined) {
// val = false;
// }
// config.isoKeymap = val;
// updateKeymapBottomRow();
// if (!nosave) saveConfigToCookie();
// }
function keymapShowIsoKey(tf) {
if (tf) {
$(".keymap .r4 .keymap-key.first").removeClass("hidden-key");
@ -1454,10 +1353,6 @@ function setKeymapLayout(layout, nosave) {
config.keymapLayout = layout;
refreshKeymapKeys(layout);
if (!nosave) saveConfigToCookie();
// layouts[layout].forEach((x) => {
// console.log(x);
// });
// console.log(all.join());
}
function refreshKeymapKeys(layout) {
@ -1486,16 +1381,10 @@ function refreshKeymapKeys(layout) {
keymapShowIsoKey(lts.iso);
var toReplace = lts.keys.slice(1, 48);
// var _ = toReplace.splice(12, 1);
var count = 0;
$(".keymap .letter")
.map(function () {
// if (
// !this.parentElement.classList.contains("hidden-key") &&
// !this.classList.contains("hidden-key")
// ) {
if (count < toReplace.length) {
var key = toReplace[count].charAt(0);
this.innerHTML = key;
@ -1556,7 +1445,6 @@ function setFontSize(fontSize, nosave) {
if (fontSize == null || fontSize == undefined) {
fontSize = 1;
}
// $("#words").stop(true, true).animate({ opacity: 0 }, 125, e => {
config.fontSize = fontSize;
$("#words").removeClass("size125");
$("#caret, #paceCaret").removeClass("size125");
@ -1590,6 +1478,4 @@ function setFontSize(fontSize, nosave) {
$("#miniTimerAndLiveWpm").addClass("size3");
}
if (!nosave) saveConfigToCookie();
// restartTest();
// });
}

View file

@ -3,5 +3,5 @@
} */
#words .word {
color: var(--bg-color) !important;
color: transparent !important;
}

View file

@ -6,7 +6,7 @@
<title>Monkeytype</title>
<!-- <link rel="stylesheet" href="css/fa.css" /> -->
<link rel="stylesheet" href="css/balloon.css" />
<link rel="stylesheet" href="css/style.css?v=58" />
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="themes/serika_dark.css" id="currentTheme" />
<link rel="stylesheet" href="" id="funBoxTheme" />
<link id="favicon" rel="shortcut icon" href="fav.png" />
@ -3411,14 +3411,14 @@
</div>
</body>
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="/__/firebase/7.14.3/firebase-app.js"></script>
<script src="/__/firebase/8.0.2/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="/__/firebase/7.14.3/firebase-analytics.js"></script>
<script src="/__/firebase/7.14.3/firebase-auth.js"></script>
<script src="/__/firebase/7.14.2/firebase-firestore.js"></script>
<script src="/__/firebase/7.14.2/firebase-functions.js"></script>
<script src="/__/firebase/8.0.2/firebase-analytics.js"></script>
<script src="/__/firebase/8.0.2/firebase-auth.js"></script>
<script src="/__/firebase/8.0.2/firebase-firestore.js"></script>
<script src="/__/firebase/8.0.2/firebase-functions.js"></script>
<!-- Initialize Firebase -->
<script src="/__/firebase/init.js"></script>

View file

@ -399,14 +399,14 @@
"approximate",
"approximately",
"apps",
"april",
"April",
"apt",
"aqua",
"aquarium",
"aquatic",
"Arab",
"Arabia",
"arabic",
"Arabic",
"arbitrary",
"arbitration",
"arc",
@ -520,7 +520,7 @@
"athletic",
"athletics",
"Atlanta",
"atlantic",
"Atlantic",
"atlas",
"atmosphere",
"atmospheric",
@ -560,7 +560,7 @@
"audio",
"audit",
"auditor",
"august",
"August",
"aurora",
"Australia",
"Australian",
@ -1069,7 +1069,7 @@
"calendar",
"calendars",
"calibration",
"california",
"California",
"call",
"called",
"calling",
@ -1181,7 +1181,7 @@
"causing",
"caution",
"cave",
"cayman",
"Cayman",
"cedar",
"ceiling",
"celebrate",
@ -1213,7 +1213,7 @@
"certificates",
"certification",
"certified",
"chad",
"Chad",
"chain",
"chains",
"chair",
@ -1312,11 +1312,11 @@
"chorus",
"chose",
"chosen",
"christ",
"Christ",
"christian",
"christianity",
"Christianity",
"christians",
"christmas",
"Christmas",
"chrome",
"chronic",
"chronicle",
@ -1874,7 +1874,7 @@
"critical",
"criticism",
"critics",
"croatia",
"Croatia",
"crop",
"crops",
"cross",
@ -1980,7 +1980,7 @@
"debut",
"decade",
"decades",
"december",
"December",
"decent",
"decide",
"decided",
@ -2454,8 +2454,8 @@
"efforts",
"egg",
"eggs",
"egypt",
"egyptian",
"Egypt",
"Egyptian",
"eh",
"eight",
"either",
@ -2863,7 +2863,7 @@
"featured",
"features",
"featuring",
"february",
"February",
"federal",
"federation",
"fee",
@ -3322,8 +3322,8 @@
"greater",
"greatest",
"greatly",
"greece",
"greek",
"Greece",
"Greek",
"green",
"greenhouse",
"greeting",
@ -3971,7 +3971,7 @@
"jail",
"jam",
"Jamaica",
"january",
"January",
"Japan",
"Japanese",
"jar",
@ -3981,7 +3981,7 @@
"jeep",
"jersey",
"Jerusalem",
"jesus",
"Jesus",
"jet",
"jets",
"jewel",
@ -4011,11 +4011,11 @@
"judicial",
"judy",
"juice",
"july",
"July",
"jump",
"jumping",
"junction",
"june",
"June",
"jungle",
"junior",
"junk",
@ -4213,7 +4213,7 @@
"liability",
"liable",
"liberal",
"liberia",
"Liberia",
"liberty",
"librarian",
"libraries",
@ -4316,7 +4316,7 @@
"logical",
"login",
"logistics",
"logitech",
"Logitech",
"logo",
"logos",
"logs",
@ -4536,7 +4536,7 @@
"medicines",
"medieval",
"meditation",
"mediterranean",
"Mediterranean",
"medium",
"meet",
"meeting",
@ -4699,7 +4699,7 @@
"moments",
"momentum",
"Monaco",
"monday",
"Monday",
"monetary",
"money",
"Mongolia",
@ -4726,7 +4726,7 @@
"mortgage",
"mortgages",
"Moscow",
"moses",
"Moses",
"moss",
"most",
"mostly",
@ -4779,8 +4779,8 @@
"musical",
"musician",
"musicians",
"muslim",
"muslims",
"Muslim",
"Muslims",
"must",
"mutual",
"Myanmar",
@ -4922,7 +4922,7 @@
"novel",
"novels",
"novelty",
"november",
"November",
"now",
"nowhere",
"nuclear",
@ -4977,7 +4977,7 @@
"occurring",
"occurs",
"ocean",
"october",
"October",
"odd",
"odds",
"of",
@ -5086,7 +5086,7 @@
"organized",
"organizer",
"organizing",
"oriental",
"Oriental",
"orientation",
"oriented",
"origin",
@ -5138,7 +5138,7 @@
"oxygen",
"ozone",
"pace",
"pacific",
"Pacific",
"pack",
"package",
"packages",
@ -5434,7 +5434,7 @@
"playing",
"playlist",
"plays",
"playstation",
"PlayStation",
"plaza",
"pleasant",
"please",
@ -5463,7 +5463,7 @@
"pointer",
"pointing",
"points",
"pokemon",
"Pokemon",
"poker",
"Poland",
"polar",
@ -5488,7 +5488,7 @@
"pools",
"poor",
"pop",
"pope",
"Pope",
"popular",
"popularity",
"population",
@ -5501,7 +5501,7 @@
"portfolio",
"portion",
"portions",
"portland",
"Portland",
"portrait",
"portraits",
"ports",
@ -6093,7 +6093,7 @@
"remove",
"removed",
"removing",
"renaissance",
"Renaissance",
"render",
"rendered",
"rendering",
@ -6138,8 +6138,8 @@
"reproduction",
"reproductive",
"republic",
"republican",
"republicans",
"Republican",
"Republicans",
"reputation",
"request",
"requested",
@ -6545,7 +6545,7 @@
"separated",
"separately",
"separation",
"september",
"September",
"sequence",
"sequences",
"Serbia",
@ -6585,7 +6585,7 @@
"shake",
"shall",
"shame",
"shanghai",
"Shanghai",
"shannon",
"shape",
"shaped",
@ -7646,7 +7646,7 @@
"typical",
"typically",
"typing",
"uganda",
"Uganda",
"ugly",
"Ukraine",
"ultimate",
@ -7809,8 +7809,8 @@
"victim",
"victims",
"victor",
"victoria",
"victorian",
"Victoria",
"Victorian",
"victory",
"video",
"videos",
@ -7960,7 +7960,7 @@
"wed",
"wedding",
"weddings",
"wednesday",
"Wednesday",
"week",
"weekend",
"weekends",
@ -7974,7 +7974,7 @@
"welding",
"welfare",
"well",
"wellington",
"Wellington",
"wellness",
"wells",
"Welsh",

View file

@ -27,5 +27,7 @@
"finnish",
"persian",
"kazakh",
"vietnamese"
"vietnamese",
"vietnamese_1k",
"python"
]

View file

@ -0,0 +1,58 @@
{
"name": "python",
"leftToRight": true,
"words":[
"and",
"as",
"assert",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"False",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"None",
"not",
"or",
"pass",
"raise",
"return",
"True",
"try",
"while",
"with",
"yield",
"print",
"len",
"str",
"int",
"float",
"list",
"tuple",
"dict",
"set",
"range",
"sum",
"enumerate",
"zip",
"bool",
"reversed",
"sorted",
"min",
"max",
"any",
"all"
]
}

View file

@ -2,156 +2,323 @@
"name": "vietnamese",
"leftToRight": true,
"words": [
"chào",
"má",
"ba",
"cha",
"con",
"anh",
"em",
"chị",
"bà",
"ngoại",
"ông",
"nội",
"ăn",
"cơm",
"chưa",
"rồi",
"sáng",
"đi",
"học",
"làm",
"bài",
"tập",
"trái",
"cây",
"tắm",
"chơi",
"bia",
"rượu",
"cà",
"phê",
"cơm",
"tấm",
"hủ",
"tiếu",
"sướng",
"ngày",
"là",
"độc",
"lập",
"trong",
"tim",
"mỗi",
"người",
"sung",
"đời",
"à",
"sướng",
"bếp",
"sài",
"gòn",
"phải",
"tiền",
"nhiêu",
"lấy",
"của",
"để",
"không",
"phí",
"sữa",
"văn",
"chút",
"thuốc",
"hút",
"điện",
"thoại",
"di",
"động",
"máy",
"vi",
"tính",
"công",
"cộng",
"siêu",
"thị",
"được",
"trường",
"khoa",
"mình",
"hạnh",
"phúc",
"công",
"ty",
"ngân",
"ở",
"tại",
"sao",
"ai",
"cảm",
"ơn",
"xin",
"lỗi",
"mắc",
"quận",
"đói",
"nhung",
"lụa",
"thích",
"yêu",
"hiểu",
"gì",
"cười",
"bởi",
"hôm",
"qua",
"ngày",
"nhục",
"phục",
"thù",
"xào",
"luộc",
"tri",
"thức",
"nước",
"tương",
"nước",
"đá",
"đọc",
"nắng",
"kính",
"bao",
"lâu",
"quát",
"trường",
"học",
"rán",
"thi",
"hành",
"nhà",
"vệ",
"sinh",
"đúng",
"giận",
"dỗi",
"mang",
"xà",
"bông",
"bởi",
"vì",
"dầu",
"gội",
"đầu",
"trai",
"quán",
"ăn",
"chúng",
"mình",
"hoàn",
"xong",
"việc",
"dự",
"định",
"đến",
"trễ",
"giặt",
"chuẩn",
"bị",
"nhanh",
"nhức",
"đầu",
"mập",
"vui",
"mừng",
"loài",
"vật",
"cười",
"tự",
"do",
"tôi",
"nhạc",
"kính",
"lịch",
"sử",
"đất",
"tổ",
"quốc",
"bay",
"ngày",
"tỉnh",
"lũ",
"đinh",
"tham",
"cầu",
"đường",
"du",
"lịch",
"phương",
"đinh",
"đất",
"xin",
"lỗi",
"mà",
"giao",
"thông",
"trong",
"xây",
"dựng",
"bà",
"cầu",
"đường",
"cười",
"công",
"trình",
"hoài",
"hay",
"nói",
"đỏ",
"trần",
"pháp",
"luật",
"làm",
"tổ",
"quốc",
"hà",
"lao",
"xao",
"chăm",
"bánh",
"xanh",
"sống",
"hỷ",
"thế",
"giới",
"hướng",
"xin",
"kinh",
"chị",
"quá",
"viết",
"lách",
"tia",
"nắng",
"thế",
"giới",
"gửi",
"tự",
"do",
"phép",
"sợ",
"thanh",
"tháng",
"phối",
"hợp",
"cô",
"giấy",
"tờ",
"thanh",
"niên",
"sư",
"phạm",
"phương",
"tri",
"xinh",
"đẹp",
"quảng",
"nam",
"báo",
"sư",
"phạm",
"ngoài",
"ngành",
"khoa",
"lang",
"cảm",
"trang",
"đợi",
"chi",
"xã",
"hội",
"im",
"vui",
"vẻ",
"khó",
"khăn",
"màu",
"tình",
"yêu",
"trong",
"nhân",
"dân",
"khoa",
"phải",
"giành",
"lựu",
"ba",
"khoa",
"thành",
"cảm",
"ơn",
"biển",
"phối",
"hợp",
"hãy",
"cảm",
"ơn",
"chim",
"khóc",
"điện",
"tử",
"gì",
"trời",
"chú",
"sài",
"gòn",
"nắng",
"phép",
"biển",
"lành",
"độc",
"lập",
"đánh",
"vệ",
"sinh",
"vì",
"nhung",
"em",
"da",
"bếp",
"công",
"trình",
"theo",
"hả",
"trang",
"xã",
"hội",
"bóng",
"nào",
"ký",
"tên",
"bão",
"dạ",
"vâng",
"làm",
"ẩm",
"thực",
"áo",
"quần",
"hà",
"nội",
"mà",
"chính",
"chú",
"minh",
"hạnh",
"phúc",
"chia",
"sẻ",
"công",
"nghệ",
"thư",
"quảng",
"nam",
"lành",
"huế",
"dũng",
"thành",
"rán",
"thang",
"tham",
"cuộc",
"đời",
"thay",
"mặt",
"gửi",
"dạy",
"sơ",
"chào",
"dạy",
"lại",
"đi",
"xanh",
"sơ",
"màu",
"món",
"ăn",
"hay",
"đàn",
"sáo",
"gió",
"em",
"ba",
"báo",
"đỏ",
"chăm",
"khóc",
"kiến",
"trúc",
"phủ",
"ngữ",
"văn",
"bão",
"tin",
"minh",
"công",
"nghệ",
"hãy",
"chào",
"cao",
"anh",
"sợ",
"vệ",
"sinh",
"tay",
"quảng",
"bình",
"huế",
"con",
"người",
"bà",
"khánh",
"mưa",
"tuổi",
"giao",
"nam",
"đơn",
"thư",
"phần",
"bay",
"thi",
"hành",
"khởi"
"hướng",
"là",
"phép",
"chính",
"dễ",
"dàng",
"tên",
"phép",
"ngủ",
"hạt",
"bướm",
"quá",
"nào",
"tháng",
"hoàn",
"toàn",
"mẹ",
"phố",
"ngày",
"kĩ",
"thuật",
"phần",
"thang",
"trần",
"cảm",
"điện",
"tử",
"năm",
"giao",
"nam",
"nga",
"nhạc",
"bóng",
"lựu",
"hả",
"anh",
"cổ",
"tích"
]
}
}

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@
<title>Monkeytype</title>
<!-- <link rel="stylesheet" href="css/fa.css" /> -->
<link rel="stylesheet" href="css/balloon.css" />
<link rel="stylesheet" href="css/style.min.css?v=58" />
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="themes/serika_dark.css" id="currentTheme" />
<link rel="stylesheet" href="" id="funBoxTheme" />
<link id="favicon" rel="shortcut icon" href="fav.png" />

View file

@ -433,5 +433,10 @@
"name": "iceberg_light",
"bgColor": "#e8e9ec",
"textColor": "#33374c"
},
{
"name": "onedark",
"bgColor": "#2f343f",
"textColor": "#98c379"
}
]

11
static/themes/onedark.css Normal file
View file

@ -0,0 +1,11 @@
:root {
--bg-color: #2f343f;
--caret-color: #61afef;
--main-color: #61afef;
--sub-color: #eceff4;
--text-color: #98c379;
--error-color: #e06c75;
--error-extra-color: #d62436;
--colorful-error-color: #d62436;
--colorful-error-extra-color: #ff0019;
}