mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 23:36:37 +08:00
Merge branch 'master' of https://github.com/Smithster/monkeytype
This commit is contained in:
commit
c422e0c548
|
@ -846,7 +846,7 @@ function validateResult(result) {
|
|||
return total + val;
|
||||
}) / 1000;
|
||||
if (
|
||||
keyPressTimeSum < result.testDuration - 8 ||
|
||||
keyPressTimeSum < result.testDuration - 1 ||
|
||||
keyPressTimeSum > result.testDuration + 1
|
||||
) {
|
||||
console.error(
|
||||
|
@ -1052,6 +1052,13 @@ async function getIncrementedTypingStats(userData, resultObj) {
|
|||
}
|
||||
tt = resultObj.testDuration + resultObj.incompleteTestSeconds - afk;
|
||||
|
||||
if (tt > 500)
|
||||
console.log(
|
||||
`FUCK, INCREASING BY A LOT ${resultObj.uid}: ${JSON.stringify(
|
||||
resultObj
|
||||
)}`
|
||||
);
|
||||
|
||||
if (userData.startedTests === undefined) {
|
||||
newStarted = resultObj.restartCount + 1;
|
||||
} else {
|
||||
|
@ -1229,81 +1236,6 @@ async function incrementStartedTestCounter(uid, num, userData) {
|
|||
}
|
||||
}
|
||||
|
||||
async function incrementTimeSpentTyping(uid, res, userData) {
|
||||
try {
|
||||
if (userData.timeTyping === undefined) {
|
||||
let stepSize = 1000;
|
||||
let results = [];
|
||||
let query = await db
|
||||
.collection(`users/${uid}/results`)
|
||||
.orderBy("timestamp", "desc")
|
||||
.limit(stepSize)
|
||||
.get();
|
||||
let lastDoc;
|
||||
while (query.docs.length > 0) {
|
||||
lastDoc = query.docs[query.docs.length - 1];
|
||||
query.docs.forEach((doc) => {
|
||||
let dd = doc.data();
|
||||
results.push({
|
||||
testDuration: dd.testDuration,
|
||||
incompleteTestSeconds: dd.incompleteTestSeconds,
|
||||
});
|
||||
});
|
||||
query = await db
|
||||
.collection(`users/${uid}/results`)
|
||||
.orderBy("timestamp", "desc")
|
||||
.limit(stepSize)
|
||||
.startAfter(lastDoc)
|
||||
.get();
|
||||
}
|
||||
|
||||
let timeSum = 0;
|
||||
results.forEach((result) => {
|
||||
try {
|
||||
let ts = result.testDuration;
|
||||
let its = result.incompleteTestSeconds;
|
||||
let s1 = ts == undefined ? 0 : ts;
|
||||
let s2 = its == undefined ? 0 : its;
|
||||
|
||||
timeSum += parseFloat(s1) + parseFloat(s2);
|
||||
} catch (e) {}
|
||||
});
|
||||
db.collection("users")
|
||||
.doc(uid)
|
||||
.update({
|
||||
timeTyping: admin.firestore.FieldValue.increment(timeSum),
|
||||
});
|
||||
db.collection("public")
|
||||
.doc("stats")
|
||||
.update({
|
||||
timeTyping: admin.firestore.FieldValue.increment(timeSum),
|
||||
});
|
||||
} else {
|
||||
let afk = res.afkDuration;
|
||||
if (afk == undefined) {
|
||||
afk = 0;
|
||||
}
|
||||
|
||||
db.collection("users")
|
||||
.doc(uid)
|
||||
.update({
|
||||
timeTyping: admin.firestore.FieldValue.increment(
|
||||
res.testDuration + res.incompleteTestSeconds - afk
|
||||
),
|
||||
});
|
||||
db.collection("public")
|
||||
.doc("stats")
|
||||
.update({
|
||||
timeTyping: admin.firestore.FieldValue.increment(
|
||||
res.testDuration + res.incompleteTestSeconds - afk
|
||||
),
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Error while incrementing time typing for user ${uid}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
exports.testCompleted = functions.https.onRequest(async (request, response) => {
|
||||
response.set("Access-Control-Allow-Origin", origin);
|
||||
if (request.method === "OPTIONS") {
|
||||
|
@ -1328,6 +1260,13 @@ exports.testCompleted = functions.https.onRequest(async (request, response) => {
|
|||
|
||||
let obj = request.obj;
|
||||
|
||||
if (obj.incompleteTestSeconds > 500)
|
||||
console.log(
|
||||
`FUCK, HIGH INCOMPLETE TEST SECONDS ${request.uid}: ${JSON.stringify(
|
||||
obj
|
||||
)}`
|
||||
);
|
||||
|
||||
function verifyValue(val) {
|
||||
let errCount = 0;
|
||||
if (val === null || val === undefined) {
|
||||
|
@ -1373,20 +1312,20 @@ exports.testCompleted = functions.https.onRequest(async (request, response) => {
|
|||
(obj.mode === "words" && obj.mode2 < 10 && obj.mode2 > 0) ||
|
||||
(obj.mode === "words" && obj.mode2 == 0 && obj.testDuration < 15) ||
|
||||
(obj.mode === "custom" &&
|
||||
obj.CustomText !== undefined &&
|
||||
!obj.CustomText.isWordRandom &&
|
||||
!obj.CustomText.isTimeRandom &&
|
||||
obj.CustomText.textLen < 10) ||
|
||||
obj.customText !== undefined &&
|
||||
!obj.customText.isWordRandom &&
|
||||
!obj.customText.isTimeRandom &&
|
||||
obj.customText.textLen < 10) ||
|
||||
(obj.mode === "custom" &&
|
||||
obj.CustomText !== undefined &&
|
||||
obj.CustomText.isWordRandom &&
|
||||
!obj.CustomText.isTimeRandom &&
|
||||
obj.CustomText.word < 10) ||
|
||||
obj.customText !== undefined &&
|
||||
obj.customText.isWordRandom &&
|
||||
!obj.customText.isTimeRandom &&
|
||||
obj.customText.word < 10) ||
|
||||
(obj.mode === "custom" &&
|
||||
obj.CustomText !== undefined &&
|
||||
!obj.CustomText.isWordRandom &&
|
||||
obj.CustomText.isTimeRandom &&
|
||||
obj.CustomText.time < 15)
|
||||
obj.customText !== undefined &&
|
||||
!obj.customText.isWordRandom &&
|
||||
obj.customText.isTimeRandom &&
|
||||
obj.customText.time < 15)
|
||||
) {
|
||||
response
|
||||
.status(200)
|
||||
|
@ -1552,14 +1491,6 @@ exports.testCompleted = functions.https.onRequest(async (request, response) => {
|
|||
incrementT60Bananas(request.uid, obj, userdata);
|
||||
}
|
||||
|
||||
// incrementTestCounter(request.uid, userdata);
|
||||
// incrementStartedTestCounter(
|
||||
// request.uid,
|
||||
// obj.restartCount + 1,
|
||||
// userdata
|
||||
// );
|
||||
// incrementTimeSpentTyping(request.uid, obj, userdata);
|
||||
|
||||
let newTypingStats = await getIncrementedTypingStats(userdata, obj);
|
||||
|
||||
if (
|
||||
|
@ -2489,11 +2420,11 @@ async function checkLeaderboards(
|
|||
|
||||
if (insertResult.insertedAt >= 0) {
|
||||
//update the database here
|
||||
console.log(
|
||||
`leaderboard changed ${resultObj.mode} ${
|
||||
resultObj.mode2
|
||||
} ${type} - ${JSON.stringify(lb.board)}`
|
||||
);
|
||||
// console.log(
|
||||
// `leaderboard changed ${resultObj.mode} ${
|
||||
// resultObj.mode2
|
||||
// } ${type} - ${JSON.stringify(lb.board)}`
|
||||
// );
|
||||
t.update(db.collection("leaderboards").doc(docid), {
|
||||
size: lb.size,
|
||||
type: lb.type,
|
||||
|
|
44
functions/package-lock.json
generated
44
functions/package-lock.json
generated
|
@ -295,9 +295,9 @@
|
|||
}
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
|
||||
"integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
|
||||
"version": "3.4.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
|
||||
"integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
|
@ -313,9 +313,9 @@
|
|||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.17.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz",
|
||||
"integrity": "sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA==",
|
||||
"version": "4.17.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz",
|
||||
"integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
|
@ -335,9 +335,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
|
||||
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
|
||||
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
|
@ -345,14 +345,14 @@
|
|||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.10.66",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
|
||||
"integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw=="
|
||||
"version": "14.14.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.34.tgz",
|
||||
"integrity": "sha512-dBPaxocOK6UVyvhbnpFIj2W+S+1cBTkHQbFQfeeJhoKFbzYcVUGHvddeWPSucKATb3F0+pgDq0i6ghEaZjsugA=="
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
|
||||
"integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ=="
|
||||
"version": "6.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
|
||||
"integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA=="
|
||||
},
|
||||
"@types/range-parser": {
|
||||
"version": "1.2.3",
|
||||
|
@ -360,11 +360,11 @@
|
|||
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.13.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.6.tgz",
|
||||
"integrity": "sha512-nuRJmv7jW7VmCVTn+IgYDkkbbDGyIINOeu/G0d74X3lm6E5KfMeQPJhxIt1ayQeQB3cSxvYs1RA/wipYoFB4EA==",
|
||||
"version": "1.13.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
|
||||
"integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==",
|
||||
"requires": {
|
||||
"@types/mime": "*",
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
|
@ -1265,9 +1265,9 @@
|
|||
}
|
||||
},
|
||||
"firebase-functions": {
|
||||
"version": "3.11.0",
|
||||
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.11.0.tgz",
|
||||
"integrity": "sha512-i1uMhZ/M6i5SCI3ulKo7EWX0/LD+I5o6N+sk0HbOWfzyWfOl0iJTvQkR3BVDcjrlhPVC4xG1bDTLxd+DTkLqaw==",
|
||||
"version": "3.13.2",
|
||||
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.13.2.tgz",
|
||||
"integrity": "sha512-XHgAQZqA62awr4l9mNlJv6qnv5MkMkLuo+hafdW0T7IJj1PgrZtuIo5x+ib2npAcB0XhX5Sg0QR1hMYPAlfbaA==",
|
||||
"requires": {
|
||||
"@types/express": "4.17.3",
|
||||
"cors": "^2.8.5",
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"firebase-admin": "^9.4.1",
|
||||
"firebase-functions": "^3.11.0",
|
||||
"firebase-functions": "^3.13.2",
|
||||
"pretty-quick": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -98,6 +98,9 @@ const refactoredSrc = [
|
|||
"./src/js/sound.js",
|
||||
"./src/js/custom-text.js",
|
||||
"./src/js/shift-tracker.js",
|
||||
"./src/js/test/test-stats.js",
|
||||
"./src/js/theme-colors.js",
|
||||
"./src/js/test/out-of-focus.js",
|
||||
];
|
||||
|
||||
//legacy files
|
||||
|
|
|
@ -954,22 +954,22 @@ function updateHoverChart(filteredId) {
|
|||
hoverChart.data.datasets[1].data = data.raw;
|
||||
hoverChart.data.datasets[2].data = data.err;
|
||||
|
||||
hoverChart.options.scales.xAxes[0].ticks.minor.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.xAxes[0].scaleLabel.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].ticks.minor.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].ticks.minor.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].scaleLabel.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].scaleLabel.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.xAxes[0].scaleLabel.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub;
|
||||
|
||||
hoverChart.data.datasets[0].borderColor = themeColors.main;
|
||||
hoverChart.data.datasets[0].pointBackgroundColor = themeColors.main;
|
||||
hoverChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
hoverChart.data.datasets[1].pointBackgroundColor = themeColors.sub;
|
||||
hoverChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
hoverChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
|
||||
hoverChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
hoverChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
|
||||
|
||||
hoverChart.options.annotation.annotations[0].borderColor = themeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].borderColor = ThemeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].label.backgroundColor =
|
||||
themeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].label.fontColor = themeColors.bg;
|
||||
ThemeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].label.fontColor = ThemeColors.bg;
|
||||
|
||||
let maxChartVal = Math.max(...[Math.max(...data.wpm), Math.max(...data.raw)]);
|
||||
let minChartVal = Math.min(...[Math.min(...data.wpm), Math.min(...data.raw)]);
|
||||
|
@ -1746,11 +1746,28 @@ function refreshGlobalStats() {
|
|||
}
|
||||
}
|
||||
|
||||
function updateAccountLoginButton() {
|
||||
if (firebase.auth().currentUser != null) {
|
||||
swapElements(
|
||||
$("#menu .icon-button.login"),
|
||||
$("#menu .icon-button.account"),
|
||||
250
|
||||
);
|
||||
} else {
|
||||
swapElements(
|
||||
$("#menu .icon-button.account"),
|
||||
$("#menu .icon-button.login"),
|
||||
250
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let totalSecondsFiltered = 0;
|
||||
|
||||
function refreshAccountPage() {
|
||||
function cont() {
|
||||
refreshThemeColorObject();
|
||||
ThemeColors.update();
|
||||
updateChartColors();
|
||||
refreshGlobalStats();
|
||||
fillPbTables();
|
||||
|
||||
|
@ -2102,42 +2119,42 @@ function refreshAccountPage() {
|
|||
activityChart.data.datasets[0].data = activityChartData_time;
|
||||
activityChart.data.datasets[1].data = activityChartData_avgWpm;
|
||||
|
||||
activityChart.options.legend.labels.fontColor = themeColors.sub;
|
||||
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
|
||||
|
||||
activityChart.options.scales.xAxes[0].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
activityChart.options.scales.yAxes[0].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
activityChart.options.scales.yAxes[0].scaleLabel.fontColor =
|
||||
themeColors.sub;
|
||||
activityChart.data.datasets[0].borderColor = themeColors.main;
|
||||
activityChart.data.datasets[0].backgroundColor = themeColors.main;
|
||||
ThemeColors.sub;
|
||||
activityChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
activityChart.data.datasets[0].backgroundColor = ThemeColors.main;
|
||||
|
||||
activityChart.data.datasets[0].trendlineLinear.style = themeColors.sub;
|
||||
activityChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
|
||||
|
||||
activityChart.options.scales.yAxes[1].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
activityChart.options.scales.yAxes[1].scaleLabel.fontColor =
|
||||
themeColors.sub;
|
||||
activityChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
activityChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
|
||||
activityChart.options.legend.labels.fontColor = themeColors.sub;
|
||||
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
|
||||
|
||||
resultHistoryChart.options.scales.xAxes[0].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[0].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[0].scaleLabel.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[1].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[1].scaleLabel.fontColor =
|
||||
themeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].borderColor = themeColors.main;
|
||||
resultHistoryChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
resultHistoryChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
|
||||
resultHistoryChart.options.legend.labels.fontColor = themeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].trendlineLinear.style = themeColors.sub;
|
||||
resultHistoryChart.options.legend.labels.fontColor = ThemeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
|
||||
|
||||
resultHistoryChart.data.datasets[0].data = chartData;
|
||||
resultHistoryChart.data.datasets[1].data = accChartData;
|
||||
|
|
|
@ -1,83 +1,4 @@
|
|||
function canBailOut() {
|
||||
return (
|
||||
(config.mode === "custom" &&
|
||||
CustomText.isWordRandom &&
|
||||
CustomText.word >= 5000) ||
|
||||
(config.mode === "custom" &&
|
||||
!CustomText.isWordRandom &&
|
||||
!CustomText.isTimeRandom &&
|
||||
CustomText.text.length >= 5000) ||
|
||||
(config.mode === "custom" &&
|
||||
CustomText.isTimeRandom &&
|
||||
CustomText.time >= 3600) ||
|
||||
(config.mode === "words" && config.words >= 5000) ||
|
||||
config.words === 0 ||
|
||||
(config.mode === "time" && (config.time >= 3600 || config.time === 0)) ||
|
||||
config.mode == "zen"
|
||||
);
|
||||
}
|
||||
|
||||
function addChildCommands(
|
||||
unifiedCommands,
|
||||
commandItem,
|
||||
parentCommandDisplay = ""
|
||||
) {
|
||||
let commandItemDisplay = commandItem.display.replace(/\s?\.\.\.$/g, "");
|
||||
if (parentCommandDisplay)
|
||||
commandItemDisplay = parentCommandDisplay + " > " + commandItemDisplay;
|
||||
if (commandItem.subgroup) {
|
||||
try {
|
||||
commandItem.exec();
|
||||
const currentCommandsIndex = currentCommands.length - 1;
|
||||
currentCommands[currentCommandsIndex].list.forEach((cmd) => {
|
||||
if (cmd.alias === undefined) cmd.alias = commandItem.alias;
|
||||
addChildCommands(unifiedCommands, cmd, commandItemDisplay);
|
||||
});
|
||||
currentCommands.pop();
|
||||
} catch (e) {}
|
||||
} else {
|
||||
let tempCommandItem = { ...commandItem };
|
||||
if (parentCommandDisplay) tempCommandItem.display = commandItemDisplay;
|
||||
unifiedCommands.push(tempCommandItem);
|
||||
}
|
||||
}
|
||||
|
||||
function generateSingleListOfCommands() {
|
||||
const allCommands = [];
|
||||
const oldShowCommandLine = showCommandLine;
|
||||
showCommandLine = () => {};
|
||||
commands.list.forEach((c) => addChildCommands(allCommands, c));
|
||||
showCommandLine = oldShowCommandLine;
|
||||
return {
|
||||
title: "All Commands",
|
||||
list: allCommands,
|
||||
};
|
||||
}
|
||||
|
||||
function isSingleListCommandLineActive() {
|
||||
return $("#commandLine").hasClass("allCommands");
|
||||
}
|
||||
|
||||
function useSingleListCommandLine(show = true) {
|
||||
let allCommands = generateSingleListOfCommands();
|
||||
if (config.singleListCommandLine == "manual")
|
||||
currentCommands.push(allCommands);
|
||||
else if (config.singleListCommandLine == "on")
|
||||
currentCommands = [allCommands];
|
||||
|
||||
if (config.singleListCommandLine != "off")
|
||||
$("#commandLine").addClass("allCommands");
|
||||
if (show) showCommandLine();
|
||||
}
|
||||
|
||||
function restoreOldCommandLine(show = true) {
|
||||
if (isSingleListCommandLineActive()) {
|
||||
$("#commandLine").removeClass("allCommands");
|
||||
currentCommands = currentCommands.filter((l) => l.title != "All Commands");
|
||||
if (currentCommands.length < 1) currentCommands = [commands];
|
||||
}
|
||||
if (show) showCommandLine();
|
||||
}
|
||||
let currentCommands = [commands];
|
||||
|
||||
let commands = {
|
||||
title: "",
|
||||
|
@ -682,7 +603,7 @@ let commands = {
|
|||
initPractiseMissedWords();
|
||||
},
|
||||
available: () => {
|
||||
return resultVisible && Object.keys(missedWords).length > 0;
|
||||
return resultVisible && Object.keys(TestStats.missedWords).length > 0;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -712,7 +633,7 @@ let commands = {
|
|||
showCustomTextPopup();
|
||||
setTimeout(() => {
|
||||
// Workaround to focus textarea since hideCommandLine() will focus test words
|
||||
$("#CustomTextPopup textarea").focus();
|
||||
$("#customTextPopup textarea").focus();
|
||||
}, 150);
|
||||
},
|
||||
},
|
||||
|
@ -1717,6 +1638,87 @@ let commandsFonts = {
|
|||
list: [],
|
||||
};
|
||||
|
||||
function canBailOut() {
|
||||
return (
|
||||
(config.mode === "custom" &&
|
||||
CustomText.isWordRandom &&
|
||||
CustomText.word >= 5000) ||
|
||||
(config.mode === "custom" &&
|
||||
!CustomText.isWordRandom &&
|
||||
!CustomText.isTimeRandom &&
|
||||
CustomText.text.length >= 5000) ||
|
||||
(config.mode === "custom" &&
|
||||
CustomText.isTimeRandom &&
|
||||
CustomText.time >= 3600) ||
|
||||
(config.mode === "words" && config.words >= 5000) ||
|
||||
config.words === 0 ||
|
||||
(config.mode === "time" && (config.time >= 3600 || config.time === 0)) ||
|
||||
config.mode == "zen"
|
||||
);
|
||||
}
|
||||
|
||||
function addChildCommands(
|
||||
unifiedCommands,
|
||||
commandItem,
|
||||
parentCommandDisplay = ""
|
||||
) {
|
||||
let commandItemDisplay = commandItem.display.replace(/\s?\.\.\.$/g, "");
|
||||
if (parentCommandDisplay)
|
||||
commandItemDisplay = parentCommandDisplay + " > " + commandItemDisplay;
|
||||
if (commandItem.subgroup) {
|
||||
try {
|
||||
commandItem.exec();
|
||||
const currentCommandsIndex = currentCommands.length - 1;
|
||||
currentCommands[currentCommandsIndex].list.forEach((cmd) => {
|
||||
if (cmd.alias === undefined) cmd.alias = commandItem.alias;
|
||||
addChildCommands(unifiedCommands, cmd, commandItemDisplay);
|
||||
});
|
||||
currentCommands.pop();
|
||||
} catch (e) {}
|
||||
} else {
|
||||
let tempCommandItem = { ...commandItem };
|
||||
if (parentCommandDisplay) tempCommandItem.display = commandItemDisplay;
|
||||
unifiedCommands.push(tempCommandItem);
|
||||
}
|
||||
}
|
||||
|
||||
function generateSingleListOfCommands() {
|
||||
const allCommands = [];
|
||||
const oldShowCommandLine = showCommandLine;
|
||||
showCommandLine = () => {};
|
||||
commands.list.forEach((c) => addChildCommands(allCommands, c));
|
||||
showCommandLine = oldShowCommandLine;
|
||||
return {
|
||||
title: "All Commands",
|
||||
list: allCommands,
|
||||
};
|
||||
}
|
||||
|
||||
function isSingleListCommandLineActive() {
|
||||
return $("#commandLine").hasClass("allCommands");
|
||||
}
|
||||
|
||||
function useSingleListCommandLine(show = true) {
|
||||
let allCommands = generateSingleListOfCommands();
|
||||
if (config.singleListCommandLine == "manual")
|
||||
currentCommands.push(allCommands);
|
||||
else if (config.singleListCommandLine == "on")
|
||||
currentCommands = [allCommands];
|
||||
|
||||
if (config.singleListCommandLine != "off")
|
||||
$("#commandLine").addClass("allCommands");
|
||||
if (show) showCommandLine();
|
||||
}
|
||||
|
||||
function restoreOldCommandLine(show = true) {
|
||||
if (isSingleListCommandLineActive()) {
|
||||
$("#commandLine").removeClass("allCommands");
|
||||
currentCommands = currentCommands.filter((l) => l.title != "All Commands");
|
||||
if (currentCommands.length < 1) currentCommands = [commands];
|
||||
}
|
||||
if (show) showCommandLine();
|
||||
}
|
||||
|
||||
Misc.getFontsList().then((fonts) => {
|
||||
fonts.forEach((font) => {
|
||||
commandsFonts.list.push({
|
||||
|
@ -2106,8 +2108,6 @@ $(document).keydown((e) => {
|
|||
}
|
||||
});
|
||||
|
||||
let currentCommands = [commands];
|
||||
|
||||
function triggerCommand(command) {
|
||||
let subgroup = false;
|
||||
let input = false;
|
||||
|
|
|
@ -5,3 +5,75 @@ export function showBackgroundLoader() {
|
|||
export function hideBackgroundLoader() {
|
||||
$("#backgroundLoader").stop(true, true).fadeOut(125);
|
||||
}
|
||||
|
||||
export function accountIconLoading(truefalse) {
|
||||
if (truefalse) {
|
||||
$("#top #menu .account .icon").html(
|
||||
'<i class="fas fa-fw fa-spin fa-circle-notch"></i>'
|
||||
);
|
||||
$("#top #menu .account").css("opacity", 1).css("pointer-events", "none");
|
||||
} else {
|
||||
$("#top #menu .account .icon").html('<i class="fas fa-fw fa-user"></i>');
|
||||
$("#top #menu .account").css("opacity", 1).css("pointer-events", "auto");
|
||||
}
|
||||
}
|
||||
|
||||
export function swapElements(
|
||||
el1,
|
||||
el2,
|
||||
totalDuration,
|
||||
callback = function () {
|
||||
return;
|
||||
}
|
||||
) {
|
||||
if (
|
||||
(el1.hasClass("hidden") && !el2.hasClass("hidden")) ||
|
||||
(!el1.hasClass("hidden") && el2.hasClass("hidden"))
|
||||
) {
|
||||
//one of them is hidden and the other is visible
|
||||
if (el1.hasClass("hidden")) {
|
||||
callback();
|
||||
return false;
|
||||
}
|
||||
$(el1)
|
||||
.removeClass("hidden")
|
||||
.css("opacity", 1)
|
||||
.animate(
|
||||
{
|
||||
opacity: 0,
|
||||
},
|
||||
totalDuration / 2,
|
||||
() => {
|
||||
$(el1).addClass("hidden");
|
||||
$(el2)
|
||||
.removeClass("hidden")
|
||||
.css("opacity", 0)
|
||||
.animate(
|
||||
{
|
||||
opacity: 1,
|
||||
},
|
||||
totalDuration / 2,
|
||||
() => {
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else if (el1.hasClass("hidden") && el2.hasClass("hidden")) {
|
||||
//both are hidden, only fade in the second
|
||||
$(el2)
|
||||
.removeClass("hidden")
|
||||
.css("opacity", 0)
|
||||
.animate(
|
||||
{
|
||||
opacity: 1,
|
||||
},
|
||||
totalDuration,
|
||||
() => {
|
||||
callback();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,12 @@ import {
|
|||
db_saveLocalTagPB,
|
||||
} from "./db";
|
||||
|
||||
import { showBackgroundLoader, hideBackgroundLoader } from "./dom-util";
|
||||
import {
|
||||
showBackgroundLoader,
|
||||
hideBackgroundLoader,
|
||||
swapElements,
|
||||
accountIconLoading,
|
||||
} from "./dom-util";
|
||||
import * as Misc from "./misc";
|
||||
import * as CloudFunctions from "./cloud-functions";
|
||||
import layouts from "./layouts";
|
||||
|
@ -31,3 +36,6 @@ import * as Leaderboards from "./leaderboards";
|
|||
import * as Sound from "./sound";
|
||||
import * as CustomText from "./custom-text";
|
||||
import * as ShiftTracker from "./shift-tracker";
|
||||
import * as TestStats from "./test-stats";
|
||||
import * as ThemeColors from "./theme-colors";
|
||||
import * as OutOfFocus from "./out-of-focus";
|
||||
|
|
|
@ -276,5 +276,5 @@ $("#leaderboardsWrapper").click((e) => {
|
|||
|
||||
$("#leaderboardsWrapper .buttons .button").click((e) => {
|
||||
currentLeaderboard = $(e.target).attr("board");
|
||||
show();
|
||||
update();
|
||||
});
|
||||
|
|
|
@ -690,3 +690,10 @@ export function canQuickRestart(mode, words, time, CustomText) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function clearTimeouts(timeouts) {
|
||||
timeouts.forEach((to) => {
|
||||
clearTimeout(to);
|
||||
to = null;
|
||||
});
|
||||
}
|
||||
|
|
668
src/js/script.js
668
src/js/script.js
File diff suppressed because it is too large
Load diff
|
@ -1013,27 +1013,29 @@ $(".pageSettings #loadCustomColorsFromPreset").click((e) => {
|
|||
});
|
||||
|
||||
setTimeout(() => {
|
||||
refreshThemeColorObject();
|
||||
ThemeColors.update();
|
||||
updateChartColors();
|
||||
|
||||
colorVars.forEach((colorName) => {
|
||||
let color;
|
||||
if (colorName === "--bg-color") {
|
||||
color = themeColors.bg;
|
||||
color = ThemeColors.bg;
|
||||
} else if (colorName === "--main-color") {
|
||||
color = themeColors.main;
|
||||
color = ThemeColors.main;
|
||||
} else if (colorName === "--sub-color") {
|
||||
color = themeColors.sub;
|
||||
color = ThemeColors.sub;
|
||||
} else if (colorName === "--caret-color") {
|
||||
color = themeColors.caret;
|
||||
color = ThemeColors.caret;
|
||||
} else if (colorName === "--text-color") {
|
||||
color = themeColors.text;
|
||||
color = ThemeColors.text;
|
||||
} else if (colorName === "--error-color") {
|
||||
color = themeColors.error;
|
||||
color = ThemeColors.error;
|
||||
} else if (colorName === "--error-extra-color") {
|
||||
color = themeColors.errorExtra;
|
||||
color = ThemeColors.errorExtra;
|
||||
} else if (colorName === "--colorful-error-color") {
|
||||
color = themeColors.colorfulError;
|
||||
color = ThemeColors.colorfulError;
|
||||
} else if (colorName === "--colorful-error-extra-color") {
|
||||
color = themeColors.colorfulErrorExtra;
|
||||
color = ThemeColors.colorfulErrorExtra;
|
||||
}
|
||||
$(".colorPicker #" + colorName).attr("value", color);
|
||||
$(".colorPicker #" + colorName).val(color);
|
||||
|
|
18
src/js/test/out-of-focus.js
Normal file
18
src/js/test/out-of-focus.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import * as Misc from "./misc";
|
||||
|
||||
let outOfFocusTimeouts = [];
|
||||
|
||||
export function hide() {
|
||||
$("#words").css("transition", "none").removeClass("blurred");
|
||||
$(".outOfFocusWarning").addClass("hidden");
|
||||
Misc.clearTimeouts(outOfFocusTimeouts);
|
||||
}
|
||||
|
||||
export function show() {
|
||||
outOfFocusTimeouts.push(
|
||||
setTimeout(() => {
|
||||
$("#words").css("transition", "0.25s").addClass("blurred");
|
||||
$(".outOfFocusWarning").removeClass("hidden");
|
||||
}, 1000)
|
||||
);
|
||||
}
|
202
src/js/test/test-stats.js
Normal file
202
src/js/test/test-stats.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
export let invalid = false;
|
||||
export let start, end;
|
||||
export let wpmHistory = [];
|
||||
export let rawHistory = [];
|
||||
|
||||
export let keypressPerSecond = [];
|
||||
export let currentKeypress = {
|
||||
count: 0,
|
||||
mod: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
};
|
||||
|
||||
// export let errorsPerSecond = [];
|
||||
// export let currentError = {
|
||||
// count: 0,
|
||||
// words: [],
|
||||
// };
|
||||
export let lastSecondNotRound = false;
|
||||
export let missedWords = {};
|
||||
export let accuracy = {
|
||||
correct: 0,
|
||||
incorrect: 0,
|
||||
};
|
||||
export let keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
|
||||
export function restart() {
|
||||
start = 0;
|
||||
end = 0;
|
||||
invalid = false;
|
||||
wpmHistory = [];
|
||||
rawHistory = [];
|
||||
keypressPerSecond = [];
|
||||
currentKeypress = {
|
||||
count: 0,
|
||||
mod: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
};
|
||||
// errorsPerSecond = [];
|
||||
// currentError = {
|
||||
// count: 0,
|
||||
// words: [],
|
||||
// };
|
||||
lastSecondNotRound = false;
|
||||
missedWords = {};
|
||||
accuracy = {
|
||||
correct: 0,
|
||||
incorrect: 0,
|
||||
};
|
||||
keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export let restartCount = 0;
|
||||
export let incompleteSeconds = 0;
|
||||
|
||||
export function incrementRestartCount() {
|
||||
restartCount++;
|
||||
}
|
||||
|
||||
export function incrementIncompleteSeconds(val) {
|
||||
incompleteSeconds += val;
|
||||
}
|
||||
|
||||
export function resetIncomplete() {
|
||||
restartCount = 0;
|
||||
incompleteSeconds = 0;
|
||||
}
|
||||
|
||||
export function setInvalid() {
|
||||
invalid = true;
|
||||
}
|
||||
|
||||
export function calculateTestSeconds(now) {
|
||||
if (now === undefined) {
|
||||
return (end - start) / 1000;
|
||||
} else {
|
||||
return (now - start) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
export function setEnd(e) {
|
||||
end = e;
|
||||
}
|
||||
|
||||
export function setStart(s) {
|
||||
start = s;
|
||||
}
|
||||
|
||||
export function pushToWpmHistory(word) {
|
||||
wpmHistory.push(word);
|
||||
}
|
||||
|
||||
export function pushToRawHistory(word) {
|
||||
rawHistory.push(word);
|
||||
}
|
||||
|
||||
export function incrementKeypressCount() {
|
||||
currentKeypress.count++;
|
||||
}
|
||||
|
||||
export function incrementKeypressMod() {
|
||||
currentKeypress.mod++;
|
||||
}
|
||||
|
||||
export function incrementKeypressErrors() {
|
||||
currentKeypress.errors++;
|
||||
}
|
||||
|
||||
export function pushKeypressWord(word) {
|
||||
currentKeypress.words.push(word);
|
||||
}
|
||||
|
||||
export function pushKeypressesToHistory() {
|
||||
keypressPerSecond.push(currentKeypress);
|
||||
currentKeypress = {
|
||||
count: 0,
|
||||
mod: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
};
|
||||
}
|
||||
|
||||
export function calculateAfkSeconds() {
|
||||
return keypressPerSecond.filter((x) => x.count == 0 && x.mod == 0).length;
|
||||
}
|
||||
|
||||
export function setLastSecondNotRound() {
|
||||
lastSecondNotRound = true;
|
||||
}
|
||||
|
||||
export function calculateAccuracy() {
|
||||
return (accuracy.correct / (accuracy.correct + accuracy.incorrect)) * 100;
|
||||
}
|
||||
|
||||
export function incrementAccuracy(correctincorrect) {
|
||||
if (correctincorrect) {
|
||||
accuracy.correct++;
|
||||
} else {
|
||||
accuracy.incorrect++;
|
||||
}
|
||||
}
|
||||
|
||||
export function setKeypressTimingsTooLong() {
|
||||
keypressTimings.spacing.array = "toolong";
|
||||
keypressTimings.duration.array = "toolong";
|
||||
}
|
||||
|
||||
export function pushKeypressDuration(val) {
|
||||
keypressTimings.duration.array.push(val);
|
||||
}
|
||||
|
||||
export function setKeypressDuration(val) {
|
||||
keypressTimings.duration.current = val;
|
||||
}
|
||||
|
||||
export function pushKeypressSpacing(val) {
|
||||
keypressTimings.spacing.array.push(val);
|
||||
}
|
||||
|
||||
export function setKeypressSpacing(val) {
|
||||
keypressTimings.spacing.current = val;
|
||||
}
|
||||
|
||||
export function resetKeypressTimings() {
|
||||
keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function pushMissedWord(word) {
|
||||
if (!Object.keys(missedWords).includes(word)) {
|
||||
missedWords[word] = 1;
|
||||
} else {
|
||||
missedWords[word]++;
|
||||
}
|
||||
}
|
27
src/js/theme-colors.js
Normal file
27
src/js/theme-colors.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
export let bg = "#323437";
|
||||
export let main = "#e2b714";
|
||||
export let caret = "#e2b714";
|
||||
export let sub = "#646669";
|
||||
export let text = "#d1d0c5";
|
||||
export let error = "#ca4754";
|
||||
export let errorExtra = "#7e2a33";
|
||||
export let colorfulError = "#ca4754";
|
||||
export let colorfulErrorExtra = "#7e2a33";
|
||||
|
||||
export function update() {
|
||||
let st = getComputedStyle(document.body);
|
||||
|
||||
bg = st.getPropertyValue("--bg-color").replace(" ", "");
|
||||
main = st.getPropertyValue("--main-color").replace(" ", "");
|
||||
caret = st.getPropertyValue("--caret-color").replace(" ", "");
|
||||
sub = st.getPropertyValue("--sub-color").replace(" ", "");
|
||||
text = st.getPropertyValue("--text-color").replace(" ", "");
|
||||
error = st.getPropertyValue("--error-color").replace(" ", "");
|
||||
errorExtra = st.getPropertyValue("--error-extra-color").replace(" ", "");
|
||||
colorfulError = st
|
||||
.getPropertyValue("--colorful-error-color")
|
||||
.replace(" ", "");
|
||||
colorfulErrorExtra = st
|
||||
.getPropertyValue("--colorful-error-extra-color")
|
||||
.replace(" ", "");
|
||||
}
|
|
@ -102,7 +102,7 @@ async function saveConfigToCookie(noDbCheck = false) {
|
|||
let save = config;
|
||||
delete save.resultFilters;
|
||||
Misc.setCookie("config", JSON.stringify(save), 365);
|
||||
restartCount = 0;
|
||||
// restartCount = 0;
|
||||
if (!noDbCheck) await saveConfigToDB();
|
||||
}
|
||||
|
||||
|
@ -358,9 +358,7 @@ function setAlwaysShowCPM(val, nosave) {
|
|||
function toggleShowOutOfFocusWarning() {
|
||||
config.showOutOfFocusWarning = !config.showOutOfFocusWarning;
|
||||
if (!config.showOutOfFocusWarning) {
|
||||
$("#words").css("transition", "none").removeClass("blurred");
|
||||
$(".outOfFocusWarning").addClass("hidden");
|
||||
clearTimeouts(outOfFocusTimeouts);
|
||||
OutOfFocus.hide();
|
||||
}
|
||||
saveConfigToCookie();
|
||||
}
|
||||
|
@ -371,9 +369,7 @@ function setShowOutOfFocusWarning(val, nosave) {
|
|||
}
|
||||
config.showOutOfFocusWarning = val;
|
||||
if (!config.showOutOfFocusWarning) {
|
||||
$("#words").css("transition", "none").removeClass("blurred");
|
||||
$(".outOfFocusWarning").addClass("hidden");
|
||||
clearTimeouts(outOfFocusTimeouts);
|
||||
OutOfFocus.hide();
|
||||
}
|
||||
if (!nosave) saveConfigToCookie();
|
||||
}
|
||||
|
@ -1065,58 +1061,58 @@ function setIndicateTypos(it, nosave) {
|
|||
}
|
||||
|
||||
function updateChartColors() {
|
||||
hoverChart.options.scales.xAxes[0].ticks.minor.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.xAxes[0].scaleLabel.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].ticks.minor.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].ticks.minor.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].scaleLabel.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].scaleLabel.fontColor = themeColors.sub;
|
||||
hoverChart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.xAxes[0].scaleLabel.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
|
||||
hoverChart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub;
|
||||
|
||||
hoverChart.data.datasets[0].borderColor = themeColors.main;
|
||||
hoverChart.data.datasets[0].pointBackgroundColor = themeColors.main;
|
||||
hoverChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
hoverChart.data.datasets[1].pointBackgroundColor = themeColors.sub;
|
||||
hoverChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
hoverChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
|
||||
hoverChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
hoverChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
|
||||
|
||||
hoverChart.options.annotation.annotations[0].borderColor = themeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].borderColor = ThemeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].label.backgroundColor =
|
||||
themeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].label.fontColor = themeColors.bg;
|
||||
ThemeColors.sub;
|
||||
hoverChart.options.annotation.annotations[0].label.fontColor = ThemeColors.bg;
|
||||
|
||||
activityChart.options.legend.labels.fontColor = themeColors.sub;
|
||||
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
|
||||
|
||||
activityChart.options.scales.xAxes[0].ticks.minor.fontColor = themeColors.sub;
|
||||
activityChart.options.scales.yAxes[0].ticks.minor.fontColor = themeColors.sub;
|
||||
activityChart.options.scales.yAxes[0].scaleLabel.fontColor = themeColors.sub;
|
||||
activityChart.data.datasets[0].borderColor = themeColors.main;
|
||||
activityChart.data.datasets[0].backgroundColor = themeColors.main;
|
||||
activityChart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
|
||||
activityChart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
|
||||
activityChart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
|
||||
activityChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
activityChart.data.datasets[0].backgroundColor = ThemeColors.main;
|
||||
|
||||
activityChart.data.datasets[0].trendlineLinear.style = themeColors.sub;
|
||||
activityChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
|
||||
|
||||
activityChart.options.scales.yAxes[1].ticks.minor.fontColor = themeColors.sub;
|
||||
activityChart.options.scales.yAxes[1].scaleLabel.fontColor = themeColors.sub;
|
||||
activityChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
activityChart.options.scales.yAxes[1].ticks.minor.fontColor = ThemeColors.sub;
|
||||
activityChart.options.scales.yAxes[1].scaleLabel.fontColor = ThemeColors.sub;
|
||||
activityChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
|
||||
activityChart.options.legend.labels.fontColor = themeColors.sub;
|
||||
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
|
||||
|
||||
resultHistoryChart.options.scales.xAxes[0].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[0].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[0].scaleLabel.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[1].ticks.minor.fontColor =
|
||||
themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.options.scales.yAxes[1].scaleLabel.fontColor =
|
||||
themeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].borderColor = themeColors.main;
|
||||
resultHistoryChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
ThemeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
resultHistoryChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
|
||||
resultHistoryChart.options.legend.labels.fontColor = themeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].trendlineLinear.style = themeColors.sub;
|
||||
wpmOverTimeChart.data.datasets[0].borderColor = themeColors.main;
|
||||
wpmOverTimeChart.data.datasets[0].pointBackgroundColor = themeColors.main;
|
||||
wpmOverTimeChart.data.datasets[1].borderColor = themeColors.sub;
|
||||
wpmOverTimeChart.data.datasets[1].pointBackgroundColor = themeColors.sub;
|
||||
resultHistoryChart.options.legend.labels.fontColor = ThemeColors.sub;
|
||||
resultHistoryChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
|
||||
wpmOverTimeChart.data.datasets[0].borderColor = ThemeColors.main;
|
||||
wpmOverTimeChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
|
||||
wpmOverTimeChart.data.datasets[1].borderColor = ThemeColors.sub;
|
||||
wpmOverTimeChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
|
||||
|
||||
hoverChart.update();
|
||||
wpmOverTimeChart.update();
|
||||
|
@ -1124,6 +1120,7 @@ function updateChartColors() {
|
|||
activityChart.update();
|
||||
}
|
||||
|
||||
let isPreviewingTheme = false;
|
||||
function previewTheme(name, setIsPreviewingVar = true) {
|
||||
if (
|
||||
(testActive || resultVisible) &&
|
||||
|
@ -1136,7 +1133,8 @@ function previewTheme(name, setIsPreviewingVar = true) {
|
|||
clearCustomTheme();
|
||||
$("#currentTheme").attr("href", `themes/${name}.css`);
|
||||
setTimeout(() => {
|
||||
refreshThemeColorObject();
|
||||
ThemeColors.update();
|
||||
updateChartColors();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
|
@ -1168,8 +1166,10 @@ function setTheme(name, nosave) {
|
|||
// applyCustomThemeColors();
|
||||
setTimeout(() => {
|
||||
$(".keymap-key").attr("style", "");
|
||||
refreshThemeColorObject();
|
||||
$("#metaThemeColor").attr("content", themeColors.main);
|
||||
ThemeColors.update();
|
||||
updateChartColors();
|
||||
|
||||
$("#metaThemeColor").attr("content", ThemeColors.main);
|
||||
}, 500);
|
||||
if (!nosave) saveConfigToCookie();
|
||||
}
|
||||
|
@ -1232,7 +1232,8 @@ function applyCustomThemeColors() {
|
|||
clearCustomTheme();
|
||||
}
|
||||
setTimeout(() => {
|
||||
refreshThemeColorObject();
|
||||
ThemeColors.update();
|
||||
updateChartColors();
|
||||
updateFavicon(32, 14);
|
||||
$(".keymap-key").attr("style", "");
|
||||
}, 500);
|
||||
|
|
|
@ -389,7 +389,7 @@ a:hover {
|
|||
}
|
||||
}
|
||||
|
||||
#CustomTextPopupWrapper {
|
||||
#customTextPopupWrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
|
@ -402,7 +402,7 @@ a:hover {
|
|||
align-items: center;
|
||||
padding: 5rem 0;
|
||||
|
||||
#CustomTextPopup {
|
||||
#customTextPopup {
|
||||
background: var(--bg-color);
|
||||
border-radius: var(--roundness);
|
||||
padding: 2rem;
|
||||
|
@ -455,7 +455,7 @@ a:hover {
|
|||
height: 0;
|
||||
display: none;
|
||||
|
||||
& ~ .CustomTextRandomCheckbox {
|
||||
& ~ .customTextRandomCheckbox {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
|
@ -466,7 +466,7 @@ a:hover {
|
|||
transition: 0.25s;
|
||||
}
|
||||
|
||||
&:checked ~ .CustomTextRandomCheckbox {
|
||||
&:checked ~ .customTextRandomCheckbox {
|
||||
background: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ a:hover {
|
|||
height: 0;
|
||||
display: none;
|
||||
|
||||
& ~ .CustomTextTypographyCheckbox {
|
||||
& ~ .customTextTypographyCheckbox {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
|
@ -500,7 +500,7 @@ a:hover {
|
|||
transition: 0.25s;
|
||||
}
|
||||
|
||||
&:checked ~ .CustomTextTypographyCheckbox {
|
||||
&:checked ~ .customTextTypographyCheckbox {
|
||||
background: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,13 +101,13 @@
|
|||
<div class="button">ok</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="CustomTextPopupWrapper" class="hidden">
|
||||
<div id="CustomTextPopup" action="">
|
||||
<div id="customTextPopupWrapper" class="hidden">
|
||||
<div id="customTextPopup" action="">
|
||||
<textarea class="textarea" placeholder="Custom text"></textarea>
|
||||
<div class="inputs">
|
||||
<label class="check">
|
||||
<input type="checkbox" />
|
||||
<div class="CustomTextRandomCheckbox"></div>
|
||||
<div class="customTextRandomCheckbox"></div>
|
||||
Random
|
||||
<span>
|
||||
Randomise the above words, and control how many words are
|
||||
|
@ -127,7 +127,7 @@
|
|||
</div>
|
||||
<label class="typographyCheck">
|
||||
<input type="checkbox" checked />
|
||||
<div class="CustomTextTypographyCheckbox"></div>
|
||||
<div class="customTextTypographyCheckbox"></div>
|
||||
Remove Fancy Typography
|
||||
<span>
|
||||
Standardises typography symbols (for example “ and ” become ")
|
||||
|
@ -994,7 +994,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group CustomText hidden">
|
||||
<div class="group customText hidden">
|
||||
<!-- <div class="title">time</div> -->
|
||||
<div class="buttons">
|
||||
<div class="text-button">change</div>
|
||||
|
@ -1972,11 +1972,12 @@
|
|||
<div class="text">
|
||||
This mode will force you to use opposite
|
||||
<key>shift</key>
|
||||
keys for shifting. Using an incorrect one will count as
|
||||
an error. This feature ignores keys in locations
|
||||
<key>B</key>,
|
||||
<key>Y</key>,
|
||||
and
|
||||
keys for shifting. Using an incorrect one will count as an
|
||||
error. This feature ignores keys in locations
|
||||
<key>B</key>
|
||||
,
|
||||
<key>Y</key>
|
||||
, and
|
||||
<key>^</key>
|
||||
because many people use the other hand for those keys.
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue