mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-03-04 18:53:26 +08:00
refactor(google sign up modal): use new modal system
This commit is contained in:
parent
9e064fd57c
commit
d454783d11
5 changed files with 114 additions and 144 deletions
|
@ -576,15 +576,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="googleSignUpPopupWrapper" class="popupWrapper hidden">
|
||||
<div id="googleSignUpPopup">
|
||||
<dialog id="googleSignUpModal" class="modalWrapper hidden">
|
||||
<form class="modal">
|
||||
<div class="title">Account name</div>
|
||||
<div class="text">You need to choose a username before continuing</div>
|
||||
<div class="text">Please enter a username before continuing</div>
|
||||
<input type="text" placeholder="username" />
|
||||
<div class="captcha"></div>
|
||||
<div class="button disabled">Sign up</div>
|
||||
</div>
|
||||
</div>
|
||||
<button>continue</button>
|
||||
</form>
|
||||
</dialog>
|
||||
<dialog id="customWordAmountModal" class="modalWrapper hidden">
|
||||
<form class="modal">
|
||||
<div class="title">Custom word amount</div>
|
||||
|
|
|
@ -531,53 +531,51 @@
|
|||
}
|
||||
}
|
||||
|
||||
#googleSignUpPopup {
|
||||
background: var(--bg-color);
|
||||
border-radius: var(--roundness);
|
||||
padding: 2rem;
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
width: 400px;
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
color: var(--sub-color);
|
||||
}
|
||||
.inputAndIndicator {
|
||||
input {
|
||||
width: 100%;
|
||||
#googleSignUpModal {
|
||||
.modal {
|
||||
max-width: 425px;
|
||||
overflow: unset;
|
||||
.captcha {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
position: relative;
|
||||
.checkStatus {
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
/* background: red; */
|
||||
display: grid;
|
||||
grid-template-columns: 2.25rem;
|
||||
grid-template-rows: 2.25rem;
|
||||
place-items: center center;
|
||||
cursor: pointer;
|
||||
// .inputAndIndicator {
|
||||
// input {
|
||||
// width: 100%;
|
||||
// }
|
||||
// position: relative;
|
||||
// .checkStatus {
|
||||
// width: 2.25rem;
|
||||
// height: 2.25rem;
|
||||
// position: absolute;
|
||||
// right: 0;
|
||||
// top: 0;
|
||||
// /* background: red; */
|
||||
// display: grid;
|
||||
// grid-template-columns: 2.25rem;
|
||||
// grid-template-rows: 2.25rem;
|
||||
// place-items: center center;
|
||||
// cursor: pointer;
|
||||
|
||||
.checking,
|
||||
.available,
|
||||
.unavailable,
|
||||
.taken {
|
||||
grid-column: 1/2;
|
||||
grid-row: 1/2;
|
||||
}
|
||||
.checking {
|
||||
color: var(--sub-color);
|
||||
}
|
||||
.available {
|
||||
color: var(--main-color);
|
||||
}
|
||||
.unavailable,
|
||||
.taken {
|
||||
color: var(--error-color);
|
||||
}
|
||||
}
|
||||
// .checking,
|
||||
// .available,
|
||||
// .unavailable,
|
||||
// .taken {
|
||||
// grid-column: 1/2;
|
||||
// grid-row: 1/2;
|
||||
// }
|
||||
// .checking {
|
||||
// color: var(--sub-color);
|
||||
// }
|
||||
// .available {
|
||||
// color: var(--main-color);
|
||||
// }
|
||||
// .unavailable,
|
||||
// .taken {
|
||||
// color: var(--error-color);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import "./event-handlers/about";
|
|||
import "./event-handlers/settings";
|
||||
import "./event-handlers/account";
|
||||
|
||||
import "./modals/google-sign-up";
|
||||
|
||||
import "./firebase";
|
||||
import * as Logger from "./utils/logger";
|
||||
import * as DB from "./db";
|
||||
|
@ -29,7 +31,6 @@ import "./ready";
|
|||
import "./controllers/route-controller";
|
||||
import "./pages/about";
|
||||
import "./elements/scroll-to-top";
|
||||
import "./popups/google-sign-up-popup";
|
||||
import * as Account from "./pages/account";
|
||||
import "./elements/leaderboards";
|
||||
import "./elements/no-css";
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
getAdditionalUserInfo,
|
||||
} from "firebase/auth";
|
||||
import Ape from "../ape";
|
||||
import { createErrorMessage, isPopupVisible } from "../utils/misc";
|
||||
import { createErrorMessage } from "../utils/misc";
|
||||
import * as LoginPage from "../pages/login";
|
||||
import * as AllTimeStats from "../account/all-time-stats";
|
||||
import * as AccountController from "../controllers/account-controller";
|
||||
|
@ -17,68 +17,48 @@ import * as DB from "../db";
|
|||
import * as Loader from "../elements/loader";
|
||||
import { subscribe as subscribeToSignUpEvent } from "../observables/google-sign-up-event";
|
||||
import { InputIndicator } from "../elements/input-indicator";
|
||||
import * as Skeleton from "../utils/skeleton";
|
||||
|
||||
const wrapperId = "googleSignUpPopupWrapper";
|
||||
import AnimatedModal from "../utils/animated-modal";
|
||||
|
||||
let signedInUser: UserCredential | undefined = undefined;
|
||||
|
||||
function show(credential: UserCredential): void {
|
||||
Skeleton.append(wrapperId, "popups");
|
||||
|
||||
if (!isPopupVisible(wrapperId)) {
|
||||
CaptchaController.reset("googleSignUpPopup");
|
||||
CaptchaController.render(
|
||||
$("#googleSignUpPopupWrapper .captcha")[0] as HTMLElement,
|
||||
"googleSignUpPopup"
|
||||
);
|
||||
enableInput();
|
||||
disableButton();
|
||||
signedInUser = credential;
|
||||
$("#googleSignUpPopupWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 0)
|
||||
.removeClass("hidden")
|
||||
.animate({ opacity: 1 }, 125, () => {
|
||||
$("#googleSignUpPopup input").trigger("focus").trigger("select");
|
||||
});
|
||||
}
|
||||
console.log("showing google sign up modal");
|
||||
void modal.show({
|
||||
focusFirstInput: true,
|
||||
beforeAnimation: async () => {
|
||||
CaptchaController.reset("googleSignUpModal");
|
||||
CaptchaController.render(
|
||||
$("#googleSignUpModal .captcha")[0] as HTMLElement,
|
||||
"googleSignUpModal"
|
||||
);
|
||||
enableInput();
|
||||
disableButton();
|
||||
signedInUser = credential;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function hide(): Promise<void> {
|
||||
if (isPopupVisible(wrapperId)) {
|
||||
if (signedInUser !== undefined) {
|
||||
Notifications.add("Sign up process cancelled", 0, {
|
||||
duration: 5,
|
||||
});
|
||||
LoginPage.hidePreloader();
|
||||
LoginPage.enableInputs();
|
||||
if (getAdditionalUserInfo(signedInUser)?.isNewUser) {
|
||||
await Ape.users.delete();
|
||||
await signedInUser.user.delete();
|
||||
}
|
||||
AccountController.signOut();
|
||||
signedInUser = undefined;
|
||||
}
|
||||
$("#googleSignUpPopupWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 1)
|
||||
.animate(
|
||||
{
|
||||
opacity: 0,
|
||||
},
|
||||
125,
|
||||
() => {
|
||||
$("#googleSignUpPopupWrapper").addClass("hidden");
|
||||
Skeleton.remove(wrapperId);
|
||||
void modal.hide({
|
||||
afterAnimation: async () => {
|
||||
if (signedInUser !== undefined) {
|
||||
Notifications.add("Sign up process cancelled", 0, {
|
||||
duration: 5,
|
||||
});
|
||||
LoginPage.hidePreloader();
|
||||
LoginPage.enableInputs();
|
||||
if (getAdditionalUserInfo(signedInUser)?.isNewUser) {
|
||||
await Ape.users.delete();
|
||||
await signedInUser.user.delete();
|
||||
}
|
||||
);
|
||||
}
|
||||
AccountController.signOut();
|
||||
signedInUser = undefined;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function apply(): Promise<void> {
|
||||
if ($("#googleSignUpPopup .button").hasClass("disabled")) return;
|
||||
|
||||
if (!signedInUser) {
|
||||
return Notifications.add(
|
||||
"Missing user credential. Please close the popup and try again.",
|
||||
|
@ -86,16 +66,16 @@ async function apply(): Promise<void> {
|
|||
);
|
||||
}
|
||||
|
||||
const captcha = CaptchaController.getResponse("googleSignUpPopup");
|
||||
const captcha = CaptchaController.getResponse("googleSignUpModal");
|
||||
if (!captcha) {
|
||||
return Notifications.add("Please complete the captcha", -1);
|
||||
return Notifications.add("Please complete the captcha", 0);
|
||||
}
|
||||
|
||||
disableInput();
|
||||
disableButton();
|
||||
|
||||
Loader.show();
|
||||
const name = $("#googleSignUpPopup input").val() as string;
|
||||
const name = $("#googleSignUpModal input").val() as string;
|
||||
try {
|
||||
if (name.length === 0) throw new Error("Name cannot be empty");
|
||||
const response = await Ape.users.create(name, captcha);
|
||||
|
@ -154,28 +134,22 @@ async function apply(): Promise<void> {
|
|||
}
|
||||
|
||||
function enableButton(): void {
|
||||
$("#googleSignUpPopup .button").removeClass("disabled");
|
||||
$("#googleSignUpModal button").prop("disabled", false);
|
||||
}
|
||||
|
||||
function disableButton(): void {
|
||||
$("#googleSignUpPopup .button").addClass("disabled");
|
||||
$("#googleSignUpModal button").prop("disabled", true);
|
||||
}
|
||||
|
||||
function enableInput(): void {
|
||||
$("#googleSignUpPopup input").prop("disabled", false);
|
||||
$("#googleSignUpModal input").prop("disabled", false);
|
||||
}
|
||||
|
||||
function disableInput(): void {
|
||||
$("#googleSignUpPopup input").prop("disabled", true);
|
||||
$("#googleSignUpModal input").prop("disabled", true);
|
||||
}
|
||||
|
||||
$("#googleSignUpPopupWrapper").on("mousedown", (e) => {
|
||||
if ($(e.target).attr("id") === "googleSignUpPopupWrapper") {
|
||||
void hide();
|
||||
}
|
||||
});
|
||||
|
||||
const nameIndicator = new InputIndicator($("#googleSignUpPopup input"), {
|
||||
const nameIndicator = new InputIndicator($("#googleSignUpModal input"), {
|
||||
available: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
|
@ -185,7 +159,7 @@ const nameIndicator = new InputIndicator($("#googleSignUpPopup input"), {
|
|||
level: -1,
|
||||
},
|
||||
taken: {
|
||||
icon: "fa-times",
|
||||
icon: "fa-user",
|
||||
level: -1,
|
||||
},
|
||||
checking: {
|
||||
|
@ -196,7 +170,7 @@ const nameIndicator = new InputIndicator($("#googleSignUpPopup input"), {
|
|||
});
|
||||
|
||||
const checkNameDebounced = debounce(1000, async () => {
|
||||
const val = $("#googleSignUpPopup input").val() as string;
|
||||
const val = $("#googleSignUpModal input").val() as string;
|
||||
if (!val) return;
|
||||
const response = await Ape.users.getNameAvailability(val);
|
||||
|
||||
|
@ -225,35 +199,23 @@ const checkNameDebounced = debounce(1000, async () => {
|
|||
}
|
||||
});
|
||||
|
||||
$("#googleSignUpPopupWrapper input").on("input", () => {
|
||||
setTimeout(() => {
|
||||
function setup(modalEl: HTMLElement): void {
|
||||
modalEl.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
void apply();
|
||||
});
|
||||
modalEl.querySelector("input")?.addEventListener("input", () => {
|
||||
disableButton();
|
||||
const val = $("#googleSignUpPopup input").val() as string;
|
||||
const val = $("#googleSignUpModal input").val() as string;
|
||||
console.log("checking", val);
|
||||
if (val === "") {
|
||||
return nameIndicator.hide();
|
||||
} else {
|
||||
nameIndicator.show("checking");
|
||||
void checkNameDebounced();
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
|
||||
$("#googleSignUpPopupWrapper input").on("keypress", (e) => {
|
||||
if (e.key === "Enter") {
|
||||
void apply();
|
||||
}
|
||||
});
|
||||
|
||||
$("#googleSignUpPopupWrapper .button").on("click", () => {
|
||||
void apply();
|
||||
});
|
||||
|
||||
$(document).on("keydown", (event) => {
|
||||
if (event.key === "Escape" && isPopupVisible(wrapperId)) {
|
||||
void hide();
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
subscribeToSignUpEvent((signedInUser, isNewUser) => {
|
||||
if (signedInUser !== undefined && isNewUser) {
|
||||
|
@ -261,4 +223,13 @@ subscribeToSignUpEvent((signedInUser, isNewUser) => {
|
|||
}
|
||||
});
|
||||
|
||||
Skeleton.save(wrapperId);
|
||||
const modal = new AnimatedModal({
|
||||
dialogId: "googleSignUpModal",
|
||||
setup,
|
||||
customEscapeHandler: async (): Promise<void> => {
|
||||
void hide();
|
||||
},
|
||||
customWrapperClickHandler: async (): Promise<void> => {
|
||||
void hide();
|
||||
},
|
||||
});
|
|
@ -171,7 +171,7 @@ const nameIndicator = new InputIndicator(
|
|||
level: -1,
|
||||
},
|
||||
taken: {
|
||||
icon: "fa-times",
|
||||
icon: "fa-user",
|
||||
level: -1,
|
||||
},
|
||||
checking: {
|
||||
|
|
Loading…
Reference in a new issue