Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/src/ts/pages/test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as TestStats from "../test/test-stats";
import * as TestLogic from "../test/test-logic";
import * as Funbox from "../test/funbox/funbox";
import Page from "./page";
Expand All @@ -7,6 +6,7 @@ import * as ModesNotice from "../elements/modes-notice";
import * as Keymap from "../elements/keymap";
import { blurInputElement } from "../input/input-element";
import { qsr } from "../utils/dom";
import { resetIncompleteTests } from "../states/test";

export const page = new Page({
id: "test",
Expand All @@ -25,7 +25,7 @@ export const page = new Page({
},
beforeShow: async (): Promise<void> => {
updateFooterAndVerticalAds(false);
TestStats.resetIncomplete();
resetIncompleteTests();
TestLogic.restart({
noAnim: true,
});
Expand Down
22 changes: 20 additions & 2 deletions frontend/src/ts/states/test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { createSignal, createEffect } from "solid-js";
import { createSignal, createEffect, createMemo } from "solid-js";
import { Challenge } from "@monkeytype/schemas/challenges";
import { getConfig } from "../config/store";
import { getActivePage } from "./core";
import { canQuickRestart } from "../utils/quick-restart";
import { getData as getCustomTextData } from "../test/custom-text";
import { isCustomTextLong } from "../legacy-states/custom-text-name";
import { CompletedEvent, IncompleteTest } from "@monkeytype/schemas/results";
import { createSignalWithSetters } from "../hooks/createSignalWithSetters";

export const [wordsHaveNewline, setWordsHaveNewline] = createSignal(false);
export const [wordsHaveTab, setWordsHaveTab] = createSignal(false);
Expand All @@ -13,8 +15,24 @@ export const [getLoadedChallenge, setLoadedChallenge] =
createSignal<Challenge | null>(null);
export const [getResultVisible, setResultVisible] = createSignal(false);
export const [getFocus, setFocus] = createSignal(false);

export const [isTestInvalid, setIsTestInvalid] = createSignal(false);
export const [isLongTest, setIsLongTest] = createSignal(false);
export const [getLastResult, setLastResult] = createSignal<Omit<
CompletedEvent,
"hash" | "uid"
> | null>(null);
Comment thread
Miodec marked this conversation as resolved.
export const [
getIncompleteTests,
{ push: pushIncompleteTest, reset: resetIncompleteTests },
] = createSignalWithSetters<IncompleteTest[]>([])({
push: (set, val: IncompleteTest) => set((arr) => [...arr, val]),
reset: (set) => set([]),
});

export const getRestartCount = createMemo(() => getIncompleteTests().length);
export const getIncompleteSeconds = createMemo(() =>
getIncompleteTests().reduce((sum, test) => sum + test.seconds, 0),
);

createEffect(() => {
getActivePage(); // depend on active page
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/ts/test/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import * as ConnectionState from "../legacy-states/connection";
import { currentQuote } from "./test-words";
import { qs, qsa } from "../utils/dom";
import { getTheme } from "../states/theme";
import { isTestInvalid } from "../states/test";

let result: CompletedEvent;
let minChartVal: number;
Expand Down Expand Up @@ -833,7 +834,7 @@ function updateOther(
if (afkDetected) {
otherText += "<br>afk detected";
}
if (TestStats.invalid) {
if (isTestInvalid()) {
otherText += "<br>invalid";
const extra: string[] = [];
if (
Expand Down
42 changes: 22 additions & 20 deletions frontend/src/ts/test/test-logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ import { clearQuoteStats } from "../states/quote-rate";
import * as Result from "./result";
import { getActivePage, isAuthenticated } from "../states/core";
import {
getIncompleteSeconds,
getIncompleteTests,
getRestartCount,
pushIncompleteTest,
resetIncompleteTests,
setIsTestInvalid,
setLastResult,
setResultVisible,
setWordsHaveNewline,
setWordsHaveTab,
Expand Down Expand Up @@ -253,10 +260,8 @@ export function restart(options = {} as RestartOptions): void {
const afkseconds = TestStats.calculateAfkSeconds(testSeconds);
let tt = Numbers.roundTo2(testSeconds - afkseconds);
if (tt < 0) tt = 0;
TestStats.incrementIncompleteSeconds(tt);
TestStats.incrementRestartCount();
const acc = Numbers.roundTo2(TestStats.calculateAccuracy());
TestStats.pushIncompleteTest(acc, tt);
pushIncompleteTest({ acc, seconds: tt });
}
}

Expand Down Expand Up @@ -297,6 +302,7 @@ export function restart(options = {} as RestartOptions): void {
}

TestTimer.clear();
setIsTestInvalid(false);
TestStats.restart();
TestInput.restart();
TestInput.corrected.reset();
Expand Down Expand Up @@ -846,12 +852,10 @@ function buildCompletedEvent(
lazyMode: Config.lazyMode,
timestamp: Date.now(),
language: language,
restartCount: TestStats.restartCount,
incompleteTests: TestStats.incompleteTests,
restartCount: getRestartCount(),
incompleteTests: getIncompleteTests(),
incompleteTestSeconds:
TestStats.incompleteSeconds < 0
? 0
: Numbers.roundTo2(TestStats.incompleteSeconds),
getIncompleteSeconds() < 0 ? 0 : Numbers.roundTo2(getIncompleteSeconds()),
difficulty: Config.difficulty,
blindMode: Config.blindMode,
tags: activeTagsIds,
Expand Down Expand Up @@ -1013,7 +1017,7 @@ export async function finish(difficultyFailed = false): Promise<void> {

const completedEvent = structuredClone(ce) as CompletedEvent;

TestStats.setLastResult(structuredClone(completedEvent));
setLastResult(structuredClone(completedEvent));

///////// completed event ready

Expand All @@ -1036,7 +1040,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
) {
showNoticeNotification("Test invalid - inconsistent test duration");
console.error("Test duration inconsistent", ce.testDuration, dateDur);
TestStats.setInvalid();
setIsTestInvalid(true);
dontSave = true;
} else if (difficultyFailed) {
showNoticeNotification(`Test failed - ${failReason}`, {
Expand All @@ -1063,16 +1067,16 @@ export async function finish(difficultyFailed = false): Promise<void> {
(Config.mode === "zen" && completedEvent.testDuration < 15)
) {
showNoticeNotification("Test invalid - too short");
TestStats.setInvalid();
setIsTestInvalid(true);
tooShort = true;
dontSave = true;
} else if (afkDetected) {
showNoticeNotification("Test invalid - AFK detected");
TestStats.setInvalid();
setIsTestInvalid(true);
dontSave = true;
} else if (TestState.isRepeated) {
showNoticeNotification("Test invalid - repeated");
TestStats.setInvalid();
setIsTestInvalid(true);
dontSave = true;
} else if (
completedEvent.wpm < 0 ||
Expand All @@ -1084,7 +1088,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
completedEvent.mode2 === "10")
) {
showNoticeNotification("Test invalid - wpm");
TestStats.setInvalid();
setIsTestInvalid(true);
dontSave = true;
} else if (
completedEvent.rawWpm < 0 ||
Expand All @@ -1096,7 +1100,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
completedEvent.mode2 === "10")
) {
showNoticeNotification("Test invalid - raw");
TestStats.setInvalid();
setIsTestInvalid(true);
dontSave = true;
} else if (
(!DB.getSnapshot()?.lbOptOut &&
Expand All @@ -1105,7 +1109,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
(completedEvent.acc < 50 || completedEvent.acc > 100))
) {
showNoticeNotification("Test invalid - accuracy");
TestStats.setInvalid();
setIsTestInvalid(true);
dontSave = true;
}

Expand All @@ -1118,9 +1122,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
let tt = Numbers.roundTo2(testSeconds - afkseconds);
if (tt < 0) tt = 0;
const acc = completedEvent.acc;
TestStats.incrementIncompleteSeconds(tt);
TestStats.incrementRestartCount();
TestStats.pushIncompleteTest(acc, tt);
pushIncompleteTest({ acc, seconds: tt });
}
}

Expand Down Expand Up @@ -1180,7 +1182,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
if (dontSave) {
void AnalyticsController.log("testCompletedInvalid");
} else {
TestStats.resetIncomplete();
resetIncompleteTests();

if (!completedEvent.bailedOut) {
const challenge = ChallengeContoller.verify(completedEvent);
Expand Down
39 changes: 2 additions & 37 deletions frontend/src/ts/test/test-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import * as TestInput from "./test-input";
import * as TestWords from "./test-words";
import * as TestState from "./test-state";
import * as Numbers from "@monkeytype/util/numbers";
import { CompletedEvent, IncompleteTest } from "@monkeytype/schemas/results";
import { isFunboxActiveWithProperty } from "./funbox/list";
import * as CustomText from "./custom-text";
import { getLastResult } from "../states/test";

type CharCount = {
spaces: number;
Expand All @@ -33,21 +33,14 @@ export type Stats = {
correctSpaces: number;
};

export let invalid = false;
export let start: number, end: number;
export let start2: number, end2: number;
export let start3: number, end3: number;
export let lastSecondNotRound = false;

export let lastResult: Omit<CompletedEvent, "hash" | "uid">;

export function setLastResult(result: CompletedEvent): void {
lastResult = result;
}

export function getStats(): unknown {
const ret = {
lastResult,
lastResult: getLastResult(),
start,
end,
start3,
Expand Down Expand Up @@ -106,37 +99,9 @@ export function getStats(): unknown {
export function restart(): void {
start = 0;
end = 0;
invalid = false;
lastSecondNotRound = false;
}

export let restartCount = 0;
export let incompleteSeconds = 0;

export let incompleteTests: IncompleteTest[] = [];

export function incrementRestartCount(): void {
restartCount++;
}

export function incrementIncompleteSeconds(val: number): void {
incompleteSeconds += val;
}

export function pushIncompleteTest(acc: number, seconds: number): void {
incompleteTests.push({ acc, seconds });
}

export function resetIncomplete(): void {
restartCount = 0;
incompleteSeconds = 0;
incompleteTests = [];
}

export function setInvalid(): void {
invalid = true;
}

export function calculateTestSeconds(now?: number): number {
let duration = (end - start) / 1000;

Expand Down
Loading