From 55a6c28118b09a961083663c757b877065de747a Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 19:19:20 +0100 Subject: [PATCH 01/58] updated returned data --- public/js/script.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 04983dfa6..a834cd12f 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1077,9 +1077,10 @@ function showResult(difficultyFailed = false) { obj: completedEvent, }).then((e) => { accountIconLoading(false); - if (e.data === -1) { + console.log(e.data); + if (e.data.resultCode === -1) { showNotification("Could not save result", 3000); - } else if (e.data === 1 || e.data === 2) { + } else if (e.data.resultCode === 1 || e.data.resultCode === 2) { dbSnapshot.results.unshift(completedEvent); try { firebase @@ -1088,7 +1089,7 @@ function showResult(difficultyFailed = false) { } catch (e) { console.log("Analytics unavailable"); } - if (e.data === 2) { + if (e.data.resultCode === 2) { //new pb if (!localPb) { showNotification( From 2b3eaf1696512621cf86699ea72b115155637bc0 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 19:29:48 +0100 Subject: [PATCH 02/58] added raw to the leaderboards --- functions/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/functions/index.js b/functions/index.js index fd28593ee..bc88546e6 100644 --- a/functions/index.js +++ b/functions/index.js @@ -625,6 +625,7 @@ class Leaderboard { this.board.push({ uid: entry.uid, wpm: parseFloat(entry.wpm), + raw: parseFloat(entry.raw), acc: parseFloat(entry.acc), mode: entry.mode, mode2: entry.mode2, @@ -671,6 +672,7 @@ class Leaderboard { this.board.splice(index, 0, { uid: a.uid, wpm: parseFloat(a.wpm), + raw: parseFloat(a.raw), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -683,6 +685,7 @@ class Leaderboard { this.board.splice(index, 0, { uid: a.uid, wpm: parseFloat(a.wpm), + raw: parseFloat(a.raw), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -696,6 +699,7 @@ class Leaderboard { this.board.splice(index, 0, { uid: a.uid, wpm: parseFloat(a.wpm), + raw: parseFloat(a.raw), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -709,6 +713,7 @@ class Leaderboard { this.board.push({ uid: a.uid, wpm: parseFloat(a.wpm), + raw: parseFloat(a.raw), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, From 5f2dcecab3e06fe3794950fdbc2e8347197b421c Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 19:30:05 +0100 Subject: [PATCH 03/58] added leaderboards skeleton --- public/css/style.scss | 85 +++++++++++++ public/index.html | 249 ++++++++++++++++++++++++++++++++++++++ public/js/leaderboards.js | 36 ++++++ public/js/script.js | 8 +- 4 files changed, 376 insertions(+), 2 deletions(-) create mode 100644 public/js/leaderboards.js diff --git a/public/css/style.scss b/public/css/style.scss index 7d91543dd..300550c1a 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -154,6 +154,91 @@ a:hover { } } +#leaderboardsWrapper { + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.75); + position: fixed; + left: 0; + top: 0; + z-index: 1000; + display: grid; + justify-content: center; + align-items: center; + padding: 5rem 0; + + #leaderboards { + width: 75vw; + background: var(--bg-color); + border-radius: var(--roundness); + padding: 2rem; + display: grid; + gap: 1rem; + grid-template-rows: auto auto 1fr; + grid-template-areas: "title buttons" + "tables tables"; + grid-template-columns: 1fr 1fr; + + .mainTitle { + font-size: 3rem; + line-height: 3rem; + grid-area: title; + } + + .title { + font-size: 2rem; + line-height: 2rem; + } + + .tables { + grid-area: tables; + display: grid; + gap: 1rem; + grid-template-columns: 1fr 1fr; + + table { + width: 100%; + border-spacing: 0; + border-collapse: collapse; + + td { + padding: .25rem .5rem; + } + + thead { + color: var(--sub-color); + font-size: .75rem; + } + + tbody { + color: var(--text-color); + + tr:nth-child(odd) td { + background: rgba(0, 0, 0, .1); + } + } + } + } + + .buttons { + grid-area: buttons; + display: -ms-grid; + display: grid; + gap: 1rem; + grid-template-columns: 1fr 1fr; + align-self: center; + + .buttonGroup { + display: grid; + grid-auto-flow: column; + gap: 1rem; + + } + } + } +} + + #tagsWrapper { width: 100%; height: 100%; diff --git a/public/index.html b/public/index.html index ce9cb2aa8..4a503cc26 100644 --- a/public/index.html +++ b/public/index.html @@ -52,6 +52,249 @@
+
+
+
+ Leaderboards +
+
+
+
words
+
time
+
+
+
10
+
100
+
+ +
+
+
+
+ Overall +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#namewpmrawacctestdate
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
+
+
+
+ Daily (30-05-2020) +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#namewpmrawacctestdate
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
1jack10011095words10now
+
+
+
+
+
+
+ +
+
@@ -832,6 +1080,7 @@ + diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js new file mode 100644 index 000000000..df8d7b7c5 --- /dev/null +++ b/public/js/leaderboards.js @@ -0,0 +1,36 @@ +function showLeaderboards() { + if ($("#leaderboardsWrapper").hasClass("hidden")) { + $("#leaderboardsWrapper") + .stop(true, true) + .css("opacity", 0) + .removeClass("hidden") + .animate( + { + opacity: 1, + }, + 125 + ); + } +} + +function hideLeaderboards() { + $("#leaderboardsWrapper") + .stop(true, true) + .css("opacity", 1) + .animate( + { + opacity: 0, + }, + 100, + () => { + $("#leaderboardsWrapper").addClass("hidden"); + } + ); + focusWords(); +} + +$("#leaderboardsWrapper").click((e) => { + if ($(e.target).attr("id") === "leaderboardsWrapper") { + hideLeaderboards(); + } +}); diff --git a/public/js/script.js b/public/js/script.js index a834cd12f..19ad539ac 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1979,8 +1979,12 @@ $(document).on("click", "#top .config .mode .text-button", (e) => { $(document).on("click", "#top #menu .icon-button", (e) => { if ($(e.currentTarget).hasClass("discord")) return; - href = $(e.currentTarget).attr("href"); - changePage(href.replace("/", "")); + if ($(e.currentTarget).hasClass("leaderboards")) { + showLeaderboards(); + } else { + href = $(e.currentTarget).attr("href"); + changePage(href.replace("/", "")); + } }); $(window).on("popstate", (e) => { From ee2a5436d57f26f2a27c4def3452fdc53eff8e90 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 20:10:22 +0100 Subject: [PATCH 04/58] fixed rawwpm, removed logs --- functions/index.js | 48 +++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/functions/index.js b/functions/index.js index bc88546e6..0f6ce6dc4 100644 --- a/functions/index.js +++ b/functions/index.js @@ -672,7 +672,7 @@ class Leaderboard { this.board.splice(index, 0, { uid: a.uid, wpm: parseFloat(a.wpm), - raw: parseFloat(a.raw), + raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -685,7 +685,7 @@ class Leaderboard { this.board.splice(index, 0, { uid: a.uid, wpm: parseFloat(a.wpm), - raw: parseFloat(a.raw), + raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -699,7 +699,7 @@ class Leaderboard { this.board.splice(index, 0, { uid: a.uid, wpm: parseFloat(a.wpm), - raw: parseFloat(a.raw), + raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -713,7 +713,7 @@ class Leaderboard { this.board.push({ uid: a.uid, wpm: parseFloat(a.wpm), - raw: parseFloat(a.raw), + raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, mode2: a.mode2, @@ -741,36 +741,38 @@ async function checkLeaderboards(resultObj) { let boardInfo = data.docs[0].data(); let boardData = boardInfo.board; - console.log(`info ${JSON.stringify(boardInfo)}`); - console.log(`data ${JSON.stringify(boardData)}`); + // console.log(`info ${JSON.stringify(boardInfo)}`); + // console.log(`data ${JSON.stringify(boardData)}`); let lb = new Leaderboard( - 20, + boardInfo.size, resultObj.mode, resultObj.mode2, boardInfo.type, boardData ); - console.log("board created"); + // console.log("board created"); lb.logBoard(); let insertResult = lb.insert(resultObj); - console.log("board after inseft"); + // console.log("board after inseft"); lb.logBoard(); if (insertResult >= 0) { //update the database here - console.log("board changed"); + // console.log("board changed"); admin.firestore().collection("leaderboards").doc(data.docs[0].id).set( { + size: lb.size, + type: lb.type, board: lb.board, }, { merge: true } ); } else { - console.log("board is the same"); + // console.log("board is the same"); } return insertResult; @@ -783,19 +785,25 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { .collection("leaderboards") .where("mode", "==", String(request.mode)) .where("mode2", "==", String(request.mode2)) + .where("type", "==", String(request.type)) .get() .then(async (data) => { + if (data.docs.length === 0) return null; let lbdata = data.docs[0].data(); - for (let i = 0; i < lbdata.board.length; i++) { - await admin - .auth() - .getUser(lbdata.board[i].uid) - .then((userrecord) => { - lbdata.board[i].name = userrecord.displayName; - lbdata.board[i].uid = null; - }); + if (lbdata.board !== undefined) { + for (let i = 0; i < lbdata.board.length; i++) { + await admin + .auth() + .getUser(lbdata.board[i].uid) + .then((userrecord) => { + lbdata.board[i].name = userrecord.displayName; + lbdata.board[i].uid = null; + }); + } + return lbdata; + } else { + return []; } - return lbdata; }); }); From 208a36e84ad08baece0721cbe3539e12f6680a87 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 20:10:40 +0100 Subject: [PATCH 05/58] leaderboard now pull data from db --- public/css/style.scss | 1 + public/index.html | 211 +++----------------------------------- public/js/leaderboards.js | 85 ++++++++++++++- 3 files changed, 102 insertions(+), 195 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 300550c1a..7837dc9b0 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -135,6 +135,7 @@ a:hover { animation-iteration-count: infinite; animation-duration: 2s; animation-timing-function: cubic-bezier(0.38, 0.16, 0.57, 0.82); + z-index: 9999; } @keyframes loader { diff --git a/public/index.html b/public/index.html index 4a503cc26..4dd02e56f 100644 --- a/public/index.html +++ b/public/index.html @@ -52,31 +52,31 @@
-
+
diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index bc5150ce1..2c905309f 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -70,6 +70,57 @@ function updateLeaderboards() { } showBackgroundLoader(); + Promise.all([ + firebase.functions().httpsCallable("getLeaderboard")({ + mode: currentLeaderboard.mode, + mode2: mode2, + type: "daily", + }), + firebase.functions().httpsCallable("getLeaderboard")({ + mode: currentLeaderboard.mode, + mode2: mode2, + type: "global", + }), + ]).then((lbdata) => { + hideBackgroundLoader(); + let dailyData = lbdata[0].data; + let globalData = lbdata[1].data; + + $("#leaderboardsWrapper table.daily tbody").empty(); + if (dailyData.board !== undefined) { + dailyData.board.forEach((entry, index) => { + $("#leaderboardsWrapper table.daily tbody").append(` + + ${index + 1} + ${entry.name} + ${entry.wpm} + ${entry.raw} + ${entry.acc}% + ${entry.mode} ${entry.mode2} + ${moment(entry.timestamp).format("DD MMM YYYY
HH:mm")} + + `); + }); + } + + $("#leaderboardsWrapper table.global tbody").empty(); + if (globalData.board !== undefined) { + globalData.board.forEach((entry, index) => { + $("#leaderboardsWrapper table.global tbody").append(` + + ${index + 1} + ${entry.name} + ${entry.wpm} + ${entry.raw} + ${entry.acc}% + ${entry.mode} ${entry.mode2} + ${moment(entry.timestamp).format("DD MMM YYYY
HH:mm")} + + `); + }); + } + }); + firebase .functions() .httpsCallable("getLeaderboard")({ @@ -79,7 +130,6 @@ function updateLeaderboards() { }) .then((data) => { // console.log(data); - hideBackgroundLoader(); $("#leaderboardsWrapper table.global tbody").empty(); if (data.data.board !== undefined) { data.data.board.forEach((entry, index) => { diff --git a/public/js/script.js b/public/js/script.js index 556efe1f4..8f36e56b2 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1090,16 +1090,16 @@ function showResult(difficultyFailed = false) { } catch (e) { console.log("Analytics unavailable"); } + + //global + let globalLbString = ""; if (e.data.globalLeaderboard === null) { - $("#result .stats .leaderboards .bottom").html("not found"); + globalLbString = "global: not found"; } else if (e.data.globalLeaderboard === -1) { - $("#result .stats .leaderboards .bottom").html( - "global: not qualified" - ); + globalLbString = "global: not qualified"; } else if (e.data.globalLeaderboard === -2) { - $("#result .stats .leaderboards .bottom").html( - "global: already on the leaderboard with a better result" - ); + globalLbString = + "global: already on the leaderboard with a better result"; } else if (e.data.globalLeaderboard >= 0) { let pos = e.data.globalLeaderboard + 1; let numend = "th"; @@ -1110,10 +1110,34 @@ function showResult(difficultyFailed = false) { } else if (pos === 3) { numend = "rd"; } - $("#result .stats .leaderboards .bottom").html( - `global: ${pos}${numend} place` - ); + globalLbString = `global: ${pos}${numend} place`; } + + //daily + let dailyLbString = ""; + if (e.data.dailyLeaderboard === null) { + dailyLbString = "daily: not found"; + } else if (e.data.dailyLeaderboard === -1) { + dailyLbString = "daily: not qualified"; + } else if (e.data.dailyLeaderboard === -2) { + dailyLbString = + "daily: already on the leaderboard with a better result"; + } else if (e.data.dailyLeaderboard >= 0) { + let pos = e.data.dailyLeaderboard + 1; + let numend = "th"; + if (pos === 1) { + numend = "st"; + } else if (pos === 2) { + numend = "nd"; + } else if (pos === 3) { + numend = "rd"; + } + dailyLbString = `daily: ${pos}${numend} place`; + } + + $("#result .stats .leaderboards .bottom").html( + globalLbString + "
" + dailyLbString + ); if (e.data.resultCode === 2) { //new pb if (!localPb) { From 295d02b70da8cc5663aa74e6ebb199576adfd4dc Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 23:45:22 +0100 Subject: [PATCH 14/58] removed unnecassary row --- public/css/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/css/style.scss b/public/css/style.scss index 3a54df9c2..9c9aad545 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -177,7 +177,7 @@ a:hover { padding: 2rem; display: grid; gap: 1rem; - grid-template-rows: auto auto 1fr; + grid-template-rows: auto auto; grid-template-areas: "title buttons" "tables tables"; grid-template-columns: 1fr 1fr; From 650f0c29b1e9f6ab22e9ccf20beb3a3f34ca97f8 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 00:11:26 +0100 Subject: [PATCH 15/58] added a function to move daily leaderboards to history --- functions/index.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/functions/index.js b/functions/index.js index 9835bdf34..515d42c08 100644 --- a/functions/index.js +++ b/functions/index.js @@ -908,6 +908,36 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { }); }); +exports.scheduledFunctionCrontab = functions.pubsub + .schedule("59 23 * * *") + .timeZone("Europe/London") // Users can choose timezone - default is America/Los_Angeles + .onRun((context) => { + console.log("moving daily leaderboards to history"); + admin + .firestore() + .collection("leaderboards") + .where("type", "==", "daily") + .get() + .then((res) => { + res.docs.forEach((doc) => { + let lbdata = doc.data(); + t = new Date(); + admin + .firestore() + .collection("leaderboards_history") + .doc(`${t.getDate()}_${t.getMonth()}_${t.getFullYear()}`) + .set(lbdata); + admin.firestore().collection("leaderboards").doc(doc.id).set( + { + board: [], + }, + { merge: true } + ); + }); + }); + return null; + }); + // exports.getConfig = functions.https.onCall((request,response) => { // try{ // if(request.uid === undefined){ From 05442539f5435f698d15201905a74ced40d23c8b Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 00:32:45 +0100 Subject: [PATCH 16/58] added some error logs --- functions/index.js | 149 +++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 67 deletions(-) diff --git a/functions/index.js b/functions/index.js index 515d42c08..d6967799d 100644 --- a/functions/index.js +++ b/functions/index.js @@ -823,54 +823,65 @@ class Leaderboard { } async function checkLeaderboards(resultObj, type) { - return admin - .firestore() - .collection("leaderboards") - .where("mode", "==", String(resultObj.mode)) - .where("mode2", "==", String(resultObj.mode2)) - .where("type", "==", type) - .get() - .then((data) => { - if (data.docs.length === 0) return null; - let boardInfo = data.docs[0].data(); - let boardData = boardInfo.board; + try { + return admin + .firestore() + .collection("leaderboards") + .where("mode", "==", String(resultObj.mode)) + .where("mode2", "==", String(resultObj.mode2)) + .where("type", "==", type) + .get() + .then((data) => { + if (data.docs.length === 0) return null; + let boardInfo = data.docs[0].data(); + let boardData = boardInfo.board; - // console.log(`info ${JSON.stringify(boardInfo)}`); - // console.log(`data ${JSON.stringify(boardData)}`); + // console.log(`info ${JSON.stringify(boardInfo)}`); + // console.log(`data ${JSON.stringify(boardData)}`); - let lb = new Leaderboard( - boardInfo.size, - resultObj.mode, - resultObj.mode2, - boardInfo.type, - boardData - ); - - // console.log("board created"); - // lb.logBoard(); - - let insertResult = lb.insert(resultObj); - - // console.log("board after inseft"); - // lb.logBoard(); - - if (insertResult >= 0) { - //update the database here - // console.log("board changed"); - admin.firestore().collection("leaderboards").doc(data.docs[0].id).set( - { - size: lb.size, - type: lb.type, - board: lb.board, - }, - { merge: true } + let lb = new Leaderboard( + boardInfo.size, + resultObj.mode, + resultObj.mode2, + boardInfo.type, + boardData ); - } else { - // console.log("board is the same"); - } - return insertResult; - }); + // console.log("board created"); + // lb.logBoard(); + + let insertResult = lb.insert(resultObj); + + // console.log("board after inseft"); + // lb.logBoard(); + + if (insertResult >= 0) { + //update the database here + console.log( + `leaderboard changed ${mode} ${mode2} ${type} - ${JSON.stringify( + lb.board + )}` + ); + admin.firestore().collection("leaderboards").doc(data.docs[0].id).set( + { + size: lb.size, + type: lb.type, + board: lb.board, + }, + { merge: true } + ); + } else { + // console.log("board is the same"); + } + + return insertResult; + }); + } catch (e) { + console.error( + `error while checking leaderboards - ${e} - ${type} ${resultObj}` + ); + return null; + } } exports.getLeaderboard = functions.https.onCall((request, response) => { @@ -912,30 +923,34 @@ exports.scheduledFunctionCrontab = functions.pubsub .schedule("59 23 * * *") .timeZone("Europe/London") // Users can choose timezone - default is America/Los_Angeles .onRun((context) => { - console.log("moving daily leaderboards to history"); - admin - .firestore() - .collection("leaderboards") - .where("type", "==", "daily") - .get() - .then((res) => { - res.docs.forEach((doc) => { - let lbdata = doc.data(); - t = new Date(); - admin - .firestore() - .collection("leaderboards_history") - .doc(`${t.getDate()}_${t.getMonth()}_${t.getFullYear()}`) - .set(lbdata); - admin.firestore().collection("leaderboards").doc(doc.id).set( - { - board: [], - }, - { merge: true } - ); + try { + console.log("moving daily leaderboards to history"); + admin + .firestore() + .collection("leaderboards") + .where("type", "==", "daily") + .get() + .then((res) => { + res.docs.forEach((doc) => { + let lbdata = doc.data(); + t = new Date(); + admin + .firestore() + .collection("leaderboards_history") + .doc(`${t.getDate()}_${t.getMonth()}_${t.getFullYear()}`) + .set(lbdata); + admin.firestore().collection("leaderboards").doc(doc.id).set( + { + board: [], + }, + { merge: true } + ); + }); }); - }); - return null; + return null; + } catch (e) { + console.error(`error while moving daily leaderboards to history - ${e}`); + } }); // exports.getConfig = functions.https.onCall((request,response) => { From 43dc325153ca39be7d9da64c5e5de003f3acff9f Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 00:51:09 +0100 Subject: [PATCH 17/58] fixed console log --- functions/index.js | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/functions/index.js b/functions/index.js index d6967799d..554772ee2 100644 --- a/functions/index.js +++ b/functions/index.js @@ -436,33 +436,9 @@ exports.testCompleted = functions.https.onCall((request, response) => { // console.log(returnobj); return returnobj; }); - - // return checkLeaderboards(request.obj, "global").then((globallb) => { - // return checkIfPB(request.uid, request.obj).then((e) => { - // let returnobj = { - // resultCode: null, - // globalLeaderboard: globallb, - // }; - // if (e) { - // console.log( - // `saved result for ${request.uid} (new PB) - ${JSON.stringify( - // request.obj - // )}` - // ); - // returnobj.resultCode = 2; - // } else { - // console.log( - // `saved result for ${request.uid} - ${JSON.stringify( - // request.obj - // )}` - // ); - // returnobj.resultCode = 1; - // } - // return returnobj; - // }); - // }); }) .catch((e) => { + throw e; console.error( `error saving result when checking for PB for ${request.uid} - ${e.message}` ); @@ -858,9 +834,10 @@ async function checkLeaderboards(resultObj, type) { if (insertResult >= 0) { //update the database here console.log( - `leaderboard changed ${mode} ${mode2} ${type} - ${JSON.stringify( - lb.board - )}` + `leaderboard changed + ${resultObj.mode} + ${resultObj.mode2} + ${type} - ${JSON.stringify(lb.board)}` ); admin.firestore().collection("leaderboards").doc(data.docs[0].id).set( { From 0492d42ead5e9a6ee7244deda37fb402baa84045 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 00:51:32 +0100 Subject: [PATCH 18/58] removed throw --- functions/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 554772ee2..a3dd77064 100644 --- a/functions/index.js +++ b/functions/index.js @@ -438,7 +438,6 @@ exports.testCompleted = functions.https.onCall((request, response) => { }); }) .catch((e) => { - throw e; console.error( `error saving result when checking for PB for ${request.uid} - ${e.message}` ); From 90377b7906e992ff566936ba8a91090d4977ecf8 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 00:53:29 +0100 Subject: [PATCH 19/58] updated log --- functions/index.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/functions/index.js b/functions/index.js index a3dd77064..6d27e1bbe 100644 --- a/functions/index.js +++ b/functions/index.js @@ -833,10 +833,9 @@ async function checkLeaderboards(resultObj, type) { if (insertResult >= 0) { //update the database here console.log( - `leaderboard changed - ${resultObj.mode} - ${resultObj.mode2} - ${type} - ${JSON.stringify(lb.board)}` + `leaderboard changed ${resultObj.mode} ${ + resultObj.mode2 + } ${type} - ${JSON.stringify(lb.board)}` ); admin.firestore().collection("leaderboards").doc(data.docs[0].id).set( { From 067744bbce92b6be1b5d116565569b1e9bf43fa9 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 00:58:49 +0100 Subject: [PATCH 20/58] removed more logs --- functions/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/index.js b/functions/index.js index 6d27e1bbe..5a0e740c3 100644 --- a/functions/index.js +++ b/functions/index.js @@ -868,11 +868,11 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { .where("type", "==", String(request.type)) .get() .then(async (data) => { - console.log("got data"); + // console.log("got data"); if (data.docs.length === 0) return null; let lbdata = data.docs[0].data(); if (lbdata.board !== undefined) { - console.log("replacing users"); + // console.log("replacing users"); for (let i = 0; i < lbdata.board.length; i++) { await admin @@ -885,7 +885,7 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { lbdata.board[i].uid = null; }); } - console.log("done"); + // console.log("done"); return lbdata; } else { From b25abb2f2418dff7f19468b0bdfee8364ddc508d Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 01:39:29 +0100 Subject: [PATCH 21/58] added dynamic leaderboard creation --- functions/index.js | 63 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/functions/index.js b/functions/index.js index 5a0e740c3..ef5e1ea38 100644 --- a/functions/index.js +++ b/functions/index.js @@ -799,16 +799,54 @@ class Leaderboard { async function checkLeaderboards(resultObj, type) { try { - return admin - .firestore() - .collection("leaderboards") - .where("mode", "==", String(resultObj.mode)) - .where("mode2", "==", String(resultObj.mode2)) - .where("type", "==", type) - .get() - .then((data) => { - if (data.docs.length === 0) return null; - let boardInfo = data.docs[0].data(); + if ( + (resultObj.mode === "words" && + ["10", "100"].includes(String(resultObj.mode2))) || + (resultObj.mode === "time" && + ["15", "60"].includes(String(resultObj.mode2))) + ) { + return admin + .firestore() + .collection("leaderboards") + .where("mode", "==", String(resultObj.mode)) + .where("mode2", "==", String(resultObj.mode2)) + .where("type", "==", type) + .get() + .then((ret) => { + if (ret.docs.length === 0) { + //no lb found, create + console.log( + `no ${resultObj.mode} ${resultObj.mode2} ${type} leaderboard found - creating` + ); + let toAdd = { + size: 20, + mode: String(resultObj.mode), + mode2: String(resultObj.mode2), + type: type, + }; + return admin + .firestore() + .collection("leaderboards") + .doc( + `${String(resultObj.mode)}_${String(resultObj.mode2)}_${type}` + ) + .set(toAdd) + .then((ret) => { + return cont( + `${String(resultObj.mode)}_${String( + resultObj.mode2 + )}_${type}`, + toAdd + ); + }); + } else { + //continue + return cont(ret.id, ret.docs[0].data()); + } + }); + + function cont(docid, documentData) { + let boardInfo = documentData; let boardData = boardInfo.board; // console.log(`info ${JSON.stringify(boardInfo)}`); @@ -837,7 +875,7 @@ async function checkLeaderboards(resultObj, type) { resultObj.mode2 } ${type} - ${JSON.stringify(lb.board)}` ); - admin.firestore().collection("leaderboards").doc(data.docs[0].id).set( + admin.firestore().collection("leaderboards").doc(docid).set( { size: lb.size, type: lb.type, @@ -850,7 +888,8 @@ async function checkLeaderboards(resultObj, type) { } return insertResult; - }); + } + } } catch (e) { console.error( `error while checking leaderboards - ${e} - ${type} ${resultObj}` From ab3a2d00a3005a997133a095796b648c737ce252 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 01:39:39 +0100 Subject: [PATCH 22/58] updated result screen styles --- public/css/style.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/css/style.scss b/public/css/style.scss index 9c9aad545..46f5e079e 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -879,7 +879,7 @@ key { .stats { display: grid; - gap: .5rem; + column-gap: .5rem; justify-content: center; align-items: center; grid-template-areas: @@ -892,6 +892,8 @@ key { .group { + margin-bottom: .5rem; + .top { color: var(--sub-color); font-size: 1rem; From f31ae15dea7aa50e43764874d4bd1a452e33e810 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 01:40:03 +0100 Subject: [PATCH 23/58] removing leaderboards group if both are null --- public/js/script.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 8f36e56b2..faeb85225 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1072,6 +1072,7 @@ function showResult(difficultyFailed = false) { ); wpmOverTimeChart.update({ duration: 0 }); } + $("#result .stats .leaderboards").removeClass("hidden"); $("#result .stats .leaderboards .bottom").html("checking..."); testCompleted({ uid: firebase.auth().currentUser.uid, @@ -1134,10 +1135,18 @@ function showResult(difficultyFailed = false) { } dailyLbString = `daily: ${pos}${numend} place`; } + if ( + e.data.dailyLeaderboard === null && + e.data.globalLeaderboard === null + ) { + $("#result .stats .leaderboards").addClass("hidden"); + } else { + $("#result .stats .leaderboards").removeClass("hidden"); + $("#result .stats .leaderboards .bottom").html( + globalLbString + "
" + dailyLbString + ); + } - $("#result .stats .leaderboards .bottom").html( - globalLbString + "
" + dailyLbString - ); if (e.data.resultCode === 2) { //new pb if (!localPb) { From a6b43d75185017790a7416c6dc36ca4c296dcac7 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 01:54:55 +0100 Subject: [PATCH 24/58] showing empty rows in leaderboards --- public/index.html | 361 +++++++++++++++++++++++++++++++++++++- public/js/leaderboards.js | 53 +++--- 2 files changed, 388 insertions(+), 26 deletions(-) diff --git a/public/index.html b/public/index.html index 6b7a1c4a8..d4376cee4 100644 --- a/public/index.html +++ b/public/index.html @@ -89,7 +89,186 @@ - + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + @@ -110,6 +289,186 @@ + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + + + - + - + - + - + - + - + -
- + diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 2c905309f..7f824567e 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -101,6 +101,21 @@ function updateLeaderboards() { `); }); + if (dailyData.board.length !== dailyData.size) { + for (let i = dailyData.board.length; i < dailyData.size; i++) { + $("#leaderboardsWrapper table.daily tbody").append(` + + ${i + 1} + - + - + - + - + - + -
- + + `); + } + } } $("#leaderboardsWrapper table.global tbody").empty(); @@ -118,35 +133,23 @@ function updateLeaderboards() { `); }); - } - }); - - firebase - .functions() - .httpsCallable("getLeaderboard")({ - mode: currentLeaderboard.mode, - mode2: mode2, - type: "global", - }) - .then((data) => { - // console.log(data); - $("#leaderboardsWrapper table.global tbody").empty(); - if (data.data.board !== undefined) { - data.data.board.forEach((entry, index) => { + if (globalData.board.length !== globalData.size) { + for (let i = globalData.board.length; i < globalData.size; i++) { $("#leaderboardsWrapper table.global tbody").append(` - ${index + 1} - ${entry.name} - ${entry.wpm} - ${entry.raw} - ${entry.acc} - ${entry.mode} ${entry.mode2} - ${moment(entry.timestamp).format("DD MMM YYYY
HH:mm")} - + ${i + 1} + - + - + - + - + - + -
- + `); - }); + } } - }); + } + }); } $("#leaderboardsWrapper").click((e) => { From 48bb52079554ac922cc5645ba2181b949eb06a8d Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 02:44:08 +0100 Subject: [PATCH 25/58] made sure to return board info, and triple checking that the board is empty to not return uids --- functions/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index ef5e1ea38..041eb1974 100644 --- a/functions/index.js +++ b/functions/index.js @@ -928,7 +928,15 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { return lbdata; } else { - return []; + if ( + lbdata.board === undefined || + lbdata.board === [] || + lbdata.board.length === 0 + ) { + return lbdata; + } else { + return []; + } } }); }); From 1b7322b4335ee5f0069b88fd721b9a6ff316b460 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 02:44:21 +0100 Subject: [PATCH 26/58] changed the way leaderboards scrol --- public/css/style.scss | 15 +- public/index.html | 784 +++++++++++++++++++++--------------------- 2 files changed, 405 insertions(+), 394 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 46f5e079e..97e848d3b 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -170,14 +170,13 @@ a:hover { #leaderboards { width: 75vw; - max-height: calc(100vh - 5rem); - overflow-y: scroll; + height: calc(100vh - 10rem); background: var(--bg-color); border-radius: var(--roundness); padding: 2rem; display: grid; - gap: 1rem; - grid-template-rows: auto auto; + gap: 2rem; + grid-template-rows: 3rem auto; grid-template-areas: "title buttons" "tables tables"; grid-template-columns: 1fr 1fr; @@ -191,6 +190,7 @@ a:hover { .title { font-size: 2rem; line-height: 2rem; + margin-bottom: .5rem; } .tables { @@ -198,6 +198,13 @@ a:hover { display: grid; gap: 1rem; grid-template-columns: 1fr 1fr; + margin-bottom: 2rem; + + .globalTableWrapper, + .dailyTableWrapper { + height: calc(100vh - 22rem); + overflow-y: scroll; + } table { width: 100%; diff --git a/public/index.html b/public/index.html index d4376cee4..1118abc14 100644 --- a/public/index.html +++ b/public/index.html @@ -76,401 +76,405 @@
Global
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#namewpmrawacctestdate
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#namewpmrawacctestdate
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
+
Daily
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#namewpmrawacctestdate
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#namewpmrawacctestdate
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
-------
-
+
From 5d2391282125a3daf4ad90867e3f0d28470e915d Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 02:44:35 +0100 Subject: [PATCH 27/58] filling leaderboards with blank rows --- public/js/leaderboards.js | 40 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 7f824567e..30caac0cb 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -101,9 +101,12 @@ function updateLeaderboards() { `); }); - if (dailyData.board.length !== dailyData.size) { - for (let i = dailyData.board.length; i < dailyData.size; i++) { - $("#leaderboardsWrapper table.daily tbody").append(` + } + 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(` ${i + 1} - @@ -114,7 +117,6 @@ function updateLeaderboards() { -
- `); - } } } @@ -133,20 +135,22 @@ function updateLeaderboards() { `); }); - if (globalData.board.length !== globalData.size) { - for (let i = globalData.board.length; i < globalData.size; i++) { - $("#leaderboardsWrapper table.global tbody").append(` - - ${i + 1} - - - - - - - - - - - -
- - - `); - } + } + 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(` + + ${i + 1} + - + - + - + - + - + -
- + + `); } } }); From 54a11611d860b85e2d738a705334fc21f27630d0 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 13:07:59 +0100 Subject: [PATCH 28/58] removed linting --- firebase.json | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/firebase.json b/firebase.json index 64d0fa9b9..a148775e0 100644 --- a/firebase.json +++ b/firebase.json @@ -6,25 +6,22 @@ "**/.*", "**/node_modules/**" ], - "redirects": [ - { - "source": "/soon", - "destination": "/", - "type": 301 - } - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ], + "redirects": [{ + "source": "/soon", + "destination": "/", + "type": 301 + }], + "rewrites": [{ + "source": "**", + "destination": "/index.html" + }], "cleanUrls": true, "trailingSlash": false - }, - "functions": { - "predeploy": [ - "npm --prefix \"$RESOURCE_DIR\" run lint" - ] } -} + // }, + // "functions": { + // "predeploy": [ + // "npm --prefix \"$RESOURCE_DIR\" run lint" + // ] + // } +} \ No newline at end of file From ec31fedec47ba3f92ffc267c9bb5be2ad87d7b55 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 13:08:25 +0100 Subject: [PATCH 29/58] added some errors, fixed issue with doc id --- functions/index.js | 104 +++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/functions/index.js b/functions/index.js index 041eb1974..0bda7a604 100644 --- a/functions/index.js +++ b/functions/index.js @@ -174,55 +174,27 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( } else { //valid name, but need to change if not duplicate - return getAllUsers().then((users) => { - let sameName = []; + return getAllUsers() + .then((users) => { + let sameName = []; - //look for name names - users.forEach((user) => { - if (user.uid !== requestUser.uid) { - try { - if ( - user.displayName.toLowerCase() === - requestUser.displayName.toLowerCase() - ) { - sameName.push(user); + //look for name names + users.forEach((user) => { + if (user.uid !== requestUser.uid) { + try { + if ( + user.displayName.toLowerCase() === + requestUser.displayName.toLowerCase() + ) { + sameName.push(user); + } + } catch (e) { + // } - } catch (e) { - // - } - } - }); - - if (sameName.length === 0) { - admin - .firestore() - .collection("users") - .doc(request.uid) - .update({ name: requestUser.displayName }) - .then(() => { - return 0; - }); - } else { - //check when the request user made the account compared to others - let earliestTimestamp = 999999999999999; - sameName.forEach((sn) => { - let ts = - new Date(sn.metadata.creationTime).getTime() / 1000; - if (ts <= earliestTimestamp) { - earliestTimestamp = ts; } }); - if ( - new Date(requestUser.metadata.creationTime).getTime() / - 1000 > - earliestTimestamp - ) { - console.log( - `user ${requestUser.uid} ${requestUser.displayName} needs to change name` - ); - return 2; - } else { + if (sameName.length === 0) { admin .firestore() .collection("users") @@ -231,13 +203,48 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( .then(() => { return 0; }); + } else { + //check when the request user made the account compared to others + let earliestTimestamp = 999999999999999; + sameName.forEach((sn) => { + let ts = + new Date(sn.metadata.creationTime).getTime() / 1000; + if (ts <= earliestTimestamp) { + earliestTimestamp = ts; + } + }); + + if ( + new Date( + requestUser.metadata.creationTime + ).getTime() / + 1000 > + earliestTimestamp + ) { + console.log( + `user ${requestUser.uid} ${requestUser.displayName} needs to change name` + ); + return 2; + } else { + admin + .firestore() + .collection("users") + .doc(request.uid) + .update({ name: requestUser.displayName }) + .then(() => { + return 0; + }); + } } - } - }); + }) + .catch((e) => { + console.error(`error getting all users - ${e}`); + }); } }); } else { console.log("name is good"); + return 0; } }); } catch (e) { @@ -841,7 +848,10 @@ async function checkLeaderboards(resultObj, type) { }); } else { //continue - return cont(ret.id, ret.docs[0].data()); + return cont( + `${String(resultObj.mode)}_${String(resultObj.mode2)}_${type}`, + ret.docs[0].data() + ); } }); From 352cac2e2107b076b6f7ee2ae57c00e78ec24569 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 13:08:37 +0100 Subject: [PATCH 30/58] made sure registering actually works --- public/js/account.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/public/js/account.js b/public/js/account.js index 671cb22b2..e1effdc82 100644 --- a/public/js/account.js +++ b/public/js/account.js @@ -135,6 +135,11 @@ function signUp() { }) .then(function () { // Update successful. + firebase + .firestore() + .collection("users") + .doc(usr.uid) + .set({ name: nname }, { merge: true }); showNotification("Account created", 2000); $("#menu .icon-button.account .text").text(nname); try { @@ -147,11 +152,12 @@ function signUp() { }) .catch(function (error) { // An error happened. + console.error(error); usr .delete() .then(function () { // User deleted. - showNotification("Name invalid", 2000); + showNotification("An error occured", 2000); $(".pageLogin .preloader").addClass("hidden"); }) .catch(function (error) { @@ -209,7 +215,7 @@ firebase.auth().onAuthStateChanged(function (user) { // showNotification('Applying db config',3000); updateSettingsPage(); saveConfigToCookie(); - } else { + } else if (dbSnapshot.config !== undefined) { let configsDifferent = false; Object.keys(config).forEach((key) => { if (!configsDifferent) { From 0ce1d34ddfbaa32914279d8685bb6263d035971e Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 14:15:15 +0100 Subject: [PATCH 31/58] updated check leaderboard to include info if the new result is best --- functions/index.js | 53 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/functions/index.js b/functions/index.js index 0bda7a604..4821215a6 100644 --- a/functions/index.js +++ b/functions/index.js @@ -705,28 +705,29 @@ class Leaderboard { removeDuplicates(insertedAt, uid) { //return true if a better result is found let found = false; - let ret; + // let ret; + let foundAt = null; if (this.board !== undefined) { this.board.forEach((entry, index) => { if (entry.uid === uid) { if (found) { - //remove duplicate - // console.log("removing at " + index); this.board.splice(index, 1); - if (index > insertedAt) { - //removed old result - ret = false; - } else { - ret = true; - } + // if (index > insertedAt) { + // //removed old result + // ret = false; + // } else { + // ret = true; + // } } else { found = true; + foundAt = index; } } }); } // console.log(ret); - return ret; + // return ret; + return foundAt; } insert(a) { let insertedAt = -1; @@ -790,16 +791,28 @@ class Leaderboard { } // console.log("before duplicate remove"); // console.log(this.board); + let newBest = false; if (insertedAt >= 0) { - if (this.removeDuplicates(insertedAt, a.uid)) { - insertedAt = -2; + // if (this.removeDuplicates(insertedAt, a.uid)) { + // insertedAt = -2; + // } + let foundAt = this.removeDuplicates(insertedAt, a.uid); + + if (foundAt > insertedAt) { + //new better result + newBest = true; } } // console.log(this.board); this.clipBoard(); - return insertedAt; + return { + insertedAt: insertedAt, + newBest: newBest, + }; } else { - return -999; + return { + insertedAt: -999, + }; } } } @@ -878,7 +891,7 @@ async function checkLeaderboards(resultObj, type) { // console.log("board after inseft"); // lb.logBoard(); - if (insertResult >= 0) { + if (insertResult.insertedAt >= 0) { //update the database here console.log( `leaderboard changed ${resultObj.mode} ${ @@ -930,11 +943,19 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { .doc(lbdata.board[i].uid) .get() .then((doc) => { + console.log(lbdata.board[i].uid); + console.log(request.uid); + if ( + lbdata.board[i].uid !== null && + lbdata.board[i].uid === request.uid + ) { + lbdata.board[i].currentUser = true; + } lbdata.board[i].name = doc.data().name; lbdata.board[i].uid = null; }); } - // console.log("done"); + // console.log(lbdata); return lbdata; } else { From 1da30b84b590ed954a8fecb007c2417a2391bb43 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 14:15:36 +0100 Subject: [PATCH 32/58] updated 'already on the leaderboard' mesasge --- public/js/script.js | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index faeb85225..fb1ef0219 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1094,15 +1094,12 @@ function showResult(difficultyFailed = false) { //global let globalLbString = ""; - if (e.data.globalLeaderboard === null) { + if (e.data.globalLeaderboard.insertedAt === null) { globalLbString = "global: not found"; - } else if (e.data.globalLeaderboard === -1) { + } else if (e.data.globalLeaderboard.insertedAt === -1) { globalLbString = "global: not qualified"; - } else if (e.data.globalLeaderboard === -2) { - globalLbString = - "global: already on the leaderboard with a better result"; - } else if (e.data.globalLeaderboard >= 0) { - let pos = e.data.globalLeaderboard + 1; + } else if (e.data.globalLeaderboard.insertedAt >= 0) { + let pos = e.data.globalLeaderboard.insertedAt + 1; let numend = "th"; if (pos === 1) { numend = "st"; @@ -1111,20 +1108,21 @@ function showResult(difficultyFailed = false) { } else if (pos === 3) { numend = "rd"; } - globalLbString = `global: ${pos}${numend} place`; + if (e.data.globalLeaderboard.newBest) { + globalLbString = `global: ${pos}${numend} place`; + } else { + globalLbString = `global: already ${pos}${numend}`; + } } //daily let dailyLbString = ""; - if (e.data.dailyLeaderboard === null) { + if (e.data.dailyLeaderboard.insertedAt === null) { dailyLbString = "daily: not found"; - } else if (e.data.dailyLeaderboard === -1) { + } else if (e.data.dailyLeaderboard.insertedAt === -1) { dailyLbString = "daily: not qualified"; - } else if (e.data.dailyLeaderboard === -2) { - dailyLbString = - "daily: already on the leaderboard with a better result"; - } else if (e.data.dailyLeaderboard >= 0) { - let pos = e.data.dailyLeaderboard + 1; + } else if (e.data.dailyLeaderboard.insertedAt >= 0) { + let pos = e.data.dailyLeaderboard.insertedAt + 1; let numend = "th"; if (pos === 1) { numend = "st"; @@ -1133,7 +1131,11 @@ function showResult(difficultyFailed = false) { } else if (pos === 3) { numend = "rd"; } - dailyLbString = `daily: ${pos}${numend} place`; + if (e.data.dailyLeaderboard.newBest) { + dailyLbString = `daily: ${pos}${numend} place`; + } else { + dailyLbString = `daily: already ${pos}${numend}`; + } } if ( e.data.dailyLeaderboard === null && @@ -1198,6 +1200,7 @@ function showResult(difficultyFailed = false) { if (firebase.auth().currentUser != null) { $("#result .loginTip").addClass("hidden"); } else { + $("#result .stats .leaderboards").addClass("hidden"); $("#result .loginTip").removeClass("hidden"); } From a323dbccb4f077a9e4bdb5780625dd29299c5e26 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 14:15:43 +0100 Subject: [PATCH 33/58] highlighting current user on the lb --- public/css/style.scss | 5 +++++ public/js/leaderboards.js | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 97e848d3b..77600e55f 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -213,6 +213,11 @@ a:hover { td { padding: .25rem .5rem; + + &.me { + color: var(--main-color); + font-weight: 900; + } } thead { diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 30caac0cb..7084e5200 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -69,17 +69,24 @@ function updateLeaderboards() { mode2 = currentLeaderboard.time; } + let uid = null; + if (firebase.auth().currentUser !== null) { + uid = firebase.auth().currentUser.uid; + } + showBackgroundLoader(); Promise.all([ firebase.functions().httpsCallable("getLeaderboard")({ mode: currentLeaderboard.mode, mode2: mode2, type: "daily", + uid: uid, }), firebase.functions().httpsCallable("getLeaderboard")({ mode: currentLeaderboard.mode, mode2: mode2, type: "global", + uid: uid, }), ]).then((lbdata) => { hideBackgroundLoader(); @@ -89,10 +96,12 @@ function updateLeaderboards() { $("#leaderboardsWrapper table.daily tbody").empty(); if (dailyData.board !== undefined) { dailyData.board.forEach((entry, index) => { + let meClassString = ""; + if (entry.currentUser) meClassString = ' class="me"'; $("#leaderboardsWrapper table.daily tbody").append(` ${index + 1} - ${entry.name} + ${entry.name} ${entry.wpm} ${entry.raw} ${entry.acc}% @@ -123,10 +132,12 @@ function updateLeaderboards() { $("#leaderboardsWrapper table.global tbody").empty(); if (globalData.board !== undefined) { globalData.board.forEach((entry, index) => { + let meClassString = ""; + if (entry.currentUser) meClassString = ' class="me"'; $("#leaderboardsWrapper table.global tbody").append(` ${index + 1} - ${entry.name} + ${entry.name} ${entry.wpm} ${entry.raw} ${entry.acc}% From 7f82d85e5d7383ecbf2fadb74b0440322d40e1a2 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 16:43:48 +0100 Subject: [PATCH 34/58] fixed a bug where wrong pos would be shown --- functions/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 4821215a6..f7acc51c2 100644 --- a/functions/index.js +++ b/functions/index.js @@ -792,11 +792,12 @@ class Leaderboard { // console.log("before duplicate remove"); // console.log(this.board); let newBest = false; + let foundAt = null; if (insertedAt >= 0) { // if (this.removeDuplicates(insertedAt, a.uid)) { // insertedAt = -2; // } - let foundAt = this.removeDuplicates(insertedAt, a.uid); + foundAt = this.removeDuplicates(insertedAt, a.uid); if (foundAt > insertedAt) { //new better result @@ -808,6 +809,7 @@ class Leaderboard { return { insertedAt: insertedAt, newBest: newBest, + foundAt: foundAt, }; } else { return { From 12ac4f43aee4665ccb96f1246c91355899a94de4 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 16:44:43 +0100 Subject: [PATCH 35/58] fixed lb message --- public/js/script.js | 54 ++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index fb1ef0219..9b0f13b99 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1099,18 +1099,27 @@ function showResult(difficultyFailed = false) { } else if (e.data.globalLeaderboard.insertedAt === -1) { globalLbString = "global: not qualified"; } else if (e.data.globalLeaderboard.insertedAt >= 0) { - let pos = e.data.globalLeaderboard.insertedAt + 1; - let numend = "th"; - if (pos === 1) { - numend = "st"; - } else if (pos === 2) { - numend = "nd"; - } else if (pos === 3) { - numend = "rd"; - } if (e.data.globalLeaderboard.newBest) { + let pos = e.data.globalLeaderboard.insertedAt + 1; + let numend = "th"; + if (pos === 1) { + numend = "st"; + } else if (pos === 2) { + numend = "nd"; + } else if (pos === 3) { + numend = "rd"; + } globalLbString = `global: ${pos}${numend} place`; } else { + let pos = e.data.globalLeaderboard.foundAt + 1; + let numend = "th"; + if (pos === 1) { + numend = "st"; + } else if (pos === 2) { + numend = "nd"; + } else if (pos === 3) { + numend = "rd"; + } globalLbString = `global: already ${pos}${numend}`; } } @@ -1122,18 +1131,27 @@ function showResult(difficultyFailed = false) { } else if (e.data.dailyLeaderboard.insertedAt === -1) { dailyLbString = "daily: not qualified"; } else if (e.data.dailyLeaderboard.insertedAt >= 0) { - let pos = e.data.dailyLeaderboard.insertedAt + 1; - let numend = "th"; - if (pos === 1) { - numend = "st"; - } else if (pos === 2) { - numend = "nd"; - } else if (pos === 3) { - numend = "rd"; - } if (e.data.dailyLeaderboard.newBest) { + let pos = e.data.dailyLeaderboard.insertedAt + 1; + let numend = "th"; + if (pos === 1) { + numend = "st"; + } else if (pos === 2) { + numend = "nd"; + } else if (pos === 3) { + numend = "rd"; + } dailyLbString = `daily: ${pos}${numend} place`; } else { + let pos = e.data.dailyLeaderboard.foundAt + 1; + let numend = "th"; + if (pos === 1) { + numend = "st"; + } else if (pos === 2) { + numend = "nd"; + } else if (pos === 3) { + numend = "rd"; + } dailyLbString = `daily: already ${pos}${numend}`; } } From 9ef35138784317518ed21bb7943dabbcd775f67d Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 16:44:47 +0100 Subject: [PATCH 36/58] ff scrollbar --- public/css/style.scss | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/public/css/style.scss b/public/css/style.scss index 77600e55f..5212631d1 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -10,6 +10,15 @@ /* Firefox */ } +html { + @extend .ffscroll; +} + +.ffscroll { + scrollbar-width: thin; + scrollbar-color: var(--sub-color) transparent; +} + input { outline: none; border: none; @@ -85,7 +94,7 @@ html { /* width */ ::-webkit-scrollbar { - width: 10px; + width: 7px; } /* Track */ @@ -203,6 +212,7 @@ a:hover { .globalTableWrapper, .dailyTableWrapper { height: calc(100vh - 22rem); + @extend .ffscroll; overflow-y: scroll; } @@ -330,6 +340,7 @@ a:hover { padding: 2rem; display: grid; gap: 1rem; + @extend .ffscroll; overflow-y: scroll; .tip { @@ -446,6 +457,7 @@ a:hover { .suggestions { display: block; + @extend .ffscroll; overflow-y: scroll; max-height: calc(100vh - 10rem - 3rem); display: grid; From 657efb9fb78c5f91ea12ad8da8398aa89aa9c080 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 4 Jul 2020 17:12:58 +0100 Subject: [PATCH 37/58] made leaderboards larged, reduced font size --- public/css/style.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/css/style.scss b/public/css/style.scss index 5212631d1..41fac2472 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -178,7 +178,7 @@ a:hover { padding: 5rem 0; #leaderboards { - width: 75vw; + width: 85vw; height: calc(100vh - 10rem); background: var(--bg-color); border-radius: var(--roundness); @@ -208,6 +208,7 @@ a:hover { gap: 1rem; grid-template-columns: 1fr 1fr; margin-bottom: 2rem; + font-size: .8rem; .globalTableWrapper, .dailyTableWrapper { From 1d5d30f6ada574785d17143aecb9c495241296fd Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 00:27:24 +0100 Subject: [PATCH 38/58] fixed a bug where newbest variable would not be true when it had to --- functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index f7acc51c2..637ffdc89 100644 --- a/functions/index.js +++ b/functions/index.js @@ -799,7 +799,7 @@ class Leaderboard { // } foundAt = this.removeDuplicates(insertedAt, a.uid); - if (foundAt > insertedAt) { + if (foundAt >= insertedAt) { //new better result newBest = true; } From 678d4932dfa3b7bda8e59e8cf0b9f9f5f1d61374 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 16:29:57 +0100 Subject: [PATCH 39/58] limiting leaderboards to english --- functions/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/functions/index.js b/functions/index.js index 637ffdc89..9067e3fdd 100644 --- a/functions/index.js +++ b/functions/index.js @@ -822,10 +822,11 @@ class Leaderboard { async function checkLeaderboards(resultObj, type) { try { if ( - (resultObj.mode === "words" && + ((resultObj.mode === "words" && ["10", "100"].includes(String(resultObj.mode2))) || - (resultObj.mode === "time" && - ["15", "60"].includes(String(resultObj.mode2))) + (resultObj.mode === "time" && + ["15", "60"].includes(String(resultObj.mode2)))) && + resultObj.language === "english" ) { return admin .firestore() From ee98123772f72911e8d109458725d56d97567a79 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 16:36:55 +0100 Subject: [PATCH 40/58] fixed a bug where leaderboards would override eachother when going to history --- functions/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 9067e3fdd..55de17433 100644 --- a/functions/index.js +++ b/functions/index.js @@ -993,7 +993,11 @@ exports.scheduledFunctionCrontab = functions.pubsub admin .firestore() .collection("leaderboards_history") - .doc(`${t.getDate()}_${t.getMonth()}_${t.getFullYear()}`) + .doc( + `${t.getDate()}_${t.getMonth()}_${t.getFullYear()}_${ + lbdata.mode + }_${lbdata.mode2}` + ) .set(lbdata); admin.firestore().collection("leaderboards").doc(doc.id).set( { From fb696f6c04744e341a9e4a1c9f934e65b4eea3ba Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 16:38:08 +0100 Subject: [PATCH 41/58] lb reset now happens at 00:00 --- functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 55de17433..5419db365 100644 --- a/functions/index.js +++ b/functions/index.js @@ -976,7 +976,7 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { }); exports.scheduledFunctionCrontab = functions.pubsub - .schedule("59 23 * * *") + .schedule("00 00 * * *") .timeZone("Europe/London") // Users can choose timezone - default is America/Los_Angeles .onRun((context) => { try { From 524b8aa96bb4b749f91b742835b3fa507d6e2dd3 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 17:02:02 +0100 Subject: [PATCH 42/58] added a subtitle that says when the lb will reset --- functions/index.js | 7 +++ public/css/style.scss | 16 +++++++ public/index.html | 3 ++ public/js/leaderboards.js | 95 +++++++++++++++++++++++++-------------- 4 files changed, 88 insertions(+), 33 deletions(-) diff --git a/functions/index.js b/functions/index.js index 5419db365..5252429fb 100644 --- a/functions/index.js +++ b/functions/index.js @@ -959,6 +959,13 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { }); } // console.log(lbdata); + if (request.type === "daily") { + let resetTime = new Date(); + resetTime.setHours(0, 0, 0, 0); + resetTime.setDate(resetTime.getDate() + 1); + resetTime = resetTime.valueOf(); + lbdata.resetTime = resetTime; + } return lbdata; } else { diff --git a/public/css/style.scss b/public/css/style.scss index 41fac2472..8c7a13361 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -210,11 +210,27 @@ a:hover { margin-bottom: 2rem; font-size: .8rem; + .titleAndTable { + display: grid; + + .title { + grid-area: 1/1; + } + + .subtitle { + grid-area: 1/1; + align-self: center; + justify-self: right; + color: var(--sub-color); + } + } + .globalTableWrapper, .dailyTableWrapper { height: calc(100vh - 22rem); @extend .ffscroll; overflow-y: scroll; + overflow-x: hidden; } table { diff --git a/public/index.html b/public/index.html index 1118abc14..8bb14520e 100644 --- a/public/index.html +++ b/public/index.html @@ -278,6 +278,9 @@
Daily
+
+ - +
diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 7084e5200..b23d2b93b 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -88,17 +88,42 @@ function updateLeaderboards() { type: "global", uid: uid, }), - ]).then((lbdata) => { - hideBackgroundLoader(); - let dailyData = lbdata[0].data; - let globalData = lbdata[1].data; + ]) + .then((lbdata) => { + hideBackgroundLoader(); + let dailyData = lbdata[0].data; + let globalData = lbdata[1].data; - $("#leaderboardsWrapper table.daily tbody").empty(); - if (dailyData.board !== undefined) { - dailyData.board.forEach((entry, index) => { - let meClassString = ""; - if (entry.currentUser) meClassString = ' class="me"'; - $("#leaderboardsWrapper table.daily tbody").append(` + //daily + let diffAsDate = new Date(dailyData.resetTime - Date.now()); + + let diffHours = diffAsDate.getHours(); + let diffMinutes = diffAsDate.getMinutes(); + let diffSeconds = diffAsDate.getSeconds(); + + let resetString = ""; + if (diffHours > 0) { + resetString = `resets in ${diffHours} ${ + diffHours == 1 ? "hour" : "hours" + }`; + } else if (diffMinutes > 0) { + resetString = `resets in ${diffMinutes} ${ + diffMinutes == 1 ? "minute" : "minutes" + }`; + } else if (diffSeconds > 0) { + resetString = `resets in ${diffSeconds} ${ + diffSeconds == 1 ? "second" : "seconds" + }`; + } + + $("#leaderboardsWrapper .subtitle").text(resetString); + + $("#leaderboardsWrapper table.daily tbody").empty(); + if (dailyData.board !== undefined) { + dailyData.board.forEach((entry, index) => { + let meClassString = ""; + if (entry.currentUser) meClassString = ' class="me"'; + $("#leaderboardsWrapper table.daily tbody").append(` @@ -109,13 +134,13 @@ function updateLeaderboards() { `); - }); - } - 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(` + }); + } + 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(` @@ -126,15 +151,16 @@ function updateLeaderboards() { `); + } } - } - $("#leaderboardsWrapper table.global tbody").empty(); - if (globalData.board !== undefined) { - globalData.board.forEach((entry, index) => { - let meClassString = ""; - if (entry.currentUser) meClassString = ' class="me"'; - $("#leaderboardsWrapper table.global tbody").append(` + //global + $("#leaderboardsWrapper table.global tbody").empty(); + if (globalData.board !== undefined) { + globalData.board.forEach((entry, index) => { + let meClassString = ""; + if (entry.currentUser) meClassString = ' class="me"'; + $("#leaderboardsWrapper table.global tbody").append(` @@ -145,13 +171,13 @@ function updateLeaderboards() { `); - }); - } - 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(` + }); + } + 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(` @@ -162,9 +188,12 @@ function updateLeaderboards() { `); + } } - } - }); + }) + .catch((e) => { + showNotification("Something went wrong", 3000); + }); } $("#leaderboardsWrapper").click((e) => { From 6433119764599ef565be2313d70016b4d0138a47 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 17:23:07 +0100 Subject: [PATCH 43/58] leaderboards now reset at midnight UTC --- functions/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 5252429fb..492ee2bdb 100644 --- a/functions/index.js +++ b/functions/index.js @@ -984,7 +984,6 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { exports.scheduledFunctionCrontab = functions.pubsub .schedule("00 00 * * *") - .timeZone("Europe/London") // Users can choose timezone - default is America/Los_Angeles .onRun((context) => { try { console.log("moving daily leaderboards to history"); From 0f286d67d4f6090c1d4fb3eb6bd32041daf9351b Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 17:27:18 +0100 Subject: [PATCH 44/58] using utc for resettime --- functions/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions/index.js b/functions/index.js index 492ee2bdb..a484e5331 100644 --- a/functions/index.js +++ b/functions/index.js @@ -962,7 +962,7 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { if (request.type === "daily") { let resetTime = new Date(); resetTime.setHours(0, 0, 0, 0); - resetTime.setDate(resetTime.getDate() + 1); + resetTime.setDate(resetTime.getUTCDate() + 1); resetTime = resetTime.valueOf(); lbdata.resetTime = resetTime; } @@ -1000,7 +1000,7 @@ exports.scheduledFunctionCrontab = functions.pubsub .firestore() .collection("leaderboards_history") .doc( - `${t.getDate()}_${t.getMonth()}_${t.getFullYear()}_${ + `${t.getUTCDate()}_${t.getUTCMonth()}_${t.getUTCFullYear()}_${ lbdata.mode }_${lbdata.mode2}` ) From 340ed1e45846bfd29ff6e352159cdd7527807850 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 5 Jul 2020 17:56:16 +0100 Subject: [PATCH 45/58] making sure to use utc --- functions/index.js | 2 +- public/js/leaderboards.js | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/functions/index.js b/functions/index.js index a484e5331..5d26f4d10 100644 --- a/functions/index.js +++ b/functions/index.js @@ -960,7 +960,7 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { } // console.log(lbdata); if (request.type === "daily") { - let resetTime = new Date(); + let resetTime = new Date(Date.now()); resetTime.setHours(0, 0, 0, 0); resetTime.setDate(resetTime.getUTCDate() + 1); resetTime = resetTime.valueOf(); diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index b23d2b93b..6c4aa11b2 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -97,19 +97,20 @@ function updateLeaderboards() { //daily let diffAsDate = new Date(dailyData.resetTime - Date.now()); - let diffHours = diffAsDate.getHours(); - let diffMinutes = diffAsDate.getMinutes(); - let diffSeconds = diffAsDate.getSeconds(); + 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 == 1 ? "second" : "seconds"}`; } else if (diffSeconds > 0) { resetString = `resets in ${diffSeconds} ${ diffSeconds == 1 ? "second" : "seconds" From c06444a66e221c69265741f4572ae213fcbea25d Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:05:26 +0100 Subject: [PATCH 46/58] fixed lb reset timer wrong --- public/js/leaderboards.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 6c4aa11b2..48ab20494 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -95,7 +95,7 @@ function updateLeaderboards() { let globalData = lbdata[1].data; //daily - let diffAsDate = new Date(dailyData.resetTime - Date.now()); + let diffAsDate = new Date(dailyData.resetTime - Date.now() + 3600000); let diffHours = diffAsDate.getUTCHours(); let diffMinutes = diffAsDate.getUTCMinutes(); @@ -110,7 +110,7 @@ function updateLeaderboards() { } else if (diffMinutes > 0) { resetString = `resets in ${diffMinutes} ${ diffMinutes == 1 ? "minute" : "minutes" - } ${diffSeconds == 1 ? "second" : "seconds"}`; + } ${diffSeconds} ${diffSeconds == 1 ? "second" : "seconds"}`; } else if (diffSeconds > 0) { resetString = `resets in ${diffSeconds} ${ diffSeconds == 1 ? "second" : "seconds" From 1bee07c44faa8af8ee90eb4a4c7ad40d6266549b Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:05:42 +0100 Subject: [PATCH 47/58] added keystats --- public/js/script.js | 80 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 9b0f13b99..35136ec1a 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -29,6 +29,17 @@ let accuracyStats = { incorrect: 0, }; +let keypressStats = { + spacing: { + current: -1, + array: [], + }, + duration: { + current: -1, + array: [], + }, +}; + let customText = "The quick brown fox jumps over the lazy dog".split(" "); let randomQuote = null; @@ -969,6 +980,29 @@ function showResult(difficultyFailed = false) { }); } + function stdDev(array) { + const n = array.length; + const mean = array.reduce((a, b) => a + b) / n; + return Math.sqrt( + array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n + ); + } + + console.log( + `avg time between keys ${ + keypressStats.spacing.array.reduce( + (previous, current) => (current += previous) + ) / keypressStats.spacing.array.length + } std(${stdDev(keypressStats.spacing.array)})` + ); + console.log( + `avg key down time ${ + keypressStats.duration.array.reduce( + (previous, current) => (current += previous) + ) / keypressStats.duration.array.length + } std(${stdDev(keypressStats.duration.array)})` + ); + wpmOverTimeChart.data.datasets[2].data = errorsNoZero; if (difficultyFailed) { @@ -1094,7 +1128,7 @@ function showResult(difficultyFailed = false) { //global let globalLbString = ""; - if (e.data.globalLeaderboard.insertedAt === null) { + if (e.data.globalLeaderboard === null) { globalLbString = "global: not found"; } else if (e.data.globalLeaderboard.insertedAt === -1) { globalLbString = "global: not qualified"; @@ -1126,7 +1160,7 @@ function showResult(difficultyFailed = false) { //daily let dailyLbString = ""; - if (e.data.dailyLeaderboard.insertedAt === null) { + if (e.data.dailyLeaderboard === null) { dailyLbString = "daily: not found"; } else if (e.data.dailyLeaderboard.insertedAt === -1) { dailyLbString = "daily: not qualified"; @@ -1337,6 +1371,16 @@ function restartTest(withSameWordset = false) { currentErrorCount = 0; currentTestLine = 0; activeWordJumped = false; + keypressStats = { + spacing: { + current: -1, + array: [], + }, + duration: { + current: -1, + array: [], + }, + }; hideTimer(); // restartTimer(); let el = null; @@ -2191,6 +2235,16 @@ $(document).keypress(function (event) { updateActiveElement(); updateTimer(); clearIntervals(); + keypressStats = { + spacing: { + current: -1, + array: [], + }, + duration: { + current: -1, + array: [], + }, + }; timers.push( setInterval(function () { time++; @@ -2242,6 +2296,7 @@ $(document).keypress(function (event) { } else { accuracyStats.correct++; } + currentKeypressCount++; currentInput += event["key"]; $("#words .word.active").attr("input", currentInput); @@ -2256,10 +2311,29 @@ $(document).keypress(function (event) { updateCaretPosition(); }); +$(document).keydown((event) => { + keypressStats.duration.current = performance.now(); +}); + +$(document).keyup((event) => { + let now = performance.now(); + let diff = Math.abs(keypressStats.duration.current - now); + if (keypressStats.duration.current !== -1) { + keypressStats.duration.array.push(diff); + } + keypressStats.duration.current = now; +}); + //handle keyboard events $(document).keydown((event) => { - //tab + let now = performance.now(); + let diff = Math.abs(keypressStats.spacing.current - now); + if (keypressStats.spacing.current !== -1) { + keypressStats.spacing.array.push(diff); + } + keypressStats.spacing.current = now; + //tab if (event["keyCode"] == 9) { if (config.quickTab) { event.preventDefault(); From c4e667924fd15e0dafcae9b7cd524edf73bc67de Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:05:49 +0100 Subject: [PATCH 48/58] updated gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 78ebee5fe..ea41f90c0 100644 --- a/.gitignore +++ b/.gitignore @@ -73,4 +73,7 @@ public/css/style.css public/css/style.css.map functions/serviceAccountKey.json functions/serviceAccountKey_live.json +functions/serviceAccountKey_copy.json +functions/serviceAccountKey_live_copy.json .firebaserc +.firebaserc_copy From 6913724687ab305a389a28c7a228646d3846f932 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:58:03 +0100 Subject: [PATCH 49/58] fixed time --- public/js/leaderboards.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 48ab20494..f1eafc0ec 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -95,7 +95,7 @@ function updateLeaderboards() { let globalData = lbdata[1].data; //daily - let diffAsDate = new Date(dailyData.resetTime - Date.now() + 3600000); + let diffAsDate = new Date(dailyData.resetTime - Date.now()); let diffHours = diffAsDate.getUTCHours(); let diffMinutes = diffAsDate.getUTCMinutes(); From bf957f92156e7e064ff69e1551a688b14894a8bc Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 01:09:17 +0100 Subject: [PATCH 50/58] changed timezone of cron task --- functions/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/functions/index.js b/functions/index.js index 5d26f4d10..0e3b6f69f 100644 --- a/functions/index.js +++ b/functions/index.js @@ -984,6 +984,7 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { exports.scheduledFunctionCrontab = functions.pubsub .schedule("00 00 * * *") + .timeZone("Africa/Abidjan") .onRun((context) => { try { console.log("moving daily leaderboards to history"); From 1eff3973a0e68cc5b92bef1d86331a2578306778 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 19:40:52 +0100 Subject: [PATCH 51/58] added verified and banned and anibot --- functions/index.js | 144 ++++++++++++++++++++++++++++++++------------ public/js/script.js | 27 +++++++-- 2 files changed, 127 insertions(+), 44 deletions(-) diff --git a/functions/index.js b/functions/index.js index 0e3b6f69f..1b0a51aef 100644 --- a/functions/index.js +++ b/functions/index.js @@ -374,11 +374,19 @@ function checkIfPB(uid, obj) { }); } +function stdDev(array) { + const n = array.length; + const mean = array.reduce((a, b) => a + b) / n; + return Math.sqrt( + array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n + ); +} + exports.testCompleted = functions.https.onCall((request, response) => { try { if (request.uid === undefined || request.obj === undefined) { console.error(`error saving result for ${request.uid} - missing input`); - return { resultCode: -1 }; + return { resultCode: -999 }; } let obj = request.obj; @@ -407,52 +415,105 @@ exports.testCompleted = functions.https.onCall((request, response) => { return { resultCode: -1 }; } + let keySpacing = { + average: + obj.keySpacing.reduce((previous, current) => (current += previous)) / + obj.keySpacing.length, + sd: stdDev(obj.keySpacing), + }; + + let keyDuration = { + average: + obj.keyDuration.reduce((previous, current) => (current += previous)) / + obj.keyDuration.length, + sd: stdDev(obj.keyDuration), + }; + return admin .firestore() - .collection(`users/${request.uid}/results`) - .add(obj) - .then((e) => { - return Promise.all([ - checkLeaderboards(request.obj, "global"), - checkLeaderboards(request.obj, "daily"), - checkIfPB(request.uid, request.obj), - ]).then((values) => { - let globallb = values[0]; - let dailylb = values[1]; - let ispb = values[2]; - // console.log(values); + .collection("users") + .doc(request.uid) + .get() + .then((doc) => { + let docdata = doc.data(); + let banned = docdata.banned === undefined ? false : docdata.banned; + let verified = + docdata.verified === undefined ? false : docdata.verified; - let returnobj = { - resultCode: null, - globalLeaderboard: globallb, - dailyLeaderboard: dailylb, - }; - if (ispb) { - console.log( - `saved result for ${request.uid} (new PB) - ${JSON.stringify( - request.obj - )}` + //check keyspacing and duration here + if (!verified) { + if ( + keySpacing.sd < 15 || + keyDuration.sd < 15 || + keyDuration.average < 15 + ) { + console.error( + `possible bot detected by user ${request.uid} ${ + docdata.name + } - ${JSON.stringify(keySpacing)} ${JSON.stringify(keyDuration)}` ); - returnobj.resultCode = 2; - } else { - console.log( - `saved result for ${request.uid} - ${JSON.stringify(request.obj)}` - ); - returnobj.resultCode = 1; + return { resultCode: -2 }; } - // console.log(returnobj); - return returnobj; - }); + } + + return admin + .firestore() + .collection(`users/${request.uid}/results`) + .add(obj) + .then((e) => { + return Promise.all([ + checkLeaderboards(request.obj, "global", banned), + checkLeaderboards(request.obj, "daily", banned), + checkIfPB(request.uid, request.obj), + ]).then((values) => { + let globallb = values[0].insertedAt; + let dailylb = values[1].insertedAt; + let ispb = values[2]; + // console.log(values); + + let returnobj = { + resultCode: null, + globalLeaderboard: globallb, + dailyLeaderboard: dailylb, + lbBanned: banned, + }; + request.obj.keySpacing = "removed"; + request.obj.keyDuration = "removed"; + if (ispb) { + console.log( + `saved result for ${request.uid} (new PB) - ${JSON.stringify( + request.obj + )}` + ); + returnobj.resultCode = 2; + } else { + console.log( + `saved result for ${request.uid} - ${JSON.stringify( + request.obj + )}` + ); + returnobj.resultCode = 1; + } + // console.log(returnobj); + return returnobj; + }); + }) + .catch((e) => { + console.error( + `error saving result when checking for PB / checking leaderboards for ${request.uid} - ${e.message}` + ); + return { resultCode: -999 }; + }); }) .catch((e) => { console.error( - `error saving result when checking for PB for ${request.uid} - ${e.message}` + `error saving result when getting user data for ${request.uid} - ${e.message}` ); - return { resultCode: -1 }; + return { resultCode: -999 }; }); } catch (e) { console.error(`error saving result for ${request.uid} - ${e}`); - return { resultCode: -1 }; + return { resultCode: -999 }; } }); @@ -819,8 +880,13 @@ class Leaderboard { } } -async function checkLeaderboards(resultObj, type) { +async function checkLeaderboards(resultObj, type, banned) { try { + if (banned) + return { + insertedAt: null, + banned: true, + }; if ( ((resultObj.mode === "words" && ["10", "100"].includes(String(resultObj.mode2))) || @@ -913,7 +979,9 @@ async function checkLeaderboards(resultObj, type) { // console.log("board is the same"); } - return insertResult; + return { + insertedAt: insertResult, + }; } } } catch (e) { @@ -946,8 +1014,6 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { .doc(lbdata.board[i].uid) .get() .then((doc) => { - console.log(lbdata.board[i].uid); - console.log(request.uid); if ( lbdata.board[i].uid !== null && lbdata.board[i].uid === request.uid diff --git a/public/js/script.js b/public/js/script.js index 35136ec1a..ea79c8df5 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -916,6 +916,9 @@ function showResult(difficultyFailed = false) { // 'margin-bottom': 0 }); + $("#result .stats .leaderboards .bottom").text(""); + $("#result .stats .leaderboards").addClass("hidden"); + let mode2 = ""; if (config.mode === "time") { mode2 = config.time; @@ -1039,6 +1042,8 @@ function showResult(difficultyFailed = false) { blindMode: config.blindMode, theme: config.theme, tags: activeTags, + keySpacing: keypressStats.spacing.array, + keyDuration: keypressStats.duration.array, }; if ( config.difficulty == "normal" || @@ -1113,9 +1118,16 @@ function showResult(difficultyFailed = false) { obj: completedEvent, }).then((e) => { accountIconLoading(false); - // console.log(e.data); + console.log(e.data); if (e.data.resultCode === -1) { showNotification("Could not save result", 3000); + } else if (e.data.resultCode === -2) { + showNotification( + "Possible bot detected. Result not saved.", + 4000 + ); + } else if (e.data.resultCode === -999) { + showNotification("Internal error. Result not saved.", 4000); } else if (e.data.resultCode === 1 || e.data.resultCode === 2) { dbSnapshot.results.unshift(completedEvent); try { @@ -1191,14 +1203,19 @@ function showResult(difficultyFailed = false) { } if ( e.data.dailyLeaderboard === null && - e.data.globalLeaderboard === null + e.data.globalLeaderboard === null && + e.data.lbBanned === false ) { $("#result .stats .leaderboards").addClass("hidden"); } else { $("#result .stats .leaderboards").removeClass("hidden"); - $("#result .stats .leaderboards .bottom").html( - globalLbString + "
" + dailyLbString - ); + if (e.data.lbBanned) { + $("#result .stats .leaderboards .bottom").html("banned"); + } else { + $("#result .stats .leaderboards .bottom").html( + globalLbString + "
" + dailyLbString + ); + } } if (e.data.resultCode === 2) { From 29df39aa379d1044ed96cbe1029d1786c5f51904 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 22:28:04 +0100 Subject: [PATCH 52/58] fixed result not saving for other modes --- functions/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/functions/index.js b/functions/index.js index 1b0a51aef..b777b5b2b 100644 --- a/functions/index.js +++ b/functions/index.js @@ -983,6 +983,10 @@ async function checkLeaderboards(resultObj, type, banned) { insertedAt: insertResult, }; } + } else { + return { + insertedAt: null, + }; } } catch (e) { console.error( From 086bbc4f77708720e986961e32eacea46e2704e7 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 22:51:03 +0100 Subject: [PATCH 53/58] added a check if the user has correct name --- functions/index.js | 15 +++++++++++---- public/js/script.js | 7 ++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/functions/index.js b/functions/index.js index b777b5b2b..3f2071210 100644 --- a/functions/index.js +++ b/functions/index.js @@ -73,7 +73,7 @@ function getAllUsers() { function isUsernameValid(name) { if (name === null || name === undefined || name === "") return false; - if (/miodec/.test(name)) return false; + if (/miodec/.test(name.toLowerCase())) return false; if (name.length > 12) return false; return /^[0-9a-zA-Z_.-]+$/.test(name); } @@ -436,6 +436,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { .get() .then((doc) => { let docdata = doc.data(); + let name = docdata.name === undefined ? false : docdata.name; let banned = docdata.banned === undefined ? false : docdata.banned; let verified = docdata.verified === undefined ? false : docdata.verified; @@ -462,8 +463,8 @@ exports.testCompleted = functions.https.onCall((request, response) => { .add(obj) .then((e) => { return Promise.all([ - checkLeaderboards(request.obj, "global", banned), - checkLeaderboards(request.obj, "daily", banned), + checkLeaderboards(request.obj, "global", banned, name), + checkLeaderboards(request.obj, "daily", banned, name), checkIfPB(request.uid, request.obj), ]).then((values) => { let globallb = values[0].insertedAt; @@ -476,6 +477,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { globalLeaderboard: globallb, dailyLeaderboard: dailylb, lbBanned: banned, + name: name, }; request.obj.keySpacing = "removed"; request.obj.keyDuration = "removed"; @@ -880,8 +882,13 @@ class Leaderboard { } } -async function checkLeaderboards(resultObj, type, banned) { +async function checkLeaderboards(resultObj, type, banned, name) { try { + if (!name) + return { + insertedAt: null, + noName: true, + }; if (banned) return { insertedAt: null, diff --git a/public/js/script.js b/public/js/script.js index ea79c8df5..2fcc74d4e 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1204,13 +1204,18 @@ function showResult(difficultyFailed = false) { if ( e.data.dailyLeaderboard === null && e.data.globalLeaderboard === null && - e.data.lbBanned === false + e.data.lbBanned === false && + e.data.name !== false ) { $("#result .stats .leaderboards").addClass("hidden"); } else { $("#result .stats .leaderboards").removeClass("hidden"); if (e.data.lbBanned) { $("#result .stats .leaderboards .bottom").html("banned"); + } else if (e.data.name === false) { + $("#result .stats .leaderboards .bottom").html( + "update your name to access leaderboards" + ); } else { $("#result .stats .leaderboards .bottom").html( globalLbString + "
" + dailyLbString From 356a61cebd71b671e8eab675d9a7294e6d57af0b Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 22:51:14 +0100 Subject: [PATCH 54/58] added crown for the first person on the lb --- public/css/style.scss | 4 ++++ public/js/leaderboards.js | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 8c7a13361..8430cfade 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -238,6 +238,10 @@ a:hover { border-spacing: 0; border-collapse: collapse; + tr td:first-child { + text-align: center; + } + td { padding: .25rem .5rem; diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index f1eafc0ec..5635cb42f 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -126,7 +126,9 @@ function updateLeaderboards() { if (entry.currentUser) meClassString = ' class="me"'; $("#leaderboardsWrapper table.daily tbody").append(`
- + @@ -163,7 +165,9 @@ function updateLeaderboards() { if (entry.currentUser) meClassString = ' class="me"'; $("#leaderboardsWrapper table.global tbody").append(` - + From 6188191ac5c5ff8166d8c7658139335efac946ee Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 22:53:03 +0100 Subject: [PATCH 55/58] updated log --- functions/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 3f2071210..223561c40 100644 --- a/functions/index.js +++ b/functions/index.js @@ -451,7 +451,9 @@ exports.testCompleted = functions.https.onCall((request, response) => { console.error( `possible bot detected by user ${request.uid} ${ docdata.name - } - ${JSON.stringify(keySpacing)} ${JSON.stringify(keyDuration)}` + } - spacing ${JSON.stringify( + keySpacing + )} duration ${JSON.stringify(keyDuration)}` ); return { resultCode: -2 }; } From 2d69b78ee244f878ed6a860891e4aa4a2ae1ae39 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 8 Jul 2020 00:14:03 +0100 Subject: [PATCH 56/58] initialising firebase once, limiting leaderboards to time 15 and 60 --- functions/index.js | 153 +++++++++++++++++---------------------------- 1 file changed, 58 insertions(+), 95 deletions(-) diff --git a/functions/index.js b/functions/index.js index 223561c40..7bc235772 100644 --- a/functions/index.js +++ b/functions/index.js @@ -13,6 +13,8 @@ admin.initializeApp({ credential: admin.credential.cert(serviceAccount), }); +const db = admin.firestore(); + // // Create and Deploy Your First Cloud Functions // // https://firebase.google.com/docs/functions/write-firebase-functions // @@ -23,8 +25,7 @@ admin.initializeApp({ exports.moveResults = functions .runWith({ timeoutSeconds: 540, memory: "2GB" }) .https.onCall((request, response) => { - return admin - .firestore() + return db .collection("results") .orderBy("timestamp", "desc") .limit(2000) @@ -33,15 +34,8 @@ exports.moveResults = functions data.docs.forEach((doc) => { let result = doc.data(); if (result.moved === undefined || result.moved === false) { - admin - .firestore() - .collection(`results`) - .doc(doc.id) - .update({ moved: true }); - admin - .firestore() - .collection(`users/${result.uid}/results`) - .add(result); + db.collection(`results`).doc(doc.id).update({ moved: true }); + db.collection(`users/${result.uid}/results`).add(result); console.log(`moving doc ${doc.id}`); } }); @@ -154,8 +148,7 @@ exports.changeName = functions.https.onCall((request, response) => { exports.checkIfNeedsToChangeName = functions.https.onCall( (request, response) => { try { - return admin - .firestore() + return db .collection("users") .doc(request.uid) .get() @@ -195,9 +188,7 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( }); if (sameName.length === 0) { - admin - .firestore() - .collection("users") + db.collection("users") .doc(request.uid) .update({ name: requestUser.displayName }) .then(() => { @@ -226,9 +217,7 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( ); return 2; } else { - admin - .firestore() - .collection("users") + db.collection("users") .doc(request.uid) .update({ name: requestUser.displayName }) .then(() => { @@ -254,8 +243,7 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( ); function checkIfPB(uid, obj) { - return admin - .firestore() + return db .collection(`users`) .doc(uid) .get() @@ -267,8 +255,7 @@ function checkIfPB(uid, obj) { throw new Error("pb is undefined"); } } catch (e) { - return admin - .firestore() + return db .collection("users") .doc(uid) .update({ @@ -289,8 +276,7 @@ function checkIfPB(uid, obj) { return true; }) .catch((e) => { - return admin - .firestore() + return db .collection("users") .doc(uid) .set({ @@ -360,8 +346,7 @@ function checkIfPB(uid, obj) { } if (toUpdate) { - return admin - .firestore() + return db .collection("users") .doc(uid) .update({ personalBests: pbs }) @@ -429,8 +414,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { sd: stdDev(obj.keyDuration), }; - return admin - .firestore() + return db .collection("users") .doc(request.uid) .get() @@ -441,6 +425,8 @@ exports.testCompleted = functions.https.onCall((request, response) => { let verified = docdata.verified === undefined ? false : docdata.verified; + request.obj.name = name; + //check keyspacing and duration here if (!verified) { if ( @@ -459,8 +445,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { } } - return admin - .firestore() + return db .collection(`users/${request.uid}/results`) .add(obj) .then((e) => { @@ -532,8 +517,7 @@ exports.addTag = functions.https.onCall((request, response) => { if (!isTagValid(request.name)) { return { resultCode: -1 }; } else { - return admin - .firestore() + return db .collection(`users/${request.uid}/tags`) .add({ name: request.name, @@ -563,8 +547,7 @@ exports.editTag = functions.https.onCall((request, response) => { if (!isTagValid(request.name)) { return { resultCode: -1 }; } else { - return admin - .firestore() + return db .collection(`users/${request.uid}/tags`) .doc(request.tagid) .update({ @@ -591,8 +574,7 @@ exports.editTag = functions.https.onCall((request, response) => { exports.removeTag = functions.https.onCall((request, response) => { try { - return admin - .firestore() + return db .collection(`users/${request.uid}/tags`) .doc(request.tagid) .delete() @@ -621,8 +603,7 @@ exports.updateResultTags = functions.https.onCall((request, response) => { if (!/^[0-9a-zA-Z]+$/.test(tag)) validTags = false; }); if (validTags) { - return admin - .firestore() + return db .collection(`users/${request.uid}/results`) .doc(request.resultid) .update({ @@ -693,8 +674,7 @@ exports.saveConfig = functions.https.onCall((request, response) => { return -1; } - return admin - .firestore() + return db .collection(`users`) .doc(request.uid) .set( @@ -804,6 +784,7 @@ class Leaderboard { if (a.timestamp < b.timestamp) { this.board.splice(index, 0, { uid: a.uid, + name: a.name, wpm: parseFloat(a.wpm), raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), @@ -817,6 +798,7 @@ class Leaderboard { if (a.acc > b.acc) { this.board.splice(index, 0, { uid: a.uid, + name: a.name, wpm: parseFloat(a.wpm), raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), @@ -831,6 +813,7 @@ class Leaderboard { if (a.wpm > b.wpm) { this.board.splice(index, 0, { uid: a.uid, + name: a.name, wpm: parseFloat(a.wpm), raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), @@ -845,6 +828,7 @@ class Leaderboard { if (this.board.length < this.size && insertedAt === -1) { this.board.push({ uid: a.uid, + name: a.name, wpm: parseFloat(a.wpm), raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), @@ -897,14 +881,11 @@ async function checkLeaderboards(resultObj, type, banned, name) { banned: true, }; if ( - ((resultObj.mode === "words" && - ["10", "100"].includes(String(resultObj.mode2))) || - (resultObj.mode === "time" && - ["15", "60"].includes(String(resultObj.mode2)))) && + resultObj.mode === "time" && + ["15", "60"].includes(String(resultObj.mode2)) && resultObj.language === "english" ) { - return admin - .firestore() + return db .collection("leaderboards") .where("mode", "==", String(resultObj.mode)) .where("mode2", "==", String(resultObj.mode2)) @@ -922,8 +903,7 @@ async function checkLeaderboards(resultObj, type, banned, name) { mode2: String(resultObj.mode2), type: type, }; - return admin - .firestore() + return db .collection("leaderboards") .doc( `${String(resultObj.mode)}_${String(resultObj.mode2)}_${type}` @@ -976,7 +956,7 @@ async function checkLeaderboards(resultObj, type, banned, name) { resultObj.mode2 } ${type} - ${JSON.stringify(lb.board)}` ); - admin.firestore().collection("leaderboards").doc(docid).set( + db.collection("leaderboards").doc(docid).set( { size: lb.size, type: lb.type, @@ -1006,8 +986,7 @@ async function checkLeaderboards(resultObj, type, banned, name) { } exports.getLeaderboard = functions.https.onCall((request, response) => { - return admin - .firestore() + return db .collection("leaderboards") .where("mode", "==", String(request.mode)) .where("mode2", "==", String(request.mode2)) @@ -1020,23 +999,30 @@ exports.getLeaderboard = functions.https.onCall((request, response) => { if (lbdata.board !== undefined) { // console.log("replacing users"); - for (let i = 0; i < lbdata.board.length; i++) { - await admin - .firestore() - .collection("users") - .doc(lbdata.board[i].uid) - .get() - .then((doc) => { - if ( - lbdata.board[i].uid !== null && - lbdata.board[i].uid === request.uid - ) { - lbdata.board[i].currentUser = true; - } - lbdata.board[i].name = doc.data().name; - lbdata.board[i].uid = null; - }); - } + // for (let i = 0; i < lbdata.board.length; i++) { + // await db + // .collection("users") + // .doc(lbdata.board[i].uid) + // .get() + // .then((doc) => { + // if ( + // lbdata.board[i].uid !== null && + // lbdata.board[i].uid === request.uid + // ) { + // lbdata.board[i].currentUser = true; + // } + // lbdata.board[i].name = doc.data().name; + // lbdata.board[i].uid = null; + // }); + // } + + lbdata.board.forEach((boardentry) => { + if (boardentry.uid !== null && boardentry.uid === request.uid) { + boardentry.currentUser = true; + } + boardentry.uid = null; + }); + // console.log(lbdata); if (request.type === "daily") { let resetTime = new Date(Date.now()); @@ -1067,25 +1053,21 @@ exports.scheduledFunctionCrontab = functions.pubsub .onRun((context) => { try { console.log("moving daily leaderboards to history"); - admin - .firestore() - .collection("leaderboards") + db.collection("leaderboards") .where("type", "==", "daily") .get() .then((res) => { res.docs.forEach((doc) => { let lbdata = doc.data(); t = new Date(); - admin - .firestore() - .collection("leaderboards_history") + db.collection("leaderboards_history") .doc( `${t.getUTCDate()}_${t.getUTCMonth()}_${t.getUTCFullYear()}_${ lbdata.mode }_${lbdata.mode2}` ) .set(lbdata); - admin.firestore().collection("leaderboards").doc(doc.id).set( + db.collection("leaderboards").doc(doc.id).set( { board: [], }, @@ -1098,22 +1080,3 @@ exports.scheduledFunctionCrontab = functions.pubsub console.error(`error while moving daily leaderboards to history - ${e}`); } }); - -// exports.getConfig = functions.https.onCall((request,response) => { -// try{ -// if(request.uid === undefined){ -// console.error(`error getting config for ${request.uid} - missing input`); -// return -1; -// } - -// return admin.firestore().collection(`users`).doc(request.uid).get().then(e => { -// return e.data().config; -// }).catch(e => { -// console.error(`error getting config from DB for ${request.uid} - ${e.message}`); -// return -1; -// }); -// }catch(e){ -// console.error(`error getting config for ${request.uid} - ${e}`); -// return {resultCode:-999}; -// } -// }) From f1401d76ef57aaaf7d259dc1e110b56d316bfe34 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 8 Jul 2020 00:28:40 +0100 Subject: [PATCH 57/58] now only using time 15 and 60 leaderboards --- public/css/style.scss | 2 +- public/index.html | 14 ++----- public/js/leaderboards.js | 86 ++++++++++++++++++++------------------- 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 8430cfade..d470eea24 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -278,7 +278,7 @@ a:hover { display: grid; grid-auto-flow: column; gap: 1rem; - + grid-area: 1/2; } } } diff --git a/public/index.html b/public/index.html index 8bb14520e..229dcbd3d 100644 --- a/public/index.html +++ b/public/index.html @@ -58,17 +58,9 @@ Leaderboards
-
-
words
-
time
-
-
-
10
-
100
-
-
diff --git a/public/js/leaderboards.js b/public/js/leaderboards.js index 5635cb42f..f8e54af89 100644 --- a/public/js/leaderboards.js +++ b/public/js/leaderboards.js @@ -1,8 +1,4 @@ -let currentLeaderboard = { - mode: "words", - words: "10", - time: "15", -}; +let currentLeaderboard = "time_15"; function showLeaderboards() { if ($("#leaderboardsWrapper").hasClass("hidden")) { @@ -39,35 +35,41 @@ function hideLeaderboards() { } function updateLeaderboards() { - $("#leaderboardsWrapper .leaderboardMode .button").removeClass("active"); + $("#leaderboardsWrapper .buttons .button").removeClass("active"); $( - `#leaderboardsWrapper .leaderboardMode .button[mode=${currentLeaderboard.mode}]` + `#leaderboardsWrapper .buttons .button[board=${currentLeaderboard}]` ).addClass("active"); - $("#leaderboardsWrapper .leaderboardWords .button").removeClass("active"); - $( - `#leaderboardsWrapper .leaderboardWords .button[words=${currentLeaderboard.words}]` - ).addClass("active"); + // $( + // `#leaderboardsWrapper .leaderboardMode .button[mode=${currentLeaderboard.mode}]` + // ).addClass("active"); - $("#leaderboardsWrapper .leaderboardTime .button").removeClass("active"); - $( - `#leaderboardsWrapper .leaderboardTime .button[time=${currentLeaderboard.time}]` - ).addClass("active"); + // $("#leaderboardsWrapper .leaderboardWords .button").removeClass("active"); + // $( + // `#leaderboardsWrapper .leaderboardWords .button[words=${currentLeaderboard.words}]` + // ).addClass("active"); - if (currentLeaderboard.mode === "time") { - $("#leaderboardsWrapper .leaderboardWords").addClass("hidden"); - $("#leaderboardsWrapper .leaderboardTime").removeClass("hidden"); - } else if (currentLeaderboard.mode === "words") { - $("#leaderboardsWrapper .leaderboardWords").removeClass("hidden"); - $("#leaderboardsWrapper .leaderboardTime").addClass("hidden"); - } + // $("#leaderboardsWrapper .leaderboardTime .button").removeClass("active"); + // $( + // `#leaderboardsWrapper .leaderboardTime .button[time=${currentLeaderboard.time}]` + // ).addClass("active"); - let mode2; - if (currentLeaderboard.mode === "words") { - mode2 = currentLeaderboard.words; - } else if (currentLeaderboard.mode === "time") { - mode2 = currentLeaderboard.time; - } + 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) { @@ -77,14 +79,14 @@ function updateLeaderboards() { showBackgroundLoader(); Promise.all([ firebase.functions().httpsCallable("getLeaderboard")({ - mode: currentLeaderboard.mode, - mode2: mode2, + mode: boardinfo[0], + mode2: boardinfo[1], type: "daily", uid: uid, }), firebase.functions().httpsCallable("getLeaderboard")({ - mode: currentLeaderboard.mode, - mode2: mode2, + mode: boardinfo[0], + mode2: boardinfo[1], type: "global", uid: uid, }), @@ -207,17 +209,17 @@ $("#leaderboardsWrapper").click((e) => { } }); -$("#leaderboardsWrapper .leaderboardMode .button").click((e) => { - currentLeaderboard.mode = $(e.target).attr("mode"); +$("#leaderboardsWrapper .buttons .button").click((e) => { + currentLeaderboard = $(e.target).attr("board"); updateLeaderboards(); }); -$("#leaderboardsWrapper .leaderboardWords .button").click((e) => { - currentLeaderboard.words = $(e.target).attr("words"); - 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(); -}); +// $("#leaderboardsWrapper .leaderboardTime .button").click((e) => { +// currentLeaderboard.time = $(e.target).attr("time"); +// updateLeaderboards(); +// }); From 99abbd739985e372654e83c4c838c5076ee09545 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 14:45:47 +0100 Subject: [PATCH 58/58] added function to announce lb updates in the future --- functions/index.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/functions/index.js b/functions/index.js index 7bc235772..fd2f2379b 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1080,3 +1080,12 @@ exports.scheduledFunctionCrontab = functions.pubsub console.error(`error while moving daily leaderboards to history - ${e}`); } }); + +async function announceLbUpdate(discordId, pos, lb, wpm) { + db.collection("bot-commands").add({ + command: "updateRole", + arguments: [discordId, pos, lb, wpm], + executed: false, + requestTimestamp: Date.now(), + }); +}
${index + 1} ${entry.name}${moment(entry.timestamp).format("DD MMM YYYY
HH:mm")}
${i + 1} --
-
${index + 1} ${entry.name}${moment(entry.timestamp).format("DD MMM YYYY
HH:mm")}
${i + 1} --
-
${index + 1}${ + index === 0 ? '' : index + 1 + } ${entry.name} ${entry.wpm} ${entry.raw}
${index + 1}${ + index === 0 ? '' : index + 1 + } ${entry.name} ${entry.wpm} ${entry.raw}