Merge pull request #1145 from 0x8b/custom-test-duration-input-parser

custom test duration input parser
This commit is contained in:
Jack 2021-03-28 15:40:45 +01:00 committed by GitHub
commit e2fa8cfa97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 273 additions and 128 deletions

View file

@ -130,7 +130,8 @@ const refactoredSrc = [
"./src/js/commandline-lists.js",
"./src/js/commandline.js",
"./src/js/challenge-controller.js",
"./src/js/custom-mode2-popup.js",
"./src/js/custom-word-amount-popup.js",
"./src/js/custom-test-duration-popup.js",
"./src/js/test/test-config.js",
"./src/js/loader.js",
"./src/js/mini-result-chart.js",

View file

@ -1,99 +0,0 @@
import * as UpdateConfig from "./config";
import * as ManualRestart from "./manual-restart-tracker";
import * as Notifications from "./notification-center";
import * as TestLogic from "./test-logic";
export function show(mode) {
if ($("#customMode2PopupWrapper").hasClass("hidden")) {
if (mode == "time") {
$("#customMode2Popup .title").text("Test length");
$("#customMode2Popup").attr("mode", "time");
} else if (mode == "words") {
$("#customMode2Popup .title").text("Word amount");
$("#customMode2Popup").attr("mode", "words");
}
$("#customMode2PopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 100, (e) => {
$("#customMode2Popup input").focus().select();
});
}
}
function hide() {
if (!$("#customMode2PopupWrapper").hasClass("hidden")) {
$("#customMode2PopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
(e) => {
$("#customMode2PopupWrapper").addClass("hidden");
}
);
}
}
function apply() {
let mode = $("#customMode2Popup").attr("mode");
let val = parseInt($("#customMode2Popup input").val());
if (mode == "time") {
if (val !== null && !isNaN(val) && val >= 0) {
UpdateConfig.setTimeConfig(val);
ManualRestart.set();
TestLogic.restart();
if (val >= 1800) {
Notifications.add("Stay safe and take breaks!", 0);
} else if (val == 0) {
Notifications.add(
"Infinite time! Make sure to use Bail Out from the command line to save your result.",
0,
7
);
}
} else {
Notifications.add("Custom time must be at least 1", 0);
}
} else if (mode == "words") {
if (val !== null && !isNaN(val) && val >= 0) {
UpdateConfig.setWordCount(val);
ManualRestart.set();
TestLogic.restart();
if (val > 2000) {
Notifications.add("Stay safe and take breaks!", 0);
} else if (val == 0) {
Notifications.add(
"Infinite words! Make sure to use Bail Out from the command line to save your result.",
0,
7
);
}
} else {
Notifications.add("Custom word amount must be at least 1", 0);
}
}
hide();
}
$("#customMode2PopupWrapper").click((e) => {
if ($(e.target).attr("id") === "customMode2PopupWrapper") {
hide();
}
});
$("#customMode2Popup input").keypress((e) => {
if (e.keyCode == 13) {
apply();
}
});
$("#customMode2Popup .button").click(() => {
apply();
});

View file

@ -0,0 +1,140 @@
import * as UpdateConfig from "./config";
import * as ManualRestart from "./manual-restart-tracker";
import * as Notifications from "./notification-center";
import * as TestLogic from "./test-logic";
function parseInput(input) {
const re = /((-\s*)?\d+(\.\d+)?\s*[hms]?)/g;
const seconds = [...input.toLowerCase().matchAll(re)]
.map((match) => {
const part = match[0];
const duration = parseFloat(part.replaceAll(/\s+/g, ""));
if (part.includes("h")) {
return 3600 * duration;
} else if (part.includes("m")) {
return 60 * duration;
} else {
return duration;
}
})
.reduce((total, dur) => total + dur, 0);
return Math.floor(seconds);
}
function format(duration) {
const hours = Math.floor(duration / 3600);
const minutes = Math.floor((duration % 3600) / 60);
const seconds = (duration % 3600) % 60;
const time = [];
if (hours > 0) {
time.push(`${hours} hour${hours === 1 ? "" : "s"}`);
}
if (minutes > 0) {
time.push(`${minutes} minute${minutes === 1 ? "" : "s"}`);
}
if (seconds > 0) {
time.push(`${seconds} second${seconds === 1 ? "" : "s"}`);
}
if (time.length === 3) {
return `${time[0]}, ${time[1]} and ${time[2]}`;
} else if (time.length === 2) {
return `${time[0]} and ${time[1]}`;
} else {
return `${time[0]}`;
}
}
function previewDuration() {
const input = $("#customTestDurationPopup input").val();
const duration = parseInput(input);
let formattedDuration = "";
if (duration < 0) {
formattedDuration = "NEGATIVE TIME";
} else if (duration == 0) {
formattedDuration = "Infinite test";
} else {
formattedDuration = "Total time: " + format(duration);
}
$("#customTestDurationPopup .preview").text(formattedDuration);
}
export function show() {
if ($("#customTestDurationPopupWrapper").hasClass("hidden")) {
$("#customTestDurationPopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 100, (e) => {
$("#customTestDurationPopup input").focus().select();
});
}
previewDuration();
}
function hide() {
if (!$("#customTestDurationPopupWrapper").hasClass("hidden")) {
$("#customTestDurationPopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
(e) => {
$("#customTestDurationPopupWrapper").addClass("hidden");
}
);
}
}
function apply() {
let val = parseInput($("#customTestDurationPopup input").val());
if (val !== null && !isNaN(val) && val >= 0) {
UpdateConfig.setTimeConfig(val);
ManualRestart.set();
TestLogic.restart();
if (val >= 1800) {
Notifications.add("Stay safe and take breaks!", 0);
} else if (val == 0) {
Notifications.add(
"Infinite time! Make sure to use Bail Out from the command line to save your result.",
0,
7
);
}
} else {
Notifications.add("Custom time must be at least 1", 0);
}
hide();
}
$("#customTestDurationPopupWrapper").click((e) => {
if ($(e.target).attr("id") === "customTestDurationPopupWrapper") {
hide();
}
});
$("#customTestDurationPopup input").keyup((e) => {
previewDuration();
if (e.keyCode == 13) {
apply();
}
});
$("#customTestDurationPopup .button").click(() => {
apply();
});

View file

@ -0,0 +1,72 @@
import * as UpdateConfig from "./config";
import * as ManualRestart from "./manual-restart-tracker";
import * as Notifications from "./notification-center";
import * as TestLogic from "./test-logic";
export function show() {
if ($("#customWordAmountPopupWrapper").hasClass("hidden")) {
$("#customWordAmountPopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 100, (e) => {
$("#customWordAmountPopup input").focus().select();
});
}
}
function hide() {
if (!$("#customWordAmountPopupWrapper").hasClass("hidden")) {
$("#customWordAmountPopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
(e) => {
$("#customWordAmountPopupWrapper").addClass("hidden");
}
);
}
}
function apply() {
let val = parseInt($("#customWordAmountPopup input").val());
if (val !== null && !isNaN(val) && val >= 0) {
UpdateConfig.setWordCount(val);
ManualRestart.set();
TestLogic.restart();
if (val > 2000) {
Notifications.add("Stay safe and take breaks!", 0);
} else if (val == 0) {
Notifications.add(
"Infinite words! Make sure to use Bail Out from the command line to save your result.",
0,
7
);
}
} else {
Notifications.add("Custom word amount must be at least 1", 0);
}
hide();
}
$("#customWordAmountPopupWrapper").click((e) => {
if ($(e.target).attr("id") === "customWordAmountPopupWrapper") {
hide();
}
});
$("#customWordAmountPopup input").keypress((e) => {
if (e.keyCode == 13) {
apply();
}
});
$("#customWordAmountPopup .button").click(() => {
apply();
});

View file

@ -645,7 +645,8 @@ $(document).keydown(function (event) {
let wordsFocused = $("#wordsInput").is(":focus");
let modePopupVisible =
!$("#customTextPopupWrapper").hasClass("hidden") ||
!$("#customMode2PopupWrapper").hasClass("hidden") ||
!$("#customWordAmountPopupWrapper").hasClass("hidden") ||
!$("#customTestDurationPopupWrapper").hasClass("hidden") ||
!$("#quoteSearchPopupWrapper").hasClass("hidden");
if (
pageTestActive &&

View file

@ -1,4 +1,5 @@
import * as CustomMode2Popup from "./custom-mode2-popup";
import * as CustomWordAmountPopup from "./custom-word-amount-popup";
import * as CustomTestDurationPopup from "./custom-test-duration-popup";
import * as UpdateConfig from "./config";
import * as ManualRestart from "./manual-restart-tracker";
import * as TestLogic from "./test-logic";
@ -16,7 +17,7 @@ export function hide() {
$(document).on("click", "#top .config .wordCount .text-button", (e) => {
const wrd = $(e.currentTarget).attr("wordCount");
if (wrd == "custom") {
CustomMode2Popup.show("words");
CustomWordAmountPopup.show();
} else {
UpdateConfig.setWordCount(wrd);
ManualRestart.set();
@ -27,7 +28,7 @@ $(document).on("click", "#top .config .wordCount .text-button", (e) => {
$(document).on("click", "#top .config .time .text-button", (e) => {
let mode = $(e.currentTarget).attr("timeConfig");
if (mode == "custom") {
CustomMode2Popup.show("time");
CustomTestDurationPopup.show();
} else {
UpdateConfig.setTimeConfig(mode);
ManualRestart.set();

View file

@ -134,12 +134,15 @@ html {
outline: none;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
.select2-container--default
.select2-selection--single
.select2-selection__rendered {
color: var(--text-color);
outline: none;
}
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
.select2-container--default
.select2-results__option--highlighted.select2-results__option--selectable {
background-color: var(--sub-color);
color: var(--text-color);
}
@ -156,16 +159,15 @@ html {
border-radius: var(--roundness);
}
.select2-container--default .select2-selection--single
{
.select2-container--default .select2-selection--single {
color: var(--text-color);
background: rgba(0, 0, 0, 0.1);
outline: none;
border: none;
height:auto;
height: auto;
}
.select2-selection:focus{
.select2-selection:focus {
height: fit-content;
padding: 5px;
border-radius: var(--roundness);
@ -174,7 +176,7 @@ html {
border: none;
outline: none;
}
.select2-selection:active{
.select2-selection:active {
height: fit-content;
padding: 5px;
border-radius: var(--roundness);
@ -184,15 +186,23 @@ html {
outline: none;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
.select2-container--default
.select2-selection--single
.select2-selection__arrow {
height: 35px;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
.select2-container--default
.select2-selection--single
.select2-selection__arrow
b {
border-color: var(--main-color) transparent transparent transparent;
}
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
.select2-container--default.select2-container--open
.select2-selection--single
.select2-selection__arrow
b {
border-color: var(--main-color) transparent;
}
@ -591,7 +601,7 @@ a:hover {
}
}
#wordFilterPopupWrapper{
#wordFilterPopupWrapper {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
@ -604,7 +614,7 @@ a:hover {
align-items: center;
padding: 5rem 0;
#wordFilterPopup{
#wordFilterPopup {
background: var(--bg-color);
border-radius: var(--roundness);
padding: 2rem;
@ -612,25 +622,23 @@ a:hover {
gap: 1rem;
width: 400px;
.lengthgrid{
display:grid;
.lengthgrid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0.2rem;
}
.wordLength{
.wordLength {
width: 10rem;
}
.wftip{
.wftip {
color: var(--sub-color);
font-size: 0.8rem;
}
.wfload{
.wfload {
justify-self: center;
}
}
@ -674,7 +682,8 @@ a:hover {
}
}
#customMode2PopupWrapper {
#customWordAmountPopupWrapper,
#customTestDurationPopupWrapper {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
@ -687,7 +696,8 @@ a:hover {
align-items: center;
padding: 5rem 0;
#customMode2Popup {
#customWordAmountPopup,
#customTestDurationPopup {
background: var(--bg-color);
border-radius: var(--roundness);
padding: 2rem;
@ -705,6 +715,13 @@ a:hover {
color: var(--sub-color);
}
}
#customTestDurationPopup {
.preview {
font-size: 0.75rem;
color: var(--sub-color);
}
}
}
#customThemeShareWrapper {

View file

@ -136,9 +136,9 @@
<div class="button">ok</div>
</div>
</div>
<div id="customMode2PopupWrapper" class="hidden">
<div id="customMode2Popup" mode="">
<div class="title">Test length</div>
<div id="customWordAmountPopupWrapper" class="hidden">
<div id="customWordAmountPopup">
<div class="title">Word amount</div>
<input type="number" value="1" min="1" max="10000" />
<div class="tip">
You can start an infinite test by inputting 0. Then, to stop the test,
@ -147,6 +147,18 @@
<div class="button">ok</div>
</div>
</div>
<div id="customTestDurationPopupWrapper" class="hidden">
<div id="customTestDurationPopup">
<div class="title">Test duration</div>
<div class="preview"></div>
<input value="1" />
<div class="tip">
You can start an infinite test by inputting 0. Then, to stop the test,
use the Bail Out feature (esc > Bail Out)
</div>
<div class="button">ok</div>
</div>
</div>
<div id="quoteSearchPopupWrapper" class="hidden">
<div id="quoteSearchPopup" mode="">
<div class="title">Quote Search</div>