mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-03-12 23:20:25 +08:00
lost stash
This commit is contained in:
parent
97f328f88c
commit
eccbcfb615
6 changed files with 244 additions and 117 deletions
38
backend/api/controllers/leaderboards.js
Normal file
38
backend/api/controllers/leaderboards.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
const LeaderboardsDAO = require("../../dao/leaderboards");
|
||||
|
||||
class LeaderboardsController {
|
||||
static async get(req, res, next) {
|
||||
try {
|
||||
const { language, mode, mode2 } = req.query;
|
||||
if (!language || !mode || !mode2) {
|
||||
return res.status(400).json({
|
||||
message: "Missing parameters",
|
||||
});
|
||||
}
|
||||
let retval = await LeaderboardsDAO.get(mode, mode2, language);
|
||||
retval.forEach((item) => {
|
||||
delete item.uid;
|
||||
});
|
||||
return res.status(200).json(retval);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async update(req, res, next) {
|
||||
try {
|
||||
const { language, mode, mode2 } = req.body;
|
||||
if (!language || !mode || !mode2) {
|
||||
return res.status(400).json({
|
||||
message: "Missing parameters",
|
||||
});
|
||||
}
|
||||
let retval = await LeaderboardsDAO.update(mode, mode2, language);
|
||||
return res.status(200).json(retval);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LeaderboardsController;
|
22
backend/api/routes/leaderboards.js
Normal file
22
backend/api/routes/leaderboards.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
const { authenticateRequest } = require("../../middlewares/auth");
|
||||
const LeaderboardsController = require("../controllers/leaderboards");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
|
||||
const { Router } = require("express");
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
RateLimit.limit1persec,
|
||||
authenticateRequest,
|
||||
LeaderboardsController.get
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/debug_update",
|
||||
RateLimit.limit1persec,
|
||||
LeaderboardsController.update
|
||||
);
|
||||
|
||||
module.exports = router;
|
126
backend/dao/leaderboards.js
Normal file
126
backend/dao/leaderboards.js
Normal file
|
@ -0,0 +1,126 @@
|
|||
const MonkeyError = require("../handlers/error");
|
||||
const { mongoDB } = require("../init/mongodb");
|
||||
const { ObjectID } = require("mongodb");
|
||||
|
||||
class LeaderboardsDAO {
|
||||
static async get(mode, mode2, language) {
|
||||
const preset = await mongoDB()
|
||||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.find()
|
||||
.toArray();
|
||||
return preset;
|
||||
}
|
||||
|
||||
static async getRank(mode, mode2, language, uid) {
|
||||
const res = await mongoDB()
|
||||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.findOne({ uid });
|
||||
return res.rank;
|
||||
}
|
||||
|
||||
static async update(mode, mode2, language, uid = undefined) {
|
||||
let str = `personalBests.${mode}.${mode2}`;
|
||||
let lb = await mongoDB()
|
||||
.collection("users")
|
||||
.aggregate([
|
||||
{
|
||||
$unset: [
|
||||
"_id",
|
||||
"addedAt",
|
||||
"email",
|
||||
"oldTypingStats",
|
||||
"tags",
|
||||
"bananas",
|
||||
"discordId",
|
||||
"timeTyping",
|
||||
"startedTests",
|
||||
"completedTests",
|
||||
],
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
banned: {
|
||||
$exists: false,
|
||||
},
|
||||
[str]: {
|
||||
$elemMatch: {
|
||||
language: "english",
|
||||
difficulty: "normal",
|
||||
timestamp: {
|
||||
$exists: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$replaceWith: {
|
||||
name: "$name",
|
||||
uid: "$uid",
|
||||
result: "$" + str,
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: "$result",
|
||||
},
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
"result.language": language,
|
||||
"result.difficulty": "normal",
|
||||
"result.punctuation": false,
|
||||
},
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
"result.name": "$name",
|
||||
"result.uid": "$uid",
|
||||
},
|
||||
},
|
||||
{
|
||||
$replaceRoot: {
|
||||
newRoot: "$result",
|
||||
},
|
||||
},
|
||||
{
|
||||
$sort: {
|
||||
wpm: -1,
|
||||
acc: -1,
|
||||
timestamp: -1,
|
||||
},
|
||||
},
|
||||
])
|
||||
.toArray();
|
||||
|
||||
let rerval = undefined;
|
||||
lb.forEach((lbEntry, index) => {
|
||||
lbEntry.rank = index + 1;
|
||||
if (uid && lbEntry.uid === uid) {
|
||||
rerval = index + 1;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await mongoDB()
|
||||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.drop();
|
||||
} catch (e) {}
|
||||
await mongoDB()
|
||||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.insertMany(lb);
|
||||
|
||||
if (rerval) {
|
||||
return {
|
||||
message: "Successfully updated leaderboard",
|
||||
rank: retval,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
message: "Successfully updated leaderboard",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LeaderboardsDAO;
|
|
@ -30,87 +30,66 @@ function update() {
|
|||
|
||||
Loader.show();
|
||||
Promise.all([
|
||||
axiosInstance.get(
|
||||
`/results/getLeaderboard/daily/${boardinfo[0]}/${boardinfo[1]}`
|
||||
),
|
||||
axiosInstance.get(
|
||||
`/results/getLeaderboard/global/${boardinfo[0]}/${boardinfo[1]}`
|
||||
),
|
||||
axiosInstance.get(`/leaderboards`, {
|
||||
params: {
|
||||
language: "english",
|
||||
mode: "time",
|
||||
mode2: "15",
|
||||
},
|
||||
}),
|
||||
axiosInstance.get(`/leaderboards`, {
|
||||
params: {
|
||||
language: "english",
|
||||
mode: "time",
|
||||
mode2: "60",
|
||||
},
|
||||
}),
|
||||
])
|
||||
.then((lbdata) => {
|
||||
Loader.hide();
|
||||
let dailyData = lbdata[0].data;
|
||||
let globalData = lbdata[1].data;
|
||||
let time15data = lbdata[0].data;
|
||||
let time60data = lbdata[1].data;
|
||||
|
||||
//daily
|
||||
let nextReset = new Date(dailyData.resetTime);
|
||||
let diffAsDate = new Date(nextReset - Date.now());
|
||||
|
||||
let diffHours = diffAsDate.getUTCHours();
|
||||
let diffMinutes = diffAsDate.getUTCMinutes();
|
||||
let diffSeconds = diffAsDate.getUTCSeconds();
|
||||
|
||||
let resetString = "";
|
||||
if (diffHours > 0) {
|
||||
resetString = `resets in ${diffHours} ${
|
||||
diffHours == 1 ? "hour" : "hours"
|
||||
} ${diffMinutes} ${diffMinutes == 1 ? "minute" : "minutes"}
|
||||
`;
|
||||
} else if (diffMinutes > 0) {
|
||||
resetString = `resets in ${diffMinutes} ${
|
||||
diffMinutes == 1 ? "minute" : "minutes"
|
||||
} ${diffSeconds} ${diffSeconds == 1 ? "second" : "seconds"}`;
|
||||
} else if (diffSeconds > 0) {
|
||||
resetString = `resets in ${diffSeconds} ${
|
||||
diffSeconds == 1 ? "second" : "seconds"
|
||||
}`;
|
||||
}
|
||||
|
||||
$("#leaderboardsWrapper .subtitle").text(resetString);
|
||||
|
||||
$("#leaderboardsWrapper table.daily tfoot").html(`
|
||||
$("#leaderboardsWrapper table.left tfoot").html(`
|
||||
<tr>
|
||||
<td><br><br></td>
|
||||
<td colspan="4" style="text-align:center;">Not qualified</>
|
||||
<td><br><br></td>
|
||||
</tr>
|
||||
`);
|
||||
//daily
|
||||
$("#leaderboardsWrapper table.daily tbody").empty();
|
||||
//left
|
||||
$("#leaderboardsWrapper table.left tbody").empty();
|
||||
let dindex = 0;
|
||||
if (dailyData.board !== undefined) {
|
||||
dailyData.board.forEach((entry) => {
|
||||
if (time15data !== undefined) {
|
||||
time15data.forEach((entry) => {
|
||||
if (entry.hidden) return;
|
||||
let meClassString = "";
|
||||
//hacky way to get username because auth().currentUser.name isn't working after mongo switch
|
||||
if (DB.getSnapshot() && entry.name == DB.getSnapshot().name) {
|
||||
if (entry.name == DB.getSnapshot().name) {
|
||||
meClassString = ' class="me"';
|
||||
$("#leaderboardsWrapper table.daily tfoot").html(`
|
||||
<tr>
|
||||
<td>${dindex + 1}</td>
|
||||
<td>You</td>
|
||||
<td class="alignRight">${entry.wpm.toFixed(
|
||||
2
|
||||
)}<br><div class="sub">${entry.acc.toFixed(2)}%</div></td>
|
||||
<td class="alignRight">${entry.raw.toFixed(
|
||||
2
|
||||
)}<br><div class="sub">${
|
||||
$("#leaderboardsWrapper table.left tfoot").html(`
|
||||
<tr>
|
||||
<td>${dindex + 1}</td>
|
||||
<td>You</td>
|
||||
<td class="alignRight">${entry.wpm.toFixed(
|
||||
2
|
||||
)}<br><div class="sub">${entry.acc.toFixed(2)}%</div></td>
|
||||
<td class="alignRight">${entry.raw.toFixed(
|
||||
2
|
||||
)}<br><div class="sub">${
|
||||
entry.consistency === "-"
|
||||
? "-"
|
||||
: entry.consistency.toFixed(2) + "%"
|
||||
}</div></td>
|
||||
<td class="alignRight">${entry.mode}<br><div class="sub">${
|
||||
entry.mode2
|
||||
}</div></td>
|
||||
<td class="alignRight">${moment(entry.timestamp).format(
|
||||
"DD MMM YYYY"
|
||||
)}<br><div class='sub'>${moment(entry.timestamp).format(
|
||||
<td class="alignRight">time<br><div class="sub">15</div></td>
|
||||
<td class="alignRight">${moment(entry.timestamp).format(
|
||||
"DD MMM YYYY"
|
||||
)}<br><div class='sub'>${moment(entry.timestamp).format(
|
||||
"HH:mm"
|
||||
)}</div></td>
|
||||
</tr>
|
||||
</tr>
|
||||
`);
|
||||
}
|
||||
$("#leaderboardsWrapper table.daily tbody").append(`
|
||||
$("#leaderboardsWrapper table.left tbody").append(`
|
||||
<tr>
|
||||
<td>${
|
||||
dindex === 0 ? '<i class="fas fa-fw fa-crown"></i>' : dindex + 1
|
||||
|
@ -122,9 +101,7 @@ function update() {
|
|||
<td class="alignRight">${entry.raw.toFixed(2)}<br><div class="sub">${
|
||||
entry.consistency === "-" ? "-" : entry.consistency.toFixed(2) + "%"
|
||||
}</div></td>
|
||||
<td class="alignRight">${entry.mode}<br><div class="sub">${
|
||||
entry.mode2
|
||||
}</div></td>
|
||||
<td class="alignRight">time<br><div class="sub">15</div></td>
|
||||
<td class="alignRight">${moment(entry.timestamp).format(
|
||||
"DD MMM YYYY"
|
||||
)}<br><div class='sub'>${moment(entry.timestamp).format(
|
||||
|
@ -135,24 +112,8 @@ function update() {
|
|||
dindex++;
|
||||
});
|
||||
}
|
||||
let lenDaily = 0;
|
||||
if (dailyData.board !== undefined) lenDaily = dailyData.board.length;
|
||||
if (dailyData.length === 0 || lenDaily !== dailyData.size) {
|
||||
for (let i = lenDaily; i < dailyData.size; i++) {
|
||||
$("#leaderboardsWrapper table.daily tbody").append(`
|
||||
<tr>
|
||||
<td>${i + 1}</td>
|
||||
<td>-</td>
|
||||
<td class="alignRight">-</td>
|
||||
<td class="alignRight">-</td>
|
||||
<td class="alignRight">-</td>
|
||||
<td class="alignRight">-<br>-</td>
|
||||
</tr>
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
$("#leaderboardsWrapper table.global tfoot").html(`
|
||||
$("#leaderboardsWrapper table.right tfoot").html(`
|
||||
<tr>
|
||||
<td><br><br></td>
|
||||
<td colspan="4" style="text-align:center;">Not qualified</>
|
||||
|
@ -160,15 +121,15 @@ function update() {
|
|||
</tr>
|
||||
`);
|
||||
//global
|
||||
$("#leaderboardsWrapper table.global tbody").empty();
|
||||
$("#leaderboardsWrapper table.right tbody").empty();
|
||||
let index = 0;
|
||||
if (globalData.board !== undefined) {
|
||||
globalData.board.forEach((entry) => {
|
||||
if (time60data !== undefined) {
|
||||
time60data.forEach((entry) => {
|
||||
if (entry.hidden) return;
|
||||
let meClassString = "";
|
||||
if (DB.getSnapshot() && entry.name == DB.getSnapshot().name) {
|
||||
if (entry.name == DB.getSnapshot().name) {
|
||||
meClassString = ' class="me"';
|
||||
$("#leaderboardsWrapper table.global tfoot").html(`
|
||||
$("#leaderboardsWrapper table.right tfoot").html(`
|
||||
<tr>
|
||||
<td>${index + 1}</td>
|
||||
<td>You</td>
|
||||
|
@ -182,9 +143,7 @@ function update() {
|
|||
? "-"
|
||||
: entry.consistency.toFixed(2) + "%"
|
||||
}</div></td>
|
||||
<td class="alignRight">${entry.mode}<br><div class="sub">${
|
||||
entry.mode2
|
||||
}</div></td>
|
||||
<td class="alignRight">time<br><div class="sub">60</div></td>
|
||||
<td class="alignRight">${moment(entry.timestamp).format(
|
||||
"DD MMM YYYY"
|
||||
)}<br><div class='sub'>${moment(entry.timestamp).format(
|
||||
|
@ -193,7 +152,7 @@ function update() {
|
|||
</tr>
|
||||
`);
|
||||
}
|
||||
$("#leaderboardsWrapper table.global tbody").append(`
|
||||
$("#leaderboardsWrapper table.right tbody").append(`
|
||||
<tr>
|
||||
<td>${
|
||||
index === 0 ? '<i class="fas fa-fw fa-crown"></i>' : index + 1
|
||||
|
@ -205,9 +164,7 @@ function update() {
|
|||
<td class="alignRight">${entry.raw.toFixed(2)}<br><div class="sub">${
|
||||
entry.consistency === "-" ? "-" : entry.consistency.toFixed(2) + "%"
|
||||
}</div></td>
|
||||
<td class="alignRight">${entry.mode}<br><div class="sub">${
|
||||
entry.mode2
|
||||
}</div></td>
|
||||
<td class="alignRight">time<br><div class="sub">60</div></td>
|
||||
<td class="alignRight">${moment(entry.timestamp).format(
|
||||
"DD MMM YYYY"
|
||||
)}<br><div class='sub'>${moment(entry.timestamp).format(
|
||||
|
@ -218,22 +175,6 @@ function update() {
|
|||
index++;
|
||||
});
|
||||
}
|
||||
let lenGlobal = 0;
|
||||
if (globalData.board !== undefined) lenGlobal = globalData.board.length;
|
||||
if (globalData.length === 0 || lenGlobal !== globalData.size) {
|
||||
for (let i = lenGlobal; i < globalData.size; i++) {
|
||||
$("#leaderboardsWrapper table.global tbody").append(`
|
||||
<tr>
|
||||
<td>${i + 1}</td>
|
||||
<td>-</td>
|
||||
<td class="alignRight">-</td>
|
||||
<td class="alignRight">-</td>
|
||||
<td class="alignRight">-</td>
|
||||
<td class="alignRight">-<br>-</td>
|
||||
</tr>
|
||||
`);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
Loader.hide();
|
||||
|
|
|
@ -452,16 +452,16 @@ a:hover {
|
|||
}
|
||||
}
|
||||
|
||||
.globalTableWrapper,
|
||||
.dailyTableWrapper {
|
||||
.leftTableWrapper,
|
||||
.rightTableWrapper {
|
||||
height: calc(100vh - 22rem);
|
||||
@extend .ffscroll;
|
||||
overflow-y: scroll;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.globalTableWrapper::-webkit-scrollbar,
|
||||
.dailyTableWrapper::-webkit-scrollbar {
|
||||
.leftTableWrapper::-webkit-scrollbar,
|
||||
.rightTableWrapper::-webkit-scrollbar {
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
}
|
||||
|
|
|
@ -388,9 +388,9 @@
|
|||
</div>
|
||||
<div class="tables">
|
||||
<div class="titleAndTable">
|
||||
<div class="title">Global</div>
|
||||
<div class="globalTableWrapper">
|
||||
<table class="global">
|
||||
<div class="title">English Time 15</div>
|
||||
<div class="leftTableWrapper">
|
||||
<table class="left">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="1%">#</td>
|
||||
|
@ -670,10 +670,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="titleAndTable">
|
||||
<div class="title">Daily</div>
|
||||
<div class="title">English Time 60</div>
|
||||
<div class="subtitle">-</div>
|
||||
<div class="dailyTableWrapper">
|
||||
<table class="daily">
|
||||
<div class="rightTableWrapper">
|
||||
<table class="right">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="1%">#</td>
|
||||
|
|
Loading…
Reference in a new issue