diff --git a/frontend/src/scripts/popups/custom-text-popup.ts b/frontend/src/scripts/popups/custom-text-popup.ts index 29b8bca02..24b313309 100644 --- a/frontend/src/scripts/popups/custom-text-popup.ts +++ b/frontend/src/scripts/popups/custom-text-popup.ts @@ -6,6 +6,7 @@ import Config, * as UpdateConfig from "../config"; import * as Misc from "../misc"; import * as WordFilterPopup from "./word-filter-popup"; import * as Notifications from "../elements/notifications"; +import * as SavedTextsPopup from "./saved-texts-popup"; const wrapper = "#customTextPopupWrapper"; const popup = "#customTextPopup"; @@ -107,8 +108,16 @@ $(`${popup} .randomInputFields .time input`).keypress(() => { $(`${popup} .randomInputFields .wordcount input`).val(""); }); -$("#customTextPopup .apply").click(() => { - let text = ($("#customTextPopup textarea").val() as string).normalize(); +$(`${popup} .buttonsTop .showSavedTexts`).on("click", () => { + SavedTextsPopup.show(); +}); + +$(`${popup} .buttonsTop .saveCustomText`).on("click", () => { + hide(); +}); + +function apply(): void { + let text = ($(`${popup} textarea`).val() as string).normalize(); text = text.trim(); // text = text.replace(/[\r]/gm, " "); text = text.replace(/\\\\t/gm, "\t"); @@ -120,26 +129,20 @@ $("#customTextPopup .apply").click(() => { // text = text.replace(/(\n)+/g, "\n"); // text = text.replace(/(\r)+/g, "\r"); text = text.replace(/( *(\r\n|\r|\n) *)/g, "\n "); - if ($("#customTextPopup .typographyCheck input").prop("checked")) { + if ($(`${popup} .typographyCheck input`).prop("checked")) { text = Misc.cleanTypographySymbols(text); } // text = Misc.remove_non_ascii(text); text = text.replace(/[\u2060]/g, ""); CustomText.setText(text.split(CustomText.delimiter)); - CustomText.setWord( - parseInt($("#customTextPopup .wordcount input").val() as string) - ); - CustomText.setTime( - parseInt($("#customTextPopup .time input").val() as string) - ); + CustomText.setWord(parseInt($(`${popup} .wordcount input`).val() as string)); + CustomText.setTime(parseInt($(`${popup} .time input`).val() as string)); CustomText.setIsWordRandom( - $("#customTextPopup .checkbox input").prop("checked") && - !isNaN(CustomText.word) + $(`${popup} .checkbox input`).prop("checked") && !isNaN(CustomText.word) ); CustomText.setIsTimeRandom( - $("#customTextPopup .checkbox input").prop("checked") && - !isNaN(CustomText.time) + $(`${popup} .checkbox input`).prop("checked") && !isNaN(CustomText.time) ); if ( @@ -184,9 +187,13 @@ $("#customTextPopup .apply").click(() => { if (Config.mode !== "custom") UpdateConfig.setMode("custom"); TestLogic.restart(); hide(); +} + +$(document).on("click", `${popup} .button.apply`, () => { + apply(); }); -$("#customTextPopup .wordfilter").click(() => { +$(document).on("click", `${popup} .wordfilter`, () => { WordFilterPopup.show(); }); diff --git a/frontend/src/scripts/popups/saved-texts-popup.ts b/frontend/src/scripts/popups/saved-texts-popup.ts new file mode 100644 index 000000000..b53715f67 --- /dev/null +++ b/frontend/src/scripts/popups/saved-texts-popup.ts @@ -0,0 +1,56 @@ +import * as CustomText from "../test/custom-text"; + +export async function show(): Promise { + const names = CustomText.getCustomTextNames(); + const listEl = $(`#savedTextsPopup .list`).empty(); + let list = ""; + if (names.length === 0) { + list += "
No saved custom texts found
"; + } else { + for (const name of names) { + list += `
+
${name}
+
+ +
+
`; + } + } + listEl.html(list); + $("#savedTextsPopupWrapper").removeClass("hidden"); + $("#customTextPopupWrapper").addClass("hidden"); +} + +function hide(full = false): void { + $("#savedTextsPopupWrapper").addClass("hidden"); + if (!full) $("#customTextPopupWrapper").removeClass("hidden"); +} + +function applySaved(name: string): void { + const text = CustomText.getCustomText(name); + $(`#customTextPopupWrapper textarea`).val(text.join(CustomText.delimiter)); +} + +$(document).on( + "click", + `#savedTextsPopupWrapper .list .savedText .button.name`, + (e) => { + const name = $(e.target).text(); + applySaved(name); + hide(); + } +); + +$(document).on( + "click", + `#savedTextsPopupWrapper .list .savedText .button.delete`, + () => { + hide(true); + } +); + +$("#savedTextsPopupWrapper").mousedown((e) => { + if ($(e.target).attr("id") === "savedTextsPopupWrapper") { + hide(); + } +}); diff --git a/frontend/src/scripts/popups/simple-popups.ts b/frontend/src/scripts/popups/simple-popups.ts index 10729e76f..7f4310497 100644 --- a/frontend/src/scripts/popups/simple-popups.ts +++ b/frontend/src/scripts/popups/simple-popups.ts @@ -7,6 +7,9 @@ import * as Loader from "../elements/loader"; import * as Notifications from "../elements/notifications"; import * as Settings from "../pages/settings"; import * as ApeKeysPopup from "../popups/ape-keys-popup"; +import * as CustomText from "../test/custom-text"; +import * as CustomTextPopup from "../popups/custom-text-popup"; +import * as SavedTextsPopup from "./saved-texts-popup"; type Input = { placeholder: string; @@ -885,6 +888,52 @@ list["editApeKey"] = new SimplePopup( } ); +list["saveCustomText"] = new SimplePopup( + "saveCustomText", + "text", + "Save custom text", + [ + { + placeholder: "Name", + initVal: "", + }, + ], + "", + "Save", + (_thisPopup, input) => { + const text = ($(`#customTextPopup textarea`).val() as string).normalize(); + CustomText.setCustomText(input, text); + Notifications.add("Custom text saved", 1); + CustomTextPopup.show(); + }, + () => { + // + }, + () => { + // + } +); + +list["deleteCustomText"] = new SimplePopup( + "deleteCustomText", + "text", + "Delete custom text", + [], + "Are you sure?", + "Delete", + (_thisPopup) => { + CustomText.deleteCustomText(_thisPopup.parameters[0]); + Notifications.add("Custom text deleted", 1); + SavedTextsPopup.show(); + }, + (_thisPopup) => { + _thisPopup.text = `Are you sure you want to delete custom text ${_thisPopup.parameters[0]}?`; + }, + () => { + // + } +); + $(".pageSettings .section.discordIntegration #unlinkDiscordButton").click( () => { list["unlinkDiscord"].show(); @@ -923,6 +972,19 @@ $("#apeKeysPopup .generateApeKey").on("click", () => { list["generateApeKey"].show(); }); +$(`#customTextPopup .buttonsTop .saveCustomText`).on("click", () => { + list["saveCustomText"].show(); +}); + +$(document).on( + "click", + `#savedTextsPopupWrapper .list .savedText .button.delete`, + (e) => { + const name = $(e.target).siblings(".button.name").text(); + list["deleteCustomText"].show([name]); + } +); + $(document).on("click", "#apeKeysPopup table tbody tr .button.delete", (e) => { const keyId = $(e.target).closest("tr").attr("keyId") as string; list["deleteApeKey"].show([keyId]); diff --git a/frontend/src/scripts/test/custom-text.ts b/frontend/src/scripts/test/custom-text.ts index 45c36232d..72d3d05c5 100644 --- a/frontend/src/scripts/test/custom-text.ts +++ b/frontend/src/scripts/test/custom-text.ts @@ -1,4 +1,14 @@ -export let text = "The quick brown fox jumps over the lazy dog".split(" "); +export let text = [ + "The", + "quick", + "brown", + "fox", + "jumps", + "over", + "the", + "lazy", + "dog", +]; export let isWordRandom = false; export let isTimeRandom = false; export let word: number; @@ -28,3 +38,36 @@ export function setWord(val: number): void { export function setDelimiter(val: string): void { delimiter = val; } + +type CustomTextObject = { [key: string]: string }; + +export function getCustomText(name: string): string[] { + const customText = getCustomTextObject(); + + return customText[name].split(/ +/); +} + +export function setCustomText(name: string, text: string | string[]): void { + const customText = getCustomTextObject(); + + if (typeof text === "string") customText[name] = text; + else customText[name] = text.join(" "); + + window.localStorage.setItem("customText", JSON.stringify(customText)); +} + +export function deleteCustomText(name: string): void { + const customText = getCustomTextObject(); + + if (customText[name]) delete customText[name]; + + window.localStorage.setItem("customText", JSON.stringify(customText)); +} + +function getCustomTextObject(): CustomTextObject { + return JSON.parse(window.localStorage.getItem("customText") ?? "{}"); +} + +export function getCustomTextNames(): string[] { + return Object.keys(getCustomTextObject()); +} diff --git a/frontend/src/styles/popups.scss b/frontend/src/styles/popups.scss index 9f8fedd8f..e52cff9b1 100644 --- a/frontend/src/styles/popups.scss +++ b/frontend/src/styles/popups.scss @@ -20,9 +20,24 @@ display: grid; gap: 1rem; width: 60vw; - .wordfilter { - width: 33%; - justify-self: right; + + .buttonsTop { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 1rem; + } + + .savedTexts { + display: grid; + gap: 0.5rem; + .title { + color: var(--sub-color); + } + .buttons { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + } } textarea { @@ -61,6 +76,36 @@ } } +#savedTextsPopupWrapper { + #savedTextsPopup { + color: var(--sub-color); + 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); + } + + .list { + display: grid; + gap: 1rem; + .savedText { + display: grid; + gap: 0.5rem; + grid-template-columns: 1fr 3rem; + .button .fas { + pointer-events: none; + } + } + } + } +} + #wordFilterPopupWrapper { #wordFilterPopup { color: var(--sub-color); diff --git a/frontend/static/index.html b/frontend/static/index.html index c73034290..3224edccd 100644 --- a/frontend/static/index.html +++ b/frontend/static/index.html @@ -372,9 +372,23 @@