From 381bdb826d0afd6b1c158d6c83137b0563986233 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 13 Feb 2024 18:22:58 +0100 Subject: [PATCH] refactor: settings groups (#5049) * update function name * update function name * using data properties instead of classes * using data property * regex goes brrrrrrr * button not .button * fix sliders loading incorrectly and numbers missing * regex missed this one * and this one * using button instead of .button * use button element * regex goes brrr once morrrrrr * remove testing code --- frontend/src/styles/settings.scss | 4 +- frontend/src/styles/z_media-queries.scss | 6 +- .../src/ts/controllers/input-controller.ts | 2 +- .../ts/elements/custom-background-filter.ts | 121 +- frontend/src/ts/pages/settings.ts | 422 ++-- frontend/src/ts/popups/simple-popups.ts | 10 +- frontend/src/ts/settings/settings-group.ts | 41 +- frontend/src/ts/settings/theme-picker.ts | 16 +- frontend/static/html/pages/settings.html | 1900 +++-------------- 9 files changed, 664 insertions(+), 1858 deletions(-) diff --git a/frontend/src/styles/settings.scss b/frontend/src/styles/settings.scss index 4442b8b66..76f611e20 100644 --- a/frontend/src/styles/settings.scss +++ b/frontend/src/styles/settings.scss @@ -64,7 +64,7 @@ } } - &.autoSwitchThemeInputs { + &[data-config-name="autoSwitchThemeInputs"] { grid-template-areas: unset; grid-template-columns: 1fr 3fr 1fr 3fr; gap: 2rem; @@ -82,7 +82,7 @@ } } - &.customBackgroundFilter { + &[data-config-name="customBackgroundFilter"] { .groups { grid-area: buttons; display: grid; diff --git a/frontend/src/styles/z_media-queries.scss b/frontend/src/styles/z_media-queries.scss index b51a67495..16ded0f06 100644 --- a/frontend/src/styles/z_media-queries.scss +++ b/frontend/src/styles/z_media-queries.scss @@ -309,7 +309,7 @@ .section { grid-template-columns: 1.5fr 1fr; } - .section.autoSwitchThemeInputs { + .section[data-config-name="autoSwitchThemeInputs"] { grid-template-columns: 1fr 3fr; } } @@ -406,7 +406,7 @@ } } - .pageSettings .section.customBackgroundFilter { + .pageSettings .section[data-config-name="customBackgroundFilter"] { .groups { grid-template-columns: 1fr; } @@ -838,7 +838,7 @@ } .pageSettings { - .section.customBackgroundFilter .groups .group { + .section[data-config-name="customBackgroundFilter"] .groups .group { grid-template-columns: auto 1fr; .title { grid-column: 1/3; diff --git a/frontend/src/ts/controllers/input-controller.ts b/frontend/src/ts/controllers/input-controller.ts index 29846bffb..125bbca16 100644 --- a/frontend/src/ts/controllers/input-controller.ts +++ b/frontend/src/ts/controllers/input-controller.ts @@ -193,7 +193,7 @@ function handleSpace(): void { f.functions.handleSpace(); } } - Settings.groups["layout"]?.updateInput(); + Settings.groups["layout"]?.updateUI(); dontInsertSpace = true; diff --git a/frontend/src/ts/elements/custom-background-filter.ts b/frontend/src/ts/elements/custom-background-filter.ts index 9b718a05b..9698e3788 100644 --- a/frontend/src/ts/elements/custom-background-filter.ts +++ b/frontend/src/ts/elements/custom-background-filter.ts @@ -48,77 +48,106 @@ export function apply(): void { } function syncSliders(): void { - $(".section.customBackgroundFilter .blur input").val(filters.blur.value); - $(".section.customBackgroundFilter .brightness input").val( - filters.brightness.value + $(".section[data-config-name='customBackgroundFilter'] .blur input").val( + filters.blur.value ); - $(".section.customBackgroundFilter .saturate input").val( + $( + ".section[data-config-name='customBackgroundFilter'] .brightness input" + ).val(filters.brightness.value); + $(".section[data-config-name='customBackgroundFilter'] .saturate input").val( filters.saturate.value ); - $(".section.customBackgroundFilter .opacity input").val( + $(".section[data-config-name='customBackgroundFilter'] .opacity input").val( filters.opacity.value ); } function updateNumbers(): void { - $(".section.customBackgroundFilter .blur .value").html( + $(".section[data-config-name='customBackgroundFilter'] .blur .value").html( filters.blur.value.toFixed(1) ); - $(".section.customBackgroundFilter .brightness .value").html( - filters.brightness.value.toFixed(1) - ); - $(".section.customBackgroundFilter .saturate .value").html( - filters.saturate.value.toFixed(1) - ); - $(".section.customBackgroundFilter .opacity .value").html( + $( + ".section[data-config-name='customBackgroundFilter'] .brightness .value" + ).html(filters.brightness.value.toFixed(1)); + $( + ".section[data-config-name='customBackgroundFilter'] .saturate .value" + ).html(filters.saturate.value.toFixed(1)); + $(".section[data-config-name='customBackgroundFilter'] .opacity .value").html( filters.opacity.value.toFixed(1) ); } +export function updateUI(): void { + syncSliders(); + updateNumbers(); +} + function loadConfig(config: SharedTypes.Config.CustomBackgroundFilter): void { filters.blur.value = config[0]; filters.brightness.value = config[1]; filters.saturate.value = config[2]; filters.opacity.value = config[3]; - updateNumbers(); - syncSliders(); + updateUI(); } -$(".section.customBackgroundFilter .blur input").on("input", () => { - filters.blur.value = parseFloat( - $(".section.customBackgroundFilter .blur input").val() as string - ); - updateNumbers(); - apply(); -}); +$(".section[data-config-name='customBackgroundFilter'] .blur input").on( + "input", + () => { + filters.blur.value = parseFloat( + $( + ".section[data-config-name='customBackgroundFilter'] .blur input" + ).val() as string + ); + updateNumbers(); + apply(); + } +); -$(".section.customBackgroundFilter .brightness input").on("input", () => { - filters.brightness.value = parseFloat( - $(".section.customBackgroundFilter .brightness input").val() as string - ); - updateNumbers(); - apply(); -}); +$(".section[data-config-name='customBackgroundFilter'] .brightness input").on( + "input", + () => { + filters.brightness.value = parseFloat( + $( + ".section[data-config-name='customBackgroundFilter'] .brightness input" + ).val() as string + ); + updateNumbers(); + apply(); + } +); -$(".section.customBackgroundFilter .saturate input").on("input", () => { - filters.saturate.value = parseFloat( - $(".section.customBackgroundFilter .saturate input").val() as string - ); - updateNumbers(); - apply(); -}); +$(".section[data-config-name='customBackgroundFilter'] .saturate input").on( + "input", + () => { + filters.saturate.value = parseFloat( + $( + ".section[data-config-name='customBackgroundFilter'] .saturate input" + ).val() as string + ); + updateNumbers(); + apply(); + } +); -$(".section.customBackgroundFilter .opacity input").on("input", () => { - filters.opacity.value = parseFloat( - $(".section.customBackgroundFilter .opacity input").val() as string - ); - updateNumbers(); - apply(); -}); +$(".section[data-config-name='customBackgroundFilter'] .opacity input").on( + "input", + () => { + filters.opacity.value = parseFloat( + $( + ".section[data-config-name='customBackgroundFilter'] .opacity input" + ).val() as string + ); + updateNumbers(); + apply(); + } +); -$(".section.customBackgroundFilter input").on("input", () => { - void debouncedSave(); -}); +$(".section[data-config-name='customBackgroundFilter'] input").on( + "input", + () => { + void debouncedSave(); + } +); const debouncedSave = debounce(2000, async () => { const arr = Object.keys(filters).map( diff --git a/frontend/src/ts/pages/settings.ts b/frontend/src/ts/pages/settings.ts index 999906238..0c0dca105 100644 --- a/frontend/src/ts/pages/settings.ts +++ b/frontend/src/ts/pages/settings.ts @@ -20,6 +20,7 @@ import { areFunboxesCompatible } from "../test/funbox/funbox-validation"; import { get as getTypingSpeedUnit } from "../utils/typing-speed-units"; import * as Skeleton from "../popups/skeleton"; +import * as CustomBackgroundFilter from "../elements/custom-background-filter"; type SettingsGroups = Record< string, @@ -50,7 +51,7 @@ async function initGroups(): Promise { UpdateConfig.setShowLiveWpm, "button", () => { - groups["keymapMode"]?.updateInput(); + groups["keymapMode"]?.updateUI(); } ) as SettingsGroup; groups["showLiveAcc"] = new SettingsGroup( @@ -78,19 +79,35 @@ async function initGroups(): Promise { UpdateConfig.setKeymapMode, "button", () => { - groups["showLiveWpm"]?.updateInput(); + groups["showLiveWpm"]?.updateUI(); }, () => { if (Config.keymapMode === "off") { - $(".pageSettings .section.keymapStyle").addClass("hidden"); - $(".pageSettings .section.keymapLayout").addClass("hidden"); - $(".pageSettings .section.keymapLegendStyle").addClass("hidden"); - $(".pageSettings .section.keymapShowTopRow").addClass("hidden"); + $(".pageSettings .section[data-config-name='keymapStyle']").addClass( + "hidden" + ); + $(".pageSettings .section[data-config-name='keymapLayout']").addClass( + "hidden" + ); + $( + ".pageSettings .section[data-config-name='keymapLegendStyle']" + ).addClass("hidden"); + $( + ".pageSettings .section[data-config-name='keymapShowTopRow']" + ).addClass("hidden"); } else { - $(".pageSettings .section.keymapStyle").removeClass("hidden"); - $(".pageSettings .section.keymapLayout").removeClass("hidden"); - $(".pageSettings .section.keymapLegendStyle").removeClass("hidden"); - $(".pageSettings .section.keymapShowTopRow").removeClass("hidden"); + $(".pageSettings .section[data-config-name='keymapStyle']").removeClass( + "hidden" + ); + $( + ".pageSettings .section[data-config-name='keymapLayout']" + ).removeClass("hidden"); + $( + ".pageSettings .section[data-config-name='keymapLegendStyle']" + ).removeClass("hidden"); + $( + ".pageSettings .section[data-config-name='keymapShowTopRow']" + ).removeClass("hidden"); } } ) as SettingsGroup; @@ -132,7 +149,7 @@ async function initGroups(): Promise { UpdateConfig.setFreedomMode, "button", () => { - groups["confidenceMode"]?.updateInput(); + groups["confidenceMode"]?.updateUI(); } ) as SettingsGroup; groups["strictSpace"] = new SettingsGroup( @@ -150,8 +167,8 @@ async function initGroups(): Promise { UpdateConfig.setConfidenceMode, "button", () => { - groups["freedomMode"]?.updateInput(); - groups["stopOnError"]?.updateInput(); + groups["freedomMode"]?.updateUI(); + groups["stopOnError"]?.updateUI(); } ) as SettingsGroup; groups["indicateTypos"] = new SettingsGroup( @@ -239,7 +256,7 @@ async function initGroups(): Promise { UpdateConfig.setStopOnError, "button", () => { - groups["confidenceMode"]?.updateInput(); + groups["confidenceMode"]?.updateUI(); } ) as SettingsGroup; groups["soundVolume"] = new SettingsGroup( @@ -365,10 +382,12 @@ async function initGroups(): Promise { undefined, () => { const customButton = $( - ".pageSettings .section.fontFamily .buttons .custom" + ".pageSettings .section[data-config-name='fontFamily'] .buttons .custom" ); if ( - $(".pageSettings .section.fontFamily .buttons .active").length === 0 + $( + ".pageSettings .section[data-config-name='fontFamily'] .buttons .active" + ).length === 0 ) { customButton.addClass("active"); customButton.text(`Custom (${Config.fontFamily.replace(/_/g, " ")})`); @@ -404,8 +423,8 @@ function reset(): void { $(".pageSettings .section.themes .allCustomThemes.buttons").empty(); $(".pageSettings .section.languageGroups .buttons").empty(); $(".pageSettings select").empty().select2("destroy"); - $(".pageSettings .section.funbox .buttons").empty(); - $(".pageSettings .section.fontFamily .buttons").empty(); + $(".pageSettings .section[data-config-name='funbox'] .buttons").empty(); + $(".pageSettings .section[data-config-name='fontFamily'] .buttons").empty(); } let groupsInitialized = false; @@ -418,7 +437,7 @@ async function fillSettingsPage(): Promise { // Language Selection Combobox const languageEl = document.querySelector( - ".pageSettings .section.language select" + ".pageSettings .section[data-config-name='language'] select" ) as HTMLSelectElement; languageEl.innerHTML = ""; let languageElHTML = ""; @@ -455,13 +474,13 @@ async function fillSettingsPage(): Promise { await Misc.sleep(0); const layoutEl = document.querySelector( - ".pageSettings .section.layout select" + ".pageSettings .section[data-config-name='layout'] select" ) as HTMLSelectElement; layoutEl.innerHTML = ``; let layoutElHTML = ""; const keymapEl = document.querySelector( - ".pageSettings .section.keymapLayout select" + ".pageSettings .section[data-config-name='keymapLayout'] select" ) as HTMLSelectElement; keymapEl.innerHTML = ``; let keymapElHTML = ""; @@ -501,13 +520,13 @@ async function fillSettingsPage(): Promise { await Misc.sleep(0); const themeEl1 = document.querySelector( - ".pageSettings .section.autoSwitchThemeInputs select.light" + ".pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.light" ) as HTMLSelectElement; themeEl1.innerHTML = ""; let themeEl1HTML = ""; const themeEl2 = document.querySelector( - ".pageSettings .section.autoSwitchThemeInputs select.dark" + ".pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.dark" ) as HTMLSelectElement; themeEl2.innerHTML = ""; let themeEl2HTML = ""; @@ -544,17 +563,21 @@ async function fillSettingsPage(): Promise { await Misc.sleep(0); - $(`.pageSettings .section.autoSwitchThemeInputs select.light`) + $( + `.pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.light` + ) .val(Config.themeLight) .trigger("change.select2"); - $(`.pageSettings .section.autoSwitchThemeInputs select.dark`) + $( + `.pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.dark` + ) .val(Config.themeDark) .trigger("change.select2"); const funboxEl = document.querySelector( - ".pageSettings .section.funbox .buttons" + ".pageSettings .section[data-config-name='funbox'] .buttons" ) as HTMLDivElement; - funboxEl.innerHTML = `
none
`; + funboxEl.innerHTML = `
none
`; let funboxElHTML = ""; let funboxList; @@ -567,7 +590,7 @@ async function fillSettingsPage(): Promise { if (funboxList) { for (const funbox of funboxList) { if (funbox.name === "mirror") { - funboxElHTML += `
`; } else if (funbox.name === "upside_down") { - funboxElHTML += `
`; } else { - funboxElHTML += `
{ Config.fontFamily === font.name ? " active" : "" }" style="font-family:${ font.display !== undefined ? font.display : font.name - }" fontFamily="${font.name.replace(/ /g, "_")}" tabindex="0" + }" data-config-value="${font.name.replace(/ /g, "_")}" tabindex="0" onclick="this.blur();">${ font.display !== undefined ? font.display : font.name }
`; @@ -640,13 +663,15 @@ async function fillSettingsPage(): Promise { fontsEl.innerHTML = fontsElHTML; } - $(".pageSettings .section.customBackgroundSize input").val( - Config.customBackground + $( + ".pageSettings .section[data-config-name='customBackgroundSize'] input" + ).val(Config.customBackground); + + $(".pageSettings .section[data-config-name='fontSize'] input").val( + Config.fontSize ); - $(".pageSettings .section.fontSize input").val(Config.fontSize); - - $(".pageSettings .section.customLayoutfluid input").val( + $(".pageSettings .section[data-config-name='customLayoutfluid'] input").val( Config.customLayoutfluid.replace(/#/g, " ") ); @@ -657,7 +682,7 @@ async function fillSettingsPage(): Promise { groupsInitialized = true; } else { for (const groupKey of Object.keys(groups)) { - groups[groupKey]?.updateInput(); + groups[groupKey]?.updateUI(); } } setEventDisabled(false); @@ -715,8 +740,8 @@ export function updateDiscordSection(): void { } export function updateAuthSections(): void { - $(".pageSettings .section.passwordAuthSettings .button").addClass("hidden"); - $(".pageSettings .section.googleAuthSettings .button").addClass("hidden"); + $(".pageSettings .section.passwordAuthSettings button").addClass("hidden"); + $(".pageSettings .section.googleAuthSettings button").addClass("hidden"); const user = Auth?.currentUser; if (!user) return; @@ -762,8 +787,12 @@ export function updateAuthSections(): void { } function setActiveFunboxButton(): void { - $(`.pageSettings .section.funbox .button`).removeClass("active"); - $(`.pageSettings .section.funbox .button`).removeClass("disabled"); + $(`.pageSettings .section[data-config-name='funbox'] .button`).removeClass( + "active" + ); + $(`.pageSettings .section[data-config-name='funbox'] .button`).removeClass( + "disabled" + ); Misc.getFunboxList() .then((funboxModes) => { funboxModes.forEach((funbox) => { @@ -772,7 +801,7 @@ function setActiveFunboxButton(): void { !Config.funbox.split("#").includes(funbox.name) ) { $( - `.pageSettings .section.funbox .button[funbox='${funbox.name}']` + `.pageSettings .section[data-config-name='funbox'] .button[data-config-value='${funbox.name}']` ).addClass("disabled"); } }); @@ -781,9 +810,9 @@ function setActiveFunboxButton(): void { Notifications.add(`Failed to update funbox buttons: ${e.message}`, -1); }); Config.funbox.split("#").forEach((funbox) => { - $(`.pageSettings .section.funbox .button[funbox='${funbox}']`).addClass( - "active" - ); + $( + `.pageSettings .section[data-config-name='funbox'] .button[data-config-value='${funbox}']` + ).addClass("active"); }); } @@ -851,7 +880,7 @@ export async function update(groupUpdate = true): Promise { // Object.keys(groups).forEach((group) => { if (groupUpdate) { for (const group of Object.keys(groups)) { - groups[group]?.updateInput(); + groups[group]?.updateUI(); } } @@ -866,34 +895,48 @@ export async function update(groupUpdate = true): Promise { ThemePicker.setCustomInputs(true); // ThemePicker.updateActiveButton(); - $(".pageSettings .section.paceCaret input.customPaceCaretSpeed").val( + $( + ".pageSettings .section[data-config-name='paceCaret'] input.customPaceCaretSpeed" + ).val( getTypingSpeedUnit(Config.typingSpeedUnit).fromWpm( Config.paceCaretCustomSpeed ) ); - $(".pageSettings .section.minWpm input.customMinWpmSpeed").val( + $( + ".pageSettings .section[data-config-name='minWpm'] input.customMinWpmSpeed" + ).val( getTypingSpeedUnit(Config.typingSpeedUnit).fromWpm(Config.minWpmCustomSpeed) ); - $(".pageSettings .section.minAcc input.customMinAcc").val( + $(".pageSettings .section[data-config-name='minAcc'] input.customMinAcc").val( Config.minAccCustom ); - $(".pageSettings .section.minBurst input.customMinBurst").val( + $( + ".pageSettings .section[data-config-name='minBurst'] input.customMinBurst" + ).val( getTypingSpeedUnit(Config.typingSpeedUnit).fromWpm( Config.minBurstCustomSpeed ) ); if (Config.autoSwitchTheme) { - $(".pageSettings .section.autoSwitchThemeInputs").removeClass("hidden"); + $( + ".pageSettings .section[data-config-name='autoSwitchThemeInputs']" + ).removeClass("hidden"); } else { - $(".pageSettings .section.autoSwitchThemeInputs").addClass("hidden"); + $( + ".pageSettings .section[data-config-name='autoSwitchThemeInputs']" + ).addClass("hidden"); } if (Config.customBackground !== "") { - $(".pageSettings .section.customBackgroundFilter").removeClass("hidden"); + $( + ".pageSettings .section[data-config-name='customBackgroundFilter']" + ).removeClass("hidden"); } else { - $(".pageSettings .section.customBackgroundFilter").addClass("hidden"); + $( + ".pageSettings .section[data-config-name='customBackgroundFilter']" + ).addClass("hidden"); } if (Auth?.currentUser) { @@ -902,6 +945,8 @@ export async function update(groupUpdate = true): Promise { hideAccountSection(); } + CustomBackgroundFilter.updateUI(); + const modifierKey = window.navigator.userAgent.toLowerCase().includes("mac") ? "cmd" : "ctrl"; @@ -930,13 +975,13 @@ function toggleSettingsGroup(groupName: string): void { } } -$(".pageSettings .section.paceCaret").on( +$(".pageSettings .section[data-config-name='paceCaret']").on( "focusout", "input.customPaceCaretSpeed", () => { const inputValue = parseInt( $( - ".pageSettings .section.paceCaret input.customPaceCaretSpeed" + ".pageSettings .section[data-config-name='paceCaret'] input.customPaceCaretSpeed" ).val() as string ); const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( @@ -946,24 +991,30 @@ $(".pageSettings .section.paceCaret").on( } ); -$(".pageSettings .section.paceCaret").on("click", ".button.save", () => { - const inputValue = parseInt( - $( - ".pageSettings .section.paceCaret input.customPaceCaretSpeed" - ).val() as string - ); - const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( - inputValue - ); - UpdateConfig.setPaceCaretCustomSpeed(newConfigValue); -}); +$(".pageSettings .section[data-config-name='paceCaret']").on( + "click", + "button.save", + () => { + const inputValue = parseInt( + $( + ".pageSettings .section[data-config-name='paceCaret'] input.customPaceCaretSpeed" + ).val() as string + ); + const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( + inputValue + ); + UpdateConfig.setPaceCaretCustomSpeed(newConfigValue); + } +); -$(".pageSettings .section.minWpm").on( +$(".pageSettings .section[data-config-name='minWpm']").on( "focusout", "input.customMinWpmSpeed", () => { const inputValue = parseInt( - $(".pageSettings .section.minWpm input.customMinWpmSpeed").val() as string + $( + ".pageSettings .section[data-config-name='minWpm'] input.customMinWpmSpeed" + ).val() as string ); const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( inputValue @@ -972,38 +1023,58 @@ $(".pageSettings .section.minWpm").on( } ); -$(".pageSettings .section.minWpm").on("click", ".button.save", () => { - const inputValue = parseInt( - $(".pageSettings .section.minWpm input.customMinWpmSpeed").val() as string - ); - const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( - inputValue - ); - UpdateConfig.setMinWpmCustomSpeed(newConfigValue); -}); +$(".pageSettings .section[data-config-name='minWpm']").on( + "click", + "button.save", + () => { + const inputValue = parseInt( + $( + ".pageSettings .section[data-config-name='minWpm'] input.customMinWpmSpeed" + ).val() as string + ); + const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( + inputValue + ); + UpdateConfig.setMinWpmCustomSpeed(newConfigValue); + } +); -$(".pageSettings .section.minAcc").on("focusout", "input.customMinAcc", () => { - UpdateConfig.setMinAccCustom( - parseInt( - $(".pageSettings .section.minAcc input.customMinAcc").val() as string - ) - ); -}); +$(".pageSettings .section[data-config-name='minAcc']").on( + "focusout", + "input.customMinAcc", + () => { + UpdateConfig.setMinAccCustom( + parseInt( + $( + ".pageSettings .section[data-config-name='minAcc'] input.customMinAcc" + ).val() as string + ) + ); + } +); -$(".pageSettings .section.minAcc").on("click", ".button.save", () => { - UpdateConfig.setMinAccCustom( - parseInt( - $(".pageSettings .section.minAcc input.customMinAcc").val() as string - ) - ); -}); +$(".pageSettings .section[data-config-name='minAcc']").on( + "click", + "button.save", + () => { + UpdateConfig.setMinAccCustom( + parseInt( + $( + ".pageSettings .section[data-config-name='minAcc'] input.customMinAcc" + ).val() as string + ) + ); + } +); -$(".pageSettings .section.minBurst").on( +$(".pageSettings .section[data-config-name='minBurst']").on( "focusout", "input.customMinBurst", () => { const inputValue = parseInt( - $(".pageSettings .section.minBurst input.customMinBurst").val() as string + $( + ".pageSettings .section[data-config-name='minBurst'] input.customMinBurst" + ).val() as string ); const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( inputValue @@ -1012,22 +1083,32 @@ $(".pageSettings .section.minBurst").on( } ); -$(".pageSettings .section.minBurst").on("click", ".button.save", () => { - const inputValue = parseInt( - $(".pageSettings .section.minBurst input.customMinBurst").val() as string - ); - const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( - inputValue - ); - UpdateConfig.setMinBurstCustomSpeed(newConfigValue); -}); +$(".pageSettings .section[data-config-name='minBurst']").on( + "click", + "button.save", + () => { + const inputValue = parseInt( + $( + ".pageSettings .section[data-config-name='minBurst'] input.customMinBurst" + ).val() as string + ); + const newConfigValue = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( + inputValue + ); + UpdateConfig.setMinBurstCustomSpeed(newConfigValue); + } +); //funbox -$(".pageSettings .section.funbox").on("click", ".button", (e) => { - const funbox = $(e.currentTarget).attr("funbox") as string; - toggleFunbox(funbox); - setActiveFunboxButton(); -}); +$(".pageSettings .section[data-config-name='funbox']").on( + "click", + ".button", + (e) => { + const funbox = $(e.currentTarget).attr("data-config-value") as string; + toggleFunbox(funbox); + setActiveFunboxButton(); + } +); //tags $(".pageSettings .section.tags").on( @@ -1076,34 +1157,36 @@ $(".pageSettings .section.apeKeys #showApeKeysPopup").on("click", () => { void ApeKeysPopup.show(); }); -$(".pageSettings .section.customBackgroundSize .inputAndButton .save").on( - "click", - () => { +$( + ".pageSettings .section[data-config-name='customBackgroundSize'] .inputAndButton button.save" +).on("click", () => { + UpdateConfig.setCustomBackground( + $( + ".pageSettings .section[data-config-name='customBackgroundSize'] .inputAndButton input" + ).val() as string + ); +}); + +$( + ".pageSettings .section[data-config-name='customBackgroundSize'] .inputAndButton input" +).on("keypress", (e) => { + if (e.key === "Enter") { UpdateConfig.setCustomBackground( $( - ".pageSettings .section.customBackgroundSize .inputAndButton input" + ".pageSettings .section[data-config-name='customBackgroundSize'] .inputAndButton input" ).val() as string ); } -); +}); -$(".pageSettings .section.customBackgroundSize .inputAndButton input").on( - "keypress", - (e) => { - if (e.key === "Enter") { - UpdateConfig.setCustomBackground( - $( - ".pageSettings .section.customBackgroundSize .inputAndButton input" - ).val() as string - ); - } - } -); - -$(".pageSettings .section.fontSize .inputAndButton .save").on("click", () => { +$( + ".pageSettings .section[data-config-name='fontSize'] .inputAndButton button.save" +).on("click", () => { const didConfigSave = UpdateConfig.setFontSize( parseFloat( - $(".pageSettings .section.fontSize .inputAndButton input").val() as string + $( + ".pageSettings .section[data-config-name='fontSize'] .inputAndButton input" + ).val() as string ) ); if (didConfigSave) { @@ -1113,32 +1196,46 @@ $(".pageSettings .section.fontSize .inputAndButton .save").on("click", () => { } }); -$(".pageSettings .section.fontSize .inputAndButton input").on( - "keypress", - (e) => { - if (e.key === "Enter") { - const didConfigSave = UpdateConfig.setFontSize( - parseFloat( - $( - ".pageSettings .section.fontSize .inputAndButton input" - ).val() as string - ) - ); - if (didConfigSave) { - Notifications.add("Saved", 1, { - duration: 1, - }); - } +$( + ".pageSettings .section[data-config-name='fontSize'] .inputAndButton input" +).on("keypress", (e) => { + if (e.key === "Enter") { + const didConfigSave = UpdateConfig.setFontSize( + parseFloat( + $( + ".pageSettings .section[data-config-name='fontSize'] .inputAndButton input" + ).val() as string + ) + ); + if (didConfigSave) { + Notifications.add("Saved", 1, { + duration: 1, + }); } } -); +}); -$(".pageSettings .section.customLayoutfluid .inputAndButton .save").on( - "click", - () => { +$( + ".pageSettings .section[data-config-name='customLayoutfluid'] .inputAndButton button.save" +).on("click", () => { + void UpdateConfig.setCustomLayoutfluid( + $( + ".pageSettings .section[data-config-name='customLayoutfluid'] .inputAndButton input" + ).val() as MonkeyTypes.CustomLayoutFluidSpaces + ).then((bool) => { + if (bool) { + Notifications.add("Custom layoutfluid saved", 1); + } + }); +}); + +$( + ".pageSettings .section[data-config-name='customLayoutfluid'] .inputAndButton .input" +).on("keypress", (e) => { + if (e.key === "Enter") { void UpdateConfig.setCustomLayoutfluid( $( - ".pageSettings .section.customLayoutfluid .inputAndButton input" + ".pageSettings .section[data-config-name='customLayoutfluid'] .inputAndButton input" ).val() as MonkeyTypes.CustomLayoutFluidSpaces ).then((bool) => { if (bool) { @@ -1146,24 +1243,7 @@ $(".pageSettings .section.customLayoutfluid .inputAndButton .save").on( } }); } -); - -$(".pageSettings .section.customLayoutfluid .inputAndButton .input").on( - "keypress", - (e) => { - if (e.key === "Enter") { - void UpdateConfig.setCustomLayoutfluid( - $( - ".pageSettings .section.customLayoutfluid .inputAndButton input" - ).val() as MonkeyTypes.CustomLayoutFluidSpaces - ).then((bool) => { - if (bool) { - Notifications.add("Custom layoutfluid saved", 1); - } - }); - } - } -); +}); $(".pageSettings .quickNav .links a").on("click", (e) => { const settingsGroup = e.target.innerText; @@ -1173,12 +1253,12 @@ $(".pageSettings .quickNav .links a").on("click", (e) => { isOpen && toggleSettingsGroup(settingsGroup); }); -$(".pageSettings .section.updateCookiePreferences .button").on("click", () => { +$(".pageSettings .section.updateCookiePreferences button").on("click", () => { CookiePopup.show(); CookiePopup.showSettings(); }); -$(".pageSettings .section.autoSwitchThemeInputs").on( +$(".pageSettings .section[data-config-name='autoSwitchThemeInputs']").on( "change", `select.light`, (e) => { @@ -1190,7 +1270,7 @@ $(".pageSettings .section.autoSwitchThemeInputs").on( } ); -$(".pageSettings .section.autoSwitchThemeInputs").on( +$(".pageSettings .section[data-config-name='autoSwitchThemeInputs']").on( "change", `select.dark`, (e) => { diff --git a/frontend/src/ts/popups/simple-popups.ts b/frontend/src/ts/popups/simple-popups.ts index 65593888d..ce2b50048 100644 --- a/frontend/src/ts/popups/simple-popups.ts +++ b/frontend/src/ts/popups/simple-popups.ts @@ -1877,9 +1877,13 @@ $("#popups").on("click", "#apeKeysPopup table tbody tr .button.edit", (e) => { showPopup("editApeKey", [keyId]); }); -$(".pageSettings").on("click", ".section.fontFamily .button.custom", () => { - showPopup("applyCustomFont", []); -}); +$(".pageSettings").on( + "click", + ".section[data-config-name='fontFamily'] .button.custom", + () => { + showPopup("applyCustomFont", []); + } +); $(document).on("keydown", (event) => { if (event.key === "Escape" && isElementVisible("#simplePopupWrapper")) { diff --git a/frontend/src/ts/settings/settings-group.ts b/frontend/src/ts/settings/settings-group.ts index 450ae614d..13774c492 100644 --- a/frontend/src/ts/settings/settings-group.ts +++ b/frontend/src/ts/settings/settings-group.ts @@ -1,4 +1,5 @@ import Config from "../config"; +import * as Notifications from "../elements/notifications"; export default class SettingsGroup { public configName: string; @@ -21,12 +22,12 @@ export default class SettingsGroup { this.setCallback = setCallback; this.updateCallback = updateCallback; - this.updateInput(); + this.updateUI(); if (this.mode === "select") { $(".pageSettings").on( "change", - `.section.${this.configName} select`, + `.section[data-config-name='${this.configName}'] select`, (e) => { const target = $(e.currentTarget); if ( @@ -41,7 +42,7 @@ export default class SettingsGroup { } else if (this.mode === "button") { $(".pageSettings").on( "click", - `.section.${this.configName} .button`, + `.section[data-config-name='${this.configName}'] button`, (e) => { const target = $(e.currentTarget); if ( @@ -50,11 +51,21 @@ export default class SettingsGroup { ) { return; } - let value: string | boolean = target.attr(configName) as string; - if (!value) return; - if (value === "true") value = true; - if (value === "false") value = false; - this.setValue(value as T); + const value = target.attr(`data-config-value`); + if (value === undefined || value === "") { + console.error( + `Failed to handle settings button click for ${configName}: data-${configName} is missing or empty.` + ); + Notifications.add( + "Button is missing data property. Please report this.", + -1 + ); + return; + } + let typed = value as T; + if (typed === "true") typed = true as T; + if (typed === "false") typed = false as T; + this.setValue(typed as T); } ); } @@ -62,24 +73,24 @@ export default class SettingsGroup { setValue(value: T): void { this.configFunction(value); - this.updateInput(); + this.updateUI(); if (this.setCallback) this.setCallback(); } - updateInput(): void { + updateUI(): void { this.configValue = Config[this.configName as keyof typeof Config] as T; - $(`.pageSettings .section.${this.configName} .button`).removeClass( - "active" - ); + $( + `.pageSettings .section[data-config-name='${this.configName}'] button` + ).removeClass("active"); if (this.mode === "select") { - $(`.pageSettings .section.${this.configName} select`) + $(`.pageSettings .section[data-config-name='${this.configName}'] select`) .val(this.configValue as string) .trigger("change.select2"); } else if (this.mode === "button") { $( // this cant be an object? // eslint-disable-next-line @typescript-eslint/no-base-to-string - `.pageSettings .section.${this.configName} .button[${this.configName}='${this.configValue}']` + `.pageSettings .section[data-config-name='${this.configName}'] button[data-config-value='${this.configValue}']` ).addClass("active"); } if (this.updateCallback) this.updateCallback(); diff --git a/frontend/src/ts/settings/theme-picker.ts b/frontend/src/ts/settings/theme-picker.ts index 34647e720..ebfc89c7b 100644 --- a/frontend/src/ts/settings/theme-picker.ts +++ b/frontend/src/ts/settings/theme-picker.ts @@ -120,12 +120,12 @@ export async function refreshButtons(): Promise { if (!Auth?.currentUser) { $( - ".pageSettings .section.themes .customThemeEdit .saveCustomThemeButton" + ".pageSettings .section.themes .customThemeEdit #saveCustomThemeButton" ).text("save"); return; } else { $( - ".pageSettings .section.themes .customThemeEdit .saveCustomThemeButton" + ".pageSettings .section.themes .customThemeEdit #saveCustomThemeButton" ).text("save as new"); } @@ -288,10 +288,10 @@ export function updateActiveTab(forced = false): void { // Set force to true only when some change for the active tab has taken place // Prevent theme buttons from being added twice by doing an update only when the state has changed const $presetTabButton = $( - ".pageSettings .section.themes .tabs .button[tab='preset']" + ".pageSettings .section.themes .tabs button[data-tab='preset']" ); const $customTabButton = $( - ".pageSettings .section.themes .tabs .button[tab='custom']" + ".pageSettings .section.themes .tabs button[data-tab='custom']" ); if (Config.customTheme) { @@ -322,13 +322,13 @@ export function updateActiveTab(forced = false): void { // Add events to the DOM // Handle click on theme: preset or custom tab -$(".pageSettings .section.themes .tabs .button").on("click", (e) => { - $(".pageSettings .section.themes .tabs .button").removeClass("active"); +$(".pageSettings .section.themes .tabs button").on("click", (e) => { + $(".pageSettings .section.themes .tabs button").removeClass("active"); const $target = $(e.currentTarget); $target.addClass("active"); // setCustomInputs(); //test - if ($target.attr("tab") === "preset") { + if ($target.attr("data-tab") === "preset") { UpdateConfig.setCustomTheme(false); } else { UpdateConfig.setCustomTheme(true); @@ -462,7 +462,7 @@ $("#shareCustomThemeButton").on("click", () => { ShareCustomThemePopup.show(); }); -$(".pageSettings .saveCustomThemeButton").on("click", async () => { +$(".pageSettings #saveCustomThemeButton").on("click", async () => { saveCustomThemeColors(); if (Auth?.currentUser) { const newCustomTheme = { diff --git a/frontend/static/html/pages/settings.html b/frontend/static/html/pages/settings.html index 3ec5f6245..5912273aa 100644 --- a/frontend/static/html/pages/settings.html +++ b/frontend/static/html/pages/settings.html @@ -132,7 +132,7 @@ behavior
-
+
test difficulty @@ -143,33 +143,12 @@ single incorrect key (meaning you have to achieve 100% accuracy).
-
- normal -
-
- expert -
-
- master -
+ + +
-
+
quick restart @@ -188,42 +167,14 @@ key.
-
- off -
-
- tab -
-
- esc -
-
- enter -
+ + + +
-
+
repeat quotes @@ -235,29 +186,15 @@
-
- off -
-
- typing -
+ +
-
+
blind mode @@ -267,26 +204,14 @@ speed. If enabled, quick end is recommended.
-
- off -
-
+ +
+
-
+
always show words history @@ -296,24 +221,11 @@ test. Can cause slight lag with a lot of words.
-
- off -
-
- on -
+ +
-
+
single list command line @@ -326,25 +238,11 @@ .
-
- manual -
-
- on -
+ +
-
+
min speed @@ -363,26 +261,17 @@ step="1" value="" /> -
+
+
-
- off -
-
- custom -
+ +
-
+
min accuracy @@ -401,26 +290,17 @@ step="1" value="" /> -
+
+
-
- off -
-
- custom -
+ +
-
+
min burst @@ -441,39 +321,18 @@ step="1" value="" /> -
+
+
-
- off -
-
- fixed -
-
- flex -
+ + +
-
+
british english @@ -484,25 +343,11 @@ find any issues, please let us know.
-
- off -
-
- on -
+ +
-
+
language @@ -512,7 +357,7 @@
-
+
funbox @@ -525,7 +370,7 @@
-
+
custom layoutfluid @@ -541,9 +386,9 @@ class="input" tabindex="0" /> -
+
+
@@ -554,7 +399,7 @@ input
-
+
freedom mode @@ -563,25 +408,11 @@ Allows you to delete any word, even if it was typed correctly.
-
- off -
-
- on -
+ +
-
+
strict space @@ -591,25 +422,11 @@ when this mode is enabled.
-
- off -
-
- on -
+ +
-
+
opposite shift mode @@ -630,33 +447,12 @@ opposite shift based on the "keymap layout" setting.
-
- off -
-
- on -
-
- keymap -
+ + +
-
+
stop on error @@ -667,33 +463,12 @@ all mistakes.
-
- off -
-
- word -
-
- letter -
+ + +
-
+
confidence mode @@ -704,34 +479,13 @@ all.
-
- off -
+ -
- on -
-
- max -
+ +
-
+
quick end @@ -743,20 +497,11 @@ space.
-
- off -
-
- on -
+ +
-
+
indicate typos @@ -766,33 +511,12 @@ letters and replace will replace the letters with the ones you typed.
-
- off -
-
- below -
-
- replace -
+ + +
-
+
hide extra letters @@ -803,25 +527,11 @@ and nothing happens.
-
- off -
-
- on -
+ +
-
+
lazy mode @@ -831,20 +541,11 @@ letter equivalents.
-
- off -
-
- on -
+ +
-
+
layout emulator @@ -874,177 +575,44 @@ sound
-
+
sound volume
Change the volume of the sound effects.
-
- quiet -
-
- medium -
-
- loud -
+ + +
-
+
play sound on click
Plays a short sound when you press a key.
-
- off -
-
- click -
-
- beep -
-
- pop -
-
- nk creams -
-
- typewriter -
-
- osu -
-
- hitmarker -
-
- sine -
-
- sawtooth -
-
- square -
-
- triangle -
-
- pentatonic -
-
- wholetone -
-
- fist fight -
-
- rubber keys -
+ + + + + + + + + + + + + + + +
-
+
play sound on error @@ -1054,46 +622,11 @@ early.
-
- off -
-
- damage -
-
- triangle -
-
- square -
-
- missed punch -
+ + + + +
@@ -1104,7 +637,7 @@ caret
-
+
smooth caret @@ -1113,90 +646,27 @@ The caret will move smoothly between letters and words.
-
- off -
-
- slow -
-
- medium -
-
- fast -
+ + + +
-
+
caret style
Change the style of the caret during the test.
-
- off -
-
- | -
-
- ▮ -
-
- ▯ -
-
- _ -
+ + + + +
-
+
pace caret @@ -1217,63 +687,21 @@ step="1" value="" /> -
+
+
-
- off -
-
- avg -
-
- pb -
-
- last -
-
- daily -
-
- custom -
+ + + + + +
-
+
repeated pace @@ -1284,25 +712,11 @@ pace caret if it's already enabled.
-
- off -
-
- on -
+ +
-
+
pace caret style @@ -1311,46 +725,11 @@ Change the style of the pace caret during the test.
-
- off -
-
- | -
-
- ▮ -
-
- ▯ -
-
- _ -
+ + + + +
@@ -1365,7 +744,7 @@ appearance
-
+
live progress style @@ -1374,33 +753,12 @@ Change the style of the timer/word count during a timed test.
-
- bar -
-
- text -
-
- mini -
+ + +
-
+
live progress color @@ -1410,41 +768,13 @@ number.
-
- black -
-
- sub -
-
- text -
-
- main -
+ + + +
-
+
live progress opacity @@ -1454,98 +784,28 @@ number.
-
- 0.25 -
-
- 0.5 -
-
- 0.75 -
-
- 1 -
+ + + +
-
+
highlight mode
Change what is highlighted during the test.
-
- off -
-
- letter -
-
- word -
-
- next word -
-
- next two words -
-
- next three words -
+ + + + + +
-
+
tape mode @@ -1557,23 +817,12 @@ monospace font.
-
- off -
-
- letter -
-
- word -
+ + +
-
+
smooth line scroll @@ -1582,25 +831,11 @@ When enabled, the line transition will be animated.
-
- off -
-
- on -
+ +
-
+
show all lines @@ -1612,25 +847,11 @@ speed to not be visible.
-
- off -
-
- on -
+ +
-
+
00
always show decimal places @@ -1640,66 +861,24 @@ need to hover over the stats.
-
- off -
-
- on -
+ +
-
+
typing speed unit
Display typing speed in the specified unit.
-
- wpm -
-
- cpm -
-
- wps -
-
- cps -
+ + + +
-
+
start graphs at zero @@ -1709,25 +888,11 @@ Turning this off may exaggerate the value changes.
-
- off -
-
- on -
+ +
-
+
font size @@ -1741,13 +906,13 @@ class="input" tabindex="0" /> -
+
+
-
+
font family @@ -1755,31 +920,21 @@
-
+
page width
Control the width of the content.
-
- 100% -
-
- 125% -
-
- 150% -
-
- 200% -
-
- max -
+ + + + +
-
+
keymap @@ -1789,41 +944,13 @@ pressed and Next shows what you need to press next.
-
- off -
-
- static -
-
- react -
-
- next -
+ + + +
-
+
keymap layout @@ -1831,141 +958,43 @@
Controls which layout is displayed on the keymap.
-
+
keymap style
-
- staggered -
-
- alice -
-
- matrix -
-
- split -
-
- split matrix -
-
- steno -
-
- steno matrix -
+ + + + + + +
-
+
keymap legend style
-
- lowercase -
-
- uppercase -
-
- blank -
-
- dynamic -
+ + + +
-
+
keymap show top row
-
- always -
-
- layout dependent -
-
- never -
+ + +
@@ -1985,7 +1014,7 @@ theme
-
+
flip test colors @@ -1996,25 +1025,11 @@ already typed text.
-
- off -
-
- on -
+ +
-
+
colorful mode @@ -2024,25 +1039,11 @@ text color, making the website more colorful.
-
- off -
-
- on -
+ +
-
+
custom background @@ -2061,39 +1062,18 @@ tabindex="0" onClick="this.select();" /> -
+
+
-
- cover -
-
- contain -
-
- max -
+ + +
-
+
custom background filter @@ -2122,7 +1102,7 @@
-
+
auto switch theme @@ -2132,31 +1112,17 @@ depending on the system theme.
-
- off -
-
- on -
+ +
-
+
light
dark
-
+
randomize theme @@ -2169,54 +1135,12 @@ respectively. If set to 'custom', custom themes will be randomized.
-
- off -
-
- on -
-
- favorite -
-
- light -
-
- dark -
-
- custom -
+ + + + + +
@@ -2225,12 +1149,8 @@ theme
-
- preset -
-
- custom -
+ +