diff --git a/backend/__tests__/utils/pb.spec.ts b/backend/__tests__/utils/pb.spec.ts index a008af3abe86..a534a5208039 100644 --- a/backend/__tests__/utils/pb.spec.ts +++ b/backend/__tests__/utils/pb.spec.ts @@ -32,4 +32,81 @@ describe("Pb Utils", () => { expect(result).toBe(expected); }); }); + describe("checkAndUpdatePb", () => { + it("should update personal best", () => { + const userPbs: SharedTypes.PersonalBests = { + time: {}, + words: {}, + custom: {}, + quote: {}, + zen: {}, + }; + const result = { + difficulty: "normal", + language: "english", + punctuation: false, + lazyMode: false, + acc: 100, + consistency: 100, + rawWpm: 100, + wpm: 110, + numbers: false, + mode: "time", + mode2: "15", + } as unknown as SharedTypes.Result; + + const run = pb.checkAndUpdatePb(userPbs, undefined, result); + + expect(run.isPb).toBe(true); + expect(run.personalBests?.["time"]?.["15"]?.[0]).not.toBe(undefined); + }); + it("should not override default pb when saving numbers test", () => { + const userPbs: SharedTypes.PersonalBests = { + time: { + "15": [ + { + acc: 100, + consistency: 100, + difficulty: "normal", + lazyMode: false, + language: "english", + numbers: false, + punctuation: false, + raw: 100, + timestamp: 0, + wpm: 100, + }, + ], + }, + words: {}, + custom: {}, + quote: {}, + zen: {}, + }; + const result = { + difficulty: "normal", + language: "english", + punctuation: false, + lazyMode: false, + acc: 100, + consistency: 100, + rawWpm: 100, + wpm: 110, + numbers: true, + mode: "time", + mode2: "15", + } as unknown as SharedTypes.Result; + + const run = pb.checkAndUpdatePb(userPbs, undefined, result); + + expect(run.isPb).toBe(true); + + expect(run.personalBests?.["time"]?.["15"]).toEqual( + expect.arrayContaining([ + expect.objectContaining({ numbers: false, wpm: 100 }), + expect.objectContaining({ numbers: true, wpm: 110 }), + ]) + ); + }); + }); }); diff --git a/backend/src/utils/pb.ts b/backend/src/utils/pb.ts index 4399b30a58e7..bacad5d160b8 100644 --- a/backend/src/utils/pb.ts +++ b/backend/src/utils/pb.ts @@ -73,19 +73,28 @@ function matchesPersonalBest( result.difficulty === undefined || result.language === undefined || result.punctuation === undefined || - result.lazyMode === undefined + result.lazyMode === undefined || + result.numbers === undefined ) { throw new Error("Missing result data (matchesPersonalBest)"); } const sameLazyMode = - result.lazyMode === personalBest.lazyMode || - (!result.lazyMode && !personalBest.lazyMode); - const samePunctuation = result.punctuation === personalBest.punctuation; + (result.lazyMode ?? false) === (personalBest.lazyMode ?? false); + const samePunctuation = + (result.punctuation ?? false) === (personalBest.punctuation ?? false); const sameDifficulty = result.difficulty === personalBest.difficulty; const sameLanguage = result.language === personalBest.language; - - return sameLazyMode && samePunctuation && sameDifficulty && sameLanguage; + const sameNumbers = + (result.numbers ?? false) === (personalBest.numbers ?? false); + + return ( + sameLazyMode && + samePunctuation && + sameDifficulty && + sameLanguage && + sameNumbers + ); } function updatePersonalBest( @@ -104,7 +113,8 @@ function updatePersonalBest( result.acc === undefined || result.consistency === undefined || result.rawWpm === undefined || - result.wpm === undefined + result.wpm === undefined || + result.numbers === undefined ) { throw new Error("Missing result data (updatePersonalBest)"); } @@ -117,6 +127,7 @@ function updatePersonalBest( personalBest.consistency = result.consistency; personalBest.raw = result.rawWpm; personalBest.wpm = result.wpm; + personalBest.numbers = result.numbers; personalBest.timestamp = Date.now(); return true; @@ -131,7 +142,8 @@ function buildPersonalBest(result: Result): SharedTypes.PersonalBest { result.acc === undefined || result.consistency === undefined || result.rawWpm === undefined || - result.wpm === undefined + result.wpm === undefined || + result.numbers === undefined ) { throw new Error("Missing result data (buildPersonalBest)"); } @@ -144,6 +156,7 @@ function buildPersonalBest(result: Result): SharedTypes.PersonalBest { punctuation: result.punctuation, raw: result.rawWpm, wpm: result.wpm, + numbers: result.numbers, timestamp: Date.now(), }; } diff --git a/frontend/src/html/popups.html b/frontend/src/html/popups.html index 97402265091a..f36579572ea4 100644 --- a/frontend/src/html/popups.html +++ b/frontend/src/html/popups.html @@ -256,6 +256,7 @@ difficulty language punctuation + numbers lazy mode date diff --git a/frontend/src/styles/popups.scss b/frontend/src/styles/popups.scss index 064932770cf1..1a88c5c013b9 100644 --- a/frontend/src/styles/popups.scss +++ b/frontend/src/styles/popups.scss @@ -692,7 +692,7 @@ .title { color: var(--text-color); } - min-width: 50rem; + width: 100%; max-height: calc(100vh - 10rem); overflow-y: scroll; table { diff --git a/frontend/src/ts/db.ts b/frontend/src/ts/db.ts index 5847d5383479..66fa344c8c0b 100644 --- a/frontend/src/ts/db.ts +++ b/frontend/src/ts/db.ts @@ -648,6 +648,7 @@ export async function saveLocalPB( mode: M, mode2: SharedTypes.Config.Mode2, punctuation: boolean, + numbers: boolean, language: string, difficulty: SharedTypes.Config.Difficulty, lazyMode: boolean, @@ -683,10 +684,11 @@ export async function saveLocalPB( ] as unknown as SharedTypes.PersonalBest[] ).forEach((pb) => { if ( - pb.punctuation === punctuation && + (pb.punctuation ?? false) === punctuation && + (pb.numbers ?? false) === numbers && pb.difficulty === difficulty && pb.language === language && - (pb.lazyMode === lazyMode || (pb.lazyMode === undefined && !lazyMode)) + (pb.lazyMode ?? false) === lazyMode ) { found = true; pb.wpm = wpm; @@ -713,6 +715,7 @@ export async function saveLocalPB( raw, timestamp: Date.now(), consistency, + numbers, }); } } diff --git a/frontend/src/ts/popups/pb-tables-popup.ts b/frontend/src/ts/popups/pb-tables-popup.ts index c85e1baa915c..86697a5c549e 100644 --- a/frontend/src/ts/popups/pb-tables-popup.ts +++ b/frontend/src/ts/popups/pb-tables-popup.ts @@ -73,6 +73,7 @@ function update(mode: SharedTypes.Config.Mode): void { ${pb.difficulty} ${pb.language ? getLanguageDisplayString(pb.language) : "-"} ${pb.punctuation ? '' : ""} + ${pb.numbers ? '' : ""} ${pb.lazyMode ? '' : ""} ${dateText} diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts index 56fd00d8b5e5..629f1eec82af 100644 --- a/frontend/src/ts/test/test-logic.ts +++ b/frontend/src/ts/test/test-logic.ts @@ -1250,6 +1250,7 @@ async function saveResult( Config.mode, completedEvent.mode2, Config.punctuation, + Config.numbers, Config.language, Config.difficulty, Config.lazyMode, diff --git a/shared-types/types.d.ts b/shared-types/types.d.ts index 6d7370f678bb..c306a09b4499 100644 --- a/shared-types/types.d.ts +++ b/shared-types/types.d.ts @@ -112,11 +112,12 @@ declare namespace SharedTypes { interface PersonalBest { acc: number; - consistency: number; + consistency?: number; difficulty: SharedTypes.Config.Difficulty; - lazyMode: boolean; + lazyMode?: boolean; language: string; - punctuation: boolean; + punctuation?: boolean; + numbers?: boolean; raw: number; wpm: number; timestamp: number;