Added min burst (#1579) started by yzAlvin

* Added min burst

* no need to calculate burst on a timer

* added a burst history and current burst trackers, added set and push functions, removed burst calculating in stats (should be done on word completion)

* burst will not be calculated on every keypress

* calculating burst and pushing to history on space
setting start time on first keypress

* verifying that burst history and input history are the same length

* bursthistory typo
added function to calculate burst speed and updated the pushing function to consider if the word was already completed once before

* removed fail condition from timer

* removed debug notification

* added fail condition

* rounding burst

* making sure to load burst config

* styling burst display

* including burst in the result

* renamed variable

* removed burst from result screen, changed wording in settings page

* reran npm i to regenerate package lock in version 2

* audit fix

* gulp update

* added two burst modes: flex and fixed

* standardized some code

* swapped classes

* updated settings page min burst input
updated min burst description

* updated the setting sections with inputs to a new, better design

Co-authored-by: Jack <bartnikjack@gmail.com>
This commit is contained in:
Alvin Zhao 2021-06-30 03:55:59 +10:00 committed by GitHub
parent 22b29aeea7
commit 87073a3700
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 779 additions and 2416 deletions

View file

@ -7,8 +7,8 @@ const source = require("vinyl-source-stream");
const buffer = require("vinyl-buffer");
const vinylPaths = require("vinyl-paths");
const eslint = require("gulp-eslint");
var sass = require("gulp-sass");
sass.compiler = require("dart-sass");
var sass = require("gulp-sass")(require("dart-sass"));
// sass.compiler = require("dart-sass");
let eslintConfig = {
parser: "babel-eslint",
@ -156,6 +156,7 @@ const refactoredSrc = [
"./src/js/test/live-wpm.js",
"./src/js/test/caps-warning.js",
"./src/js/test/live-acc.js",
"./src/js/test/live-burst.js",
"./src/js/test/test-leaderboards.js",
"./src/js/test/timer-progress.js",
"./src/js/test/test-logic.js",

2384
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,7 @@
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-eslint": "^6.0.0",
"gulp-sass": "^4.1.0",
"gulp-sass": "^5.0.0",
"husky": "^4.3.0",
"prettier": "2.1.2",
"pretty-quick": "^3.1.0",

View file

@ -675,6 +675,33 @@ let commandsMinAcc = {
],
};
let commandsMinBurst = {
title: "Change min burst mode...",
list: [
{
id: "setMinBurstOff",
display: "off",
exec: () => {
UpdateConfig.setMinBurst("off");
},
},
{
id: "setMinBurstFixed",
display: "fixed",
exec: () => {
UpdateConfig.setMinBurst("fixed");
},
},
{
id: "setMinBurstFlex",
display: "flex",
exec: () => {
UpdateConfig.setMinBurst("flex");
},
},
],
};
let commandsKeymapStyle = {
title: "Change keymap style...",
list: [
@ -1483,6 +1510,13 @@ export let defaultCommands = {
UpdateConfig.toggleLiveAcc();
},
},
{
id: "toggleShowLiveBurst",
display: "Toggle live burst display",
exec: () => {
UpdateConfig.toggleShowLiveBurst();
},
},
{
id: "toggleTimerProgressBar",
display: "Toggle timer/progress display",
@ -1575,6 +1609,25 @@ export let defaultCommands = {
Commandline.show();
},
},
{
id: "changeMinBurst",
display: "Change min burst mode...",
alias: "minimum",
subgroup: true,
exec: () => {
current.push(commandsMinBurst);
Commandline.show();
},
},
{
id: "changeMinBurstSpeed",
display: "Change min burst speed...",
alias: "minimum",
input: true,
exec: (input) => {
UpdateConfig.setMinBurstCustomSpeed(input);
},
},
{
id: "changeOppositeShiftMode",
display: "Change opposite shift mode...",

View file

@ -6,6 +6,7 @@ import * as OutOfFocus from "./out-of-focus";
import * as TimerProgress from "./timer-progress";
import * as LiveWpm from "./live-wpm";
import * as LiveAcc from "./live-acc";
import * as LiveBurst from "./live-burst";
import * as Funbox from "./funbox";
import * as Notifications from "./notifications";
import * as ThemeController from "./theme-controller";
@ -570,6 +571,24 @@ export function setMinAccCustom(val, nosave) {
if (!nosave) saveToLocalStorage();
}
//min burst
export function setMinBurst(min, nosave) {
if (min == undefined) {
min = "off";
}
config.minBurst = min;
TestUI.updateModesNotice();
if (!nosave) saveToLocalStorage();
}
export function setMinBurstCustomSpeed(val, nosave) {
if (val == undefined || Number.isNaN(parseInt(val))) {
val = 100;
}
config.minBurstCustomSpeed = val;
if (!nosave) saveToLocalStorage();
}
//always show words history
export function setAlwaysShowWordsHistory(val, nosave) {
if (val == undefined) {
@ -851,6 +870,29 @@ export function toggleLiveAcc() {
saveToLocalStorage();
}
export function setShowLiveBurst(live, nosave) {
if (live == null || live == undefined) {
live = false;
}
config.showLiveBurst = live;
if (live) {
LiveBurst.show();
} else {
LiveAcc.hide();
}
if (!nosave) saveToLocalStorage();
}
export function toggleShowLiveBurst() {
config.showLiveBurst = !config.showLiveBurst;
if (config.showLiveBurst) {
LiveBurst.show();
} else {
LiveBurst.hide();
}
saveToLocalStorage();
}
export function setHighlightMode(mode, nosave) {
if (
mode === "word" &&
@ -1554,6 +1596,7 @@ export function apply(configObj) {
setSmoothLineScroll(configObj.smoothLineScroll, true);
setShowLiveWpm(configObj.showLiveWpm, true);
setShowLiveAcc(configObj.showLiveAcc, true);
setShowLiveBurst(configObj.showLiveBurst, true);
setShowTimerProgress(configObj.showTimerProgress, true);
setAlwaysShowDecimalPlaces(configObj.alwaysShowDecimalPlaces, true);
setAlwaysShowWordsHistory(configObj.alwaysShowWordsHistory, true);
@ -1573,6 +1616,8 @@ export function apply(configObj) {
setPageWidth(configObj.pageWidth, true);
setChartAccuracy(configObj.chartAccuracy, true);
setChartStyle(configObj.chartStyle, true);
setMinBurst(configObj.minBurst, true);
setMinBurstCustomSpeed(configObj.minBurstCustomSpeed, true);
setMinWpm(configObj.minWpm, true);
setMinWpmCustomSpeed(configObj.minWpmCustomSpeed, true);
setMinAcc(configObj.minAcc, true);

View file

@ -6,6 +6,7 @@ import Config, * as UpdateConfig from "./config";
import * as Keymap from "./keymap";
import * as Misc from "./misc";
import * as LiveAcc from "./live-acc";
import * as LiveBurst from "./live-burst";
import * as Funbox from "./funbox";
import * as Sound from "./sound";
import * as Caret from "./caret";
@ -233,6 +234,11 @@ function handleSpace(event, isEnter) {
Settings.groups.layout.updateButton();
}
dontInsertSpace = true;
let burst = TestStats.calculateBurst();
LiveBurst.update(Math.round(burst));
TestStats.pushBurstToHistory(burst);
if (currentWord == TestLogic.input.current || Config.mode == "zen") {
//correct word or in zen mode
MonkeyPower.addPower(true, true);
@ -315,6 +321,18 @@ function handleSpace(event, isEnter) {
Replay.addReplayEvent("submitErrorWord");
}
let flex = Misc.whorf(
Config.minBurstCustomSpeed,
TestLogic.words.getLast().length
);
if (
(Config.minBurst === "fixed" && burst < Config.minBurstCustomSpeed) ||
(Config.minBurst === "flex" && burst < flex)
) {
TestLogic.fail();
return;
}
TestLogic.corrected.pushHistory();
if (
@ -496,6 +514,10 @@ function handleAlpha(event) {
if (!TestLogic.active) return;
}
if (TestLogic.input.current == "") {
TestStats.setBurstStart(performance.now());
}
Focus.set(true);
Caret.stopAnimation();

View file

@ -429,6 +429,13 @@ export function kogasa(cov) {
);
}
export function whorf(speed, wordlen) {
return Math.min(
speed,
Math.floor(speed * Math.pow(1.03, -2 * (wordlen - 3)))
);
}
export function roundTo2(num) {
return Math.round((num + Number.EPSILON) * 100) / 100;
}

View file

@ -39,6 +39,10 @@ async function initGroups() {
"showLiveAcc",
UpdateConfig.setShowLiveAcc
);
groups.showLiveBurst = new SettingsGroup(
"showLiveBurst",
UpdateConfig.setShowLiveBurst
);
groups.showTimerProgress = new SettingsGroup(
"showTimerProgress",
UpdateConfig.setShowTimerProgress
@ -178,45 +182,14 @@ async function initGroups() {
"showAllLines",
UpdateConfig.setShowAllLines
);
groups.paceCaret = new SettingsGroup(
"paceCaret",
UpdateConfig.setPaceCaret,
() => {
if (Config.paceCaret === "custom") {
$(
".pageSettings .section.paceCaret input.customPaceCaretSpeed"
).removeClass("hidden");
} else {
$(
".pageSettings .section.paceCaret input.customPaceCaretSpeed"
).addClass("hidden");
}
}
);
groups.paceCaret = new SettingsGroup("paceCaret", UpdateConfig.setPaceCaret);
groups.repeatedPace = new SettingsGroup(
"repeatedPace",
UpdateConfig.setRepeatedPace
);
groups.minWpm = new SettingsGroup("minWpm", UpdateConfig.setMinWpm, () => {
if (Config.minWpm === "custom") {
$(".pageSettings .section.minWpm input.customMinWpmSpeed").removeClass(
"hidden"
);
} else {
$(".pageSettings .section.minWpm input.customMinWpmSpeed").addClass(
"hidden"
);
}
});
groups.minAcc = new SettingsGroup("minAcc", UpdateConfig.setMinAcc, () => {
if (Config.minAcc === "custom") {
$(".pageSettings .section.minAcc input.customMinAcc").removeClass(
"hidden"
);
} else {
$(".pageSettings .section.minAcc input.customMinAcc").addClass("hidden");
}
});
groups.minWpm = new SettingsGroup("minWpm", UpdateConfig.setMinWpm);
groups.minAcc = new SettingsGroup("minAcc", UpdateConfig.setMinAcc);
groups.minBurst = new SettingsGroup("minBurst", UpdateConfig.setMinBurst);
groups.smoothLineScroll = new SettingsGroup(
"smoothLineScroll",
UpdateConfig.setSmoothLineScroll
@ -517,40 +490,18 @@ export function update() {
updateDiscordSection();
ThemePicker.refreshButtons();
if (Config.paceCaret === "custom") {
$(
".pageSettings .section.paceCaret input.customPaceCaretSpeed"
).removeClass("hidden");
$(".pageSettings .section.paceCaret input.customPaceCaretSpeed").val(
Config.paceCaretCustomSpeed
);
} else {
$(".pageSettings .section.paceCaret input.customPaceCaretSpeed").addClass(
"hidden"
);
}
if (Config.minWpm === "custom") {
$(".pageSettings .section.minWpm input.customMinWpmSpeed").removeClass(
"hidden"
);
$(".pageSettings .section.minWpm input.customMinWpmSpeed").val(
Config.minWpmCustomSpeed
);
} else {
$(".pageSettings .section.minWpm input.customMinWpmSpeed").addClass(
"hidden"
);
}
if (Config.minAcc === "custom") {
$(".pageSettings .section.minAcc input.customMinAcc").removeClass("hidden");
$(".pageSettings .section.minAcc input.customMinAcc").val(
Config.minAccCustom
);
} else {
$(".pageSettings .section.minAcc input.customMinAcc").addClass("hidden");
}
$(".pageSettings .section.paceCaret input.customPaceCaretSpeed").val(
Config.paceCaretCustomSpeed
);
$(".pageSettings .section.minWpm input.customMinWpmSpeed").val(
Config.minWpmCustomSpeed
);
$(".pageSettings .section.minAcc input.customMinAcc").val(
Config.minAccCustom
);
$(".pageSettings .section.minBurst input.customMinBurst").val(
Config.minBurstCustomSpeed
);
}
function toggleSettingsGroup(groupName) {
@ -605,6 +556,18 @@ $(document).on(
}
);
$(document).on(
"click",
".pageSettings .section.paceCaret .button.save",
(e) => {
UpdateConfig.setMinBurstCustomSpeed(
parseInt(
$(".pageSettings .section.paceCaret input.customPaceCaretSpeed").val()
)
);
}
);
$(document).on(
"focusout",
".pageSettings .section.minWpm input.customMinWpmSpeed",
@ -615,6 +578,12 @@ $(document).on(
}
);
$(document).on("click", ".pageSettings .section.minWpm .button.save", (e) => {
UpdateConfig.setMinBurstCustomSpeed(
parseInt($(".pageSettings .section.minWpm input.customMinWpmSpeed").val())
);
});
$(document).on(
"focusout",
".pageSettings .section.minAcc input.customMinAcc",
@ -625,6 +594,28 @@ $(document).on(
}
);
$(document).on("click", ".pageSettings .section.minAcc .button.save", (e) => {
UpdateConfig.setMinBurstCustomSpeed(
parseInt($(".pageSettings .section.minAcc input.customMinAcc").val())
);
});
$(document).on(
"focusout",
".pageSettings .section.minBurst input.customMinBurst",
(e) => {
UpdateConfig.setMinBurstCustomSpeed(
parseInt($(".pageSettings .section.minBurst input.customMinBurst").val())
);
}
);
$(document).on("click", ".pageSettings .section.minBurst .button.save", (e) => {
UpdateConfig.setMinBurstCustomSpeed(
parseInt($(".pageSettings .section.minBurst input.customMinBurst").val())
);
});
$(document).on(
"click",
".pageSettings .section.languageGroups .button",
@ -788,23 +779,21 @@ $(".pageSettings #updateAccountPassword").on("click", (e) => {
SimplePopups.list.updatePassword.show();
});
$(".pageSettings .section.customBackgroundSize .inputAndButton .save").on(
$(".pageSettings .section.customBackgroundSize .inputAndSave .save").on(
"click",
(e) => {
UpdateConfig.setCustomBackground(
$(
".pageSettings .section.customBackgroundSize .inputAndButton input"
).val()
$(".pageSettings .section.customBackgroundSize .inputAndSave input").val()
);
}
);
$(".pageSettings .section.customBackgroundSize .inputAndButton input").keypress(
$(".pageSettings .section.customBackgroundSize .inputAndSave input").keypress(
(e) => {
if (e.keyCode == 13) {
UpdateConfig.setCustomBackground(
$(
".pageSettings .section.customBackgroundSize .inputAndButton input"
".pageSettings .section.customBackgroundSize .inputAndSave input"
).val()
);
}

57
src/js/test/live-burst.js Normal file
View file

@ -0,0 +1,57 @@
import Config from "./config";
import * as TestLogic from "./test-logic";
export function update(burst) {
let number = burst;
if (Config.blindMode) {
number = 0;
}
document.querySelector("#miniTimerAndLiveWpm .burst").innerHTML = number;
document.querySelector("#liveBurst").innerHTML = number;
}
export function show() {
if (!Config.showLiveWpm) return;
if (!TestLogic.active) return;
if (Config.timerStyle === "mini") {
if (!$("#miniTimerAndLiveWpm .burst").hasClass("hidden")) return;
$("#miniTimerAndLiveWpm .burst")
.removeClass("hidden")
.css("opacity", 0)
.animate(
{
opacity: Config.timerOpacity,
},
125
);
} else {
if (!$("#liveBurst").hasClass("hidden")) return;
$("#liveBurst").removeClass("hidden").css("opacity", 0).animate(
{
opacity: Config.timerOpacity,
},
125
);
}
}
export function hide() {
$("#liveBurst").animate(
{
opacity: Config.timerOpacity,
},
125,
() => {
$("#liveBurst").addClass("hidden");
}
);
$("#miniTimerAndLiveWpm .burst").animate(
{
opacity: Config.timerOpacity,
},
125,
() => {
$("#miniTimerAndLiveWpm .burst").addClass("hidden");
}
);
}

View file

@ -15,6 +15,7 @@ import * as PaceCaret from "./pace-caret";
import * as Caret from "./caret";
import * as LiveWpm from "./live-wpm";
import * as LiveAcc from "./live-acc";
import * as LiveBurst from "./live-burst";
import * as TimerProgress from "./timer-progress";
import * as ChartController from "./chart-controller";
import * as UI from "./ui";
@ -126,7 +127,11 @@ class Input {
}
getHistory(i) {
return this.history[i];
if (i === undefined) {
return this.history;
} else {
return this.history[i];
}
}
}
@ -347,6 +352,7 @@ export function startTest() {
$("#liveWpm").text("0");
LiveWpm.show();
LiveAcc.show();
LiveBurst.show();
TimerProgress.update(TestTimer.time);
TestTimer.clear();
@ -744,6 +750,7 @@ export function restart(
Replay.stopReplayRecording();
LiveWpm.hide();
LiveAcc.hide();
LiveBurst.hide();
TimerProgress.hide();
setBailout(false);
PaceCaret.reset();
@ -810,8 +817,10 @@ export function restart(
}
document.querySelector("#miniTimerAndLiveWpm .wpm").innerHTML = "0";
document.querySelector("#miniTimerAndLiveWpm .acc").innerHTML = "100%";
document.querySelector("#miniTimerAndLiveWpm .burst").innerHTML = "0";
document.querySelector("#liveWpm").innerHTML = "0";
document.querySelector("#liveAcc").innerHTML = "100%";
document.querySelector("#liveBurst").innerHTML = "0";
if (Config.funbox === "memory") {
Funbox.startMemoryTimer();
@ -1043,9 +1052,16 @@ export function finish(difficultyFailed = false) {
LiveWpm.hide();
PbCrown.hide();
LiveAcc.hide();
LiveBurst.hide();
TimerProgress.hide();
Funbox.activate("none", null);
if (TestStats.burstHistory.length !== input.getHistory().length) {
//auto ended test, need one more calculation for the last word
let burst = TestStats.calculateBurst();
TestStats.pushBurstToHistory(burst);
}
if (
Misc.roundTo2(TestStats.calculateTestSeconds()) % 1 != 0 &&
Config.mode !== "time"

View file

@ -8,6 +8,7 @@ export let invalid = false;
export let start, end;
export let wpmHistory = [];
export let rawHistory = [];
export let burstHistory = [];
export let keypressPerSecond = [];
export let currentKeypress = {
@ -16,8 +17,8 @@ export let currentKeypress = {
errors: 0,
words: [],
};
export let lastKeypress;
export let currentBurstStart = 0;
// export let errorsPerSecond = [];
// export let currentError = {
@ -47,6 +48,7 @@ export function restart() {
invalid = false;
wpmHistory = [];
rawHistory = [];
burstHistory = [];
keypressPerSecond = [];
currentKeypress = {
count: 0,
@ -54,6 +56,7 @@ export function restart() {
errors: 0,
words: [],
};
currentBurstStart = 0;
// errorsPerSecond = [];
// currentError = {
// count: 0,
@ -159,9 +162,9 @@ export function pushKeypressesToHistory() {
export function calculateAfkSeconds(testSeconds) {
let extraAfk = 0;
if (testSeconds !== undefined) {
if(Config.mode === "time"){
if (Config.mode === "time") {
extraAfk = Math.round(testSeconds) - keypressPerSecond.length;
}else{
} else {
extraAfk = Math.ceil(testSeconds) - keypressPerSecond.length;
}
if (extraAfk < 0) extraAfk = 0;
@ -180,6 +183,27 @@ export function setLastSecondNotRound() {
lastSecondNotRound = true;
}
export function setBurstStart(time) {
currentBurstStart = time;
}
export function calculateBurst() {
let timeToWrite = (performance.now() - currentBurstStart) / 1000;
let speed = Misc.roundTo2(
(TestLogic.words.getCurrent().length * (60 / timeToWrite)) / 5
);
return Math.round(speed);
}
export function pushBurstToHistory(speed) {
if (burstHistory[TestLogic.words.currentIndex] === undefined) {
burstHistory.push(speed);
} else {
//repeated word - override
burstHistory[TestLogic.words.currentIndex] = speed;
}
}
export function calculateAccuracy() {
return (accuracy.correct / (accuracy.correct + accuracy.incorrect)) * 100;
}

View file

@ -14,6 +14,7 @@ import * as OutOfFocus from "./out-of-focus";
import * as ManualRestart from "./manual-restart-tracker";
import * as PractiseMissed from "./practise-missed";
import * as Replay from "./replay";
import * as TestStats from "./test-stats";
export let currentWordElementIndex = 0;
export let resultVisible = false;
@ -513,8 +514,6 @@ export function updateModesNotice() {
? "average"
: Config.paceCaret === "pb"
? "pb"
: Config.paceCaret == "repeat"
? "repeated"
: "custom"
} pace${speed}</div>`
);
@ -532,6 +531,14 @@ export function updateModesNotice() {
);
}
if (Config.minBurst !== "off") {
$(".pageTest #testModesNotice").append(
`<div class="text-button" commands="commandsMinBurst"><i class="fas fa-bomb"></i>min ${
Config.minBurstCustomSpeed
} burst ${Config.minBurst === "flex" ? "(flex)" : ""}</div>`
);
}
if (Config.funbox !== "none") {
$(".pageTest #testModesNotice").append(
`<div class="text-button" commands="commandsFunbox"><i class="fas fa-gamepad"></i>${Config.funbox.replace(
@ -629,14 +636,16 @@ async function loadWordsHistory() {
TestLogic.corrected.getHistory(i) !== undefined &&
TestLogic.corrected.getHistory(i) !== ""
) {
wordEl = `<div class='word' input="${TestLogic.corrected
wordEl = `<div class='word' burst="${
TestStats.burstHistory[i]
}" input="${TestLogic.corrected
.getHistory(i)
.replace(/"/g, "&quot;")
.replace(/ /g, "_")}">`;
} else {
wordEl = `<div class='word' input="${input
.replace(/"/g, "&quot;")
.replace(/ /g, "_")}">`;
wordEl = `<div class='word' burst="${
TestStats.burstHistory[i]
}" input="${input.replace(/"/g, "&quot;").replace(/ /g, "_")}">`;
}
if (i === TestLogic.input.history.length - 1) {
//last word
@ -661,16 +670,16 @@ async function loadWordsHistory() {
}
if (wordstats.incorrect !== 0 || Config.mode !== "time") {
if (Config.mode != "zen" && input !== word) {
wordEl = `<div class='word error' input="${input
.replace(/"/g, "&quot;")
.replace(/ /g, "_")}">`;
wordEl = `<div class='word error' burst="${
TestStats.burstHistory[i]
}" input="${input.replace(/"/g, "&quot;").replace(/ /g, "_")}">`;
}
}
} else {
if (Config.mode != "zen" && input !== word) {
wordEl = `<div class='word error' input="${input
.replace(/"/g, "&quot;")
.replace(/ /g, "_")}">`;
wordEl = `<div class='word error' burst="${
TestStats.burstHistory[i]
}" input="${input.replace(/"/g, "&quot;").replace(/ /g, "_")}">`;
}
}
@ -821,13 +830,21 @@ $("#wpmChart").on("mouseleave", (e) => {
$(document).on("mouseenter", "#resultWordsHistory .words .word", (e) => {
if (resultVisible) {
let input = $(e.currentTarget).attr("input");
let burst = $(e.currentTarget).attr("burst");
if (input != undefined)
$(e.currentTarget).append(
`<div class="wordInputAfter">${input
.replace(/\t/g, "_")
.replace(/\n/g, "_")
.replace(/</g, "&lt")
.replace(/>/g, "&gt")}</div>`
`<div class="wordInputAfter">
<div class="text">
${input
.replace(/\t/g, "_")
.replace(/\n/g, "_")
.replace(/</g, "&lt")
.replace(/>/g, "&gt")}
</div>
<div class="speed">
${burst}wpm
</div>
</div>`
);
}
});

View file

@ -144,7 +144,7 @@
"chart chart"
"morestats morestats";
.stats {
grid-template-areas: "wpm acc";
grid-template-areas: "wpm acc burst";
gap: 4rem;
}
.stats.morestats {

View file

@ -1304,6 +1304,10 @@ label.checkbox {
opacity: 0;
}
#liveBurst {
opacity: 0;
}
#timerNumber {
pointer-events: none;
transition: 0.25s;
@ -1939,7 +1943,8 @@ key {
// "wpm raw time nothing infoAndTags leaderboards source";
grid-template-areas:
"wpm"
"acc";
"acc"
"burst";
&.morestats {
display: grid;
@ -2089,6 +2094,20 @@ key {
}
}
.burst {
grid-area: burst;
.top {
font-size: 2rem;
line-height: 1.5rem;
}
.bottom {
font-size: 4rem;
line-height: 4rem;
}
}
// .key {
// grid-area: key;
// }
@ -2385,13 +2404,15 @@ key {
margin-right: 2rem;
}
.wpm {
.wpm,
.acc {
margin-right: 2rem;
}
.time,
.wpm,
.acc {
.acc,
.burst {
opacity: 0;
}
@ -2483,6 +2504,11 @@ key {
transition: 0.25s;
text-shadow: none;
top: -0.5rem;
z-index: 10;
cursor: text;
.speed {
font-size: 0.75rem;
}
}
}
@ -2800,47 +2826,22 @@ key {
}
}
// I have no idea what I'm doing so I just copied the customBackgroundSize css and changed numbers so it magically worked.
&.customLayoutfluid {
.inputAndSave {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 0.5rem;
margin-bottom: 0.5rem;
input {
grid-column: 1/3;
}
.save {
grid-column: 3/4;
height: auto;
.fas {
margin-right: 0rem;
vertical-align: sub;
}
}
.inputAndSave {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 0.5rem;
margin-bottom: 0.5rem;
input {
grid-column: 1/3;
}
}
&.customBackgroundSize {
.inputAndButton {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 0.5rem;
margin-bottom: 0.5rem;
input {
grid-column: 1/3;
}
.save {
grid-column: 3/4;
height: auto;
.save {
grid-column: 3/4;
height: auto;
.fas {
margin-right: 0rem;
vertical-align: sub;
}
.fas {
margin-right: 0rem;
vertical-align: sub;
}
}
}
@ -2888,13 +2889,6 @@ key {
}
}
&.paceCaret {
.customPaceCaretSpeed {
width: 4rem;
padding: 0 0.5rem;
}
}
h1 {
font-size: 1rem;
line-height: 1rem;

View file

@ -1122,6 +1122,7 @@
<div class="time hidden">1:00</div>
<div class="wpm">60</div>
<div class="acc">100%</div>
<div class="burst">1</div>
</div>
<div class="outOfFocusWarning hidden">
<i class="fas fa-mouse-pointer"></i>
@ -1307,6 +1308,7 @@
<div id="largeLiveWpmAndAcc" class="timerMain">
<div id="liveWpm" class="hidden">123</div>
<div id="liveAcc" class="hidden">100%%</div>
<div id="liveBurst" class="hidden">1</div>
</div>
<div
id="restartTestButton"
@ -2248,31 +2250,43 @@
Automatically fails a test if your WPM falls below a
threshold.
</div>
<div class="buttons">
<div
class="button"
minWpm="off"
tabindex="0"
onclick="this.blur();"
>
off
<div>
<div class="inputAndSave">
<input
type="number"
placeholder="min wpm"
class="input customMinWpmSpeed"
tabindex="0"
min="0"
step="1"
value=""
/>
<div
class="button save"
tabindex="0"
onclick="this.blur();"
>
<i class="fas fa-save fa-fw"></i>
</div>
</div>
<div
class="button"
minWpm="custom"
tabindex="0"
onclick="this.blur();"
>
custom
<div class="buttons">
<div
class="button"
minWpm="off"
tabindex="0"
onclick="this.blur();"
>
off
</div>
<div
class="button"
minWpm="custom"
tabindex="0"
onclick="this.blur();"
>
custom
</div>
</div>
<input
type="number"
step="1"
class="customMinWpmSpeed"
placeholder="wpm"
min="0"
value=""
/>
</div>
</div>
<div class="section minAcc" section="">
@ -2281,31 +2295,97 @@
Automatically fails a test if your accuracy falls below a
threshold.
</div>
<div class="buttons">
<div
class="button"
minAcc="off"
tabindex="0"
onclick="this.blur();"
>
off
<div>
<div class="inputAndSave">
<input
type="number"
placeholder="min accuracy"
class="input customMinAcc"
tabindex="0"
min="0"
step="1"
value=""
/>
<div
class="button save"
tabindex="0"
onclick="this.blur();"
>
<i class="fas fa-save fa-fw"></i>
</div>
</div>
<div
class="button"
minAcc="custom"
tabindex="0"
onclick="this.blur();"
>
custom
<div class="buttons">
<div
class="button"
minAcc="off"
tabindex="0"
onclick="this.blur();"
>
off
</div>
<div
class="button"
minAcc="custom"
tabindex="0"
onclick="this.blur();"
>
custom
</div>
</div>
</div>
</div>
<div class="section minBurst" section="">
<h1>min burst</h1>
<div class="text">
Automatically fails a test if your burst speed falls below a
threshold. Selecting 'flex' allows for this threshold to
automatically decrease for longer words.
</div>
<div>
<div class="inputAndSave">
<input
type="number"
placeholder="min burst"
class="input customMinBurst"
tabindex="0"
min="0"
step="1"
value=""
/>
<div
class="button save"
tabindex="0"
onclick="this.blur();"
>
<i class="fas fa-save fa-fw"></i>
</div>
</div>
<div class="buttons">
<div
class="button"
minBurst="off"
tabindex="0"
onclick="this.blur();"
>
off
</div>
<div
class="button"
minBurst="fixed"
tabindex="0"
onclick="this.blur();"
>
fixed
</div>
<div
class="button"
minBurst="flex"
tabindex="0"
onclick="this.blur();"
>
flex
</div>
</div>
<input
type="number"
step="1"
class="customMinAcc"
placeholder="acc"
min="0"
value=""
/>
</div>
</div>
<div class="section languageGroups fullWidth">
@ -2709,58 +2789,61 @@
<h1>pace caret</h1>
<div class="text">
Displays a second caret that moves at constant speed. The
repeat option enables a pace caret when a test is repeated
that will have the wpm of the previous test.
'average' option average the speed of last 10 results.
</div>
<div class="buttons">
<div
class="button"
paceCaret="off"
tabindex="0"
onclick="this.blur();"
>
off
<div>
<div class="inputAndSave">
<input
type="number"
placeholder="wpm"
class="input customPaceCaretSpeed"
tabindex="0"
min="0"
step="1"
value=""
/>
<div
class="button save"
tabindex="0"
onclick="this.blur();"
>
<i class="fas fa-save fa-fw"></i>
</div>
</div>
<div
class="button"
paceCaret="average"
tabindex="0"
onclick="this.blur();"
>
average
<div class="buttons">
<div
class="button"
paceCaret="off"
tabindex="0"
onclick="this.blur();"
>
off
</div>
<div
class="button"
paceCaret="average"
tabindex="0"
onclick="this.blur();"
>
average
</div>
<div
class="button"
paceCaret="pb"
tabindex="0"
onclick="this.blur();"
>
pb
</div>
<div
class="button"
paceCaret="custom"
tabindex="0"
onclick="this.blur();"
>
custom
</div>
</div>
<div
class="button"
paceCaret="pb"
tabindex="0"
onclick="this.blur();"
>
pb
</div>
<div
class="button"
paceCaret="repeat"
tabindex="0"
onclick="this.blur();"
>
repeat
</div>
<div
class="button"
paceCaret="custom"
tabindex="0"
onclick="this.blur();"
>
custom
</div>
<input
type="number"
step="1"
class="customPaceCaretSpeed"
placeholder="wpm"
min="0"
value=""
/>
</div>
</div>
<div class="section repeatedPace" section="">
@ -3327,7 +3410,7 @@
fully visible. Max fits the image corner to corner.
</div>
<div>
<div class="inputAndButton">
<div class="inputAndSave">
<input
type="text"
placeholder="image url"
@ -3619,6 +3702,21 @@
</div>
</div>
</div>
<div class="section showLiveBurst">
<h1>live burst</h1>
<div class="text">
Displays live burst during the test of the last word you
typed.
</div>
<div class="buttons">
<div class="button off" tabindex="0" onclick="this.blur();">
hide
</div>
<div class="button on" tabindex="0" onclick="this.blur();">
show
</div>
</div>
</div>
<div class="section showTimerProgress">
<h1>timer/progress</h1>
<div class="text">