mirror of
				https://github.com/monkeytypegame/monkeytype.git
				synced 2025-10-31 19:26:22 +08:00 
			
		
		
		
	tag pbs now word like normal pbs, recording pbs per mode
This commit is contained in:
		
							parent
							
								
									8297e45b45
								
							
						
					
					
						commit
						ded7b6ac5a
					
				
					 5 changed files with 299 additions and 42 deletions
				
			
		|  | @ -501,7 +501,7 @@ function checkIfPB(uid, obj, userdata) { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| async function checkIfTagPB(uid, obj) { | ||||
| async function checkIfTagPB(uid, obj, userdata) { | ||||
|   if (obj.tags.length === 0) { | ||||
|     return []; | ||||
|   } | ||||
|  | @ -516,24 +516,152 @@ async function checkIfTagPB(uid, obj) { | |||
|         dbtags.push(data); | ||||
|       } | ||||
|     }); | ||||
|   } catch (e) { | ||||
|   } catch { | ||||
|     return []; | ||||
|   } | ||||
|   let wpm = obj.wpm; | ||||
| 
 | ||||
|   let ret = []; | ||||
|   for (let i = 0; i < dbtags.length; i++) { | ||||
|     let dbtag = dbtags[i]; | ||||
|     if (dbtag.pb === undefined || dbtag.pb < wpm) { | ||||
|       //no pb found, meaning this one is a pb
 | ||||
|       await db.collection(`users/${uid}/tags`).doc(dbtag.id).update({ | ||||
|         pb: wpm, | ||||
|     let pbs = null; | ||||
|     try { | ||||
|       pbs = dbtags[i].personalBests; | ||||
|       if (pbs === undefined) { | ||||
|         throw new Error("pb is undefined"); | ||||
|       } | ||||
|     } catch (e) { | ||||
|       //undefined personal best = new personal best
 | ||||
|       db.collection(`users/${uid}/tags`) | ||||
|         .doc(dbtags[i].id) | ||||
|         .set( | ||||
|           { | ||||
|             personalBests: { | ||||
|               [obj.mode]: { | ||||
|                 [obj.mode2]: [ | ||||
|                   { | ||||
|                     language: obj.language, | ||||
|                     difficulty: obj.difficulty, | ||||
|                     punctuation: obj.punctuation, | ||||
|                     wpm: obj.wpm, | ||||
|                     acc: obj.acc, | ||||
|                     raw: obj.rawWpm, | ||||
|                     timestamp: Date.now(), | ||||
|                     consistency: obj.consistency, | ||||
|                   }, | ||||
|                 ], | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|           { merge: true } | ||||
|         ) | ||||
|         .then((e) => { | ||||
|           ret.push(dbtags[i].id); | ||||
|         }); | ||||
|       continue; | ||||
|     } | ||||
|     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 && | ||||
|           pb.difficulty === obj.difficulty && | ||||
|           pb.language === obj.language | ||||
|         ) { | ||||
|           //entry like this already exists, compare wpm
 | ||||
|           found = true; | ||||
|           if (pb.wpm < obj.wpm) { | ||||
|             //new pb
 | ||||
|             pb.wpm = obj.wpm; | ||||
|             pb.acc = obj.acc; | ||||
|             pb.raw = obj.rawWpm; | ||||
|             pb.timestamp = Date.now(); | ||||
|             pb.consistency = obj.consistency; | ||||
|             toUpdate = true; | ||||
|           } else { | ||||
|             //no pb
 | ||||
|             return false; | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|       ret.push(dbtag.id); | ||||
|       //checked all pbs, nothing found - meaning this is a new pb
 | ||||
|       if (!found) { | ||||
|         pbs[obj.mode][obj.mode2].push({ | ||||
|           language: obj.language, | ||||
|           difficulty: obj.difficulty, | ||||
|           punctuation: obj.punctuation, | ||||
|           wpm: obj.wpm, | ||||
|           acc: obj.acc, | ||||
|           raw: obj.rawWpm, | ||||
|           timestamp: Date.now(), | ||||
|           consistency: obj.consistency, | ||||
|         }); | ||||
|         toUpdate = true; | ||||
|       } | ||||
|     } catch (e) { | ||||
|       // console.log(e);
 | ||||
|       pbs[obj.mode] = {}; | ||||
|       pbs[obj.mode][obj.mode2] = [ | ||||
|         { | ||||
|           language: obj.language, | ||||
|           difficulty: obj.difficulty, | ||||
|           punctuation: obj.punctuation, | ||||
|           wpm: obj.wpm, | ||||
|           acc: obj.acc, | ||||
|           raw: obj.rawWpm, | ||||
|           timestamp: Date.now(), | ||||
|           consistency: obj.consistency, | ||||
|         }, | ||||
|       ]; | ||||
|       toUpdate = true; | ||||
|     } | ||||
| 
 | ||||
|     if (toUpdate) { | ||||
|       db.collection(`users/${uid}/tags`) | ||||
|         .doc(dbtags[i].id) | ||||
|         .update({ personalBests: pbs }); | ||||
|       ret.push(dbtags[i].id); | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| //old
 | ||||
| // async function checkIfTagPB(uid, obj) {
 | ||||
| //   if (obj.tags.length === 0) {
 | ||||
| //     return [];
 | ||||
| //   }
 | ||||
| //   let dbtags = [];
 | ||||
| //   let restags = obj.tags;
 | ||||
| //   try {
 | ||||
| //     let snap = await db.collection(`users/${uid}/tags`).get();
 | ||||
| //     snap.forEach((doc) => {
 | ||||
| //       if (restags.includes(doc.id)) {
 | ||||
| //         let data = doc.data();
 | ||||
| //         data.id = doc.id;
 | ||||
| //         dbtags.push(data);
 | ||||
| //       }
 | ||||
| //     });
 | ||||
| //   } catch (e) {
 | ||||
| //     return [];
 | ||||
| //   }
 | ||||
| //   let wpm = obj.wpm;
 | ||||
| //   let ret = [];
 | ||||
| //   for (let i = 0; i < dbtags.length; i++) {
 | ||||
| //     let dbtag = dbtags[i];
 | ||||
| //     if (dbtag.pb === undefined || dbtag.pb < wpm) {
 | ||||
| //       //no pb found, meaning this one is a pb
 | ||||
| //       await db.collection(`users/${uid}/tags`).doc(dbtag.id).update({
 | ||||
| //         pb: wpm,
 | ||||
| //       });
 | ||||
| //       ret.push(dbtag.id);
 | ||||
| //     }
 | ||||
| //   }
 | ||||
| //   return ret;
 | ||||
| // }
 | ||||
| 
 | ||||
| exports.clearTagPb = functions.https.onCall((request, response) => { | ||||
|   try { | ||||
|     return db | ||||
|  |  | |||
							
								
								
									
										130
									
								
								src/js/db.js
									
										
									
									
									
								
							
							
						
						
									
										130
									
								
								src/js/db.js
									
										
									
									
									
								
							|  | @ -45,6 +45,9 @@ export async function db_getUserSnapshot() { | |||
|         data.docs.forEach((doc) => { | ||||
|           let tag = doc.data(); | ||||
|           tag.id = doc.id; | ||||
|           if (tag.personalBests === undefined) { | ||||
|             tag.personalBests = {}; | ||||
|           } | ||||
|           snap.tags.push(tag); | ||||
|         }); | ||||
|         snap.tags = snap.tags.sort((a, b) => { | ||||
|  | @ -305,14 +308,27 @@ export async function db_saveLocalPB( | |||
|   } | ||||
| } | ||||
| 
 | ||||
| export async function db_getLocalTagPB(tagId) { | ||||
| export async function db_getLocalTagPB( | ||||
|   tagId, | ||||
|   mode, | ||||
|   mode2, | ||||
|   punctuation, | ||||
|   language, | ||||
|   difficulty | ||||
| ) { | ||||
|   function cont() { | ||||
|     let ret = 0; | ||||
|     let filteredtag = dbSnapshot.tags.filter((t) => t.id === tagId)[0]; | ||||
|     try { | ||||
|       ret = dbSnapshot.tags.filter((t) => t.id === tagId)[0].pb; | ||||
|       if (ret == undefined) { | ||||
|         ret = 0; | ||||
|       } | ||||
|       filteredtag.personalBests[mode][mode2].forEach((pb) => { | ||||
|         if ( | ||||
|           pb.punctuation == punctuation && | ||||
|           pb.difficulty == difficulty && | ||||
|           pb.language == language | ||||
|         ) { | ||||
|           ret = pb.wpm; | ||||
|         } | ||||
|       }); | ||||
|       return ret; | ||||
|     } catch (e) { | ||||
|       return ret; | ||||
|  | @ -320,22 +336,114 @@ export async function db_getLocalTagPB(tagId) { | |||
|   } | ||||
| 
 | ||||
|   let retval; | ||||
|   if (dbSnapshot != null) { | ||||
|   if (dbSnapshot == null) { | ||||
|     retval = 0; | ||||
|   } else { | ||||
|     retval = cont(); | ||||
|   } | ||||
|   return retval; | ||||
| } | ||||
| 
 | ||||
| export async function db_saveLocalTagPB(tagId, wpm) { | ||||
| export async function db_saveLocalTagPB( | ||||
|   tagId, | ||||
|   mode, | ||||
|   mode2, | ||||
|   punctuation, | ||||
|   language, | ||||
|   difficulty, | ||||
|   wpm, | ||||
|   acc, | ||||
|   raw, | ||||
|   consistency | ||||
| ) { | ||||
|   function cont() { | ||||
|     dbSnapshot.tags.forEach((tag) => { | ||||
|       if (tag.id === tagId) { | ||||
|         tag.pb = wpm; | ||||
|     let filteredtag = dbSnapshot.tags.filter((t) => t.id === tagId)[0]; | ||||
|     try { | ||||
|       let found = false; | ||||
|       if (filteredtag.personalBests[mode][mode2] === undefined) { | ||||
|         filteredtag.personalBests[mode][mode2] = []; | ||||
|       } | ||||
|     }); | ||||
|       filteredtag.personalBests[mode][mode2].forEach((pb) => { | ||||
|         if ( | ||||
|           pb.punctuation == punctuation && | ||||
|           pb.difficulty == difficulty && | ||||
|           pb.language == language | ||||
|         ) { | ||||
|           found = true; | ||||
|           pb.wpm = wpm; | ||||
|           pb.acc = acc; | ||||
|           pb.raw = raw; | ||||
|           pb.timestamp = Date.now(); | ||||
|           pb.consistency = consistency; | ||||
|         } | ||||
|       }); | ||||
|       if (!found) { | ||||
|         //nothing found
 | ||||
|         filteredtag.personalBests[mode][mode2].push({ | ||||
|           language: language, | ||||
|           difficulty: difficulty, | ||||
|           punctuation: punctuation, | ||||
|           wpm: wpm, | ||||
|           acc: acc, | ||||
|           raw: raw, | ||||
|           timestamp: Date.now(), | ||||
|           consistency: consistency, | ||||
|         }); | ||||
|       } | ||||
|     } catch (e) { | ||||
|       //that mode or mode2 is not found
 | ||||
|       filteredtag.personalBests[mode] = {}; | ||||
|       filteredtag.personalBests[mode][mode2] = [ | ||||
|         { | ||||
|           language: language, | ||||
|           difficulty: difficulty, | ||||
|           punctuation: punctuation, | ||||
|           wpm: wpm, | ||||
|           acc: acc, | ||||
|           raw: raw, | ||||
|           timestamp: Date.now(), | ||||
|           consistency: consistency, | ||||
|         }, | ||||
|       ]; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (dbSnapshot != null) { | ||||
|     cont(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // export async function db_getLocalTagPB(tagId) {
 | ||||
| //   function cont() {
 | ||||
| //     let ret = 0;
 | ||||
| //     try {
 | ||||
| //       ret = dbSnapshot.tags.filter((t) => t.id === tagId)[0].pb;
 | ||||
| //       if (ret == undefined) {
 | ||||
| //         ret = 0;
 | ||||
| //       }
 | ||||
| //       return ret;
 | ||||
| //     } catch (e) {
 | ||||
| //       return ret;
 | ||||
| //     }
 | ||||
| //   }
 | ||||
| 
 | ||||
| //   let retval;
 | ||||
| //   if (dbSnapshot != null) {
 | ||||
| //     retval = cont();
 | ||||
| //   }
 | ||||
| //   return retval;
 | ||||
| // }
 | ||||
| 
 | ||||
| // export async function db_saveLocalTagPB(tagId, wpm) {
 | ||||
| //   function cont() {
 | ||||
| //     dbSnapshot.tags.forEach((tag) => {
 | ||||
| //       if (tag.id === tagId) {
 | ||||
| //         tag.pb = wpm;
 | ||||
| //       }
 | ||||
| //     });
 | ||||
| //   }
 | ||||
| 
 | ||||
| //   if (dbSnapshot != null) {
 | ||||
| //     cont();
 | ||||
| //   }
 | ||||
| // }
 | ||||
|  |  | |||
|  | @ -2284,14 +2284,33 @@ function showResult(difficultyFailed = false) { | |||
|               $("#result .stats .tags").removeClass("hidden"); | ||||
|             } | ||||
|             $("#result .stats .tags .bottom").text(""); | ||||
|             let annotationSide = "left"; | ||||
|             activeTags.forEach(async (tag) => { | ||||
|               let tpb = await db_getLocalTagPB(tag.id); | ||||
|               let tpb = await db_getLocalTagPB( | ||||
|                 tag.id, | ||||
|                 config.mode, | ||||
|                 mode2, | ||||
|                 config.punctuation, | ||||
|                 config.language, | ||||
|                 config.difficulty | ||||
|               ); | ||||
|               $("#result .stats .tags .bottom").append(` | ||||
|                 <div tagid="${tag.id}" aria-label="PB: ${tpb}" data-balloon-pos="up">${tag.name}<i class="fas fa-crown hidden"></i></div> | ||||
|               `);
 | ||||
|               if (tpb < stats.wpm) { | ||||
|                 //new pb for that tag
 | ||||
|                 db_saveLocalTagPB(tag.id, stats.wpm); | ||||
|                 db_saveLocalTagPB( | ||||
|                   tag.id, | ||||
|                   config.mode, | ||||
|                   mode2, | ||||
|                   config.punctuation, | ||||
|                   config.language, | ||||
|                   config.difficulty, | ||||
|                   stats.wpm, | ||||
|                   stats.acc, | ||||
|                   stats.wpmRaw, | ||||
|                   consistency | ||||
|                 ); | ||||
|                 $( | ||||
|                   `#result .stats .tags .bottom div[tagid="${tag.id}"] .fas` | ||||
|                 ).removeClass("hidden"); | ||||
|  | @ -2319,11 +2338,16 @@ function showResult(difficultyFailed = false) { | |||
|                     xPadding: 6, | ||||
|                     yPadding: 6, | ||||
|                     cornerRadius: 3, | ||||
|                     position: "center", | ||||
|                     position: annotationSide, | ||||
|                     enabled: true, | ||||
|                     content: `${tag.name} PB: ${tpb}`, | ||||
|                   }, | ||||
|                 }); | ||||
|                 if (annotationSide === "left") { | ||||
|                   annotationSide = "right"; | ||||
|                 } else { | ||||
|                   annotationSide = "left"; | ||||
|                 } | ||||
|               } | ||||
|             }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -584,7 +584,7 @@ function refreshTagsSettingsSection() { | |||
|                   </div> | ||||
|                   <div class="title">${tag.name}</div> | ||||
|                   <div class="editButton"><i class="fas fa-pen"></i></div> | ||||
|                   <div class="clearPbButton" aria-label="${tagPbString}" data-balloon-pos="up"><i class="fas fa-crown"></i></div> | ||||
|                   <div class="clearPbButton hidden" aria-label="${tagPbString}" data-balloon-pos="up"><i class="fas fa-crown"></i></div> | ||||
|                   <div class="removeButton"><i class="fas fa-trash"></i></div> | ||||
|               </div> | ||||
| 
 | ||||
|  | @ -598,7 +598,7 @@ function refreshTagsSettingsSection() { | |||
|                   </div> | ||||
|                   <div class="title">${tag.name}</div> | ||||
|                   <div class="editButton"><i class="fas fa-pen"></i></div> | ||||
|                   <div class="clearPbButton" aria-label="${tagPbString}" data-balloon-pos="up"><i class="fas fa-crown"></i></div> | ||||
|                   <div class="clearPbButton hidden" aria-label="${tagPbString}" data-balloon-pos="up"><i class="fas fa-crown"></i></div> | ||||
|                   <div class="removeButton"><i class="fas fa-trash"></i></div> | ||||
|               </div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -104,23 +104,20 @@ async function saveConfigToCookie(noDbCheck = false) { | |||
| } | ||||
| 
 | ||||
| async function saveConfigToDB() { | ||||
|   // if (firebase.auth().currentUser !== null) {
 | ||||
|   //   accountIconLoading(true);
 | ||||
|   //   CloudFunctions.saveConfig({
 | ||||
|   //     uid: firebase.auth().currentUser.uid,
 | ||||
|   //     obj: config,
 | ||||
|   //   }).then((d) => {
 | ||||
|   //     accountIconLoading(false);
 | ||||
|   //     if (d.data.returnCode === 1) {
 | ||||
|   //     } else {
 | ||||
|   //       Notifications.add(
 | ||||
|   //         `Error saving config to DB! ${d.data.message}`,
 | ||||
|   //         4000
 | ||||
|   //       );
 | ||||
|   //     }
 | ||||
|   //     return;
 | ||||
|   //   });
 | ||||
|   // }
 | ||||
|   if (firebase.auth().currentUser !== null) { | ||||
|     accountIconLoading(true); | ||||
|     CloudFunctions.saveConfig({ | ||||
|       uid: firebase.auth().currentUser.uid, | ||||
|       obj: config, | ||||
|     }).then((d) => { | ||||
|       accountIconLoading(false); | ||||
|       if (d.data.returnCode === 1) { | ||||
|       } else { | ||||
|         Notifications.add(`Error saving config to DB! ${d.data.message}`, 4000); | ||||
|       } | ||||
|       return; | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function resetConfig() { | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue