Skip to content

Commit 6ef2b9f

Browse files
committed
Merge branch 'master' into test-events-2
2 parents 5a65647 + 033c7cf commit 6ef2b9f

5 files changed

Lines changed: 48 additions & 39 deletions

File tree

frontend/src/ts/pages/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as TestState from "../test/test-state";
21
import * as TestLogic from "../test/test-logic";
32
import * as Funbox from "../test/funbox/funbox";
43
import Page from "./page";
@@ -7,6 +6,7 @@ import * as ModesNotice from "../elements/modes-notice";
76
import * as Keymap from "../elements/keymap";
87
import { blurInputElement } from "../input/input-element";
98
import { qsr } from "../utils/dom";
9+
import { resetIncompleteTests } from "../states/test";
1010

1111
export const page = new Page({
1212
id: "test",
@@ -25,7 +25,7 @@ export const page = new Page({
2525
},
2626
beforeShow: async (): Promise<void> => {
2727
updateFooterAndVerticalAds(false);
28-
TestState.resetIncomplete();
28+
resetIncompleteTests();
2929
TestLogic.restart({
3030
noAnim: true,
3131
});

frontend/src/ts/states/test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { createSignal, createEffect } from "solid-js";
1+
import { createSignal, createEffect, createMemo } from "solid-js";
22
import { Challenge } from "@monkeytype/schemas/challenges";
33
import { getConfig } from "../config/store";
44
import { getActivePage } from "./core";
55
import { canQuickRestart } from "../utils/quick-restart";
66
import { getData as getCustomTextData } from "../test/custom-text";
77
import { isCustomTextLong } from "../legacy-states/custom-text-name";
8+
import { CompletedEvent, IncompleteTest } from "@monkeytype/schemas/results";
9+
import { createSignalWithSetters } from "../hooks/createSignalWithSetters";
810

911
export const [wordsHaveNewline, setWordsHaveNewline] = createSignal(false);
1012
export const [wordsHaveTab, setWordsHaveTab] = createSignal(false);
@@ -13,8 +15,24 @@ export const [getLoadedChallenge, setLoadedChallenge] =
1315
createSignal<Challenge | null>(null);
1416
export const [getResultVisible, setResultVisible] = createSignal(false);
1517
export const [getFocus, setFocus] = createSignal(false);
16-
18+
export const [isTestInvalid, setIsTestInvalid] = createSignal(false);
1719
export const [isLongTest, setIsLongTest] = createSignal(false);
20+
export const [getLastResult, setLastResult] = createSignal<Omit<
21+
CompletedEvent,
22+
"hash" | "uid"
23+
> | null>(null);
24+
export const [
25+
getIncompleteTests,
26+
{ push: pushIncompleteTest, reset: resetIncompleteTests },
27+
] = createSignalWithSetters<IncompleteTest[]>([])({
28+
push: (set, val: IncompleteTest) => set((arr) => [...arr, val]),
29+
reset: (set) => set([]),
30+
});
31+
32+
export const getRestartCount = createMemo(() => getIncompleteTests().length);
33+
export const getIncompleteSeconds = createMemo(() =>
34+
getIncompleteTests().reduce((sum, test) => sum + test.seconds, 0),
35+
);
1836

1937
createEffect(() => {
2038
getActivePage(); // depend on active page

frontend/src/ts/test/result.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import * as ConnectionState from "../legacy-states/connection";
6161
import { currentQuote } from "./test-words";
6262
import { qs, qsa } from "../utils/dom";
6363
import { getTheme } from "../states/theme";
64+
import { isTestInvalid } from "../states/test";
6465

6566
let result: CompletedEvent;
6667
let minChartVal: number;
@@ -833,7 +834,7 @@ function updateOther(
833834
if (afkDetected) {
834835
otherText += "<br>afk detected";
835836
}
836-
if (TestStats.invalid) {
837+
if (isTestInvalid()) {
837838
otherText += "<br>invalid";
838839
const extra: string[] = [];
839840
if (

frontend/src/ts/test/test-logic.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ import { clearQuoteStats } from "../states/quote-rate";
2929
import * as Result from "./result";
3030
import { getActivePage, isAuthenticated } from "../states/core";
3131
import {
32+
getIncompleteSeconds,
33+
getIncompleteTests,
34+
getRestartCount,
35+
pushIncompleteTest,
36+
resetIncompleteTests,
37+
setIsTestInvalid,
38+
setLastResult,
3239
setResultVisible,
3340
setWordsHaveNewline,
3441
setWordsHaveTab,
@@ -271,10 +278,8 @@ export function restart(options = {} as RestartOptions): void {
271278
const afkseconds = TestStats.calculateAfkSeconds(testSeconds);
272279
let tt = Numbers.roundTo2(testSeconds - afkseconds);
273280
if (tt < 0) tt = 0;
274-
TestState.incrementIncompleteSeconds(tt);
275-
TestState.incrementRestartCount();
276281
const acc = Numbers.roundTo2(TestStats.calculateAccuracy());
277-
TestState.pushIncompleteTest(acc, tt);
282+
pushIncompleteTest({ acc, seconds: tt });
278283
}
279284
}
280285

@@ -316,6 +321,7 @@ export function restart(options = {} as RestartOptions): void {
316321

317322
resetTestEvents();
318323
TestTimer.clear();
324+
setIsTestInvalid(false);
319325
TestStats.restart();
320326
TestInput.restart();
321327
TestInput.corrected.reset();
@@ -865,12 +871,10 @@ function buildCompletedEvent(
865871
lazyMode: Config.lazyMode,
866872
timestamp: Date.now(),
867873
language: language,
868-
restartCount: TestState.restartCount,
869-
incompleteTests: TestState.incompleteTests,
874+
restartCount: getRestartCount(),
875+
incompleteTests: getIncompleteTests(),
870876
incompleteTestSeconds:
871-
TestState.incompleteSeconds < 0
872-
? 0
873-
: Numbers.roundTo2(TestState.incompleteSeconds),
877+
getIncompleteSeconds() < 0 ? 0 : Numbers.roundTo2(getIncompleteSeconds()),
874878
difficulty: Config.difficulty,
875879
blindMode: Config.blindMode,
876880
tags: activeTagsIds,
@@ -1383,7 +1387,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
13831387

13841388
const completedEvent = structuredClone(ce) as CompletedEvent;
13851389

1386-
TestStats.setLastResult(structuredClone(completedEvent));
1390+
setLastResult(structuredClone(completedEvent));
13871391

13881392
///////// completed event ready
13891393

@@ -1406,7 +1410,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
14061410
) {
14071411
showNoticeNotification("Test invalid - inconsistent test duration");
14081412
console.error("Test duration inconsistent", ce.testDuration, dateDur);
1409-
TestStats.setInvalid();
1413+
setIsTestInvalid(true);
14101414
dontSave = true;
14111415
} else if (difficultyFailed) {
14121416
showNoticeNotification(`Test failed - ${failReason}`, {
@@ -1433,16 +1437,16 @@ export async function finish(difficultyFailed = false): Promise<void> {
14331437
(Config.mode === "zen" && completedEvent.testDuration < 15)
14341438
) {
14351439
showNoticeNotification("Test invalid - too short");
1436-
TestStats.setInvalid();
1440+
setIsTestInvalid(true);
14371441
tooShort = true;
14381442
dontSave = true;
14391443
} else if (afkDetected) {
14401444
showNoticeNotification("Test invalid - AFK detected");
1441-
TestStats.setInvalid();
1445+
setIsTestInvalid(true);
14421446
dontSave = true;
14431447
} else if (TestState.isRepeated) {
14441448
showNoticeNotification("Test invalid - repeated");
1445-
TestStats.setInvalid();
1449+
setIsTestInvalid(true);
14461450
dontSave = true;
14471451
} else if (
14481452
completedEvent.wpm < 0 ||
@@ -1454,7 +1458,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
14541458
completedEvent.mode2 === "10")
14551459
) {
14561460
showNoticeNotification("Test invalid - wpm");
1457-
TestStats.setInvalid();
1461+
setIsTestInvalid(true);
14581462
dontSave = true;
14591463
} else if (
14601464
completedEvent.rawWpm < 0 ||
@@ -1466,7 +1470,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
14661470
completedEvent.mode2 === "10")
14671471
) {
14681472
showNoticeNotification("Test invalid - raw");
1469-
TestStats.setInvalid();
1473+
setIsTestInvalid(true);
14701474
dontSave = true;
14711475
} else if (
14721476
(!DB.getSnapshot()?.lbOptOut &&
@@ -1475,7 +1479,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
14751479
(completedEvent.acc < 50 || completedEvent.acc > 100))
14761480
) {
14771481
showNoticeNotification("Test invalid - accuracy");
1478-
TestStats.setInvalid();
1482+
setIsTestInvalid(true);
14791483
dontSave = true;
14801484
}
14811485

@@ -1488,9 +1492,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
14881492
let tt = Numbers.roundTo2(testSeconds - afkseconds);
14891493
if (tt < 0) tt = 0;
14901494
const acc = completedEvent.acc;
1491-
TestState.incrementIncompleteSeconds(tt);
1492-
TestState.incrementRestartCount();
1493-
TestState.pushIncompleteTest(acc, tt);
1495+
pushIncompleteTest({ acc, seconds: tt });
14941496
}
14951497
}
14961498

@@ -1550,7 +1552,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
15501552
if (dontSave) {
15511553
void AnalyticsController.log("testCompletedInvalid");
15521554
} else {
1553-
TestState.resetIncomplete();
1555+
resetIncompleteTests();
15541556

15551557
if (!completedEvent.bailedOut) {
15561558
const challenge = ChallengeContoller.verify(completedEvent);

frontend/src/ts/test/test-stats.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import * as TestInput from "./test-input";
55
import * as TestWords from "./test-words";
66
import * as TestState from "./test-state";
77
import * as Numbers from "@monkeytype/util/numbers";
8-
import { CompletedEvent } from "@monkeytype/schemas/results";
98
import { isFunboxActiveWithProperty } from "./funbox/list";
109
import * as CustomText from "./custom-text";
10+
import { getLastResult } from "../states/test";
1111

1212
type CharCount = {
1313
spaces: number;
@@ -33,21 +33,14 @@ export type Stats = {
3333
correctSpaces: number;
3434
};
3535

36-
export let invalid = false;
3736
export let start: number, end: number;
3837
export let start2: number, end2: number;
3938
export let start3: number, end3: number;
4039
export let lastSecondNotRound = false;
4140

42-
export let lastResult: Omit<CompletedEvent, "hash" | "uid">;
43-
44-
export function setLastResult(result: CompletedEvent): void {
45-
lastResult = result;
46-
}
47-
4841
export function getStats(): unknown {
4942
const ret = {
50-
lastResult,
43+
lastResult: getLastResult(),
5144
start,
5245
end,
5346
start3,
@@ -110,14 +103,9 @@ export function restart(): void {
110103
end2 = 0;
111104
start3 = 0;
112105
end3 = 0;
113-
invalid = false;
114106
lastSecondNotRound = false;
115107
}
116108

117-
export function setInvalid(): void {
118-
invalid = true;
119-
}
120-
121109
export function calculateTestSeconds(now?: number): number {
122110
let duration = (end - start) / 1000;
123111

0 commit comments

Comments
 (0)