mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-17 02:56:16 +08:00
refactor(mobile test config modal): use new modal system
This commit is contained in:
parent
5fb042c076
commit
7faefcdd76
10 changed files with 208 additions and 240 deletions
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -886,7 +886,7 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
#mobileTestConfig {
|
||||
#mobileTestConfigButton {
|
||||
display: block;
|
||||
}
|
||||
#alertsPopupWrapper {
|
||||
|
@ -997,7 +997,7 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
#mobileTestConfig {
|
||||
#mobileTestConfigButton {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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";
|
||||
|
|
177
frontend/src/ts/modals/mobile-test-config.ts
Normal file
177
frontend/src/ts/modals/mobile-test-config.ts
Normal 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,
|
||||
});
|
|
@ -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);
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Reference in a new issue