Skip to content
Open
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
25 changes: 20 additions & 5 deletions frontend/src/html/pages/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,27 @@
<div class="text">
Normal is the classic typing test experience. Expert fails the test if
you submit (press space) an incorrect word. Master fails if you press a
single incorrect key (meaning you have to achieve 100% accuracy).
single incorrect key (meaning you have to achieve 100% accuracy). Custom
allows you to set a custom accuracy threshold in words mode.
</div>
<div class="buttons">
<button data-config-value="normal">normal</button>
<button data-config-value="expert">expert</button>
<button data-config-value="master">master</button>
<div class="inputs">
<div class="inputAndButton">
<input
type="number"
placeholder="accuracy %"
class="input customDiffAcc"
tabindex="0"
min="0"
step="1"
value=""
/>
</div>
<div class="buttons">
<button data-config-value="normal">normal</button>
<button data-config-value="expert">expert</button>
<button data-config-value="master">master</button>
<button data-config-value="custom">custom</button>
</div>
</div>
</div>
<div class="section" data-config-name="quickRestart">
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/ts/config/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,21 @@ export const configMetadata: ConfigMetadataObject = {
changeRequiresRestart: true,
group: "behavior",
},
difficultyCustomAccuracy: {
key: "difficultyCustomAccuracy",
fa: { icon: "fa-star" },
displayString: "custom difficulty accuracy",
changeRequiresRestart: true,
group: "behavior",
overrideConfig: ({ currentConfig }) => {
if (currentConfig.difficulty !== "custom") {
return {
difficulty: "custom",
};
}
return {};
},
},
quickRestart: {
key: "quickRestart",
fa: { icon: "fa-redo-alt" },
Expand Down
1 change: 1 addition & 0 deletions frontend/src/ts/constants/default-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const obj: Config = {
fontSize: 2,
freedomMode: false,
difficulty: "normal",
difficultyCustomAccuracy: 100,
blindMode: false,
quickEnd: false,
caretStyle: "default",
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/ts/elements/modes-notice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ export async function update(): Promise<void> {
testModesNotice.appendHtml(
`<button class="textButton" commands="difficulty"><i class="fas fa-star"></i>master</button>`,
);
} else if (Config.difficulty === "custom") {
testModesNotice.appendHtml(
`<button class="textButton" commands="difficulty"><i class="fas fa-cog"></i>${Config.difficultyCustomAccuracy}% acc</button>`,
);
}

if (Config.blindMode) {
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/ts/pages/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,15 @@ async function fillSettingsPage(): Promise<void> {
},
});

handleConfigInput({
input: qsr(".pageSettings .section[data-config-name='difficulty'] input"),
configName: "difficultyCustomAccuracy",
validation: {
schema: true,
inputValueConvert: Number,
},
});

handleConfigInput({
input: qsr(".pageSettings .section[data-config-name='minBurst'] input"),
configName: "minBurstCustomSpeed",
Expand Down
11 changes: 5 additions & 6 deletions frontend/src/ts/test/test-timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,16 @@ function checkIfFailed(
): boolean {
if (timerDebug) console.time("fail conditions");
TestInput.pushKeypressesToHistory();
TestInput.pushErrorToHistory();
TestInput.pushAfkToHistory();

if (
Config.minWpm === "custom" &&
wpmAndRaw.wpm < Config.minWpmCustomSpeed &&
TestState.activeWordIndex > 3
Config.difficulty === "custom" &&
Config.mode === "words" &&
acc < Config.difficultyCustomAccuracy
) {
if (timer !== null) clearTimeout(timer);
SlowTimer.clear();
slowTimerCount = 0;
timerEvent.dispatch({ key: "fail", value: "min speed" });
timerEvent.dispatch({ key: "fail", value: "custom difficulty" });
return true;
}
if (Config.minAcc === "custom" && acc < Config.minAccCustom) {
Expand Down
6 changes: 6 additions & 0 deletions packages/schemas/src/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ export type MinWpmCustomSpeed = z.infer<typeof MinWpmCustomSpeedSchema>;
export const MinimumAccuracyCustomSchema = z.number().nonnegative().max(100);
export type MinimumAccuracyCustom = z.infer<typeof MinimumAccuracyCustomSchema>;

export const DifficultyCustomAccuracySchema = z.number().nonnegative().max(100);
export type DifficultyCustomAccuracy = z.infer<
typeof DifficultyCustomAccuracySchema
>;

export const MinimumBurstCustomSpeedSchema = z.number().nonnegative();
export type MinimumBurstCustomSpeed = z.infer<
typeof MinimumBurstCustomSpeedSchema
Expand Down Expand Up @@ -392,6 +397,7 @@ export const ConfigSchema = z

// behavior
difficulty: DifficultySchema,
difficultyCustomAccuracy: DifficultyCustomAccuracySchema,
quickRestart: QuickRestartSchema,
repeatQuotes: RepeatQuotesSchema,
resultSaving: z.boolean(),
Expand Down
7 changes: 6 additions & 1 deletion packages/schemas/src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { StringNumberSchema } from "./util";
import { LanguageSchema } from "./languages";

//used by config and shared
export const DifficultySchema = z.enum(["normal", "expert", "master"]);
export const DifficultySchema = z.enum([
"normal",
"expert",
"master",
"custom",
]);
export type Difficulty = z.infer<typeof DifficultySchema>;

//used by user and config
Expand Down
Loading