mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 23:36:37 +08:00
refactor(edit profile): use new modal system
This commit is contained in:
parent
7ee4340383
commit
00b5be2a38
|
@ -1125,8 +1125,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="editProfilePopupWrapper" class="popupWrapper hidden" tabindex="-1">
|
||||
<form id="editProfilePopup">
|
||||
<dialog id="editProfileModal" class="modalWrapper hidden">
|
||||
<form class="modal">
|
||||
<div class="title">Edit Profile</div>
|
||||
<div>
|
||||
<label>avatar</label>
|
||||
|
@ -1167,4 +1167,4 @@
|
|||
</div>
|
||||
<button class="edit-profile-submit" type="submit">save</button>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
|
|
@ -1532,11 +1532,9 @@
|
|||
}
|
||||
|
||||
#tagsWrapper,
|
||||
#newResultFilterPresetPopupWrapper,
|
||||
#editProfilePopupWrapper {
|
||||
#newResultFilterPresetPopupWrapper {
|
||||
#tagsEdit,
|
||||
#newResultFilterPresetPopup,
|
||||
#editProfilePopup {
|
||||
#newResultFilterPresetPopup {
|
||||
max-height: 90vh;
|
||||
background: var(--bg-color);
|
||||
border-radius: var(--roundness);
|
||||
|
@ -1557,50 +1555,60 @@
|
|||
gap: 1rem;
|
||||
}
|
||||
|
||||
#editProfilePopup {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
label {
|
||||
color: var(--sub-color);
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
textarea {
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
line-height: 1.2rem;
|
||||
min-height: 5rem;
|
||||
max-height: 10rem;
|
||||
}
|
||||
#editProfileModal {
|
||||
.modal {
|
||||
max-width: 600px;
|
||||
max-height: 100%;
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
color: var(--sub-color);
|
||||
}
|
||||
label {
|
||||
color: var(--sub-color);
|
||||
margin-bottom: 0.25em;
|
||||
display: block;
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
textarea {
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
line-height: 1.2rem;
|
||||
min-height: 5rem;
|
||||
max-height: 10rem;
|
||||
}
|
||||
|
||||
.socialURL {
|
||||
display: flex;
|
||||
}
|
||||
.socialURL {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.socialURL > p {
|
||||
margin-block: 0.5rem;
|
||||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
.socialURL > p {
|
||||
margin-block: 0.5rem;
|
||||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
.badgeSelectionContainer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.badgeSelectionContainer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.badgeSelectionItem {
|
||||
margin-bottom: 0.5rem;
|
||||
width: max-content;
|
||||
opacity: 25%;
|
||||
cursor: pointer;
|
||||
margin-right: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.badgeSelectionItem {
|
||||
margin-bottom: 0.5rem;
|
||||
width: max-content;
|
||||
opacity: 25%;
|
||||
cursor: pointer;
|
||||
margin-right: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
padding: 0;
|
||||
border-radius: calc(var(--roundness) / 2);
|
||||
}
|
||||
|
||||
.badgeSelectionItem.selected,
|
||||
.badgeSelectionItem:hover {
|
||||
opacity: 100%;
|
||||
.badgeSelectionItem.selected,
|
||||
.badgeSelectionItem:hover {
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import differenceInDays from "date-fns/differenceInDays";
|
|||
import * as Misc from "../utils/misc";
|
||||
import { getHTMLById } from "../controllers/badge-controller";
|
||||
import { throttle } from "throttle-debounce";
|
||||
import * as EditProfilePopup from "../popups/edit-profile-popup";
|
||||
import * as ActivePage from "../states/active-page";
|
||||
import formatDistanceToNowStrict from "date-fns/formatDistanceToNowStrict";
|
||||
import { getHtmlByUserFlags } from "../controllers/user-flag-controller";
|
||||
|
@ -409,14 +408,6 @@ export function updateNameFontSize(where: ProfileViewPaths): void {
|
|||
nameField.style.fontSize = `${finalFontSize}px`;
|
||||
}
|
||||
|
||||
$(".details .editProfileButton").on("click", () => {
|
||||
const snapshot = DB.getSnapshot();
|
||||
if (!snapshot) return;
|
||||
EditProfilePopup.show(() => {
|
||||
void update("account", snapshot);
|
||||
});
|
||||
});
|
||||
|
||||
const throttledEvent = throttle(1000, () => {
|
||||
const activePage = ActivePage.get();
|
||||
if (activePage && ["account", "profile"].includes(activePage)) {
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import * as PbTablesModal from "../modals/pb-tables";
|
||||
import * as EditProfileModal from "../modals/edit-profile";
|
||||
import { getSnapshot } from "../db";
|
||||
import { isAuthenticated } from "../firebase";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
|
||||
const accountPage = document.querySelector("#pageAccount") as HTMLElement;
|
||||
|
||||
|
@ -9,3 +13,23 @@ $(accountPage).on("click", ".pbsTime .showAllButton", () => {
|
|||
$(accountPage).on("click", ".pbsWords .showAllButton", () => {
|
||||
PbTablesModal.show("words");
|
||||
});
|
||||
|
||||
$(accountPage).on("click", ".editProfileButton", () => {
|
||||
if (!isAuthenticated()) {
|
||||
Notifications.add("You must be logged in to edit your profile", 0);
|
||||
return;
|
||||
}
|
||||
const snapshot = getSnapshot();
|
||||
if (!snapshot) {
|
||||
Notifications.add(
|
||||
"Failed to open edit profile modal: No user snapshot found",
|
||||
-1
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (snapshot.banned === true) {
|
||||
Notifications.add("Banned users cannot edit their profile", 0);
|
||||
return;
|
||||
}
|
||||
EditProfileModal.show();
|
||||
});
|
||||
|
|
|
@ -4,61 +4,40 @@ import * as DB from "../db";
|
|||
import * as Loader from "../elements/loader";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
import * as ConnectionState from "../states/connection";
|
||||
import { isPopupVisible } from "../utils/misc";
|
||||
import * as Skeleton from "../utils/skeleton";
|
||||
import AnimatedModal from "../utils/animated-modal";
|
||||
import * as Profile from "../elements/profile";
|
||||
|
||||
const wrapperId = "editProfilePopupWrapper";
|
||||
|
||||
let callbackFuncOnHide: (() => void) | null = null;
|
||||
|
||||
export function show(callbackOnHide: () => void): void {
|
||||
export function show(): void {
|
||||
if (!ConnectionState.get()) {
|
||||
Notifications.add("You are offline", 0, {
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
Skeleton.append(wrapperId, "popups");
|
||||
|
||||
if (!isPopupVisible(wrapperId)) {
|
||||
callbackFuncOnHide = callbackOnHide;
|
||||
|
||||
$("#editProfilePopupWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 0)
|
||||
.removeClass("hidden")
|
||||
.animate({ opacity: 1 }, 125, () => {
|
||||
hydrateInputs();
|
||||
$("#editProfilePopupWrapper").trigger("focus");
|
||||
});
|
||||
}
|
||||
void modal.show({
|
||||
beforeAnimation: async () => {
|
||||
hydrateInputs();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function hide(): void {
|
||||
if (isPopupVisible(wrapperId)) {
|
||||
callbackFuncOnHide?.();
|
||||
$("#editProfilePopupWrapper")
|
||||
.stop(true, true)
|
||||
.css("opacity", 1)
|
||||
.animate(
|
||||
{
|
||||
opacity: 0,
|
||||
},
|
||||
125,
|
||||
() => {
|
||||
$("#editProfilePopupWrapper").addClass("hidden");
|
||||
Skeleton.remove(wrapperId);
|
||||
}
|
||||
);
|
||||
}
|
||||
void modal.hide({
|
||||
afterAnimation: async () => {
|
||||
const snapshot = DB.getSnapshot();
|
||||
if (!snapshot) return;
|
||||
void Profile.update("account", snapshot);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const bioInput = $("#editProfilePopup .bio");
|
||||
const keyboardInput = $("#editProfilePopup .keyboard");
|
||||
const twitterInput = $("#editProfilePopup .twitter");
|
||||
const githubInput = $("#editProfilePopup .github");
|
||||
const websiteInput = $("#editProfilePopup .website");
|
||||
const badgeIdsSelect = $("#editProfilePopup .badgeSelectionContainer");
|
||||
const bioInput = $("#editProfileModal .bio");
|
||||
const keyboardInput = $("#editProfileModal .keyboard");
|
||||
const twitterInput = $("#editProfileModal .twitter");
|
||||
const githubInput = $("#editProfileModal .github");
|
||||
const websiteInput = $("#editProfileModal .website");
|
||||
const badgeIdsSelect = $("#editProfileModal .badgeSelectionContainer");
|
||||
|
||||
let currentSelectedBadgeId = -1;
|
||||
|
||||
|
@ -82,21 +61,21 @@ function hydrateInputs(): void {
|
|||
}
|
||||
|
||||
const badgeOption = getHTMLById(badge.id, false, true);
|
||||
const badgeWrapper = `<div class="badgeSelectionItem ${
|
||||
const badgeWrapper = `<button type="button" class="badgeSelectionItem ${
|
||||
badge.selected ? "selected" : ""
|
||||
}" selection-id=${badge.id}>${badgeOption}</div>`;
|
||||
}" selection-id=${badge.id}>${badgeOption}</button>`;
|
||||
badgeIdsSelect.append(badgeWrapper);
|
||||
});
|
||||
|
||||
badgeIdsSelect.prepend(
|
||||
`<div class="badgeSelectionItem ${
|
||||
`<button type="button" class="badgeSelectionItem ${
|
||||
currentSelectedBadgeId === -1 ? "selected" : ""
|
||||
}" selection-id=${-1}>
|
||||
<div class="badge">
|
||||
<i class="fas fa-frown-open"></i>
|
||||
<div class="text">none</div>
|
||||
</div>
|
||||
</div>`
|
||||
</button>`
|
||||
);
|
||||
|
||||
$(".badgeSelectionItem").on("click", ({ currentTarget }) => {
|
||||
|
@ -184,22 +163,12 @@ async function updateProfile(): Promise<void> {
|
|||
hide();
|
||||
}
|
||||
|
||||
$("#editProfilePopupWrapper").on("mousedown", (e) => {
|
||||
if ($(e.target).attr("id") === "editProfilePopupWrapper") {
|
||||
hide();
|
||||
}
|
||||
const modal = new AnimatedModal({
|
||||
dialogId: "editProfileModal",
|
||||
setup: (modalEl): void => {
|
||||
modalEl.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
await updateProfile();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
$("#editProfilePopupWrapper #editProfilePopup").on("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
await updateProfile();
|
||||
});
|
||||
|
||||
$(document).on("keydown", (event) => {
|
||||
if (event.key === "Escape" && isPopupVisible(wrapperId)) {
|
||||
hide();
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
Skeleton.save(wrapperId);
|
Loading…
Reference in a new issue