mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-02-26 15:54:35 +08:00
refactor(share custom theme): use new modal system
This commit is contained in:
parent
bc6cf223cf
commit
fcbc00b671
7 changed files with 107 additions and 133 deletions
|
@ -834,16 +834,16 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="shareCustomThemeWrapper" class="popupWrapper hidden">
|
||||
<div id="shareCustomThemeEdit" action="">
|
||||
<div class="title">Share Custom Theme</div>
|
||||
<dialog id="shareCustomThemeModal" class="modalWrapper hidden">
|
||||
<div class="modal">
|
||||
<div class="title">Share custom theme</div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="includeBackground" />
|
||||
Include background information
|
||||
</label>
|
||||
<div class="button copy-button">copy link to clipboard</div>
|
||||
<button>copy link to clipboard</button>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<div id="leaderboardsWrapper" class="popupWrapper hidden">
|
||||
<div id="leaderboards">
|
||||
<div class="leaderboardsTop">
|
||||
|
|
|
@ -1445,15 +1445,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
#shareCustomThemeWrapper {
|
||||
#shareCustomThemeEdit {
|
||||
background: var(--bg-color);
|
||||
border-radius: var(--roundness);
|
||||
padding: 2rem;
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
overflow-y: scroll;
|
||||
width: 500px;
|
||||
#shareCustomThemeModal {
|
||||
.modal {
|
||||
max-width: 400px;
|
||||
|
||||
.buttons {
|
||||
display: grid;
|
||||
|
@ -1463,7 +1457,7 @@
|
|||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
line-height: 1.5rem;
|
||||
color: var(--sub-color);
|
||||
}
|
||||
}
|
||||
|
|
9
frontend/src/ts/event-handlers/settings.ts
Normal file
9
frontend/src/ts/event-handlers/settings.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import * as ShareCustomThemeModal from "../modals/share-custom-theme";
|
||||
|
||||
const settingsPage = document.querySelector("#pageSettings");
|
||||
|
||||
settingsPage
|
||||
?.querySelector("#shareCustomThemeButton")
|
||||
?.addEventListener("click", () => {
|
||||
ShareCustomThemeModal.show();
|
||||
});
|
|
@ -7,6 +7,7 @@ import "./event-handlers/footer";
|
|||
import "./event-handlers/keymap";
|
||||
import "./event-handlers/test";
|
||||
import "./event-handlers/about";
|
||||
import "./event-handlers/settings";
|
||||
|
||||
import "./firebase";
|
||||
import * as Logger from "./utils/logger";
|
||||
|
|
87
frontend/src/ts/modals/share-custom-theme.ts
Normal file
87
frontend/src/ts/modals/share-custom-theme.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
import * as ThemeController from "../controllers/theme-controller";
|
||||
import Config from "../config";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
import * as CustomThemePopup from "../popups/custom-theme-popup";
|
||||
import { createErrorMessage } from "../utils/misc";
|
||||
import AnimatedModal from "../utils/animated-modal";
|
||||
|
||||
type State = {
|
||||
includeBackground: boolean;
|
||||
};
|
||||
|
||||
const state: State = {
|
||||
includeBackground: false,
|
||||
};
|
||||
|
||||
export function show(): void {
|
||||
void modal.show({
|
||||
beforeAnimation: async (m) => {
|
||||
(m.querySelector("input[type='checkbox']") as HTMLInputElement).checked =
|
||||
false;
|
||||
state.includeBackground = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function generateUrl(): Promise<string> {
|
||||
const newTheme: {
|
||||
c: string[]; //colors
|
||||
i?: string; //image
|
||||
s?: string; //size
|
||||
f?: object; //filter
|
||||
} = {
|
||||
c: ThemeController.colorVars.map(
|
||||
(color) =>
|
||||
$(
|
||||
`.pageSettings .customTheme .customThemeEdit #${color}[type='color']`
|
||||
).attr("value") as string
|
||||
),
|
||||
};
|
||||
|
||||
if (state.includeBackground) {
|
||||
newTheme.i = Config.customBackground;
|
||||
newTheme.s = Config.customBackgroundSize;
|
||||
newTheme.f = Config.customBackgroundFilter;
|
||||
}
|
||||
|
||||
return (
|
||||
window.location.origin + "?customTheme=" + btoa(JSON.stringify(newTheme))
|
||||
);
|
||||
}
|
||||
|
||||
async function copy(): Promise<void> {
|
||||
const url = await generateUrl();
|
||||
|
||||
navigator.clipboard.writeText(url).then(
|
||||
function () {
|
||||
Notifications.add("URL Copied to clipboard", 1);
|
||||
void modal.hide();
|
||||
},
|
||||
function (e) {
|
||||
Notifications.add(
|
||||
createErrorMessage(e, "Failed to copy to clipboard"),
|
||||
-1
|
||||
);
|
||||
Notifications.add(
|
||||
"Looks like we couldn't copy the link straight to your clipboard. Please copy it manually.",
|
||||
0,
|
||||
{
|
||||
duration: 5,
|
||||
}
|
||||
);
|
||||
void modal.hide();
|
||||
CustomThemePopup.show(url);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const modal = new AnimatedModal("shareCustomThemeModal", "popups", undefined, {
|
||||
setup: (modal): void => {
|
||||
modal.querySelector("button")?.addEventListener("click", copy);
|
||||
modal
|
||||
.querySelector("input[type='checkbox']")
|
||||
?.addEventListener("change", (e) => {
|
||||
state.includeBackground = (e.target as HTMLInputElement).checked;
|
||||
});
|
||||
},
|
||||
});
|
|
@ -1,117 +0,0 @@
|
|||
import * as ThemeController from "../controllers/theme-controller";
|
||||
import Config from "../config";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
import * as CustomThemePopup from "./custom-theme-popup";
|
||||
import * as Skeleton from "../utils/skeleton";
|
||||
import { createErrorMessage, isPopupVisible } from "../utils/misc";
|
||||
|
||||
const wrapperId = "shareCustomThemeWrapper";
|
||||
|
||||
export function show(): void {
|
||||
Skeleton.append(wrapperId, "popups");
|
||||
|
||||
if (!isPopupVisible(wrapperId)) {
|
||||
$(`#${wrapperId}`)
|
||||
.stop(true, true)
|
||||
.css("opacity", 0)
|
||||
.removeClass("hidden")
|
||||
.animate({ opacity: 1 }, 125, () => {
|
||||
$(`#${wrapperId} #shareCustomThemeEdit .url`).trigger("focus");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function hide(): void {
|
||||
if (isPopupVisible(wrapperId)) {
|
||||
$(`#${wrapperId}`)
|
||||
.stop(true, true)
|
||||
.css("opacity", 1)
|
||||
.animate(
|
||||
{
|
||||
opacity: 0,
|
||||
},
|
||||
125,
|
||||
() => {
|
||||
$(`#${wrapperId}`).addClass("hidden");
|
||||
Skeleton.remove(wrapperId);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateUrl(): Promise<string> {
|
||||
const newTheme: {
|
||||
c: string[]; //colors
|
||||
i?: string; //image
|
||||
s?: string; //size
|
||||
f?: object; //filter
|
||||
} = {
|
||||
c: ThemeController.colorVars.map(
|
||||
(color) =>
|
||||
$(
|
||||
`.pageSettings .customTheme .customThemeEdit #${color}[type='color']`
|
||||
).attr("value") as string
|
||||
),
|
||||
};
|
||||
|
||||
if (
|
||||
$("#shareCustomThemeWrapper #shareCustomThemeEdit #includeBackground").is(
|
||||
":checked"
|
||||
)
|
||||
) {
|
||||
newTheme.i = Config.customBackground;
|
||||
newTheme.s = Config.customBackgroundSize;
|
||||
newTheme.f = Config.customBackgroundFilter;
|
||||
}
|
||||
|
||||
return "https://monkeytype.com?customTheme=" + btoa(JSON.stringify(newTheme));
|
||||
}
|
||||
|
||||
$("#shareCustomThemeWrapper").on("click", (e) => {
|
||||
if ($(e.target).attr("id") === "shareCustomThemeWrapper") {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
$("#shareCustomThemeWrapper #shareCustomThemeEdit .copy-button").on(
|
||||
"click",
|
||||
async () => {
|
||||
const url = await generateUrl();
|
||||
|
||||
navigator.clipboard.writeText(url).then(
|
||||
function () {
|
||||
Notifications.add("URL Copied to clipboard", 1);
|
||||
hide();
|
||||
},
|
||||
function (e) {
|
||||
Notifications.add(
|
||||
createErrorMessage(e, "Failed to copy to clipboard"),
|
||||
-1
|
||||
);
|
||||
Notifications.add(
|
||||
"Looks like we couldn't copy the link straight to your clipboard. Please copy it manually.",
|
||||
0,
|
||||
{
|
||||
duration: 5,
|
||||
}
|
||||
);
|
||||
hide();
|
||||
CustomThemePopup.show(url);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$("#shareCustomThemeButton").on("click", () => {
|
||||
show();
|
||||
});
|
||||
|
||||
$(document).on("keypress", function (e) {
|
||||
if (e.key === "Enter" && isPopupVisible(wrapperId)) {
|
||||
$("#shareCustomThemeWrapper #shareCustomThemeEdit .copy-button").trigger(
|
||||
"click"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Skeleton.save(wrapperId);
|
|
@ -4,7 +4,7 @@ import * as Misc from "../utils/misc";
|
|||
import * as Notifications from "../elements/notifications";
|
||||
import * as ThemeColors from "../elements/theme-colors";
|
||||
import * as ChartController from "../controllers/chart-controller";
|
||||
import * as ShareCustomThemePopup from "../popups/share-custom-theme-popup";
|
||||
import * as ShareCustomThemePopup from "../modals/share-custom-theme";
|
||||
import * as Loader from "../elements/loader";
|
||||
import * as DB from "../db";
|
||||
import * as ConfigEvent from "../observables/config-event";
|
||||
|
|
Loading…
Reference in a new issue