refactor(mobile test config modal): use new modal system

This commit is contained in:
Miodec 2024-03-16 18:44:18 +01:00
parent 5fb042c076
commit 7faefcdd76
10 changed files with 208 additions and 240 deletions

View file

@ -87,11 +87,11 @@
</div>
</div>
</div>
<div id="mobileTestConfig">
<div class="textButton">
<div id="mobileTestConfigButton">
<button>
<i class="fas fa-fw fa-cog"></i>
Test Settings
</div>
Test settings
</button>
</div>
<div id="typingTest">
<div id="capsWarning" class="hidden">

View file

@ -180,13 +180,12 @@
</div>
</div>
<div id="mobileTestConfigPopupWrapper" class="popupWrapper hidden">
<div id="mobileTestConfigPopup">
<dialog id="mobileTestConfigModal" class="modalWrapper hidden">
<div class="modal">
<div class="group">
<button class="punctuation">punctuation</button>
<button class="numbers">numbers</button>
</div>
<div class="spacer"></div>
<div class="group modeGroup">
<button data-mode="time">time</button>
<button class="active" data-mode="words">words</button>
@ -194,7 +193,6 @@
<button data-mode="zen">zen</button>
<button data-mode="custom">custom</button>
</div>
<div class="spacer"></div>
<div class="group timeGroup">
<button data-time="15">15</button>
<button class="button active" data-time="30">30</button>
@ -221,7 +219,7 @@
<button class="customChange">change</button>
</div>
</div>
</div>
</dialog>
<div id="videoAdPopupWrapper" class="popupWrapper hidden">
<div id="videoAdPopup">

View file

@ -473,31 +473,9 @@
}
}
#mobileTestConfigPopupWrapper {
#mobileTestConfigPopup {
background: var(--bg-color);
border-radius: var(--roundness);
padding: 1rem;
display: grid;
gap: 1rem;
width: calc(100vw - 2rem);
// margin-left: 1rem;
max-width: 400px;
.title {
font-size: 1.5rem;
color: var(--sub-color);
}
.inputs {
display: grid;
gap: 1rem;
}
.text {
font-size: 1rem;
color: var(--text-color);
}
#mobileTestConfigModal {
.modal {
gap: 2rem;
.group {
display: grid;

View file

@ -946,17 +946,19 @@
}
}
#mobileTestConfig {
font-size: 0.75rem;
padding: 0.25rem 1rem;
background: var(--sub-alt-color);
border-radius: var(--roundness);
width: max-content;
justify-self: center;
#mobileTestConfigButton {
display: none;
height: max-content;
justify-self: center;
margin-bottom: 1rem;
transition: opacity 0.125s;
height: max-content;
button {
font-size: 0.75rem;
padding: 1em 2em;
color: var(--sub-color);
&:hover {
color: var(--bg-color);
}
}
}
#testConfig {
@ -1198,7 +1200,7 @@ main.focus .pageTest {
#testConfig {
opacity: 0 !important;
}
#mobileTestConfig {
#mobileTestConfigButton {
opacity: 0 !important;
}
}

View file

@ -886,7 +886,7 @@
display: none;
}
#mobileTestConfig {
#mobileTestConfigButton {
display: block;
}
#alertsPopupWrapper {
@ -997,7 +997,7 @@
display: none;
}
#mobileTestConfig {
#mobileTestConfigButton {
display: block;
}

View file

@ -2,6 +2,7 @@ import { getCommandline } from "../utils/async-modules";
import * as CustomWordAmount from "../modals/custom-word-amount";
import * as DB from "../db";
import * as EditResultTagsModal from "../modals/edit-result-tags";
import * as MobileTestConfigModal from "../modals/mobile-test-config";
$(".pageTest").on("click", "#testModesNotice .textButton", async (event) => {
const attr = $(event.currentTarget).attr("commands");
@ -28,3 +29,7 @@ $(".pageTest").on("click", ".tags .editTagsButton", () => {
EditResultTagsModal.show(resultid, tags, "resultPage");
}
});
$(".pageTest").on("click", "#mobileTestConfigButton", () => {
MobileTestConfigModal.show();
});

View file

@ -29,7 +29,6 @@ import "./ready";
import "./controllers/route-controller";
import "./pages/about";
import "./elements/scroll-to-top";
import "./popups/mobile-test-config-popup";
import "./popups/google-sign-up-popup";
import * as Account from "./pages/account";
import "./elements/leaderboards";

View file

@ -0,0 +1,177 @@
import * as TestLogic from "../test/test-logic";
import Config, * as UpdateConfig from "../config";
import * as ManualRestart from "../test/manual-restart-tracker";
import * as CustomWordAmountPopup from "./custom-word-amount";
import * as CustomTestDurationPopup from "../popups/custom-test-duration-popup";
import * as QuoteSearchPopup from "../popups/quote-search-popup";
import * as CustomTextPopup from "../popups/custom-text-popup";
import AnimatedModal from "../utils/animated-modal";
function update(): void {
const el = $("#mobileTestConfigModal");
el.find("button").removeClass("active");
el.find(`.modeGroup button[data-mode='${Config.mode}']`).addClass("active");
el.find(".timeGroup").addClass("hidden");
el.find(".wordsGroup").addClass("hidden");
el.find(".quoteGroup").addClass("hidden");
el.find(".customGroup").addClass("hidden");
el.find(`.${Config.mode}Group`).removeClass("hidden");
if (Config.punctuation) {
el.find(".punctuation").addClass("active");
} else {
el.find(".punctuation").removeClass("active");
}
if (Config.numbers) {
el.find(".numbers").addClass("active");
} else {
el.find(".numbers").removeClass("active");
}
if (Config.mode === "time") {
el.find(`.timeGroup button[data-time='${Config.time}']`).addClass("active");
el.find(".punctuation").removeClass("disabled");
el.find(".numbers").removeClass("disabled");
} else if (Config.mode === "words") {
el.find(`.wordsGroup button[data-words='${Config.words}']`).addClass(
"active"
);
el.find(".punctuation").removeClass("disabled");
el.find(".numbers").removeClass("disabled");
} else if (Config.mode === "quote") {
for (const ql of Config.quoteLength) {
el.find(`.quoteGroup button[data-quoteLength='${ql}']`).addClass(
"active"
);
}
el.find(".punctuation").addClass("disabled");
el.find(".numbers").addClass("disabled");
} else if (Config.mode === "zen") {
el.find(".punctuation").addClass("disabled");
el.find(".numbers").addClass("disabled");
} else if (Config.mode === "custom") {
el.find(".punctuation").removeClass("disabled");
el.find(".numbers").removeClass("disabled");
}
}
export function show(): void {
void modal.show({
beforeAnimation: async () => {
update();
},
});
}
function hide(): void {
void modal.hide();
}
function setup(modalEl: HTMLElement): void {
const wordsGroupButtons = modalEl.querySelectorAll(".wordsGroup button");
for (const button of wordsGroupButtons) {
button.addEventListener("click", (e) => {
const target = e.currentTarget as HTMLElement;
const wrd = target.getAttribute("data-words") as string;
if (wrd === "custom") {
CustomWordAmountPopup.show({
modalChain: modal,
});
} else if (wrd !== undefined) {
const wrdNum = parseInt(wrd);
UpdateConfig.setWordCount(wrdNum);
ManualRestart.set();
TestLogic.restart();
}
});
}
const modeGroupButtons = modalEl.querySelectorAll(".modeGroup button");
for (const button of modeGroupButtons) {
button.addEventListener("click", (e) => {
const target = e.currentTarget as HTMLElement;
const mode = target.getAttribute("data-mode");
if (mode === Config.mode) return;
UpdateConfig.setMode(mode as SharedTypes.Config.Mode);
ManualRestart.set();
TestLogic.restart();
});
}
const timeGroupButtons = modalEl.querySelectorAll(".timeGroup button");
for (const button of timeGroupButtons) {
button.addEventListener("click", (e) => {
const target = e.currentTarget as HTMLElement;
const time = target.getAttribute("data-time") as string;
if (time === "custom") {
hide(); // use modal chaining here
CustomTestDurationPopup.show();
} else if (time !== undefined) {
const timeNum = parseInt(time);
UpdateConfig.setTimeConfig(timeNum);
ManualRestart.set();
TestLogic.restart();
}
});
}
const quoteGroupButtons = modalEl.querySelectorAll(".quoteGroup button");
for (const button of quoteGroupButtons) {
button.addEventListener("click", (e) => {
const target = e.currentTarget as HTMLElement;
const len = parseInt(target.getAttribute("data-quoteLength") ?? "0", 10);
if (len === -2) {
hide(); //todo use modal chaining here
void QuoteSearchPopup.show();
} else {
let newVal: number[] | number = len;
if (len === -1) {
newVal = [0, 1, 2, 3];
}
UpdateConfig.setQuoteLength(
newVal as
| SharedTypes.Config.QuoteLength
| SharedTypes.Config.QuoteLength[],
false,
(e as MouseEvent).shiftKey
);
ManualRestart.set();
TestLogic.restart();
}
});
}
modalEl.querySelector(".customChange")?.addEventListener("click", () => {
hide(); //todo use modal chaining here
CustomTextPopup.show();
});
modalEl.querySelector(".punctuation")?.addEventListener("click", () => {
UpdateConfig.setPunctuation(!Config.punctuation);
ManualRestart.set();
TestLogic.restart();
});
modalEl.querySelector(".numbers")?.addEventListener("click", () => {
UpdateConfig.setNumbers(!Config.numbers);
ManualRestart.set();
TestLogic.restart();
});
const buttons = modalEl.querySelectorAll("button");
for (const button of buttons) {
button.addEventListener("click", () => {
update();
});
}
}
const modal = new AnimatedModal({
dialogId: "mobileTestConfigModal",
setup,
});

View file

@ -1,191 +0,0 @@
import * as TestLogic from "../test/test-logic";
import Config, * as UpdateConfig from "../config";
import * as ManualRestart from "../test/manual-restart-tracker";
import * as CustomWordAmountPopup from "../modals/custom-word-amount";
import * as CustomTestDurationPopup from "./custom-test-duration-popup";
import * as QuoteSearchPopup from "./quote-search-popup";
import * as CustomTextPopup from "./custom-text-popup";
import * as ConfigEvent from "../observables/config-event";
import * as Skeleton from "../utils/skeleton";
import { isPopupVisible } from "../utils/misc";
const wrapperId = "mobileTestConfigPopupWrapper";
const el = $("#mobileTestConfigPopup");
function update(): void {
el.find("button").removeClass("active");
el.find(`.modeGroup button[data-mode='${Config.mode}']`).addClass("active");
el.find(".timeGroup").addClass("hidden");
el.find(".wordsGroup").addClass("hidden");
el.find(".quoteGroup").addClass("hidden");
el.find(".customGroup").addClass("hidden");
el.find(`.${Config.mode}Group`).removeClass("hidden");
if (Config.punctuation) {
el.find(".punctuation").addClass("active");
} else {
el.find(".punctuation").removeClass("active");
}
if (Config.numbers) {
el.find(".numbers").addClass("active");
} else {
el.find(".numbers").removeClass("active");
}
if (Config.mode === "time") {
el.find(`.timeGroup button[data-time='${Config.time}']`).addClass("active");
el.find(".punctuation").removeClass("disabled");
el.find(".numbers").removeClass("disabled");
} else if (Config.mode === "words") {
el.find(`.wordsGroup button[data-words='${Config.words}']`).addClass(
"active"
);
el.find(".punctuation").removeClass("disabled");
el.find(".numbers").removeClass("disabled");
} else if (Config.mode === "quote") {
for (const ql of Config.quoteLength) {
el.find(`.quoteGroup button[data-quoteLength='${ql}']`).addClass(
"active"
);
}
el.find(".punctuation").addClass("disabled");
el.find(".numbers").addClass("disabled");
} else if (Config.mode === "zen") {
el.find(".punctuation").addClass("disabled");
el.find(".numbers").addClass("disabled");
} else if (Config.mode === "custom") {
el.find(".punctuation").removeClass("disabled");
el.find(".numbers").removeClass("disabled");
}
}
function showPopup(): void {
Skeleton.append(wrapperId, "popups");
if (!isPopupVisible(wrapperId)) {
update();
$("#mobileTestConfigPopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 125);
}
}
function hidePopup(): void {
if (isPopupVisible(wrapperId)) {
$("#mobileTestConfigPopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
125,
() => {
$("#mobileTestConfigPopupWrapper").addClass("hidden");
Skeleton.remove(wrapperId);
}
);
}
}
$("#mobileTestConfigPopupWrapper").on("click", (e) => {
if ($(e.target).attr("id") === "mobileTestConfigPopupWrapper") {
hidePopup();
}
});
$("#mobileTestConfig").on("click", () => {
showPopup();
});
el.find(".wordsGroup button").on("click", (e) => {
const wrd = $(e.currentTarget).attr("data-words");
if (wrd === "custom") {
hidePopup();
CustomWordAmountPopup.show();
} else if (wrd !== undefined) {
const wrdNum = parseInt(wrd);
UpdateConfig.setWordCount(wrdNum);
ManualRestart.set();
TestLogic.restart();
}
});
el.find(".timeGroup button").on("click", (e) => {
const time = $(e.currentTarget).attr("data-time");
if (time === "custom") {
hidePopup();
CustomTestDurationPopup.show();
} else if (time !== undefined) {
const timeNum = parseInt(time);
UpdateConfig.setTimeConfig(timeNum);
ManualRestart.set();
TestLogic.restart();
}
});
el.find(".quoteGroup button").on("click", (e) => {
let len: number | number[] = parseInt(
$(e.currentTarget).attr("data-quoteLength") ?? "0",
10
);
if (len === -2) {
// UpdateConfig.setQuoteLength(-2, false, e.shiftKey);
hidePopup();
void QuoteSearchPopup.show();
} else {
if (len === -1) {
len = [0, 1, 2, 3];
}
UpdateConfig.setQuoteLength(
len as SharedTypes.Config.QuoteLength | SharedTypes.Config.QuoteLength[],
false,
e.shiftKey
);
ManualRestart.set();
TestLogic.restart();
}
});
el.find(".customChange").on("click", () => {
hidePopup();
CustomTextPopup.show();
});
el.find(".punctuation").on("click", () => {
UpdateConfig.setPunctuation(!Config.punctuation);
ManualRestart.set();
TestLogic.restart();
});
el.find(".numbers").on("click", () => {
UpdateConfig.setNumbers(!Config.numbers);
ManualRestart.set();
TestLogic.restart();
});
el.find(".modeGroup button").on("click", (e) => {
if ($(e.currentTarget).hasClass("active")) return;
const mode = $(e.currentTarget).attr("data-mode");
UpdateConfig.setMode(mode as SharedTypes.Config.Mode);
ManualRestart.set();
TestLogic.restart();
});
$("#mobileTestConfigPopupWrapper button").on("click", () => {
// hidePopup();
update();
});
ConfigEvent.subscribe((eventKey) => {
if (eventKey === "mode") update();
});
Skeleton.save(wrapperId);

View file

@ -4,12 +4,12 @@ import * as ActivePage from "../states/active-page";
export function show(): void {
$("#testConfig").removeClass("invisible");
$("#mobileTestConfig").removeClass("invisible");
$("#mobileTestConfigButton").removeClass("invisible");
}
export function hide(): void {
$("#testConfig").addClass("invisible");
$("#mobileTestConfig").addClass("invisible");
$("#mobileTestConfigButton").addClass("invisible");
}
export async function instantUpdate(): Promise<void> {