Skip to content

Commit b1e4cff

Browse files
committed
remove results from snapshot
1 parent 4d5bcc8 commit b1e4cff

File tree

8 files changed

+137
-159
lines changed

8 files changed

+137
-159
lines changed

frontend/src/ts/collections/results.ts

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export function useResultsLiveQuery(options: {
144144

145145
function normalizeResult(
146146
result: ResultMinified | SnapshotResult<Mode>,
147+
knownTagIds?: Set<string>,
147148
): SnapshotResult<Mode> {
148149
const resultDate = new Date(result.timestamp);
149150
resultDate.setSeconds(0);
@@ -168,6 +169,9 @@ function normalizeResult(
168169
result.incompleteTestSeconds ??= 0;
169170
result.afkDuration ??= 0;
170171
result.tags ??= [];
172+
if (knownTagIds !== undefined) {
173+
result.tags = result.tags.filter((tagId) => knownTagIds.has(tagId));
174+
}
171175
result.isPb ??= false;
172176
return {
173177
...result,
@@ -190,6 +194,7 @@ export const resultsCollection = createCollection(
190194
staleTime: Infinity,
191195
queryKey: queryKeys.root(),
192196
queryFn: async () => {
197+
const knownTagIds = new Set(getSnapshot()?.tags.map((it) => it._id));
193198
//const options = parseLoadSubsetOptions(ctx.meta?.loadSubsetOptions);
194199

195200
const response = await Ape.results.get({
@@ -200,7 +205,9 @@ export const resultsCollection = createCollection(
200205
throw new Error("Error fetching results:" + response.body.message);
201206
}
202207

203-
return response.body.data.map((result) => normalizeResult(result));
208+
return response.body.data.map((result) =>
209+
normalizeResult(result, knownTagIds),
210+
);
204211
},
205212
onInsert: async ({ transaction }) => {
206213
//call to the backend to post a result is done outside, we just insert the result as we get it
@@ -215,6 +222,17 @@ export const resultsCollection = createCollection(
215222
//do not refetch after insert
216223
return { refetch: false };
217224
},
225+
onUpdate: async ({ transaction }) => {
226+
const updates = transaction.mutations.map((m) => m.modified);
227+
228+
resultsCollection.utils.writeBatch(() => {
229+
updates.forEach((item) => {
230+
resultsCollection.utils.writeUpdate(normalizeResult(item));
231+
});
232+
});
233+
//we don't sync local changes back
234+
return { refetch: false };
235+
},
218236
queryClient,
219237
getKey: (it) => it._id,
220238
}),
@@ -377,34 +395,30 @@ export const getSingleResultQueryOptions = (_id: string) =>
377395
staleTime: Infinity,
378396
});
379397

380-
export async function getUserAverage<M extends Mode>(
381-
options: {
382-
mode: M;
383-
mode2: Mode2<M>;
384-
punctuation: boolean;
385-
numbers: boolean;
386-
language: string;
387-
difficulty: Difficulty;
388-
lazyMode: boolean;
389-
} & ExactlyOneTrue<{
390-
last10Only: boolean;
391-
lastDayOnly: boolean;
392-
}>,
398+
export type CurrentSettingsFilter = {
399+
mode: Mode;
400+
mode2: Mode2<Mode>;
401+
punctuation: boolean;
402+
numbers: boolean;
403+
language: string;
404+
difficulty: Difficulty;
405+
lazyMode: boolean;
406+
};
407+
408+
export async function getUserAverage(
409+
options: CurrentSettingsFilter &
410+
ExactlyOneTrue<{
411+
last10Only: boolean;
412+
lastDayOnly: boolean;
413+
}>,
393414
): Promise<{ wpm: number; acc: number }> {
394415
const activeTagIds = getSnapshot()
395416
?.tags.filter((it) => it.active === true)
396417
.map((it) => it._id);
397418

398419
const result = await createLiveQueryCollection((q) => {
399420
let query = q
400-
.from({ r: resultsCollection })
401-
.where(({ r }) => eq(r.mode, options.mode))
402-
.where(({ r }) => eq(r.mode2, options.mode2))
403-
.where(({ r }) => eq(r.punctuation, options.punctuation))
404-
.where(({ r }) => eq(r.numbers, options.numbers))
405-
.where(({ r }) => eq(r.language, options.language))
406-
.where(({ r }) => eq(r.difficulty, options.difficulty))
407-
.where(({ r }) => eq(r.lazyMode, options.lazyMode))
421+
.from({ r: buildSettingsResultsQuery(options) })
408422
.where(({ r }) =>
409423
or(
410424
false,
@@ -427,3 +441,44 @@ export async function getUserAverage<M extends Mode>(
427441
? result[0]
428442
: { wpm: 0, acc: 0 };
429443
}
444+
445+
export async function findFastestResultByTagId(
446+
options: CurrentSettingsFilter & { tagId: string },
447+
): Promise<SnapshotResult<Mode> | undefined> {
448+
const result = await createLiveQueryCollection((q) =>
449+
q
450+
.from({ r: buildSettingsResultsQuery(options) })
451+
.orderBy(({ r }) => r.wpm, "desc")
452+
.limit(1)
453+
.findOne(),
454+
).toArrayWhenReady();
455+
return result.length === 1 || result[0] !== undefined
456+
? (result[0] as SnapshotResult<Mode>)
457+
: undefined;
458+
}
459+
460+
// oxlint-disable-next-line typescript/explicit-function-return-type
461+
function buildSettingsResultsQuery(filter: CurrentSettingsFilter) {
462+
return new Query()
463+
.from({ r: resultsCollection })
464+
.where(({ r }) => eq(r.mode, filter.mode))
465+
.where(({ r }) => eq(r.mode2, filter.mode2))
466+
.where(({ r }) => eq(r.punctuation, filter.punctuation))
467+
.where(({ r }) => eq(r.numbers, filter.numbers))
468+
.where(({ r }) => eq(r.language, filter.language))
469+
.where(({ r }) => eq(r.difficulty, filter.difficulty))
470+
.where(({ r }) => eq(r.lazyMode, filter.lazyMode));
471+
}
472+
473+
export function deleteLocalTag(tagId: string): void {
474+
for (const result of resultsCollection.values()) {
475+
const tagIndex = result.tags.indexOf(tagId);
476+
if (tagIndex > -1) {
477+
resultsCollection.update(result._id, (old) => {
478+
const tags = result.tags;
479+
tags.splice(tagIndex, 1);
480+
old.tags = tags;
481+
});
482+
}
483+
}
484+
}

frontend/src/ts/constants/default-snapshot.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ export type Snapshot = Omit<
7676
streakHourOffset?: number;
7777
tags: SnapshotUserTag[];
7878
presets: SnapshotPreset[];
79-
results?: SnapshotResult<Mode>[];
8079
xp: number;
8180
testActivity?: ModifiableTestActivityCalendar;
8281
testActivityByYear?: { [key: string]: TestActivityCalendar };
@@ -88,7 +87,6 @@ export type SnapshotPreset = Preset & {
8887
};
8988

9089
const defaultSnap = {
91-
results: undefined,
9290
personalBests: {
9391
time: {},
9492
words: {},

frontend/src/ts/controllers/page-controller.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import { configurationPromise as serverConfigurationPromise } from "../ape/server-configuration";
3232
import { getSnapshot } from "../db";
3333
import { resultsCollection } from "../collections/results";
34+
import * as TodayTracker from "../test/today-tracker";
3435

3536
type ChangeOptions = {
3637
force?: boolean;
@@ -47,10 +48,10 @@ const pages = {
4748
account: solidPage("account", {
4849
loadingOptions: {
4950
loadingMode: () => {
50-
if (getSnapshot()?.results === undefined) {
51-
return "sync";
52-
} else {
51+
if (resultsCollection.isReady()) {
5352
return "none";
53+
} else {
54+
return "sync";
5455
}
5556
},
5657
loadingPromise: async () => {
@@ -60,6 +61,7 @@ const pages = {
6061
);
6162
}
6263
await resultsCollection.stateWhenReady();
64+
TodayTracker.addAllFromToday();
6365
},
6466
style: "bar",
6567
keyframes: [

frontend/src/ts/db.ts

Lines changed: 22 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
showErrorNotification,
55
} from "./states/notifications";
66
import { isAuthenticated, getAuthenticatedUser } from "./firebase";
7-
import { lastElementFromArray } from "./utils/arrays";
87
import * as Dates from "date-fns";
98
import {
109
TestActivityCalendar,
@@ -34,7 +33,10 @@ import {
3433
get as getServerConfiguration,
3534
} from "./ape/server-configuration";
3635
import { Connection } from "@monkeytype/schemas/connections";
37-
import { insertLocalResult } from "./collections/results";
36+
import {
37+
findFastestResultByTagId,
38+
insertLocalResult,
39+
} from "./collections/results";
3840
import { resultFilterPresetsCollection } from "./collections/result-filter-presets";
3941
import {
4042
setLastResult,
@@ -276,66 +278,6 @@ export async function initSnapshot(): Promise<Snapshot | false> {
276278
}
277279
}
278280

279-
export async function getUserResults(offset?: number): Promise<boolean> {
280-
if (!isAuthenticated()) return false;
281-
282-
if (!dbSnapshot) return false;
283-
if (
284-
dbSnapshot.results !== undefined &&
285-
(offset === undefined || dbSnapshot.results.length > offset)
286-
) {
287-
return false;
288-
}
289-
290-
const response = await Ape.results.get({ query: { offset } });
291-
292-
if (response.status !== 200) {
293-
showErrorNotification("Error getting results", { response });
294-
return false;
295-
}
296-
297-
//another check in case user logs out while waiting for response
298-
if (!isAuthenticated()) return false;
299-
300-
const results: SnapshotResult<Mode>[] = response.body.data.map((result) => {
301-
result.bailedOut ??= false;
302-
result.blindMode ??= false;
303-
result.lazyMode ??= false;
304-
result.difficulty ??= "normal";
305-
result.funbox ??= [];
306-
result.language ??= "english";
307-
result.numbers ??= false;
308-
result.punctuation ??= false;
309-
result.numbers ??= false;
310-
result.quoteLength ??= -1;
311-
result.restartCount ??= 0;
312-
result.incompleteTestSeconds ??= 0;
313-
result.afkDuration ??= 0;
314-
result.tags ??= [];
315-
return result as SnapshotResult<Mode>;
316-
});
317-
results?.sort((a, b) => b.timestamp - a.timestamp);
318-
319-
if (dbSnapshot.results !== undefined && dbSnapshot.results.length > 0) {
320-
//merge
321-
const oldestTimestamp = lastElementFromArray(dbSnapshot.results)
322-
?.timestamp as number;
323-
const resultsWithoutDuplicates = results.filter(
324-
(it) => it.timestamp < oldestTimestamp,
325-
);
326-
dbSnapshot.results.push(...resultsWithoutDuplicates);
327-
} else {
328-
dbSnapshot.results = results;
329-
}
330-
331-
setLastResult(results[0]);
332-
return true;
333-
}
334-
335-
function _getCustomThemeById(themeID: string): CustomTheme | undefined {
336-
return dbSnapshot?.customThemes?.find((t) => t._id === themeID);
337-
}
338-
339281
export async function addCustomTheme(
340282
theme: Omit<CustomTheme, "_id">,
341283
): Promise<boolean> {
@@ -716,20 +658,10 @@ export async function saveLocalTagPB<M extends Mode>(
716658

717659
return;
718660
}
719-
720-
export function deleteLocalTag(tagId: string): void {
721-
getSnapshot()?.results?.forEach((result) => {
722-
const tagIndex = result.tags.indexOf(tagId);
723-
if (tagIndex > -1) {
724-
result.tags.splice(tagIndex, 1);
725-
}
726-
});
727-
}
728-
729-
export async function updateLocalTagPB<M extends Mode>(
661+
export async function updateLocalTagPB(
730662
tagId: string,
731-
mode: M,
732-
mode2: Mode2<M>,
663+
mode: Mode,
664+
mode2: Mode2<Mode>,
733665
punctuation: boolean,
734666
numbers: boolean,
735667
language: Language,
@@ -742,32 +674,24 @@ export async function updateLocalTagPB<M extends Mode>(
742674

743675
if (filteredtag === undefined) return;
744676

677+
const fastest = await findFastestResultByTagId({
678+
tagId,
679+
mode,
680+
mode2,
681+
punctuation,
682+
numbers,
683+
language,
684+
difficulty,
685+
lazyMode,
686+
});
687+
745688
const pb = {
746-
wpm: 0,
747-
acc: 0,
748-
rawWpm: 0,
749-
consistency: 0,
689+
wpm: fastest?.wpm ?? 0,
690+
acc: fastest?.acc ?? 0,
691+
rawWpm: fastest?.rawWpm ?? 0,
692+
consistency: fastest?.consistency ?? 0,
750693
};
751694

752-
getSnapshot()?.results?.forEach((result) => {
753-
if (result.tags.includes(tagId) && result.wpm > pb.wpm) {
754-
if (
755-
result.mode === mode &&
756-
result.mode2 === mode2 &&
757-
result.punctuation === punctuation &&
758-
result.numbers === numbers &&
759-
result.language === language &&
760-
result.difficulty === difficulty &&
761-
result.lazyMode === lazyMode
762-
) {
763-
pb.wpm = result.wpm;
764-
pb.acc = result.acc;
765-
pb.rawWpm = result.rawWpm;
766-
pb.consistency = result.consistency;
767-
}
768-
}
769-
});
770-
771695
await saveLocalTagPB(
772696
tagId,
773697
mode,
@@ -833,10 +757,6 @@ export function saveLocalResult(data: SaveLocalResultData): void {
833757
if (!snapshot) return;
834758

835759
if (data.result !== undefined) {
836-
if (snapshot?.results !== undefined) {
837-
snapshot.results.unshift(data.result);
838-
}
839-
840760
void insertLocalResult(data.result);
841761
setLastResult(data.result);
842762
if (snapshot.testActivity !== undefined) {

frontend/src/ts/elements/result-batches.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ export function show(): void {
1515
}
1616

1717
export async function update(): Promise<void> {
18-
const results = DB.getSnapshot()?.results;
18+
//TODO fix or delete?
19+
const results: string[] | undefined = [];
1920

2021
if (results === undefined) {
2122
console.error(

0 commit comments

Comments
 (0)