From 55a6c28118b09a961083663c757b877065de747a Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 3 Jul 2020 19:19:20 +0100 Subject: [PATCH 001/123] 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 002/123] 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 003/123] 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 004/123] 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 005/123] 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 014/123] 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 015/123] 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 016/123] 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 017/123] 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 018/123] 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 019/123] 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 020/123] 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 021/123] 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 022/123] 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 023/123] 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 024/123] 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 025/123] 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 026/123] 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 027/123] 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 028/123] 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 029/123] 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 030/123] 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 031/123] 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 032/123] 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 033/123] 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 034/123] 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 035/123] 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 036/123] 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 037/123] 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 038/123] 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 039/123] 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 040/123] 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 041/123] 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 042/123] 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 043/123] 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 044/123] 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 045/123] 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 046/123] 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 047/123] 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 048/123] 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 ff934462ac97f17658567b9f1545d9f11fe87817 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:06:16 +0100 Subject: [PATCH 049/123] updated gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 78ebee5fe..570edfeaa 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,5 @@ public/css/style.css.map functions/serviceAccountKey.json functions/serviceAccountKey_live.json .firebaserc +.firebaserc_copy +functions/serviceAccountKey_copy.json From f46c52a47791043b610be0b14fdcb75a9285c467 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:07:15 +0100 Subject: [PATCH 050/123] fixed tab spam hiding timer --- public/js/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 04983dfa6..d814b3c13 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -567,14 +567,14 @@ function highlightBadWord(index, showError) { function showTimer() { if (!config.showTimerBar) return; if (config.timerStyle === "bar") { - $("#timerWrapper").animate( + $("#timerWrapper").removeClass("hidden").animate( { opacity: 1, }, 250 ); } else if (config.timerStyle === "text" && config.mode === "time") { - $("#timerNumber").animate( + $("#timerNumber").removeClass("hidden").animate( { opacity: 0.25, }, From c55ea38589047087738a7b6b228248552266bf44 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:26:18 +0100 Subject: [PATCH 051/123] removed special characters from quotes, made sure to replace double spaces with singles --- public/js/english_quotes.json | 49 +++++++++++++++++------------------ public/js/script.js | 2 +- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/public/js/english_quotes.json b/public/js/english_quotes.json index a852f8e60..98a939790 100644 --- a/public/js/english_quotes.json +++ b/public/js/english_quotes.json @@ -1,5 +1,4 @@ -[ - { +[{ "text": "You have the power to heal your life, and you need to know that.", "source": "Meditations to Heal Your Life", "id": 1 @@ -835,7 +834,7 @@ "id": 167 }, { - "text": "Then we saw him pick up all the things that were down.\r\nHe picked up the cake, and the rake, and the gown, \r\nand the milk, and the strings, and the books, and the dish,\r\nand the fan, and the cup, and the ship, and the fish.", + "text": "Then we saw him pick up all the things that were down. He picked up the cake, and the rake, and the gown, and the milk, and the strings, and the books, and the dish, and the fan, and the cup, and the ship, and the fish.", "source": "The Cat in the Hat", "id": 168 }, @@ -5195,7 +5194,7 @@ "id": 1039 }, { - "text": "Living in the limelight, the universal dream for those who wish to seem. Those who wish to be must put aside the alienation, get on with the fascination, the real relation,\r\nthe underlying theme.", + "text": "Living in the limelight, the universal dream for those who wish to seem. Those who wish to be must put aside the alienation, get on with the fascination, the real relation, the underlying theme.", "source": "Limelight", "id": 1040 }, @@ -5605,7 +5604,7 @@ "id": 1121 }, { - "text": "These nights are endless, and a man can sleep through them,\r\nor he can enjoy listening to stories, and you have no need\r\nto go to bed before it is time. Too much sleep is only\r\na bore. And of the others, any one whose heart and spirit\r\nurge him can go outside and sleep, and then, when the dawn shows,\r\nbreakfast first, then go out to tend the swine of our master.", + "text": "These nights are endless, and a man can sleep through them, or he can enjoy listening to stories, and you have no need to go to bed before it is time. Too much sleep is only a bore. And of the others, any one whose heart and spirit urge him can go outside and sleep, and then, when the dawn shows, breakfast first, then go out to tend the swine of our master.", "source": "The Odyssey", "id": 1122 }, @@ -6205,7 +6204,7 @@ "id": 1241 }, { - "text": "I wanna be inside your heaven. Take me to the place you cry from, where the storm blows your way. I wanna be earth that holds you. Every bit of air you're breathing in, a soothing wind,\r\nI wanna be inside your heaven.", + "text": "I wanna be inside your heaven. Take me to the place you cry from, where the storm blows your way. I wanna be earth that holds you. Every bit of air you're breathing in, a soothing wind, I wanna be inside your heaven.", "source": "Inside Your Heaven", "id": 1242 }, @@ -7745,7 +7744,7 @@ "id": 1549 }, { - "text": "I think you're gonna find - when all this stuff is over and done - I think you're gonna find yourself one smiling guy.\r\nThing is Butch, right now you got ability. But painful as it may be, ability don't last. Now that's a hard fact of life, but it's a fact of life you're gonna have to get realistic about.", + "text": "I think you're gonna find - when all this stuff is over and done - I think you're gonna find yourself one smiling guy. Thing is Butch, right now you got ability. But painful as it may be, ability don't last. Now that's a hard fact of life, but it's a fact of life you're gonna have to get realistic about.", "source": "Pulp Fiction", "id": 1550 }, @@ -8235,7 +8234,7 @@ "id": 1647 }, { - "text": "One man, one family driven from the land; this rusty car\r\ncreaking along the highway to the west. I lost my land, a\r\nsingle tractor took my land. I am alone and bewildered.", + "text": "One man, one family driven from the land; this rusty car creaking along the highway to the west. I lost my land, a single tractor took my land. I am alone and bewildered.", "source": "The Grapes of Wrath", "id": 1648 }, @@ -8460,7 +8459,7 @@ "id": 1692 }, { - "text": "It's so warm and calm inside. I no longer have to hide.\r\nThere's talk about someone else. Sterling silver begins to melt. Nothing really bothers her. She just wants to love herself. I will move away from here. You won't be afraid of fear. No thought was put into this. I always knew it'd come to this. Things have never been so swell. And I have never failed to fail.", + "text": "It's so warm and calm inside. I no longer have to hide. There's talk about someone else. Sterling silver begins to melt. Nothing really bothers her. She just wants to love herself. I will move away from here. You won't be afraid of fear. No thought was put into this. I always knew it'd come to this. Things have never been so swell. And I have never failed to fail.", "source": "You Know You're Right", "id": 1693 }, @@ -9165,7 +9164,7 @@ "id": 1833 }, { - "text": "I thought I had the whole world in my mouth. I thought I could say what I wanted to say. For a second that thought became a sword in my hand. I could slay any problem that would stand in my way. I felt just like a crusader. Lion-heart, a Holy Land invader. But nobody can say what they really mean to say, and the impotency of speech came up and hit me that day, and I would have made this instrumental \r\nbut the words got in the way.", + "text": "I thought I had the whole world in my mouth. I thought I could say what I wanted to say. For a second that thought became a sword in my hand. I could slay any problem that would stand in my way. I felt just like a crusader. Lion-heart, a Holy Land invader. But nobody can say what they really mean to say, and the impotency of speech came up and hit me that day, and I would have made this instrumental but the words got in the way.", "source": "No Language in Our Lungs", "id": 1834 }, @@ -9185,7 +9184,7 @@ "id": 1837 }, { - "text": "Imagine for a moment if we once again knew these few unremarkable things: What it is we're eating. Where it came from. How it found its way to our table. And what, in a true\r\naccounting, it really cost. We would no longer need any reminding that however we choose to feed ourselves, we eat by\r\nthe grace of nature, not industry, and what we're eating is never anything more or less than the body of the world.", + "text": "Imagine for a moment if we once again knew these few unremarkable things: What it is we're eating. Where it came from. How it found its way to our table. And what, in a true accounting, it really cost. We would no longer need any reminding that however we choose to feed ourselves, we eat by the grace of nature, not industry, and what we're eating is never anything more or less than the body of the world.", "source": "The Omnivore's Dilemma: A Natural History of Four Meals", "id": 1838 }, @@ -9305,7 +9304,7 @@ "id": 1861 }, { - "text": "That's me in the corner, that's me in the spotlight losing my religion trying to keep up with you, and I don't know if I can do it.\r\nOh no, I've said too much, I haven't said enough.", + "text": "That's me in the corner, that's me in the spotlight losing my religion trying to keep up with you, and I don't know if I can do it. Oh no, I've said too much, I haven't said enough.", "source": "Losing My Religion", "id": 1862 }, @@ -10385,7 +10384,7 @@ "id": 2077 }, { - "text": "Sometimes you're the windshield, sometimes you're the bug.\r\nSometimes it all comes together baby. Sometimes you're a fool in love. Sometimes you're the Louisville Slugger. Sometimes you're the ball. Sometimes it all comes together baby. Sometimes you're going to lose it all.", + "text": "Sometimes you're the windshield, sometimes you're the bug. Sometimes it all comes together baby. Sometimes you're a fool in love. Sometimes you're the Louisville Slugger. Sometimes you're the ball. Sometimes it all comes together baby. Sometimes you're going to lose it all.", "source": "The Bug", "id": 2078 }, @@ -10420,7 +10419,7 @@ "id": 2084 }, { - "text": "But the queen - too long she has suffered the pain of love,\r\nhour by hour nursing the wound with her lifeblood,\r\nconsumed by the fire buried in her heart. His looks, his words, they pierce her heart and cling - no peace, no rest for her body, love will give her none.", + "text": "But the queen - too long she has suffered the pain of love, hour by hour nursing the wound with her lifeblood, consumed by the fire buried in her heart. His looks, his words, they pierce her heart and cling - no peace, no rest for her body, love will give her none.", "source": "The Aeneid", "id": 2085 }, @@ -11905,7 +11904,7 @@ "id": 2381 }, { - "text": "Once you get into the processed foods you have to be a fairly determined ecological detective to follow the intricate and\r\nincreasingly obscure lines of connection linking the Twinkie, or the nondairy creamer, to a plant growing in the earth some place, but it can be done.", + "text": "Once you get into the processed foods you have to be a fairly determined ecological detective to follow the intricate and increasingly obscure lines of connection linking the Twinkie, or the nondairy creamer, to a plant growing in the earth some place, but it can be done.", "source": "The Omnivore's Dilemma: A Natural History of Four Meals", "id": 2382 }, @@ -12605,7 +12604,7 @@ "id": 2521 }, { - "text": "Space ain't man's final frontier. Man's final frontier is the soul\r\nguided by someone more powerful than any human being. Someone felt but never seen. You will be surprised of what resides in your insides.", + "text": "Space ain't man's final frontier. Man's final frontier is the soul guided by someone more powerful than any human being. Someone felt but never seen. You will be surprised of what resides in your insides.", "source": "Man's Final Frontier", "id": 2522 }, @@ -13180,7 +13179,7 @@ "id": 2636 }, { - "text": "Last night I dreamed of chickens,\r\nthere were chickens everywhere,\r\nthey were standing on my stomach,\r\nthey were nesting in my hair,\r\nthey were pecking at my pillow,\r\nthey were hopping on my head,\r\nthey were ruffling up their feathers\r\nas they raced about my bed.\r\n\r\nThey were on the chairs and tables,\r\nthey were on the chandeliers,\r\nthey were roosting in the corners,\r\nthey were clucking in my ears,\r\nthere were chickens, chickens, chickens\r\nfor as far as I could see...\r\nwhen I woke today, I noticed\r\nthere were eggs on top of me.", + "text": "Last night I dreamed of chickens, there were chickens everywhere, they were standing on my stomach, they were nesting in my hair, they were pecking at my pillow, they were hopping on my head, they were ruffling up their feathers as they raced about my bed. They were on the chairs and tables, they were on the chandeliers, they were roosting in the corners, they were clucking in my ears, there were chickens, chickens, chickens for as far as I could see... when I woke today, I noticed there were eggs on top of me.", "source": "Last Night I Dreamed of Chickens", "id": 2637 }, @@ -14070,7 +14069,7 @@ "id": 2814 }, { - "text": "However we choose to feed ourselves, we eat by\r\nthe grace of nature, not industry, and what we're eating is never anything more or less than the body of the world.", + "text": "However we choose to feed ourselves, we eat by the grace of nature, not industry, and what we're eating is never anything more or less than the body of the world.", "source": "The Omnivore's Dilemma: A Natural History of Four Meals", "id": 2815 }, @@ -17620,7 +17619,7 @@ "id": 3524 }, { - "text": "Now this is a story all about how my life got flipped - \r\nturned upside down. And I'd like to take a minute, just sit right there; I'll tell you how I became the prince of a town called Bel-Air.", + "text": "Now this is a story all about how my life got flipped - turned upside down. And I'd like to take a minute, just sit right there; I'll tell you how I became the prince of a town called Bel-Air.", "source": "Fresh Prince of Bel Air (Theme Song)", "id": 3525 }, @@ -19715,7 +19714,7 @@ "id": 3943 }, { - "text": "Somewhere over the rainbow way up high, there's a land that I heard of once in a lullaby. Somewhere over the rainbow skies are blue, and the dreams that you dare to dream really do come true. Someday I'll wish upon a star and wake up where the clouds are far behind me. Where troubles melt like lemon drops away above the chimney tops, that's where you'll find me. Somewhere over the rainbow bluebirds fly.\r\nBirds fly over the rainbow. Why then, oh, why can't I?", + "text": "Somewhere over the rainbow way up high, there's a land that I heard of once in a lullaby. Somewhere over the rainbow skies are blue, and the dreams that you dare to dream really do come true. Someday I'll wish upon a star and wake up where the clouds are far behind me. Where troubles melt like lemon drops away above the chimney tops, that's where you'll find me. Somewhere over the rainbow bluebirds fly. Birds fly over the rainbow. Why then, oh, why can't I?", "source": "The Wizard of Oz", "id": 3944 }, @@ -21280,7 +21279,7 @@ "id": 4256 }, { - "text": "Our world, with its rules of causality, has trained us to be miserly with forgiveness. By forgiving them too readily, we can be badly hurt. But if we've learned from a mistake and became better for it, shouldn't we be rewarded for \r\nthe learning, rather than punished for the mistake?", + "text": "Our world, with its rules of causality, has trained us to be miserly with forgiveness. By forgiving them too readily, we can be badly hurt. But if we've learned from a mistake and became better for it, shouldn't we be rewarded for the learning, rather than punished for the mistake?", "source": "Braid", "id": 4257 }, @@ -21520,7 +21519,7 @@ "id": 4304 }, { - "text": "Sometimes you're the windshield, sometimes you're the bug.\r\nSometimes it all comes together baby. Sometimes you're a fool in love.", + "text": "Sometimes you're the windshield, sometimes you're the bug. Sometimes it all comes together baby. Sometimes you're a fool in love.", "source": "The Bug", "id": 4305 }, @@ -23270,7 +23269,7 @@ "id": 4654 }, { - "text": "Some people thought we were at war with the Germans -\r\n incorrect. We were at war with the clock. Britain was literally starving to death. The Americans sent over 100,000 pounds of food each week, and every week the Germans would send our desperately needed bread to the bottom of the ocean. Our daily failure was announced at the chimes of midnight. And the sound would haunt our unwelcome dreams.", + "text": "Some people thought we were at war with the Germans - incorrect. We were at war with the clock. Britain was literally starving to death. The Americans sent over 100,000 pounds of food each week, and every week the Germans would send our desperately needed bread to the bottom of the ocean. Our daily failure was announced at the chimes of midnight. And the sound would haunt our unwelcome dreams.", "source": "The Imitation Game", "id": 4655 }, @@ -23560,7 +23559,7 @@ "id": 4712 }, { - "text": "Corn is what feeds the steer that becomes the steak. Corn feeds the chicken and the pig, the turkey and the lamb, the catfish and the tilapia and, increasingly, even the salmon, a\r\ncarnivore by nature that the fish farmers are reengineering to tolerate corn. The eggs are made of corn. The milk and cheese and yogurt, which once came from dairy cows that\r\ngrazed on grass, now typically come from cows that spend their working lives indoors tethered to machines, eating corn.", + "text": "Corn is what feeds the steer that becomes the steak. Corn feeds the chicken and the pig, the turkey and the lamb, the catfish and the tilapia and, increasingly, even the salmon, a carnivore by nature that the fish farmers are reengineering to tolerate corn. The eggs are made of corn. The milk and cheese and yogurt, which once came from dairy cows that grazed on grass, now typically come from cows that spend their working lives indoors tethered to machines, eating corn.", "source": "The Omnivore's Dilemma: A Natural History of Four Meals", "id": 4713 }, @@ -24425,7 +24424,7 @@ "id": 4885 }, { - "text": "And why the winter suns so rush to bathe themselves in the sea\r\nand what slows down the nights to a long lingering crawl.", + "text": "And why the winter suns so rush to bathe themselves in the sea and what slows down the nights to a long lingering crawl.", "source": "The Aeneid", "id": 4886 }, diff --git a/public/js/script.js b/public/js/script.js index d814b3c13..7f4ff2e5f 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -303,7 +303,7 @@ function initWords() { } } else if (config.mode == "quote") { randomQuote = quotes[Math.floor(Math.random() * quotes.length)]; - let w = randomQuote.text.split(" "); + let w = randomQuote.text.split(" ").replace(" ", " "); for (let i = 0; i < w.length; i++) { wordsList.push(w[i]); } From 7d6f24ac52052fde611955946441bc7842736c4a Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:32:45 +0100 Subject: [PATCH 052/123] removed double spaces --- public/js/english_quotes.json | 144 +++++++++++++++++----------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/public/js/english_quotes.json b/public/js/english_quotes.json index 98a939790..d41c3876b 100644 --- a/public/js/english_quotes.json +++ b/public/js/english_quotes.json @@ -834,7 +834,7 @@ "id": 167 }, { - "text": "Then we saw him pick up all the things that were down. He picked up the cake, and the rake, and the gown, and the milk, and the strings, and the books, and the dish, and the fan, and the cup, and the ship, and the fish.", + "text": "Then we saw him pick up all the things that were down. He picked up the cake, and the rake, and the gown, and the milk, and the strings, and the books, and the dish, and the fan, and the cup, and the ship, and the fish.", "source": "The Cat in the Hat", "id": 168 }, @@ -2144,7 +2144,7 @@ "id": 429 }, { - "text": "The Earth is a world, the world is a ball, a ball in a game with no rules at all. And just as I wonder at the beauty of it all, you go and drop it and it breaks and falls.", + "text": "The Earth is a world, the world is a ball, a ball in a game with no rules at all. And just as I wonder at the beauty of it all, you go and drop it and it breaks and falls.", "source": "The Game", "id": 430 }, @@ -3014,7 +3014,7 @@ "id": 603 }, { - "text": "Now I want you to think and stop being a smart aleck. A man's attitude goes some ways - the way his life will be. Is that something you agree with? So since you agree, you must be someone who does not care about the good life. ", + "text": "Now I want you to think and stop being a smart aleck. A man's attitude goes some ways - the way his life will be. Is that something you agree with? So since you agree, you must be someone who does not care about the good life. ", "source": "Mulholland Drive", "id": 604 }, @@ -3085,7 +3085,7 @@ }, { "text": "Getting into trouble is not a bad thing. It's proof that someone's watching you. I've got my eyes on you, so feel free to mess up as much as you want.", - "source": "My Youth Romantic Comedy is Wrong, as I Expected", + "source": "My Youth Romantic Comedy is Wrong, as I Expected", "id": 618 }, { @@ -3669,7 +3669,7 @@ "id": 734 }, { - "text": "It is truly amazing what you can do when you believe in your own ability. That's why you need faith - a deep down, dogged belief that, regardless of the evidence, you are going to make it! You are going to achieve what you have set out to accomplish. You are going to make a difference in this life.", + "text": "It is truly amazing what you can do when you believe in your own ability. That's why you need faith - a deep down, dogged belief that, regardless of the evidence, you are going to make it! You are going to achieve what you have set out to accomplish. You are going to make a difference in this life.", "source": "The Seven Keys To Success", "id": 735 }, @@ -3959,7 +3959,7 @@ "id": 792 }, { - "text": "How sweet it is to love someone, how right it is to care. How long it's been since yesterday, what about tomorrow, and what about our dreams and all the memories we share?", + "text": "How sweet it is to love someone, how right it is to care. How long it's been since yesterday, what about tomorrow, and what about our dreams and all the memories we share?", "source": "Poems, Prayers, and Promises", "id": 793 }, @@ -4244,7 +4244,7 @@ "id": 849 }, { - "text": "Remembering you standing quiet in the rain as I ran to your heart to be near. And we kissed as the sky fell in holding you close how I always held close in your fear.", + "text": "Remembering you standing quiet in the rain as I ran to your heart to be near. And we kissed as the sky fell in holding you close how I always held close in your fear.", "source": "Pictures of You", "id": 850 }, @@ -4394,7 +4394,7 @@ "id": 879 }, { - "text": "Sometimes you concentrate more on racing the cars around you, rather than focusing on what you need to do. Having said that, some drivers actually perform best when there is a little extra incentive - like chasing another car. But be careful you don't get too caught up in what the competition is doing. Focus on your own performance rather than on the competition.", + "text": "Sometimes you concentrate more on racing the cars around you, rather than focusing on what you need to do. Having said that, some drivers actually perform best when there is a little extra incentive - like chasing another car. But be careful you don't get too caught up in what the competition is doing. Focus on your own performance rather than on the competition.", "source": "Speed Secrets: Professional Race Driving Techniques", "id": 880 }, @@ -5254,7 +5254,7 @@ "id": 1051 }, { - "text": "No matter how bad things are, you can always make things worse. At the same time, it is often within your power to make them better. I learned this lesson well on New Year's Eve, 2001.", + "text": "No matter how bad things are, you can always make things worse. At the same time, it is often within your power to make them better. I learned this lesson well on New Year's Eve, 2001.", "source": "The Last Lecture", "id": 1052 }, @@ -5369,7 +5369,7 @@ "id": 1074 }, { - "text": "I don't believe in painted roses or bleeding hearts while bullets rape the night of the merciful. I'll see you again when the stars fall from the sky and the moon has turned red over One Tree Hill.", + "text": "I don't believe in painted roses or bleeding hearts while bullets rape the night of the merciful. I'll see you again when the stars fall from the sky and the moon has turned red over One Tree Hill.", "source": "One Tree Hill", "id": 1075 }, @@ -6034,7 +6034,7 @@ "id": 1207 }, { - "text": "When the light of life has gone, no change for the meter. Then the king of spivs will come, selling blood by the litre. When nothing's sacred anymore, when the demon's knocking on your door, you'll still be staring down at the floor.", + "text": "When the light of life has gone, no change for the meter. Then the king of spivs will come, selling blood by the litre. When nothing's sacred anymore, when the demon's knocking on your door, you'll still be staring down at the floor.", "source": "Swamp Thing", "id": 1208 }, @@ -6534,7 +6534,7 @@ "id": 1307 }, { - "text": "I am learning about twenty new Italian words a day. Where am I getting the brain space to store these words? I'm hoping that maybe my mind has decided to clear out some old negative thoughts and sad memories and replace them with these shiny new words.", + "text": "I am learning about twenty new Italian words a day. Where am I getting the brain space to store these words? I'm hoping that maybe my mind has decided to clear out some old negative thoughts and sad memories and replace them with these shiny new words.", "source": "Eat, Pray, Love", "id": 1308 }, @@ -7809,7 +7809,7 @@ "id": 1562 }, { - "text": "Images of broken light which dance before me like a million eyes - they call me on and on across the universe. Thoughts meander like a restless wind inside a letter box - they tumble blindly as they make their way across the universe.", + "text": "Images of broken light which dance before me like a million eyes - they call me on and on across the universe. Thoughts meander like a restless wind inside a letter box - they tumble blindly as they make their way across the universe.", "source": "Across the Universe", "id": 1563 }, @@ -7854,7 +7854,7 @@ "id": 1571 }, { - "text": "The one place where a man ought to get a square deal is in a courtroom, be he any color of the rainbow, but people have a way of carrying their resentments right into a jury box. As you grow older, you'll see white men cheat black men every day of your life, but let me tell you something and don't you forget it - whenever a white man does that to a black man, no matter who he is, how rich he is, or how fine a family he comes from, that white man is trash.", + "text": "The one place where a man ought to get a square deal is in a courtroom, be he any color of the rainbow, but people have a way of carrying their resentments right into a jury box. As you grow older, you'll see white men cheat black men every day of your life, but let me tell you something and don't you forget it - whenever a white man does that to a black man, no matter who he is, how rich he is, or how fine a family he comes from, that white man is trash.", "source": "To Kill a Mockingbird", "id": 1572 }, @@ -8074,7 +8074,7 @@ "id": 1615 }, { - "text": "The one place where a man ought to get a square deal is in a courtroom, be he any color of the rainbow, but people have a way of carrying their resentments right into a jury box. As you grow older, you'll see white men cheat black men every day of your life, but let me tell you something and don't you forget it - whenever a white man does that to a black man, no matter who he is, how rich he is, or how fine a family he comes from, that white man is trash.", + "text": "The one place where a man ought to get a square deal is in a courtroom, be he any color of the rainbow, but people have a way of carrying their resentments right into a jury box. As you grow older, you'll see white men cheat black men every day of your life, but let me tell you something and don't you forget it - whenever a white man does that to a black man, no matter who he is, how rich he is, or how fine a family he comes from, that white man is trash.", "source": "To Kill a Mockingbird", "id": 1616 }, @@ -8279,7 +8279,7 @@ "id": 1656 }, { - "text": "I won't say another word - not one. I know I talk too much, but I am really trying to overcome it, and although I say far too much, yet if you only knew how many things I want to say and don't, you'd give me some credit for it.", + "text": "I won't say another word - not one. I know I talk too much, but I am really trying to overcome it, and although I say far too much, yet if you only knew how many things I want to say and don't, you'd give me some credit for it.", "source": "Anne of Green Gables", "id": 1657 }, @@ -8629,7 +8629,7 @@ "id": 1726 }, { - "text": "Rhymes trap you into saying things you don't want to say. A word like \"fire\" is a good example. Before you know it you're reaching for desire, or to get higher, or calling someone a liar, or putting them on a pyre, even if that wasn't what you were going to say.", + "text": "Rhymes trap you into saying things you don't want to say. A word like \"fire\" is a good example. Before you know it you're reaching for desire, or to get higher, or calling someone a liar, or putting them on a pyre, even if that wasn't what you were going to say.", "source": "Lyrics: Writing Better Words for Your Songs", "id": 1727 }, @@ -8844,7 +8844,7 @@ "id": 1769 }, { - "text": "Consider this: Is the pious being loved by the gods because it is pious, or is it pious because it is being loved by the Gods? We speak of something carried and something carrying, of something led and something leading, of something seen and something seeing, and you understand that these things are all different from one another and how they differ? So there is also something loved and - a different thing - something loving.", + "text": "Consider this: Is the pious being loved by the gods because it is pious, or is it pious because it is being loved by the Gods? We speak of something carried and something carrying, of something led and something leading, of something seen and something seeing, and you understand that these things are all different from one another and how they differ? So there is also something loved and - a different thing - something loving.", "source": "Plato: Five Dialogues", "id": 1770 }, @@ -9004,7 +9004,7 @@ "id": 1801 }, { - "text": "In detective work, there's no winning or losing... there's no being inferior or superior... that's because there's always one and only one truth.", + "text": "In detective work, there's no winning or losing... there's no being inferior or superior... that's because there's always one and only one truth.", "source": "Meitantei Conan", "id": 1802 }, @@ -9164,7 +9164,7 @@ "id": 1833 }, { - "text": "I thought I had the whole world in my mouth. I thought I could say what I wanted to say. For a second that thought became a sword in my hand. I could slay any problem that would stand in my way. I felt just like a crusader. Lion-heart, a Holy Land invader. But nobody can say what they really mean to say, and the impotency of speech came up and hit me that day, and I would have made this instrumental but the words got in the way.", + "text": "I thought I had the whole world in my mouth. I thought I could say what I wanted to say. For a second that thought became a sword in my hand. I could slay any problem that would stand in my way. I felt just like a crusader. Lion-heart, a Holy Land invader. But nobody can say what they really mean to say, and the impotency of speech came up and hit me that day, and I would have made this instrumental but the words got in the way.", "source": "No Language in Our Lungs", "id": 1834 }, @@ -9244,7 +9244,7 @@ "id": 1849 }, { - "text": "Language is one of the keys to being human. It allows us to communicate with other human beings and to leave a legacy of our thoughts and actions for future generations. The dominant temporal lobe helps to process sounds and written words into meaningful information.", + "text": "Language is one of the keys to being human. It allows us to communicate with other human beings and to leave a legacy of our thoughts and actions for future generations. The dominant temporal lobe helps to process sounds and written words into meaningful information.", "source": "Change Your Brain, Change Your Life", "id": 1850 }, @@ -9684,7 +9684,7 @@ "id": 1937 }, { - "text": "Well, all I can say Gerry is that some marches are for things and some are against things, but never has there been a march for absolutely nothing. Now is our chance to put that right. Grab your toaster and kettle and discover like me, how great it feels to devote yourself to something truly purposeless. By doing something with absolutely no point to it, we eliminate the possibility of failure, because in a sense the worse it may go then the more it can be considered a success.", + "text": "Well, all I can say Gerry is that some marches are for things and some are against things, but never has there been a march for absolutely nothing. Now is our chance to put that right. Grab your toaster and kettle and discover like me, how great it feels to devote yourself to something truly purposeless. By doing something with absolutely no point to it, we eliminate the possibility of failure, because in a sense the worse it may go then the more it can be considered a success.", "source": "Round Ireland with a Fridge", "id": 1938 }, @@ -9919,7 +9919,7 @@ "id": 1984 }, { - "text": "When I look up at the night sky, and I know that, yes, we are part of this Universe, we are in this Universe, but perhaps more important than both of those facts is that the Universe is in us. When I reflect on that fact, I look up - many people feel small, 'cause they're small and the Universe is big, but I feel big, because my atoms came from those stars.", + "text": "When I look up at the night sky, and I know that, yes, we are part of this Universe, we are in this Universe, but perhaps more important than both of those facts is that the Universe is in us. When I reflect on that fact, I look up - many people feel small, 'cause they're small and the Universe is big, but I feel big, because my atoms came from those stars.", "source": "The Most Astounding Fact", "id": 1985 }, @@ -10194,7 +10194,7 @@ "id": 2039 }, { - "text": "And in the world a heart of darkness, a firezone, where poets speak their hearts then bleed for it. Jara sang, his song a weapon, in the hands of love. You know his blood still cries from the ground. It runs like a river to the sea. We run like a river runs to the sea.", + "text": "And in the world a heart of darkness, a firezone, where poets speak their hearts then bleed for it. Jara sang, his song a weapon, in the hands of love. You know his blood still cries from the ground. It runs like a river to the sea. We run like a river runs to the sea.", "source": "One Tree Hill", "id": 2040 }, @@ -10379,7 +10379,7 @@ "id": 2076 }, { - "text": "No, the goal of war is not to kill. The goal of war is to win. By surrounding the enemy, you would force him only to fight more desperately. If you surround him on three sides and leave him an escape route, he will leave your land and there will be less blood spilled on both sides. For a warrior of the Mandinka, courage is not enough.", + "text": "No, the goal of war is not to kill. The goal of war is to win. By surrounding the enemy, you would force him only to fight more desperately. If you surround him on three sides and leave him an escape route, he will leave your land and there will be less blood spilled on both sides. For a warrior of the Mandinka, courage is not enough.", "source": "Roots", "id": 2077 }, @@ -10909,7 +10909,7 @@ "id": 2182 }, { - "text": "It was hard to toss things I had once thought were valuable enough to spend money on and just as hard to separate myself from worn and ragged clothing I had for sentimental reasons. The first ten minutes of sorting through clothing was like choosing which child of mine should live or die. Once I'd passed through the first few tough decisions, though, the momentum had been built and it was a breeze.", + "text": "It was hard to toss things I had once thought were valuable enough to spend money on and just as hard to separate myself from worn and ragged clothing I had for sentimental reasons. The first ten minutes of sorting through clothing was like choosing which child of mine should live or die. Once I'd passed through the first few tough decisions, though, the momentum had been built and it was a breeze.", "source": "The 4-Hour Workweek", "id": 2183 }, @@ -10989,7 +10989,7 @@ "id": 2198 }, { - "text": "The math is compelling. Most of the people in the world are not your customers. They haven't even heard of you actually. And while many of these people are not qualified buyers or aren't interested in buying your product, many of them might be - if only they knew you existed, if they could be convinced that your offering is worth paying for.", + "text": "The math is compelling. Most of the people in the world are not your customers. They haven't even heard of you actually. And while many of these people are not qualified buyers or aren't interested in buying your product, many of them might be - if only they knew you existed, if they could be convinced that your offering is worth paying for.", "source": "Small is the New Big", "id": 2199 }, @@ -12294,7 +12294,7 @@ "id": 2459 }, { - "text": "Is it really necessary to send that email? The more emails you send, the more work others will have to do to prioritize your requests. How many of the things you're mentioning are important? If you have 10 issues to discuss, break them into two groups and focus on the most important group.", + "text": "Is it really necessary to send that email? The more emails you send, the more work others will have to do to prioritize your requests. How many of the things you're mentioning are important? If you have 10 issues to discuss, break them into two groups and focus on the most important group.", "source": "The Art of Project Management", "id": 2460 }, @@ -12629,7 +12629,7 @@ "id": 2526 }, { - "text": "A computer needs a manager to administer its operations, just as a company needs a manager. And that is what DOS is. A manager. It manages the operations in your computer.", + "text": "A computer needs a manager to administer its operations, just as a company needs a manager. And that is what DOS is. A manager. It manages the operations in your computer.", "source": "Mastering Computer Typing (1995)", "id": 2527 }, @@ -12714,7 +12714,7 @@ "id": 2543 }, { - "text": "Desmond? I heard your name once before Desmond, a long time ago. And now it lingers in my mind like an image from an old dream. I do not know where you are, or by what means you can hear me. But I know you are listening. I have lived my life as best I could, not knowing its purpose, but drawn forward like a moth to a distant moon. And here, at last, I discover a strange truth. That I am only a conduit for a message that eludes my understanding. Who are we, who have been so blessed to share our stories like this? To speak across centuries? Maybe you will answer all the questions I have asked. Maybe you will be the one to make all this suffering worth something in the end.", + "text": "Desmond? I heard your name once before Desmond, a long time ago. And now it lingers in my mind like an image from an old dream. I do not know where you are, or by what means you can hear me. But I know you are listening. I have lived my life as best I could, not knowing its purpose, but drawn forward like a moth to a distant moon. And here, at last, I discover a strange truth. That I am only a conduit for a message that eludes my understanding. Who are we, who have been so blessed to share our stories like this? To speak across centuries? Maybe you will answer all the questions I have asked. Maybe you will be the one to make all this suffering worth something in the end.", "source": "Assassin's Creed 2", "id": 2544 }, @@ -13039,7 +13039,7 @@ "id": 2608 }, { - "text": "When you are typing on a typewriter, your input appears directly on paper. When you are typing on a computer, your input appears on a screen and is transferred to paper after the proper command has been given.", + "text": "When you are typing on a typewriter, your input appears directly on paper. When you are typing on a computer, your input appears on a screen and is transferred to paper after the proper command has been given.", "source": "Mastering Computer Typing (1995)", "id": 2609 }, @@ -13184,7 +13184,7 @@ "id": 2637 }, { - "text": "The robins were singing vespers in the high tree-tops, filling the golden air with their jubilant voices. The silver fluting of the frogs came from marshes and ponds, over fields where seeds were beginning to stir with life and thrill to the sunshine and rain that had drifted over them.", + "text": "The robins were singing vespers in the high tree-tops, filling the golden air with their jubilant voices. The silver fluting of the frogs came from marshes and ponds, over fields where seeds were beginning to stir with life and thrill to the sunshine and rain that had drifted over them.", "source": "Anne of the Island", "id": 2638 }, @@ -13264,7 +13264,7 @@ "id": 2653 }, { - "text": "We were playing checkers. I used to kid her once in a while because she wouldn't take her kings out of the back row. But I didn't kid her much though. You never wanted to kid Jane too much. I think I really like it best when you can kid the pants off a girl when the opportunity arises, but it's a funny thing. The girls I like best are ones I never feel much like kidding. Sometimes I think they'd like it if you kidded them - in fact I know they would - but it's hard to get started, once you've known them a pretty long time and never kidded them.", + "text": "We were playing checkers. I used to kid her once in a while because she wouldn't take her kings out of the back row. But I didn't kid her much though. You never wanted to kid Jane too much. I think I really like it best when you can kid the pants off a girl when the opportunity arises, but it's a funny thing. The girls I like best are ones I never feel much like kidding. Sometimes I think they'd like it if you kidded them - in fact I know they would - but it's hard to get started, once you've known them a pretty long time and never kidded them.", "source": "The Catcher in the Rye", "id": 2654 }, @@ -13449,7 +13449,7 @@ "id": 2690 }, { - "text": "Burning my bridges and smashing my mirrors, turning to see if you're cowardly. Burning the witches with modern religions, you'll strike the matches and shower me. In water games washing the rocks below. Taught and tamed in time with tear flow.", + "text": "Burning my bridges and smashing my mirrors, turning to see if you're cowardly. Burning the witches with modern religions, you'll strike the matches and shower me. In water games washing the rocks below. Taught and tamed in time with tear flow.", "source": "Seven Seas", "id": 2691 }, @@ -14244,7 +14244,7 @@ "id": 2849 }, { - "text": "We go waiting for the stars to come showering down. From Moscow to Mars, universe falling down. You got to look real hard there's a fiery star hidden out there somewhere. Not the satellite of love but a laser shooting out its shiny tongue there.", + "text": "We go waiting for the stars to come showering down. From Moscow to Mars, universe falling down. You got to look real hard there's a fiery star hidden out there somewhere. Not the satellite of love but a laser shooting out its shiny tongue there.", "source": "Star", "id": 2850 }, @@ -15649,7 +15649,7 @@ "id": 3130 }, { - "text": "God help the man who ever really loves you. You'd break his heart, my darling, cruel, destructive little cat who is so careless and confident she doesn't even trouble to sheathe her claws.", + "text": "God help the man who ever really loves you. You'd break his heart, my darling, cruel, destructive little cat who is so careless and confident she doesn't even trouble to sheathe her claws.", "source": "Gone with the Wind", "id": 3131 }, @@ -15999,7 +15999,7 @@ "id": 3200 }, { - "text": "Now! This is it! Now is the time to choose. Die and be free of pain, or live and fight your sorrow! Now is the time to shape your stories! Your fate is in your hands!", + "text": "Now! This is it! Now is the time to choose. Die and be free of pain, or live and fight your sorrow! Now is the time to shape your stories! Your fate is in your hands!", "source": "Final Fantasy X", "id": 3201 }, @@ -16629,7 +16629,7 @@ "id": 3326 }, { - "text": "Commas and periods always go inside quotation marks. Colons and semicolons always go outside quotation marks. Question marks and exclamation points go inside quotation marks when they apply to the quoted material only. They go outside when they apply to the entire sentence.", + "text": "Commas and periods always go inside quotation marks. Colons and semicolons always go outside quotation marks. Question marks and exclamation points go inside quotation marks when they apply to the quoted material only. They go outside when they apply to the entire sentence.", "source": "Mastering Computer Typing (1995)", "id": 3327 }, @@ -16649,7 +16649,7 @@ "id": 3330 }, { - "text": "He was rough around the edges. He'd been to school, but never finished. He'd been to jail, but never prison. And it was his first day off in forever, man. The festival seemed like a pretty good plan: cruise some chicks and get a suntan. And his friend gave him four, but said only take one. But then he got bored and he ended up taking all four, so now my man ain't that bored anyways. The paramedics found him, he was shaking on the side of the stage.", + "text": "He was rough around the edges. He'd been to school, but never finished. He'd been to jail, but never prison. And it was his first day off in forever, man. The festival seemed like a pretty good plan: cruise some chicks and get a suntan. And his friend gave him four, but said only take one. But then he got bored and he ended up taking all four, so now my man ain't that bored anyways. The paramedics found him, he was shaking on the side of the stage.", "source": "Chillout Tent", "id": 3331 }, @@ -16659,7 +16659,7 @@ "id": 3332 }, { - "text": "From compositional considerations the tomato layer would be expected to have a relatively high heat capacity and low conductance. It thus serves as a buffer between the mozzarella and the baked dough.", + "text": "From compositional considerations the tomato layer would be expected to have a relatively high heat capacity and low conductance. It thus serves as a buffer between the mozzarella and the baked dough.", "source": "The Thermodynamics of Pizza", "id": 3333 }, @@ -16679,7 +16679,7 @@ "id": 3336 }, { - "text": "I was hugely impressed. Kirk, I mean Shatner, was the ultimate example of a man who knew what he didn't know, was perfectly willing to admit it, and didn't want to leave until he understood. That's heroic to me.", + "text": "I was hugely impressed. Kirk, I mean Shatner, was the ultimate example of a man who knew what he didn't know, was perfectly willing to admit it, and didn't want to leave until he understood. That's heroic to me.", "source": "The Last Lecture", "id": 3337 }, @@ -16789,7 +16789,7 @@ "id": 3358 }, { - "text": "Stab a sorry heart with your favorite finger. Paint the whole world blue and stop your tears from stinging. Hear the cavemen singing. Good news they're bringing. Seven seas, swimming them so well. Glad to see my face among them kissing the tortoise shell.", + "text": "Stab a sorry heart with your favorite finger. Paint the whole world blue and stop your tears from stinging. Hear the cavemen singing. Good news they're bringing. Seven seas, swimming them so well. Glad to see my face among them kissing the tortoise shell.", "source": "Seven Seas", "id": 3359 }, @@ -16909,7 +16909,7 @@ "id": 3382 }, { - "text": "It's a blue savanna song: somewhere cross the desert, sometime in the early hours, in a restless world, on the open highways. My home is where the heart is, sweet to surrender, to you only - I send my love to you.", + "text": "It's a blue savanna song: somewhere cross the desert, sometime in the early hours, in a restless world, on the open highways. My home is where the heart is, sweet to surrender, to you only - I send my love to you.", "source": "Blue Savanna", "id": 3383 }, @@ -16954,7 +16954,7 @@ "id": 3391 }, { - "text": "We have faced our enemies a thousand times or even more; still, they cannot make us kneel. One thousand years of constant war! The giants look for any chance to bring down Asgaard's mighty walls. No matter what they send at us, we will never let it fall!", + "text": "We have faced our enemies a thousand times or even more; still, they cannot make us kneel. One thousand years of constant war! The giants look for any chance to bring down Asgaard's mighty walls. No matter what they send at us, we will never let it fall!", "source": "Guardians of Asgaard", "id": 3392 }, @@ -17189,7 +17189,7 @@ "id": 3438 }, { - "text": "A giant inverted steel pyramid is perfectly balanced on its point. Any movement of the pyramid will cause it to topple over. Underneath the pyramid is a hundred dollar bill. How do you remove the bill without disturbing the pyramid? The only way you can get the answer is if it comes to you suddenly in the blink of an eye.", + "text": "A giant inverted steel pyramid is perfectly balanced on its point. Any movement of the pyramid will cause it to topple over. Underneath the pyramid is a hundred dollar bill. How do you remove the bill without disturbing the pyramid? The only way you can get the answer is if it comes to you suddenly in the blink of an eye.", "source": "Blink", "id": 3439 }, @@ -17519,7 +17519,7 @@ "id": 3504 }, { - "text": "Hope you're feeling better now, hope you got my letter, how is my stormy weather now, is it gonna change? Can I be like everyone, pretending that there's nothing wrong? Remember when we walked upon clouds that never rain? But every cloud must drain...", + "text": "Hope you're feeling better now, hope you got my letter, how is my stormy weather now, is it gonna change? Can I be like everyone, pretending that there's nothing wrong? Remember when we walked upon clouds that never rain? But every cloud must drain...", "source": "Stormy Weather", "id": 3505 }, @@ -17619,7 +17619,7 @@ "id": 3524 }, { - "text": "Now this is a story all about how my life got flipped - turned upside down. And I'd like to take a minute, just sit right there; I'll tell you how I became the prince of a town called Bel-Air.", + "text": "Now this is a story all about how my life got flipped - turned upside down. And I'd like to take a minute, just sit right there; I'll tell you how I became the prince of a town called Bel-Air.", "source": "Fresh Prince of Bel Air (Theme Song)", "id": 3525 }, @@ -17649,7 +17649,7 @@ "id": 3530 }, { - "text": "If you are given too many choices, if you are forced to consider much more than your unconscious is comfortable with, you get paralyzed. Snap judgments can be made in a snap because they are frugal, and if we want to protect our snap judgments, we have to take steps to protect that frugality.", + "text": "If you are given too many choices, if you are forced to consider much more than your unconscious is comfortable with, you get paralyzed. Snap judgments can be made in a snap because they are frugal, and if we want to protect our snap judgments, we have to take steps to protect that frugality.", "source": "Blink", "id": 3531 }, @@ -17774,7 +17774,7 @@ "id": 3555 }, { - "text": "Lucid but wholly false recollections can easily be induced by a few cues and questions. Memory can be contaminated. False memories can be implanted even in minds that do not consider themselves vulnerable and uncritical.", + "text": "Lucid but wholly false recollections can easily be induced by a few cues and questions. Memory can be contaminated. False memories can be implanted even in minds that do not consider themselves vulnerable and uncritical.", "source": "The Demon-Haunted World: Science as a Candle in the Dark", "id": 3556 }, @@ -18024,7 +18024,7 @@ "id": 3605 }, { - "text": "At first they had tried to keep the finding quiet. After all, they were not absolutely sure it was an extraterrestrial message. A premature or mistaken announcement would be a public relations disaster. But worse than that, it would interfere with the data analysis. If the press descended, the science would surely suffer.", + "text": "At first they had tried to keep the finding quiet. After all, they were not absolutely sure it was an extraterrestrial message. A premature or mistaken announcement would be a public relations disaster. But worse than that, it would interfere with the data analysis. If the press descended, the science would surely suffer.", "source": "Contact", "id": 3606 }, @@ -18084,7 +18084,7 @@ "id": 3617 }, { - "text": "Your ring finger is the most difficult of all fingers to control. You will notice that when you move your ring finger your other fingers will move involuntarily as well. This is something that will become less of a problem as you perfect your keyboarding skills.", + "text": "Your ring finger is the most difficult of all fingers to control. You will notice that when you move your ring finger your other fingers will move involuntarily as well. This is something that will become less of a problem as you perfect your keyboarding skills.", "source": "Keyboarding Made Simple (1985)", "id": 3618 }, @@ -18774,7 +18774,7 @@ "id": 3755 }, { - "text": "He started running, up and up, until he hurled himself into the air. As he was falling face down, somehow all the years of training in martial arts at once possessed him. His body instinctively adjusted itself and even his arms spread out, swinging to ensure that he wouldn't hurt himself fatally. With a thump his feet landed on the ground.", + "text": "He started running, up and up, until he hurled himself into the air. As he was falling face down, somehow all the years of training in martial arts at once possessed him. His body instinctively adjusted itself and even his arms spread out, swinging to ensure that he wouldn't hurt himself fatally. With a thump his feet landed on the ground.", "source": "A Good Fall: Stories", "id": 3756 }, @@ -19244,7 +19244,7 @@ "id": 3849 }, { - "text": "Listen to the watch. The way it's ticking synchronizes with your heartbeat. Look into my eyes. Not above them, not around them, but deep into their center. You are completely relaxed and are becoming weightless. Are you ready to do something impossible?", + "text": "Listen to the watch. The way it's ticking synchronizes with your heartbeat. Look into my eyes. Not above them, not around them, but deep into their center. You are completely relaxed and are becoming weightless. Are you ready to do something impossible?", "source": "Gotham", "id": 3850 }, @@ -19539,7 +19539,7 @@ "id": 3908 }, { - "text": "There was a stage and a PA up in western Massachusetts and the kids came from miles around to get messed up on the music. And she drove down from Bowdoin with a carload of girlfriends, to meet some boys and maybe eat some mushrooms. And they did, and she got sick, and now she's pinned and way too shaky.", + "text": "There was a stage and a PA up in western Massachusetts and the kids came from miles around to get messed up on the music. And she drove down from Bowdoin with a carload of girlfriends, to meet some boys and maybe eat some mushrooms. And they did, and she got sick, and now she's pinned and way too shaky.", "source": "Chillout Tent", "id": 3909 }, @@ -20504,7 +20504,7 @@ "id": 4101 }, { - "text": "We don't need no education. We don't need no thought control. No dark sarcasm in the classroom - teachers leave them kids alone! All in all it's just another brick in the wall. \"If you don't eat yer meat, you can't have any pudding. How can you have any pudding if you don't eat yer meat?\"", + "text": "We don't need no education. We don't need no thought control. No dark sarcasm in the classroom - teachers leave them kids alone! All in all it's just another brick in the wall. \"If you don't eat yer meat, you can't have any pudding. How can you have any pudding if you don't eat yer meat?\"", "source": "Another Brick in the Wall", "id": 4102 }, @@ -20514,7 +20514,7 @@ "id": 4103 }, { - "text": "We don't read and write poetry because it's cute. We read and write poetry because we are members of the human race. And the human race is filled with passion. And medicine, law, business, engineering, these are noble pursuits and necessary to sustain life. But poetry, beauty, romance, love, these are what we stay alive for.", + "text": "We don't read and write poetry because it's cute. We read and write poetry because we are members of the human race. And the human race is filled with passion. And medicine, law, business, engineering, these are noble pursuits and necessary to sustain life. But poetry, beauty, romance, love, these are what we stay alive for.", "source": "Dead Poets Society", "id": 4104 }, @@ -21014,7 +21014,7 @@ "id": 4203 }, { - "text": "Most popular song lyrics have two sections - a verse and a bridge, where the bridge offers a contrast to the verse but is not the place where the song is summarized - or a verse and a chorus. A chorus is the high-point of a lyric's energy as well as the music's energy.", + "text": "Most popular song lyrics have two sections - a verse and a bridge, where the bridge offers a contrast to the verse but is not the place where the song is summarized - or a verse and a chorus. A chorus is the high-point of a lyric's energy as well as the music's energy.", "source": "Lyrics: Writing Better Words for Your Songs", "id": 4204 }, @@ -21059,7 +21059,7 @@ "id": 4212 }, { - "text": "I'm DEFINITELY NOT saying that Edley isn't a star, but I do say that people overstate the significance of small strings of statistical events based on their grouping. Granted this is the case in many, many competitive endeavors, but that doesn't mean that Joe Edley is the best player or that he was even the best player that week.", + "text": "I'm DEFINITELY NOT saying that Edley isn't a star, but I do say that people overstate the significance of small strings of statistical events based on their grouping. Granted this is the case in many, many competitive endeavors, but that doesn't mean that Joe Edley is the best player or that he was even the best player that week.", "source": "Word Freak", "id": 4213 }, @@ -21269,7 +21269,7 @@ "id": 4254 }, { - "text": "Quality humor doesn't just deliver one gag and then tax the audience's patience developing a new setup. Once you've got the audience laughing or on a roll, it's better to stay with toppers - a series of punch lines, each related to the previous one.", + "text": "Quality humor doesn't just deliver one gag and then tax the audience's patience developing a new setup. Once you've got the audience laughing or on a roll, it's better to stay with toppers - a series of punch lines, each related to the previous one.", "source": "Comedy Writing Secrets", "id": 4255 }, @@ -21279,7 +21279,7 @@ "id": 4256 }, { - "text": "Our world, with its rules of causality, has trained us to be miserly with forgiveness. By forgiving them too readily, we can be badly hurt. But if we've learned from a mistake and became better for it, shouldn't we be rewarded for the learning, rather than punished for the mistake?", + "text": "Our world, with its rules of causality, has trained us to be miserly with forgiveness. By forgiving them too readily, we can be badly hurt. But if we've learned from a mistake and became better for it, shouldn't we be rewarded for the learning, rather than punished for the mistake?", "source": "Braid", "id": 4257 }, @@ -21644,7 +21644,7 @@ "id": 4329 }, { - "text": "Since the infancy of computers, hackers have been creatively solving problems. In the late 1950s, the MIT model railroad club was given a donation of parts, mostly old telephone equipment. The club's members used this equipment to rig up a complex system that allowed multiple operators to control different parts of the track by dialing in to the appropriate sections. They called this new and inventive use of telephone equipment hacking; many people consider this group to be the original hackers.", + "text": "Since the infancy of computers, hackers have been creatively solving problems. In the late 1950s, the MIT model railroad club was given a donation of parts, mostly old telephone equipment. The club's members used this equipment to rig up a complex system that allowed multiple operators to control different parts of the track by dialing in to the appropriate sections. They called this new and inventive use of telephone equipment hacking; many people consider this group to be the original hackers.", "source": "Hacking: The Art of Exploitation", "id": 4330 }, @@ -21884,7 +21884,7 @@ "id": 4377 }, { - "text": "Some drivers actually perform best when there is a little extra incentive - like chasing another car. But be careful you don't get too caught up in what the competition is doing. Focus on your own performance rather than on the competition.", + "text": "Some drivers actually perform best when there is a little extra incentive - like chasing another car. But be careful you don't get too caught up in what the competition is doing. Focus on your own performance rather than on the competition.", "source": "Speed Secrets: Professional Race Driving Techniques", "id": 4378 }, @@ -22024,7 +22024,7 @@ "id": 4405 }, { - "text": "The study of global social phenomena raises several difficulties that are not commonly encountered when research questions are posed at less comprehensive levels. Problems of arising from aggregation, diffusion, and path dependence, to name three, plague any attempt at answering questions that are posed at a global level. Ultimately, all these problems arise from the fact that there is only one world available for us to study, and when the world itself is the scope of the analysis, additional worlds are not available for validating initial results.", + "text": "The study of global social phenomena raises several difficulties that are not commonly encountered when research questions are posed at less comprehensive levels. Problems of arising from aggregation, diffusion, and path dependence, to name three, plague any attempt at answering questions that are posed at a global level. Ultimately, all these problems arise from the fact that there is only one world available for us to study, and when the world itself is the scope of the analysis, additional worlds are not available for validating initial results.", "source": "Global Social Change: Historical and Comparative Perspectives", "id": 4406 }, @@ -23269,7 +23269,7 @@ "id": 4654 }, { - "text": "Some people thought we were at war with the Germans - incorrect. We were at war with the clock. Britain was literally starving to death. The Americans sent over 100,000 pounds of food each week, and every week the Germans would send our desperately needed bread to the bottom of the ocean. Our daily failure was announced at the chimes of midnight. And the sound would haunt our unwelcome dreams.", + "text": "Some people thought we were at war with the Germans - incorrect. We were at war with the clock. Britain was literally starving to death. The Americans sent over 100,000 pounds of food each week, and every week the Germans would send our desperately needed bread to the bottom of the ocean. Our daily failure was announced at the chimes of midnight. And the sound would haunt our unwelcome dreams.", "source": "The Imitation Game", "id": 4655 }, @@ -23324,7 +23324,7 @@ "id": 4665 }, { - "text": "And as the Strangefolk mined deeper and deeper into the mountain, holes began to appear. Bringing with them a cold and bitter wind that chilled the very soul of the Monkey. For the first time, the Happyfolk felt fearful, for they knew the Monkey would soon stir from its deep sleep. And then came a sound, distant first. It grew into castrophany, so immense it could be heard far away in space. There were no screams, there was no time. The mountain called Monkey had spoken, there was only fire. And then, nothing.", + "text": "And as the Strangefolk mined deeper and deeper into the mountain, holes began to appear. Bringing with them a cold and bitter wind that chilled the very soul of the Monkey. For the first time, the Happyfolk felt fearful, for they knew the Monkey would soon stir from its deep sleep. And then came a sound, distant first. It grew into castrophany, so immense it could be heard far away in space. There were no screams, there was no time. The mountain called Monkey had spoken, there was only fire. And then, nothing.", "source": "Fire Coming Out of the Monkey's Head", "id": 4666 }, @@ -23464,7 +23464,7 @@ "id": 4693 }, { - "text": "In order to become an elf I filled out ten pages' worth of forms, took a multiple choice personality test, underwent two interviews and a drug test. The first interview was general, designed to eliminate obvious sociopaths. During the second interview we were asked why we wanted to be elves.", + "text": "In order to become an elf I filled out ten pages' worth of forms, took a multiple choice personality test, underwent two interviews and a drug test. The first interview was general, designed to eliminate obvious sociopaths. During the second interview we were asked why we wanted to be elves.", "source": "Holidays on Ice", "id": 4694 }, @@ -23664,7 +23664,7 @@ "id": 4733 }, { - "text": "The only message I got was from the company that holds my student loan, Sallie Mae. Sallie Mae sounds like a naive and barefoot hillbilly girl but in fact they are a ruthless and aggressive conglomeration of bullies located in a tall brick building somewhere in Kansas. I picture it to be the tallest building in that state and I have decided they hire their employees straight out of prison.", + "text": "The only message I got was from the company that holds my student loan, Sallie Mae. Sallie Mae sounds like a naive and barefoot hillbilly girl but in fact they are a ruthless and aggressive conglomeration of bullies located in a tall brick building somewhere in Kansas. I picture it to be the tallest building in that state and I have decided they hire their employees straight out of prison.", "source": "Holidays on Ice", "id": 4734 }, @@ -23724,7 +23724,7 @@ "id": 4745 }, { - "text": "The treatment of atoms with more than one electron requires consideration of the effects of interelectronic repulsion, orbital penetration towards the nuclear shielding, and an extra quantum number which specifies the intrinsic energy of the electron in any orbital. All these considerations are necessary to allow construction of the modern form of the periodic classification of the elements.", + "text": "The treatment of atoms with more than one electron requires consideration of the effects of interelectronic repulsion, orbital penetration towards the nuclear shielding, and an extra quantum number which specifies the intrinsic energy of the electron in any orbital. All these considerations are necessary to allow construction of the modern form of the periodic classification of the elements.", "source": "Structure and Bonding (Basic Concepts in Chemistry)", "id": 4746 }, @@ -23784,7 +23784,7 @@ "id": 4757 }, { - "text": "The world of typing has changed. In the 1970s, every business had rooms full of secretaries whose job it was to type letters that had been hand-written. They were copying the writing into a more readable format. In the early 1980s, the personal computer became a common office machine.", + "text": "The world of typing has changed. In the 1970s, every business had rooms full of secretaries whose job it was to type letters that had been hand-written. They were copying the writing into a more readable format. In the early 1980s, the personal computer became a common office machine.", "source": "Keyboarding Made Simple (1985)", "id": 4758 }, @@ -23979,7 +23979,7 @@ "id": 4796 }, { - "text": "Milt, with the excellent timing of a master comedy writer, waited until the guns were loaded and the noose was knotted before he turned back to the class. First, he repeated himself. \"There is no such thing as writer's block.\" Then he went on, \"There is only failure to make a decision.\"", + "text": "Milt, with the excellent timing of a master comedy writer, waited until the guns were loaded and the noose was knotted before he turned back to the class. First, he repeated himself. \"There is no such thing as writer's block.\" Then he went on, \"There is only failure to make a decision.\"", "source": "UnTechnical Writing", "id": 4797 }, @@ -24034,7 +24034,7 @@ "id": 4807 }, { - "text": "Zigzagging back and forth through history this way can make you dizzy - you can get vertigo from moving through time as well as space - but it's a lovely disorientation.", + "text": "Zigzagging back and forth through history this way can make you dizzy - you can get vertigo from moving through time as well as space - but it's a lovely disorientation.", "source": "Hamilton: the Revolution", "id": 4808 }, @@ -24044,7 +24044,7 @@ "id": 4809 }, { - "text": "The day dawned bleak and chill, a moving wall of gray light out of the northeast which, instead of dissolving into moisture, seemed to disintegrate into minute and venomous particles, like dust that, when Dilsey opened the door of the cabin and emerged, needled laterally into her flesh, precipitating not so much a moisture as a substance partaking of the quality of thin, not quite congealed oil.", + "text": "The day dawned bleak and chill, a moving wall of gray light out of the northeast which, instead of dissolving into moisture, seemed to disintegrate into minute and venomous particles, like dust that, when Dilsey opened the door of the cabin and emerged, needled laterally into her flesh, precipitating not so much a moisture as a substance partaking of the quality of thin, not quite congealed oil.", "source": "The Sound and the Fury", "id": 4810 }, From 847ad91d155ba6c8d27a483d012f15b468443a62 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:35:47 +0100 Subject: [PATCH 053/123] missing _ --- public/themes/list.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/themes/list.json b/public/themes/list.json index 4ec74a359..f9af77918 100644 --- a/public/themes/list.json +++ b/public/themes/list.json @@ -244,7 +244,7 @@ "textColor": "#0c100e" }, { - "name": "red dragon", + "name": "red_dragon", "bgColor": "#1a0b0c", "textColor": "#ff3a32" } From bb08a51d5b5a8a2c82b9d1d63d8acf40ac460fdb Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:36:45 +0100 Subject: [PATCH 054/123] updated dualshot bg color --- public/themes/list.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/themes/list.json b/public/themes/list.json index f9af77918..7ed68ceda 100644 --- a/public/themes/list.json +++ b/public/themes/list.json @@ -225,7 +225,7 @@ }, { "name": "dualshot", - "bgColor": "#2d2e30", + "bgColor": "#737373", "textColor": "#212222" }, { From 8ba908b17651250702be76a659490abdf7d4e596 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:41:06 +0100 Subject: [PATCH 055/123] fixed timer not showing up --- public/js/script.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 7f4ff2e5f..9e53a8a83 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -567,14 +567,14 @@ function highlightBadWord(index, showError) { function showTimer() { if (!config.showTimerBar) return; if (config.timerStyle === "bar") { - $("#timerWrapper").removeClass("hidden").animate( + $("#timerWrapper").stop(true, true).removeClass("hidden").animate( { opacity: 1, }, 250 ); } else if (config.timerStyle === "text" && config.mode === "time") { - $("#timerNumber").removeClass("hidden").animate( + $("#timerNumber").stop(true, true).removeClass("hidden").animate( { opacity: 0.25, }, @@ -585,14 +585,14 @@ function showTimer() { function hideTimer() { if (config.timerStyle === "bar") { - $("#timerWrapper").animate( + $("#timerWrapper").stop(true, true).animate( { opacity: 0, }, 125 ); } else if (config.timerStyle === "text") { - $("#timerNumber").animate( + $("#timerNumber").stop(true, true).animate( { opacity: 0, }, From 6913724687ab305a389a28c7a228646d3846f932 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 00:58:03 +0100 Subject: [PATCH 056/123] 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 057/123] 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 c5365be41e236fbb2120e52d23746adaeac841e3 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 10:14:18 +0100 Subject: [PATCH 058/123] removed replace --- public/js/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/script.js b/public/js/script.js index 9e53a8a83..ce5055846 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -303,7 +303,7 @@ function initWords() { } } else if (config.mode == "quote") { randomQuote = quotes[Math.floor(Math.random() * quotes.length)]; - let w = randomQuote.text.split(" ").replace(" ", " "); + let w = randomQuote.text.split(" "); for (let i = 0; i < w.length; i++) { wordsList.push(w[i]); } From 8ce94846659938e3685a46821fe82e14431cbc08 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 17:16:44 +0100 Subject: [PATCH 059/123] moved button tooltips down --- public/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index fa7c038e6..fa1d88dd3 100644 --- a/public/index.html +++ b/public/index.html @@ -242,14 +242,14 @@
123
-
From 1eff3973a0e68cc5b92bef1d86331a2578306778 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 19:40:52 +0100 Subject: [PATCH 060/123] 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 16e2db9353f50d0bc3c05e06a9c27df17f8fd02d Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 21:01:39 +0100 Subject: [PATCH 061/123] added Hammerhead --- public/themes/hammerhead.css | 11 +++++++++++ public/themes/list.json | 5 +++++ 2 files changed, 16 insertions(+) create mode 100644 public/themes/hammerhead.css diff --git a/public/themes/hammerhead.css b/public/themes/hammerhead.css new file mode 100644 index 000000000..16dd8fcb3 --- /dev/null +++ b/public/themes/hammerhead.css @@ -0,0 +1,11 @@ +:root { + --bg-color: #030613; + --main-color: #4fcdb9; + --caret-color: #4fcdb9; + --sub-color: #1e283a; + --text-color: #e2f1f5; + --error-color: #e32b2b; + --error-extra-color: #A62626; + --colorful-error-color: #e32b2b; + --colorful-error-extra-color: #A62626; +} \ No newline at end of file diff --git a/public/themes/list.json b/public/themes/list.json index 7ed68ceda..7f8101619 100644 --- a/public/themes/list.json +++ b/public/themes/list.json @@ -247,5 +247,10 @@ "name": "red_dragon", "bgColor": "#1a0b0c", "textColor": "#ff3a32" + }, + { + "name": "hammerhead", + "bgColor": "#030613", + "textColor": "#4fcdb9" } ] \ No newline at end of file From 29df39aa379d1044ed96cbe1029d1786c5f51904 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 6 Jul 2020 22:28:04 +0100 Subject: [PATCH 062/123] 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 063/123] 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 064/123] 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 065/123] 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 ffa4123648992cde356c983f9426902bb5b82fd7 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 13:26:52 +0100 Subject: [PATCH 066/123] making sure to initalise firestore once --- functions/index.js | 54 ++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/functions/index.js b/functions/index.js index 6579c6a80..4df888099 100644 --- a/functions/index.js +++ b/functions/index.js @@ -7,6 +7,8 @@ if (process.env.GCLOUD_PROJECT === "monkey-type") { key = "./serviceAccountKey_live.json"; } +const db = admin.firestore(); + var serviceAccount = require(key); admin.initializeApp({ @@ -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}`); } }); @@ -220,8 +214,7 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( ); function checkIfPB(uid, obj) { - return admin - .firestore() + return db .collection(`users`) .doc(uid) .get() @@ -233,8 +226,7 @@ function checkIfPB(uid, obj) { throw new Error("pb is undefined"); } } catch (e) { - return admin - .firestore() + return db .collection("users") .doc(uid) .update({ @@ -255,8 +247,7 @@ function checkIfPB(uid, obj) { return true; }) .catch((e) => { - return admin - .firestore() + return db .collection("users") .doc(uid) .set({ @@ -326,8 +317,7 @@ function checkIfPB(uid, obj) { } if (toUpdate) { - return admin - .firestore() + return db .collection("users") .doc(uid) .update({ personalBests: pbs }) @@ -373,8 +363,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { return -1; } - return admin - .firestore() + return db .collection(`users/${request.uid}/results`) .add(obj) .then((e) => { @@ -417,8 +406,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, @@ -448,8 +436,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({ @@ -476,8 +463,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() @@ -506,8 +492,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({ @@ -578,8 +563,7 @@ exports.saveConfig = functions.https.onCall((request, response) => { return -1; } - return admin - .firestore() + return db .collection(`users`) .doc(request.uid) .set( @@ -603,6 +587,14 @@ exports.saveConfig = functions.https.onCall((request, response) => { } }); +exports.generateDiscordCode = functions.https.onCall((request, response) => { + db.collection("users") + .get() + .then((res) => { + console.log(res.docs[0].data()); + }); +}); + // exports.getConfig = functions.https.onCall((request,response) => { // try{ // if(request.uid === undefined){ From 44f7dc1808269ed3c70e9cdda9f69ff10dee8186 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 13:28:01 +0100 Subject: [PATCH 067/123] initialised firestore too early --- functions/index.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/functions/index.js b/functions/index.js index 4df888099..75643806b 100644 --- a/functions/index.js +++ b/functions/index.js @@ -7,20 +7,13 @@ if (process.env.GCLOUD_PROJECT === "monkey-type") { key = "./serviceAccountKey_live.json"; } -const db = admin.firestore(); - var serviceAccount = require(key); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), }); -// // Create and Deploy Your First Cloud Functions -// // https://firebase.google.com/docs/functions/write-firebase-functions -// -// exports.helloWorld = functions.https.onRequest((request, response) => { -// response.send("Hello from Firebase!"); -// }); +const db = admin.firestore(); exports.moveResults = functions .runWith({ timeoutSeconds: 540, memory: "2GB" }) From f6fc41b8ed36cc0c8201a21773fd7cfaca6afbbe Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 13:50:24 +0100 Subject: [PATCH 068/123] added a function to generate a discord pairing code --- functions/index.js | 105 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 6 deletions(-) diff --git a/functions/index.js b/functions/index.js index 75643806b..b3d5ec171 100644 --- a/functions/index.js +++ b/functions/index.js @@ -580,12 +580,105 @@ exports.saveConfig = functions.https.onCall((request, response) => { } }); -exports.generateDiscordCode = functions.https.onCall((request, response) => { - db.collection("users") - .get() - .then((res) => { - console.log(res.docs[0].data()); - }); +function generate(n) { + var add = 1, + max = 12 - add; + + if (n > max) { + return generate(max) + generate(n - max); + } + + max = Math.pow(10, n + add); + var min = max / 10; // Math.pow(10, n) basically + var number = Math.floor(Math.random() * (max - min + 1)) + min; + + return ("" + number).substring(add); +} + +exports.generatePairingCode = functions.https.onCall((request, response) => { + try { + if (request === null) { + console.error( + `error while trying to generate discord pairing code - no input` + ); + return { + status: -999, + }; + } + + return db + .collection("users") + .doc(request.uid) + .get() + .then((userDoc) => { + userDocData = userDoc.data(); + if (userDocData.discordPairingCode !== undefined) { + console.log( + `user ${request.uid} already has code ${userDocData.discordPairingCode}` + ); + return { + status: 2, + pairingCode: userDocData.discordPairingCode, + }; + } else { + return db + .collection("users") + .get() + .then((res) => { + let existingCodes = []; + + res.docs.forEach((doc) => { + let docData = doc.data(); + if (docData.discordPairingCode !== undefined) { + existingCodes.push(docData.discordPairingCode); + } + }); + + console.log(`existing codes ${JSON.stringify(existingCodes)}`); + + let randomCode = generate(9); + + while (existingCodes.includes(randomCode)) { + randomCode = generate(9); + } + + return db + .collection("users") + .doc(request.uid) + .update( + { + discordPairingCode: randomCode, + }, + { merge: true } + ) + .then((res) => { + console.log( + `generated ${randomCode} for user ${request.uid}` + ); + return { + status: 1, + pairingCode: randomCode, + }; + }) + .catch((e) => { + console.error( + `error while trying to set discord pairing code ${randomCode} for user ${request.uid} - ${e}` + ); + return { + status: -999, + }; + }); + }); + } + }); + } catch (e) { + console.error( + `error while trying to generate discord pairing code for user ${request.uid} - ${e}` + ); + return { + status: -999, + }; + } }); // exports.getConfig = functions.https.onCall((request,response) => { From 5e83f01e25009e445b2be1a04fc2cb7a2cdbb601 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 16:39:10 +0100 Subject: [PATCH 069/123] sending a command to the bot if the user got a pb --- functions/index.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/functions/index.js b/functions/index.js index b3d5ec171..3b777346b 100644 --- a/functions/index.js +++ b/functions/index.js @@ -367,6 +367,12 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj )}` ); + if (obj.mode === "time" && String(obj.mode2) === "60") { + console.log( + `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` + ); + updateDiscordRole(obj.discordId, obj.wpm); + } return 2; } else { console.log( @@ -388,6 +394,15 @@ exports.testCompleted = functions.https.onCall((request, response) => { } }); +function updateDiscordRole(discordId, wpm) { + db.collection("bot-commands").add({ + command: "updateRole", + arguments: [discordId, wpm], + executed: false, + requestTimestamp: Date.now(), + }); +} + function isTagValid(name) { if (name === null || name === undefined || name === "") return false; if (name.length > 16) return false; From b0939c4d4db788c0320a8e7006099d8a4d431aad Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 16:39:48 +0100 Subject: [PATCH 070/123] added a discord integration section to the settings page --- public/css/style.scss | 27 +++++++++++++++ public/index.html | 21 ++++++++++++ public/js/account.js | 1 + public/js/db.js | 11 ++++--- public/js/script.js | 4 +++ public/js/settings.js | 77 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 137 insertions(+), 4 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 7d91543dd..0afb06322 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -1333,6 +1333,33 @@ key { grid-area: buttons; } + &.discordIntegration { + .code { + justify-content: center; + display: grid; + + .top { + font-size: 1rem; + line-height: 1rem; + color: var(--sub-color); + } + + .bottom { + font-size: 2rem; + line-height: 2rem; + } + } + + .info { + text-align: center; + } + + .howto { + margin-top: 1rem; + color: var(--text-color); + } + } + &.tags { .tagsList { display: grid; diff --git a/public/index.html b/public/index.html index fa1d88dd3..f2b743641 100644 --- a/public/index.html +++ b/public/index.html @@ -382,6 +382,27 @@
+
+

discord integration

+
When you connect your monkey-type account to your Discord account, you will be automatically + assigned a new role every time you achieve a new personal best in a 60 second test. +
+
+
Generate pairing code
+
+ + +

layout override

diff --git a/public/js/account.js b/public/js/account.js index 671cb22b2..bb49c3c9d 100644 --- a/public/js/account.js +++ b/public/js/account.js @@ -204,6 +204,7 @@ firebase.auth().onAuthStateChanged(function (user) { } }); refreshTagsSettingsSection(); + updateDiscordSettingsSection(); if (cookieConfig === null) { applyConfig(dbSnapshot.config); // showNotification('Applying db config',3000); diff --git a/public/js/db.js b/public/js/db.js index f1971e8ac..2584a3695 100644 --- a/public/js/db.js +++ b/public/js/db.js @@ -47,13 +47,16 @@ async function db_getUserSnapshot() { .collection("users") .doc(user.uid) .get() - .then((data) => { + .then((res) => { // console.log('getting data from db!'); + let data = res.data(); try { - if (data.data().personalBests !== undefined) { - snap.personalBests = data.data().personalBests; + if (data.personalBests !== undefined) { + snap.personalBests = data.personalBests; } - snap.config = data.data().config; + snap.discordId = data.discordId; + snap.pairingCode = data.discordPairingCode; + snap.config = data.config; } catch (e) { // } diff --git a/public/js/script.js b/public/js/script.js index ce5055846..f5f6ec33c 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -38,6 +38,9 @@ const editTag = firebase.functions().httpsCallable("editTag"); const removeTag = firebase.functions().httpsCallable("removeTag"); const updateResultTags = firebase.functions().httpsCallable("updateResultTags"); const saveConfig = firebase.functions().httpsCallable("saveConfig"); +const generatePairingCode = firebase + .functions() + .httpsCallable("generatePairingCode"); function smooth(arr, windowSize, getter = (value) => value, setter) { const get = getter; @@ -1005,6 +1008,7 @@ function showResult(difficultyFailed = false) { blindMode: config.blindMode, theme: config.theme, tags: activeTags, + discordId: dbSnapshot.discordId, }; if ( config.difficulty == "normal" || diff --git a/public/js/settings.js b/public/js/settings.js index 92bc9d4d2..cee666670 100644 --- a/public/js/settings.js +++ b/public/js/settings.js @@ -60,6 +60,8 @@ function updateSettingsPage() { setActiveThemeTab(); setCustomThemeInputs(); + updateDiscordSettingsSection(); + if (config.showKeyTips) { $(".pageSettings .tip").removeClass("hidden"); } else { @@ -246,6 +248,61 @@ function toggleTag(tagid, nosave = false) { if (!nosave) saveActiveTagsToCookie(); } +function updateDiscordSettingsSection() { + //no code and no discord + if (firebase.auth().currentUser == null) { + $(".pageSettings .section.discordIntegration").addClass("hidden"); + } else { + $(".pageSettings .section.discordIntegration").removeClass("hidden"); + + if ( + dbSnapshot.pairingCode === undefined && + dbSnapshot.discordId === undefined + ) { + //show button + $(".pageSettings .section.discordIntegration .howto").addClass("hidden"); + $(".pageSettings .section.discordIntegration .buttons").removeClass( + "hidden" + ); + $(".pageSettings .section.discordIntegration .info").addClass("hidden"); + $(".pageSettings .section.discordIntegration .code").addClass("hidden"); + } else if ( + dbSnapshot.pairingCode !== undefined && + dbSnapshot.discordId === undefined + ) { + //show code + $(".pageSettings .section.discordIntegration .code .bottom").text( + dbSnapshot.pairingCode + ); + $(".pageSettings .section.discordIntegration .howtocode").text( + dbSnapshot.pairingCode + ); + $(".pageSettings .section.discordIntegration .howto").removeClass( + "hidden" + ); + $(".pageSettings .section.discordIntegration .buttons").addClass( + "hidden" + ); + $(".pageSettings .section.discordIntegration .info").addClass("hidden"); + $(".pageSettings .section.discordIntegration .code").removeClass( + "hidden" + ); + } else if ( + dbSnapshot.pairingCode !== undefined && + dbSnapshot.discordId !== undefined + ) { + $(".pageSettings .section.discordIntegration .howto").addClass("hidden"); + $(".pageSettings .section.discordIntegration .buttons").addClass( + "hidden" + ); + $(".pageSettings .section.discordIntegration .info").removeClass( + "hidden" + ); + $(".pageSettings .section.discordIntegration .code").addClass("hidden"); + } + } +} + //smooth caret $(".pageSettings .section.smoothCaret .buttons .button.on").click((e) => { setSmoothCaret(true); @@ -489,6 +546,26 @@ $(".pageSettings .section.randomTheme .buttons .button.off").click((e) => { setSettingsButton("randomTheme", config.randomTheme); }); +//discord +$( + ".pageSettings .section.discordIntegration .buttons .generateCodeButton" +).click((e) => { + showBackgroundLoader(); + generatePairingCode({ uid: firebase.auth().currentUser.uid }).then((ret) => { + hideBackgroundLoader(); + if (ret.data.status === 1 || ret.data.status === 2) { + dbSnapshot.pairingCode = ret.data.pairingCode; + $(".pageSettings .section.discordIntegration .code .bottom").text( + ret.data.pairingCode + ); + $(".pageSettings .section.discordIntegration .howtocode").text( + ret.data.pairingCode + ); + updateDiscordSettingsSection(); + } + }); +}); + //tags $(document).on( "click", From 0a452ba2f9a0a0832f896f30164cd9fe18764d05 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 18:38:41 +0100 Subject: [PATCH 071/123] cache --- public/index.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/public/index.html b/public/index.html index f2b743641..935fa3174 100644 --- a/public/index.html +++ b/public/index.html @@ -845,17 +845,17 @@ - + - - - - - - - - + + + + + + + + \ No newline at end of file From 2f48de8759d2abe4ccef0a189dc4806585239fa5 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 19:14:49 +0100 Subject: [PATCH 072/123] showing decimals on acocunt page --- public/js/account.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/js/account.js b/public/js/account.js index bb49c3c9d..da5f67b86 100644 --- a/public/js/account.js +++ b/public/js/account.js @@ -651,9 +651,9 @@ function loadMoreLines() { $(".pageAccount .history table tbody").append(`
- - - + + + From 2e4761fa5e0208adaa253f45b99a01e332bb1e5d Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 19:14:58 +0100 Subject: [PATCH 073/123] updated gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 570edfeaa..863580d68 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,4 @@ functions/serviceAccountKey_live.json .firebaserc .firebaserc_copy functions/serviceAccountKey_copy.json +functions/serviceAccountKey_live_copy.json From c2bde75103db8e8c314db95868abe9767a1e6e3e Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 19:28:09 +0100 Subject: [PATCH 074/123] made sure not to send the command to the bot if the discordid is undefined --- functions/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 3b777346b..262f2aef0 100644 --- a/functions/index.js +++ b/functions/index.js @@ -367,7 +367,12 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj )}` ); - if (obj.mode === "time" && String(obj.mode2) === "60") { + if ( + obj.mode === "time" && + String(obj.mode2) === "60" && + obj.discordId !== null && + obj.discordId !== undefined + ) { console.log( `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` ); From 269e1857c8e41a4fc74a7b2f60625bfbe681d890 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 19:47:46 +0100 Subject: [PATCH 075/123] fixed a bug where users that are not logged in would be punished, and the test would break. sorry --- public/js/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/script.js b/public/js/script.js index f5f6ec33c..e46df5798 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1008,7 +1008,7 @@ function showResult(difficultyFailed = false) { blindMode: config.blindMode, theme: config.theme, tags: activeTags, - discordId: dbSnapshot.discordId, + discordId: dbSnapshot !== null ? dbSnapshot.discordId : null, }; if ( config.difficulty == "normal" || From 95729dc08aeda402f4e1e2e92bdace9140e095e0 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 19:48:00 +0100 Subject: [PATCH 076/123] cache --- public/index.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/public/index.html b/public/index.html index 935fa3174..e03fced42 100644 --- a/public/index.html +++ b/public/index.html @@ -845,17 +845,17 @@ - + - - - - - - - - + + + + + + + + \ No newline at end of file From bc4ea7baf44ae41abc312853a14bf5a928291dd9 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 20:14:28 +0100 Subject: [PATCH 077/123] avoiding unnecessary error when showing discord settings section --- public/js/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/js/settings.js b/public/js/settings.js index cee666670..601ffd80b 100644 --- a/public/js/settings.js +++ b/public/js/settings.js @@ -253,6 +253,7 @@ function updateDiscordSettingsSection() { if (firebase.auth().currentUser == null) { $(".pageSettings .section.discordIntegration").addClass("hidden"); } else { + if (dbSnapshot == null) return; $(".pageSettings .section.discordIntegration").removeClass("hidden"); if ( From 4925224b0faaaa154c41d27b29a06668d6f1fea7 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 20:30:39 +0100 Subject: [PATCH 078/123] fix for a bug where the role would get overwritten --- functions/index.js | 31 +++++++++++++++++++++---------- public/js/script.js | 1 - 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/functions/index.js b/functions/index.js index 262f2aef0..f6a5f9b03 100644 --- a/functions/index.js +++ b/functions/index.js @@ -367,16 +367,27 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj )}` ); - if ( - obj.mode === "time" && - String(obj.mode2) === "60" && - obj.discordId !== null && - obj.discordId !== undefined - ) { - console.log( - `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` - ); - updateDiscordRole(obj.discordId, obj.wpm); + if (obj.mode === "time" && String(obj.mode2) === "60") { + db.collection("users") + .doc(request.uid) + .get() + .then((ret) => { + let userdata = ret.data(); + + let besttime60 = 0; + try { + dbSnapshot.personalBests.time[60].forEach((result) => { + if (result.wpm > besttime60) besttime60 = result.wpm; + }); + } catch (e) {} + + if (obj.wpm > besttime60) { + console.log( + `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` + ); + updateDiscordRole(userdata.discordId, obj.wpm); + } + }); } return 2; } else { diff --git a/public/js/script.js b/public/js/script.js index e46df5798..d614d187f 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1008,7 +1008,6 @@ function showResult(difficultyFailed = false) { blindMode: config.blindMode, theme: config.theme, tags: activeTags, - discordId: dbSnapshot !== null ? dbSnapshot.discordId : null, }; if ( config.difficulty == "normal" || From 94ad2175df89f6e8ae912b58c865f954161d8dc8 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 20:42:26 +0100 Subject: [PATCH 079/123] fixed the fix >:| --- functions/index.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/functions/index.js b/functions/index.js index f6a5f9b03..a857aad13 100644 --- a/functions/index.js +++ b/functions/index.js @@ -376,10 +376,16 @@ exports.testCompleted = functions.https.onCall((request, response) => { let besttime60 = 0; try { - dbSnapshot.personalBests.time[60].forEach((result) => { + userdata.personalBests.time[60].forEach((result) => { if (result.wpm > besttime60) besttime60 = result.wpm; }); - } catch (e) {} + } catch (e) { + besttime60 = 0; + console.log("caught"); + } + + console.log(besttime60); + console.log(obj.wpm); if (obj.wpm > besttime60) { console.log( @@ -387,6 +393,13 @@ exports.testCompleted = functions.https.onCall((request, response) => { ); updateDiscordRole(userdata.discordId, obj.wpm); } + return; + }) + .catch((e) => { + console.error( + `error saving result when getting user info ${request.uid} - ${e.message}` + ); + return -1; }); } return 2; From 7137c18371fadb1176fdc827ac747efffc2cebab Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:12:24 +0100 Subject: [PATCH 080/123] removed logs --- functions/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/functions/index.js b/functions/index.js index a857aad13..7246c5ad4 100644 --- a/functions/index.js +++ b/functions/index.js @@ -381,12 +381,8 @@ exports.testCompleted = functions.https.onCall((request, response) => { }); } catch (e) { besttime60 = 0; - console.log("caught"); } - console.log(besttime60); - console.log(obj.wpm); - if (obj.wpm > besttime60) { console.log( `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` From 13bb3e71e93a64f4b3593865feffa0c9aa281c6b Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:12:28 +0100 Subject: [PATCH 081/123] updated bot name --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index e03fced42..5014d71ad 100644 --- a/public/index.html +++ b/public/index.html @@ -387,7 +387,7 @@
When you connect your monkey-type account to your Discord account, you will be automatically assigned a new role every time you achieve a new personal best in a 60 second test.
From f64eb7ce9af821e5bc94c00d55adaba811a71310 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:15:48 +0100 Subject: [PATCH 082/123] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a7fc0ef63..1c5b7a57b 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ You can use `tab` and `enter` (or just `tab` if you have quick tab mode enabled) - acc - percentage of correctly pressed keys - key - correct characters / incorrect characters. Calculated after the test has ended +# discord bot +Recently, a Discord bot was added to autoassign roles. You can find the code for it over at https://github.com/Miodec/monkey-bot + # bug report or feature request If you encounter a bug, or have a feature request - send me a message on Reddit, create an issue on GitHub or send me a message using the command line `esc`. From 41b8d778e9975a7d6c4505362cf45fd75f2bfc3c Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:20:31 +0100 Subject: [PATCH 083/123] typo --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 5014d71ad..9d5dc7940 100644 --- a/public/index.html +++ b/public/index.html @@ -387,7 +387,7 @@
When you connect your monkey-type account to your Discord account, you will be automatically assigned a new role every time you achieve a new personal best in a 60 second test.
From 3f3058e023f423c42418a7018ce0c7f1545c9003 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:44:03 +0100 Subject: [PATCH 084/123] fixed bot not giving roles --- functions/index.js | 69 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/functions/index.js b/functions/index.js index 7246c5ad4..c1933eb72 100644 --- a/functions/index.js +++ b/functions/index.js @@ -356,24 +356,23 @@ exports.testCompleted = functions.https.onCall((request, response) => { return -1; } - return db - .collection(`users/${request.uid}/results`) - .add(obj) - .then((e) => { - return checkIfPB(request.uid, request.obj).then((e) => { - if (e) { - console.log( - `saved result for ${request.uid} (new PB) - ${JSON.stringify( - request.obj - )}` - ); - if (obj.mode === "time" && String(obj.mode2) === "60") { - db.collection("users") - .doc(request.uid) - .get() - .then((ret) => { - let userdata = ret.data(); - + db.collection("users") + .doc(request.uid) + .get() + .then((ret) => { + let userdata = ret.data(); + return db + .collection(`users/${request.uid}/results`) + .add(obj) + .then((e) => { + return checkIfPB(request.uid, request.obj).then((e) => { + if (e) { + console.log( + `saved result for ${request.uid} (new PB) - ${JSON.stringify( + request.obj + )}` + ); + if (obj.mode === "time" && String(obj.mode2) === "60") { let besttime60 = 0; try { userdata.personalBests.time[60].forEach((result) => { @@ -390,26 +389,28 @@ exports.testCompleted = functions.https.onCall((request, response) => { updateDiscordRole(userdata.discordId, obj.wpm); } return; - }) - .catch((e) => { - console.error( - `error saving result when getting user info ${request.uid} - ${e.message}` - ); - return -1; - }); - } - return 2; - } else { - console.log( - `saved result for ${request.uid} - ${JSON.stringify(request.obj)}` + } + return 2; + } else { + console.log( + `saved result for ${request.uid} - ${JSON.stringify( + request.obj + )}` + ); + return 1; + } + }); + }) + .catch((e) => { + console.error( + `error saving result when checking for PB for ${request.uid} - ${e.message}` ); - return 1; - } - }); + return -1; + }); }) .catch((e) => { console.error( - `error saving result when checking for PB for ${request.uid} - ${e.message}` + `error saving result when getting user info ${request.uid} - ${e.message}` ); return -1; }); From 0ec199ce0352a282582bfd76698dd1cc14dfe18b Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:46:39 +0100 Subject: [PATCH 085/123] missing = --- functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index c1933eb72..697618c54 100644 --- a/functions/index.js +++ b/functions/index.js @@ -382,7 +382,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { besttime60 = 0; } - if (obj.wpm > besttime60) { + if (obj.wpm >= besttime60) { console.log( `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` ); From 50c441bee5a4744ab68d25037d341fe73196177c Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Jul 2020 21:47:51 +0100 Subject: [PATCH 086/123] missing null/undefined checks --- functions/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 697618c54..3a4944847 100644 --- a/functions/index.js +++ b/functions/index.js @@ -372,7 +372,12 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj )}` ); - if (obj.mode === "time" && String(obj.mode2) === "60") { + if ( + obj.mode === "time" && + String(obj.mode2) === "60" && + userdata.discordId !== null && + userdata.discordId !== undefined + ) { let besttime60 = 0; try { userdata.personalBests.time[60].forEach((result) => { From 2d69b78ee244f878ed6a860891e4aa4a2ae1ae39 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 8 Jul 2020 00:14:03 +0100 Subject: [PATCH 087/123] 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 088/123] 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 f18c232f161d6a25d64de6312afae3d90580c39f Mon Sep 17 00:00:00 2001 From: HyperAMIR Date: Wed, 8 Jul 2020 10:00:31 +0430 Subject: [PATCH 089/123] fixed issue #177 --- public/css/style.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 0afb06322..76ee8517b 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -1200,7 +1200,8 @@ key { cursor: pointer; width: 0; height: 0; - + display: none; + &~.customCheckbox { width: 12px; height: 12px; @@ -1802,4 +1803,4 @@ key { border: none; outline: none; } -} \ No newline at end of file +} From f31aa801021c9a86a663c51ec9bf0d7ac6d83a10 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 8 Jul 2020 16:32:22 +0100 Subject: [PATCH 090/123] fixed a bug that would cause the pb object to not be saved correctly --- functions/index.js | 6 +++++- public/js/db.js | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 3a4944847..a01c56886 100644 --- a/functions/index.js +++ b/functions/index.js @@ -267,6 +267,9 @@ function checkIfPB(uid, obj) { let toUpdate = false; let found = false; try { + if (pbs[obj.mode][obj.mode2] === undefined) { + pbs[obj.mode][obj.mode2] = []; + } pbs[obj.mode][obj.mode2].forEach((pb) => { if ( pb.punctuation === obj.punctuation && @@ -356,7 +359,8 @@ exports.testCompleted = functions.https.onCall((request, response) => { return -1; } - db.collection("users") + return db + .collection("users") .doc(request.uid) .get() .then((ret) => { diff --git a/public/js/db.js b/public/js/db.js index 2584a3695..653a2a325 100644 --- a/public/js/db.js +++ b/public/js/db.js @@ -142,6 +142,9 @@ async function db_saveLocalPB( function cont() { try { let found = false; + if (dbSnapshot.personalBests[mode][mode2] === undefined) { + dbSnapshot.personalBests[mode][mode2] = []; + } dbSnapshot.personalBests[mode][mode2].forEach((pb) => { if ( pb.punctuation == punctuation && From 4b480767eb91195f7ae85efa0820bd02241502fc Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 01:34:17 +0100 Subject: [PATCH 091/123] made sure to round up the wpm that is sent to the role bot --- functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index a01c56886..1e42c66e9 100644 --- a/functions/index.js +++ b/functions/index.js @@ -395,7 +395,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { console.log( `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` ); - updateDiscordRole(userdata.discordId, obj.wpm); + updateDiscordRole(userdata.discordId, Math.round(obj.wpm)); } return; } From e50f0cd6603075b9d10d4ce0d45f7b42cd2ca06b Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 01:54:53 +0100 Subject: [PATCH 092/123] added back donation links to the footer and about page --- public/index.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 9d5dc7940..f45a63d0b 100644 --- a/public/index.html +++ b/public/index.html @@ -296,9 +296,8 @@

support

-

If you wish to support this project, help pay for hosting and fuel my caffeine addiction, you can find the - support link in the GitHub's readme.

+

If you wish to support this project, help pay for hosting and fuel my caffeine addiction, you can donate here.

- Contribute to this project on GitHub + Contribute on GitHub +
+
+ Support by donating
version
From acfef5f003ba8c2659068917847746ca2204c2a6 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 01:57:59 +0100 Subject: [PATCH 093/123] added contributors section to the about page --- public/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/index.html b/public/index.html index f45a63d0b..1a11132d1 100644 --- a/public/index.html +++ b/public/index.html @@ -293,6 +293,8 @@ href="https://www.reddit.com/r/MechanicalKeyboards/comments/gc6wx3/experimenting_with_a_completely_new_type_of/" target="_blank">everyone who provided valuable feedback on the original reddit post for the prototype of this website

+

All the contributors on GitHub that + added features, themes and more.

support

From a7ba1a7a0468f1cb6447c2da944b55db6211871e Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 02:00:54 +0100 Subject: [PATCH 094/123] updated about --- public/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/index.html b/public/index.html index 1a11132d1..8b0552822 100644 --- a/public/index.html +++ b/public/index.html @@ -291,10 +291,10 @@

montydrei - name suggestion

everyone who provided + target="_blank">Everyone who provided valuable feedback on the original reddit post for the prototype of this website

-

All the contributors on GitHub that - added features, themes and more.

+

Contributors on GitHub that + have helped with implementing various features, adding themes and more.

support

From 77401ebd2a81f2c83b1d8619092078ed9781553a Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 11:27:16 +0100 Subject: [PATCH 095/123] added a log --- functions/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/functions/index.js b/functions/index.js index 1e42c66e9..ef0bba8e8 100644 --- a/functions/index.js +++ b/functions/index.js @@ -396,6 +396,10 @@ exports.testCompleted = functions.https.onCall((request, response) => { `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` ); updateDiscordRole(userdata.discordId, Math.round(obj.wpm)); + } else { + console.log( + `not updating role for user ${request.uid} higher pb found ${besttime60} than ${obj.wpm}` + ); } return; } From 7801089d91c57512d6740a9c5648be22ebc2841f Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 12:14:00 +0100 Subject: [PATCH 096/123] moved the check to the bot --- functions/index.js | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/functions/index.js b/functions/index.js index ef0bba8e8..caa96bf34 100644 --- a/functions/index.js +++ b/functions/index.js @@ -382,25 +382,10 @@ exports.testCompleted = functions.https.onCall((request, response) => { userdata.discordId !== null && userdata.discordId !== undefined ) { - let besttime60 = 0; - try { - userdata.personalBests.time[60].forEach((result) => { - if (result.wpm > besttime60) besttime60 = result.wpm; - }); - } catch (e) { - besttime60 = 0; - } - - if (obj.wpm >= besttime60) { - console.log( - `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` - ); - updateDiscordRole(userdata.discordId, Math.round(obj.wpm)); - } else { - console.log( - `not updating role for user ${request.uid} higher pb found ${besttime60} than ${obj.wpm}` - ); - } + console.log( + `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` + ); + updateDiscordRole(userdata.discordId, Math.round(obj.wpm)); return; } return 2; From a0c54a77694b5e0cef3e24ffceb038e23a183052 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 14:03:21 +0100 Subject: [PATCH 097/123] added filter for 10k results --- public/js/account.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/js/account.js b/public/js/account.js index da5f67b86..52e639729 100644 --- a/public/js/account.js +++ b/public/js/account.js @@ -397,6 +397,11 @@ Object.keys(words).forEach((language) => { " " )}
` ); + if (language === "english_expanded") { + $(".pageAccount .content .filterButtons .buttons.languages").append( + `
english 10k
` + ); + } }); let activeFilters = ["all"]; From 8565dd233b2e568e83551b72255c7652baaa2ae9 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 14:07:28 +0100 Subject: [PATCH 098/123] potential fix for the freedommode issue --- public/js/userconfig.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/js/userconfig.js b/public/js/userconfig.js index 082f86480..fc8b4e12e 100644 --- a/public/js/userconfig.js +++ b/public/js/userconfig.js @@ -45,6 +45,7 @@ let config = defaultConfig; //cookies function saveConfigToCookie() { // showNotification('saving to cookie',1000); + if (config.freedomMode === null) config.freedomMode = false; let d = new Date(); d.setFullYear(d.getFullYear() + 1); $.cookie("config", null); @@ -424,7 +425,7 @@ function togglePunctuation() { //freedom function setFreedomMode(freedom, nosave) { - if (freedom === null) { + if (freedom == null) { freedom = false; } config.freedomMode = freedom; From 99abbd739985e372654e83c4c838c5076ee09545 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 14:45:47 +0100 Subject: [PATCH 099/123] 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(), + }); +} From f7cd09deb47243125eb37d7f04566cb25721a047 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 15:55:02 +0100 Subject: [PATCH 100/123] added code to announce lb changes --- functions/index.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index ca7cc43ea..988b8ea63 100644 --- a/functions/index.js +++ b/functions/index.js @@ -455,6 +455,31 @@ exports.testCompleted = functions.https.onCall((request, response) => { let ispb = values[2]; // console.log(values); + let usr = + userdata.discordId !== undefined + ? userdata.discordId + : userdata.name; + + if ( + globallb !== null && + [1, 2, 3].includes(globallb.insertedAt + 1) && + globallb.newBest + ) { + let lbstring = `${obj.mode} ${obj.mode2} global`; + console.log( + `sending command to the bot to announce lb update ${ + userdata.discordId + } ${globallb + 1} ${lbstring} ${obj.wpm}` + ); + + announceLbUpdate( + usr, + globallb.insertedAt + 1, + lbstring, + obj.wpm + ); + } + let returnobj = { resultCode: null, globalLeaderboard: globallb, @@ -1201,7 +1226,7 @@ exports.scheduledFunctionCrontab = functions.pubsub async function announceLbUpdate(discordId, pos, lb, wpm) { db.collection("bot-commands").add({ - command: "updateRole", + command: "sayLbUpdate", arguments: [discordId, pos, lb, wpm], executed: false, requestTimestamp: Date.now(), From f07840ed59c3d221d55f914d9adb1777ca9c4ee5 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 15:55:13 +0100 Subject: [PATCH 101/123] prettier doesnt like whitespace --- public/css/style.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index af6f5f488..55bcf6a73 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -1354,7 +1354,7 @@ key { width: 0; height: 0; display: none; - + &~.customCheckbox { width: 12px; height: 12px; @@ -1956,4 +1956,4 @@ key { border: none; outline: none; } -} +} \ No newline at end of file From 684b764731d18d7d215444dcf032387589923ee3 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 16:20:52 +0100 Subject: [PATCH 102/123] leaderboards off for now added a check if cant verify key stats tried a fix for name not saving on lb --- functions/index.js | 74 +++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/functions/index.js b/functions/index.js index 988b8ea63..431fdfa8e 100644 --- a/functions/index.js +++ b/functions/index.js @@ -396,19 +396,27 @@ exports.testCompleted = functions.https.onCall((request, response) => { return -1; } - let keySpacing = { - average: - obj.keySpacing.reduce((previous, current) => (current += previous)) / - obj.keySpacing.length, - sd: stdDev(obj.keySpacing), - }; + let keySpacing = null; + let keyDuration = null; - let keyDuration = { - average: - obj.keyDuration.reduce((previous, current) => (current += previous)) / - obj.keyDuration.length, - sd: stdDev(obj.keyDuration), - }; + try{ + keySpacing = { + average: + obj.keySpacing.reduce((previous, current) => (current += previous)) / + obj.keySpacing.length, + sd: stdDev(obj.keySpacing), + }; + + keyDuration = { + average: + obj.keyDuration.reduce((previous, current) => (current += previous)) / + obj.keyDuration.length, + sd: stdDev(obj.keyDuration), + }; + }catch(){ + console.error(`cant verify key spacing or duration! - ${obj.keySpacing} ${obj.keyDuration}`); + } + return db .collection("users") @@ -425,19 +433,21 @@ exports.testCompleted = functions.https.onCall((request, response) => { //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 - } ${name} - spacing ${JSON.stringify( - keySpacing - )} duration ${JSON.stringify(keyDuration)}` - ); - return { resultCode: -2 }; + if(keySpacing !== null && keyDuration !== null){ + if ( + keySpacing.sd < 15 || + keyDuration.sd < 15 || + keyDuration.average < 15 + ) { + console.error( + `possible bot detected by user ${ + request.uid + } ${name} - spacing ${JSON.stringify( + keySpacing + )} duration ${JSON.stringify(keyDuration)}` + ); + return { resultCode: -2 }; + } } } @@ -534,7 +544,11 @@ exports.testCompleted = functions.https.onCall((request, response) => { return { resultCode: -999 }; }); } catch (e) { - console.error(`error saving result for ${request.uid} - ${e}`); + console.error( + `error saving result for ${request.uid} - ${JSON.stringify( + request.obj + )} - ${e}` + ); return { resultCode: -999 }; } }); @@ -767,6 +781,7 @@ class Leaderboard { if (entry.mode === this.mode && entry.mode2 === this.mode2) { this.board.push({ uid: entry.uid, + name: entry.name, wpm: parseFloat(entry.wpm), raw: parseFloat(entry.raw), acc: parseFloat(entry.acc), @@ -1012,6 +1027,9 @@ exports.generatePairingCode = functions.https.onCall((request, response) => { }); async function checkLeaderboards(resultObj, type, banned, name) { + return { + insertedAt: null, + }; try { if (!name) return { @@ -1124,7 +1142,9 @@ async function checkLeaderboards(resultObj, type, banned, name) { console.error( `error while checking leaderboards - ${e} - ${type} ${resultObj}` ); - return null; + return { + insertedAt: null, + }; } } From 3acf11b11175b5afb0538cc90a7936759dfd5267 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 16:21:10 +0100 Subject: [PATCH 103/123] cache --- public/index.html | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/public/index.html b/public/index.html index 215065fa9..60fd2b858 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ Monkey Type - + @@ -1280,17 +1280,17 @@ - + - - - - - - - - - + + + + + + + + + \ No newline at end of file From f339ac70a18e3f721e5297bb8f797b5778fda126 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 16:21:18 +0100 Subject: [PATCH 104/123] removed unnecessary logs --- public/js/script.js | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 1378c8321..9fe1f10de 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -986,29 +986,6 @@ 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) { From ca033f6e9a62ea75894a99603bb8d2b5e6adf938 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 16:22:00 +0100 Subject: [PATCH 105/123] fixed bug --- functions/index.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/functions/index.js b/functions/index.js index 431fdfa8e..b566e924f 100644 --- a/functions/index.js +++ b/functions/index.js @@ -399,24 +399,25 @@ exports.testCompleted = functions.https.onCall((request, response) => { let keySpacing = null; let keyDuration = null; - try{ + try { keySpacing = { average: obj.keySpacing.reduce((previous, current) => (current += previous)) / obj.keySpacing.length, sd: stdDev(obj.keySpacing), }; - + keyDuration = { average: obj.keyDuration.reduce((previous, current) => (current += previous)) / obj.keyDuration.length, sd: stdDev(obj.keyDuration), }; - }catch(){ - console.error(`cant verify key spacing or duration! - ${obj.keySpacing} ${obj.keyDuration}`); + } catch (e) { + console.error( + `cant verify key spacing or duration! - ${e} - ${obj.keySpacing} ${obj.keyDuration}` + ); } - return db .collection("users") @@ -433,7 +434,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { //check keyspacing and duration here if (!verified) { - if(keySpacing !== null && keyDuration !== null){ + if (keySpacing !== null && keyDuration !== null) { if ( keySpacing.sd < 15 || keyDuration.sd < 15 || From 0b112a5dabeedc4d3147d1b49bf2121ea5c957c4 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 16:52:37 +0100 Subject: [PATCH 106/123] lb live again --- functions/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/index.js b/functions/index.js index b566e924f..9c1345bcc 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1028,9 +1028,9 @@ exports.generatePairingCode = functions.https.onCall((request, response) => { }); async function checkLeaderboards(resultObj, type, banned, name) { - return { - insertedAt: null, - }; + // return { + // insertedAt: null, + // }; try { if (!name) return { From e5816742c184207240fc2403c31eb4b21da31532 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 17:01:40 +0100 Subject: [PATCH 107/123] dont add to lb if cant verify keys --- functions/index.js | 2 ++ public/index.html | 22 +++++++++++----------- public/js/script.js | 10 +++++++++- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/functions/index.js b/functions/index.js index 9c1345bcc..2d4dfc779 100644 --- a/functions/index.js +++ b/functions/index.js @@ -449,6 +449,8 @@ exports.testCompleted = functions.https.onCall((request, response) => { ); return { resultCode: -2 }; } + } else { + return { resultCode: -3 }; } } diff --git a/public/index.html b/public/index.html index 60fd2b858..063222a26 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ Monkey Type - + @@ -1280,17 +1280,17 @@ - + - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/public/js/script.js b/public/js/script.js index 9fe1f10de..77a05a854 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1106,8 +1106,16 @@ function showResult(difficultyFailed = false) { "Possible bot detected. Result not saved.", 4000 ); + } else if (e.data.resultCode === -3) { + showNotification( + "Could not verify. Result not saved. Refresh or contact Miodec on Discord.", + 4000 + ); } else if (e.data.resultCode === -999) { - showNotification("Internal error. Result not saved.", 4000); + showNotification( + "Internal error. Result not saved. Refresh or contact Miodec on Discord.", + 6000 + ); } else if (e.data.resultCode === 1 || e.data.resultCode === 2) { dbSnapshot.results.unshift(completedEvent); try { From a7933f352824293e45285144bf137e8246c9d699 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 17:44:39 +0100 Subject: [PATCH 108/123] better log --- functions/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/index.js b/functions/index.js index 2d4dfc779..e4782c378 100644 --- a/functions/index.js +++ b/functions/index.js @@ -441,9 +441,9 @@ exports.testCompleted = functions.https.onCall((request, response) => { keyDuration.average < 15 ) { console.error( - `possible bot detected by user ${ - request.uid - } ${name} - spacing ${JSON.stringify( + `possible bot detected by user (${obj.wpm} ${obj.raw} ${ + obj.acc + }) ${request.uid} ${name} - spacing ${JSON.stringify( keySpacing )} duration ${JSON.stringify(keyDuration)}` ); From d4cc081250df725590456becc9b0db658c1ca564 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 17:49:17 +0100 Subject: [PATCH 109/123] log update --- functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index e4782c378..4d84b5865 100644 --- a/functions/index.js +++ b/functions/index.js @@ -441,7 +441,7 @@ exports.testCompleted = functions.https.onCall((request, response) => { keyDuration.average < 15 ) { console.error( - `possible bot detected by user (${obj.wpm} ${obj.raw} ${ + `possible bot detected by user (${obj.wpm} ${obj.rawWpm} ${ obj.acc }) ${request.uid} ${name} - spacing ${JSON.stringify( keySpacing From b109c9ec38ad9dcf426913f305be00f65ffaa11d Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 17:58:00 +0100 Subject: [PATCH 110/123] updated log --- functions/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index 4d84b5865..e09bd276f 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1107,7 +1107,9 @@ async function checkLeaderboards(resultObj, type, banned, name) { // console.log("board created"); // lb.logBoard(); - + console.log( + `inserting result by user ${resultObj.uid} ${resultObj.wpm} ${resultObj.rawWpm} ${resultObj.acc} into leaderboard ${resultObj.mode} ${resultObj.mode2} ${type}` + ); let insertResult = lb.insert(resultObj); // console.log("board after inseft"); From 0ca2384695a76b2425c2c9747242d7f1ec1a327b Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 18:29:01 +0100 Subject: [PATCH 111/123] only checking keypress stats if mode is time --- functions/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index e09bd276f..6a9bde47f 100644 --- a/functions/index.js +++ b/functions/index.js @@ -434,7 +434,11 @@ exports.testCompleted = functions.https.onCall((request, response) => { //check keyspacing and duration here if (!verified) { - if (keySpacing !== null && keyDuration !== null) { + if ( + keySpacing !== null && + keyDuration !== null && + obj.mode === "time" + ) { if ( keySpacing.sd < 15 || keyDuration.sd < 15 || From ea43290ca033aa4635e2c133ad1fc8b95c4568d2 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 18:31:25 +0100 Subject: [PATCH 112/123] fixed previous update --- functions/index.js | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/functions/index.js b/functions/index.js index 6a9bde47f..47f7c35bb 100644 --- a/functions/index.js +++ b/functions/index.js @@ -433,28 +433,29 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj.name = name; //check keyspacing and duration here - if (!verified) { - if ( - keySpacing !== null && - keyDuration !== null && - obj.mode === "time" - ) { + if(obj.mode === "time"){ + if (!verified) { if ( - keySpacing.sd < 15 || - keyDuration.sd < 15 || - keyDuration.average < 15 + keySpacing !== null && + keyDuration !== null && ) { - console.error( - `possible bot detected by user (${obj.wpm} ${obj.rawWpm} ${ - obj.acc - }) ${request.uid} ${name} - spacing ${JSON.stringify( - keySpacing - )} duration ${JSON.stringify(keyDuration)}` - ); - return { resultCode: -2 }; + if ( + keySpacing.sd < 15 || + keyDuration.sd < 15 || + keyDuration.average < 15 + ) { + console.error( + `possible bot detected by user (${obj.wpm} ${obj.rawWpm} ${ + obj.acc + }) ${request.uid} ${name} - spacing ${JSON.stringify( + keySpacing + )} duration ${JSON.stringify(keyDuration)}` + ); + return { resultCode: -2 }; + } + } else { + return { resultCode: -3 }; } - } else { - return { resultCode: -3 }; } } From a3129295bc8ee84a860ef61519985eea0c1e7058 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 18:32:54 +0100 Subject: [PATCH 113/123] typo --- functions/index.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/functions/index.js b/functions/index.js index 47f7c35bb..b30d13e50 100644 --- a/functions/index.js +++ b/functions/index.js @@ -433,12 +433,9 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj.name = name; //check keyspacing and duration here - if(obj.mode === "time"){ + if (obj.mode === "time") { if (!verified) { - if ( - keySpacing !== null && - keyDuration !== null && - ) { + if (keySpacing !== null && keyDuration !== null) { if ( keySpacing.sd < 15 || keyDuration.sd < 15 || From 9921688e7dce3a99cbe3b8767d25debf34b1e09f Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 20:01:16 +0100 Subject: [PATCH 114/123] fixed test completed not returning data --- functions/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions/index.js b/functions/index.js index b30d13e50..fbaf16872 100644 --- a/functions/index.js +++ b/functions/index.js @@ -389,11 +389,11 @@ exports.testCompleted = functions.https.onCall((request, response) => { request.obj )}` ); - return -1; + return { resultCode: -1 }; } if (obj.wpm <= 0 || obj.wpm > 350 || obj.acc < 50 || obj.acc > 100) { - return -1; + return { resultCode: -1 }; } let keySpacing = null; From c12d078b6e664a92c209e80c249e1d087216ee82 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 20:33:54 +0100 Subject: [PATCH 115/123] added a log when something unexpected cameback from the server --- public/js/script.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/js/script.js b/public/js/script.js index 77a05a854..0063af1ab 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1098,7 +1098,7 @@ function showResult(difficultyFailed = false) { obj: completedEvent, }).then((e) => { accountIconLoading(false); - console.log(e.data); + console.log(JSON.stringify(e.data)); if (e.data.resultCode === -1) { showNotification("Could not save result", 3000); } else if (e.data.resultCode === -2) { @@ -1235,6 +1235,8 @@ function showResult(difficultyFailed = false) { ); } } + } else { + showNotification("Unexpected response from the server.", 4000); } }); }); From bf050a8d6c73c2e877ae99c5a5111f6174a76240 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2020 21:50:00 +0100 Subject: [PATCH 116/123] fixed a bug where leaderboards would get cleared --- functions/index.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/functions/index.js b/functions/index.js index fbaf16872..a6e7522ab 100644 --- a/functions/index.js +++ b/functions/index.js @@ -779,11 +779,14 @@ class Leaderboard { this.size = size; this.board = []; this.mode = mode; - this.mode2 = mode2; + this.mode2 = parseInt(mode2); this.type = type; if (starting !== undefined && starting !== null) { starting.forEach((entry) => { - if (entry.mode === this.mode && entry.mode2 === this.mode2) { + if ( + entry.mode == this.mode && + parseInt(entry.mode2) === parseInt(this.mode2) + ) { this.board.push({ uid: entry.uid, name: entry.name, @@ -791,7 +794,7 @@ class Leaderboard { raw: parseFloat(entry.raw), acc: parseFloat(entry.acc), mode: entry.mode, - mode2: entry.mode2, + mode2: parseInt(entry.mode2), timestamp: entry.timestamp, }); } @@ -853,7 +856,7 @@ class Leaderboard { } insert(a) { let insertedAt = -1; - if (a.mode === this.mode && a.mode2 === this.mode2) { + if (a.mode == this.mode && parseInt(a.mode2) === parseInt(this.mode2)) { this.board.forEach((b, index) => { if (insertedAt !== -1) return; if (a.wpm === b.wpm) { @@ -866,7 +869,7 @@ class Leaderboard { raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, - mode2: a.mode2, + mode2: parseInt(a.mode2), timestamp: a.timestamp, }); insertedAt = index; @@ -880,7 +883,7 @@ class Leaderboard { raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, - mode2: a.mode2, + mode2: parseInt(a.mode2), timestamp: a.timestamp, }); insertedAt = index; @@ -895,7 +898,7 @@ class Leaderboard { raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, - mode2: a.mode2, + mode2: parseInt(a.mode2), timestamp: a.timestamp, }); insertedAt = index; @@ -910,7 +913,7 @@ class Leaderboard { raw: parseFloat(a.rawWpm), acc: parseFloat(a.acc), mode: a.mode, - mode2: a.mode2, + mode2: parseInt(a.mode2), timestamp: a.timestamp, }); insertedAt = this.board.length - 1; From 865bfc3deaef1c046f91ed7a628f4d682367d6a6 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 11 Jul 2020 10:53:04 +0100 Subject: [PATCH 117/123] added daily lb announce --- functions/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/functions/index.js b/functions/index.js index a6e7522ab..a47a80d3d 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1232,6 +1232,7 @@ exports.scheduledFunctionCrontab = functions.pubsub .then((res) => { res.docs.forEach((doc) => { let lbdata = doc.data(); + announceDailyLbResult(lbdata); t = new Date(); db.collection("leaderboards_history") .doc( @@ -1262,3 +1263,12 @@ async function announceLbUpdate(discordId, pos, lb, wpm) { requestTimestamp: Date.now(), }); } + +async function announceDailyLbResult(lbdata) { + db.collection("bot-commands").add({ + command: "announceDailyLbResult", + arguments: [lbdata], + executed: false, + requestTimestamp: Date.now(), + }); +} From 48e412a31fbed3dbb3477a603b3a91302865a85b Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 11 Jul 2020 10:53:13 +0100 Subject: [PATCH 118/123] updated stat name --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 063222a26..81924bda5 100644 --- a/public/index.html +++ b/public/index.html @@ -709,7 +709,7 @@

wpm - total amount of characters in the correctly typed words, divided by 5

raw wpm - calculated just like wpm, but also includes incorrect words

acc - percentage of correctly pressed keys

-

key - correct characters / incorrect characters. Calculated after the test has ended

+

char - correct characters / incorrect characters. Calculated after the test has ended

bug report or feature request

From d1bfc564f5080412c602118565e272710bda10e5 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 11 Jul 2020 17:03:25 +0100 Subject: [PATCH 119/123] added a getuid function --- public/js/script.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/public/js/script.js b/public/js/script.js index 0063af1ab..399da191d 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -218,6 +218,12 @@ function verifyUsername() { }); } +function getuid() { + console.error("Only share this uid with Miodec and nobody else!"); + console.log(firebase.auth().currentUser.uid); + console.error("Only share this uid with Miodec and nobody else!"); +} + function getLastChar(word) { return word.charAt(word.length - 1); } From 677702eee1ca6724d88fe2ccd06acf6dc8d20aae Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 11 Jul 2020 17:21:34 +0100 Subject: [PATCH 120/123] updated check if needs to check name function --- functions/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/functions/index.js b/functions/index.js index a47a80d3d..783478dd2 100644 --- a/functions/index.js +++ b/functions/index.js @@ -146,7 +146,11 @@ exports.checkIfNeedsToChangeName = functions.https.onCall( .doc(request.uid) .get() .then((doc) => { - if (doc.data().name === undefined) { + if ( + doc.data().name === undefined || + doc.data().name === null || + doc.data().name === "" + ) { return admin .auth() .getUser(request.uid) From 3d57e1c23bc9baaa9118e31eae76754f6990d8b6 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 12 Jul 2020 00:41:14 +0100 Subject: [PATCH 121/123] added timer color setting --- public/css/style.scss | 33 ++++++++++++++++++++--- public/index.html | 10 +++++++ public/js/script.js | 60 ++++++++++++++++++++++++++++++++++++++--- public/js/settings.js | 18 +++++++++++++ public/js/userconfig.js | 11 ++++++++ 5 files changed, 125 insertions(+), 7 deletions(-) diff --git a/public/css/style.scss b/public/css/style.scss index 55bcf6a73..dc3fcb168 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -532,7 +532,7 @@ a:hover { width: 100vw; /* height: 0.5rem; */ height: 0.5rem; - background: var(--sub-color); + background: black; /* background: #0f0f0f; */ /* background: red; */ // transition: 1s linear; @@ -555,12 +555,39 @@ a:hover { } #timerNumber { - bottom: 4rem; + bottom: 6rem; transition: none; } +#liveWpm.timerMain, +#timerNumber.timerMain { + color: var(--main-color); +} + +#timer.timerMain { + background: var(--main-color); +} + +#liveWpm.timerSub, +#timerNumber.timerSub { + color: var(--sub-color); +} + +#timer.timerSub { + background: var(--sub-color); +} + +#liveWpm.timerText, +#timerNumber.timerText { + color: var(--text-color); +} + +#timer.timerText { + background: var(--text-color); +} + #liveWpm { - top: 4rem; + top: 6rem; } diff --git a/public/index.html b/public/index.html index 81924bda5..066f437b8 100644 --- a/public/index.html +++ b/public/index.html @@ -875,6 +875,16 @@
text
+
+

timer color

+
Change the color of the timer number/bar and live wpm number.
+
+
black
+
sub
+
text
+
main
+
+

flip test colors

By default, typed text is brighter than the future text. When enabled, the colors will be diff --git a/public/js/script.js b/public/js/script.js index 399da191d..90bd35e65 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -587,16 +587,32 @@ function highlightBadWord(index, showError) { function showTimer() { if (!config.showTimerBar) return; if (config.timerStyle === "bar") { + let op = 0.25; + if ( + $("#timerNumber").hasClass("timerSub") || + $("#timerNumber").hasClass("timerText") || + $("#timerNumber").hasClass("timerMain") + ) { + op = 1; + } $("#timerWrapper").stop(true, true).removeClass("hidden").animate( { - opacity: 1, + opacity: op, }, 250 ); } else if (config.timerStyle === "text" && config.mode === "time") { + let op = 0.25; + if ( + $("#timerNumber").hasClass("timerSub") || + $("#timerNumber").hasClass("timerText") || + $("#timerNumber").hasClass("timerMain") + ) { + op = 1; + } $("#timerNumber").stop(true, true).removeClass("hidden").animate( { - opacity: 0.25, + opacity: op, }, 250 ); @@ -621,6 +637,34 @@ function hideTimer() { } } +function changeTimerColor(color) { + $("#timer").removeClass("timerSub"); + $("#timer").removeClass("timerText"); + $("#timer").removeClass("timerMain"); + + $("#timerNumber").removeClass("timerSub"); + $("#timerNumber").removeClass("timerText"); + $("#timerNumber").removeClass("timerMain"); + + $("#liveWpm").removeClass("timerSub"); + $("#liveWpm").removeClass("timerText"); + $("#liveWpm").removeClass("timerMain"); + + if (color === "main") { + $("#timer").addClass("timerMain"); + $("#timerNumber").addClass("timerMain"); + $("#liveWpm").addClass("timerMain"); + } else if (color === "sub") { + $("#timer").addClass("timerSub"); + $("#timerNumber").addClass("timerSub"); + $("#liveWpm").addClass("timerSub"); + } else if (color === "text") { + $("#timer").addClass("timerText"); + $("#timerNumber").addClass("timerText"); + $("#liveWpm").addClass("timerText"); + } +} + function restartTimer() { if (config.timerStyle === "bar") { if (config.mode === "time") { @@ -1104,7 +1148,7 @@ function showResult(difficultyFailed = false) { obj: completedEvent, }).then((e) => { accountIconLoading(false); - console.log(JSON.stringify(e.data)); + // console.log(JSON.stringify(e.data)); if (e.data.resultCode === -1) { showNotification("Could not save result", 3000); } else if (e.data.resultCode === -2) { @@ -1673,7 +1717,15 @@ function updateLiveWpm(wpm) { function showLiveWpm() { if (!config.showLiveWpm) return; if (!testActive) return; - $("#liveWpm").css("opacity", 0.25); + let op = 0.25; + if ( + $("#liveWpm").hasClass("timerSub") || + $("#liveWpm").hasClass("timerText") || + $("#liveWpm").hasClass("timerMain") + ) { + op = 1; + } + $("#liveWpm").css("opacity", op); } function hideLiveWpm() { diff --git a/public/js/settings.js b/public/js/settings.js index 601ffd80b..03b85e245 100644 --- a/public/js/settings.js +++ b/public/js/settings.js @@ -57,6 +57,7 @@ function updateSettingsPage() { setActiveDifficultyButton(); setActiveCaretStyleButton(); setActiveTimerStyleButton(); + setActiveTimerColorButton(); setActiveThemeTab(); setCustomThemeInputs(); @@ -180,6 +181,15 @@ function setActiveTimerStyleButton() { ).addClass("active"); } +function setActiveTimerColorButton() { + $(`.pageSettings .section.timerColor .buttons .button`).removeClass("active"); + $( + `.pageSettings .section.timerColor .buttons .button[color=` + + config.timerColor + + `]` + ).addClass("active"); +} + function setSettingsButton(buttonSection, tf) { if (tf) { $( @@ -487,6 +497,14 @@ $(document).on("click", ".pageSettings .section.timerStyle .button", (e) => { setActiveTimerStyleButton(); }); +//timer color +$(document).on("click", ".pageSettings .section.timerColor .button", (e) => { + let color = $(e.currentTarget).attr("color"); + setTimerColor(color); + // showNotification('Timer style updated', 1000); + setActiveTimerColorButton(); +}); + //blind mode $(".pageSettings .section.blindMode .buttons .button.on").click((e) => { setBlindMode(true); diff --git a/public/js/userconfig.js b/public/js/userconfig.js index fc8b4e12e..c95d30f51 100644 --- a/public/js/userconfig.js +++ b/public/js/userconfig.js @@ -36,6 +36,7 @@ let defaultConfig = { timerStyle: "bar", colorfulMode: true, randomTheme: false, + timerColor: "black", }; let cookieConfig = null; @@ -128,6 +129,7 @@ function applyConfig(configObj) { setColorfulMode(configObj.colorfulMode, true); setMaxConfidence(configObj.maxConfidence, true); setTimerStyle(configObj.timerStyle, true); + setTimerColor(configObj.timerColor, true); if ( configObj.resultFilters == null || configObj.resultFilters == undefined @@ -304,6 +306,15 @@ function setTimerStyle(style, nosave) { if (!nosave) saveConfigToCookie(); } +function setTimerColor(color, nosave) { + if (color == null || color == undefined) { + color = "black"; + } + config.timerColor = color; + changeTimerColor(color); + if (!nosave) saveConfigToCookie(); +} + //key tips function setKeyTips(keyTips, nosave) { config.showKeyTips = keyTips; From de4ad793046ce7201ac412aadd3995a0e240ba6c Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 12 Jul 2020 00:45:52 +0100 Subject: [PATCH 122/123] added commands for the timer color --- public/js/commandline.js | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/public/js/commandline.js b/public/js/commandline.js index 6a54c3a48..59b01e543 100644 --- a/public/js/commandline.js +++ b/public/js/commandline.js @@ -164,6 +164,15 @@ let commands = { showCommandLine(); }, }, + { + id: "changeTimerColor", + display: "Change timer color...", + subgroup: true, + exec: () => { + currentCommands.push(commandsTimerColor); + showCommandLine(); + }, + }, { id: "changeTheme", display: "Change theme...", @@ -291,6 +300,40 @@ let commandsTimerStyle = { ], }; +let commandsTimerColor = { + title: "Change timer color...", + list: [ + { + id: "setTimerColorBlack", + display: "black", + exec: () => { + setTimerColor("bar"); + }, + }, + { + id: "setTimerColorSub", + display: "sub", + exec: () => { + setTimerColor("sub"); + }, + }, + { + id: "setTimerColorText", + display: "text", + exec: () => { + setTimerColor("text"); + }, + }, + { + id: "setTimerColorMain", + display: "main", + exec: () => { + setTimerColor("main"); + }, + }, + ], +}; + let commandsWordCount = { title: "Change word count...", list: [ From 083ec608b35de0865dd1e15166bc2e6e48ed70b8 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 12 Jul 2020 00:46:10 +0100 Subject: [PATCH 123/123] cache --- public/index.html | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/public/index.html b/public/index.html index 066f437b8..0d29012e4 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ Monkey Type - + @@ -1290,17 +1290,17 @@ - + - - - - - - - - - + + + + + + + + + \ No newline at end of file
${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}
${Math.round(result.wpm)}${Math.round(raw)}${Math.round(result.acc)}%${result.wpm}${raw}${result.acc}% ${result.correctChars} ${result.incorrectChars} ${result.mode} ${result.mode2}${withpunc}