mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2026-01-09 00:45:32 +08:00
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:
parent
22b29aeea7
commit
87073a3700
15 changed files with 779 additions and 2416 deletions
|
|
@ -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
2384
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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...",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
57
src/js/test/live-burst.js
Normal 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");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, """)
|
||||
.replace(/ /g, "_")}">`;
|
||||
} else {
|
||||
wordEl = `<div class='word' input="${input
|
||||
.replace(/"/g, """)
|
||||
.replace(/ /g, "_")}">`;
|
||||
wordEl = `<div class='word' burst="${
|
||||
TestStats.burstHistory[i]
|
||||
}" input="${input.replace(/"/g, """).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, """)
|
||||
.replace(/ /g, "_")}">`;
|
||||
wordEl = `<div class='word error' burst="${
|
||||
TestStats.burstHistory[i]
|
||||
}" input="${input.replace(/"/g, """).replace(/ /g, "_")}">`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Config.mode != "zen" && input !== word) {
|
||||
wordEl = `<div class='word error' input="${input
|
||||
.replace(/"/g, """)
|
||||
.replace(/ /g, "_")}">`;
|
||||
wordEl = `<div class='word error' burst="${
|
||||
TestStats.burstHistory[i]
|
||||
}" input="${input.replace(/"/g, """).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, "<")
|
||||
.replace(/>/g, ">")}</div>`
|
||||
`<div class="wordInputAfter">
|
||||
<div class="text">
|
||||
${input
|
||||
.replace(/\t/g, "_")
|
||||
.replace(/\n/g, "_")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")}
|
||||
</div>
|
||||
<div class="speed">
|
||||
${burst}wpm
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@
|
|||
"chart chart"
|
||||
"morestats morestats";
|
||||
.stats {
|
||||
grid-template-areas: "wpm acc";
|
||||
grid-template-areas: "wpm acc burst";
|
||||
gap: 4rem;
|
||||
}
|
||||
.stats.morestats {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue