diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a3b437b0c..b85e9a923 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -28,7 +28,7 @@ "konami": "1.6.3", "lz-ts": "1.1.2", "object-hash": "3.0.0", - "select2": "4.1.0-rc.0", + "slim-select": "2.8.1", "stemmer": "2.0.0", "throttle-debounce": "3.0.1", "workbox-window": "6.5.4" @@ -42,7 +42,6 @@ "@types/jest": "27.5.0", "@types/jquery": "3.5.14", "@types/object-hash": "2.2.1", - "@types/select2": "4.0.55", "@types/throttle-debounce": "2.1.0", "@types/tinycolor2": "1.4.3", "autoprefixer": "10.4.14", @@ -3860,15 +3859,6 @@ "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", "dev": true }, - "node_modules/@types/select2": { - "version": "4.0.55", - "resolved": "https://registry.npmjs.org/@types/select2/-/select2-4.0.55.tgz", - "integrity": "sha512-lqngYTv7W1e8HiLSEq7cJhnnKqV3vuwCBkfka6ZXBoM0Z8aVoZrR9gxjbwRzcqBBw4EpAvVXZGPuaDOM+apeZw==", - "dev": true, - "dependencies": { - "@types/jquery": "*" - } - }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -14699,8 +14689,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -15400,6 +15389,17 @@ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -18248,6 +18248,29 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -19092,6 +19115,14 @@ "node": ">=v12.22.7" } }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -19116,11 +19147,6 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, - "node_modules/select2": { - "version": "4.1.0-rc.0", - "resolved": "https://registry.npmjs.org/select2/-/select2-4.1.0-rc.0.tgz", - "integrity": "sha512-Hr9TdhyHCZUtwznEH2CBf7967mEM0idtJ5nMtjvk3Up5tPukOLXbHUNmh10oRfeNIhj+3GD3niu+g6sVK+gK0A==" - }, "node_modules/selfsigned": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", @@ -19616,6 +19642,15 @@ "node": ">=8" } }, + "node_modules/slim-select": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/slim-select/-/slim-select-2.8.1.tgz", + "integrity": "sha512-/wi+4dau48edrPZ/ggD+R8qD6FbCLGv5zvrYh4rqp1RNEIbkb1pRYJbljLjvr7/QqBvX3Hjbnvdnw9FPzJ8o5Q==", + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 0b90a48e5..ddba91f41 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,7 +31,6 @@ "@types/jest": "27.5.0", "@types/jquery": "3.5.14", "@types/object-hash": "2.2.1", - "@types/select2": "4.0.55", "@types/throttle-debounce": "2.1.0", "@types/tinycolor2": "1.4.3", "autoprefixer": "10.4.14", @@ -99,7 +98,7 @@ "konami": "1.6.3", "lz-ts": "1.1.2", "object-hash": "3.0.0", - "select2": "4.1.0-rc.0", + "slim-select": "2.8.1", "stemmer": "2.0.0", "throttle-debounce": "3.0.1", "workbox-window": "6.5.4" diff --git a/frontend/src/styles/inputs.scss b/frontend/src/styles/inputs.scss index b5312788b..ac3f04401 100644 --- a/frontend/src/styles/inputs.scss +++ b/frontend/src/styles/inputs.scss @@ -178,189 +178,145 @@ select:-webkit-autofill:focus { caret-color: var(--text-color); } -.select2-dropdown { - background-color: var(--bg-color); - color: var(--text-color); +// slim-select styles +.ss-main { + border-radius: var(--roundness); outline: none; -} -.select2-container--default.select2-container--disabled - .select2-selection--single { - background: var(--sub-alt-color) !important; - opacity: 0.33; - cursor: default; - pointer-events: none; -} - -.select2-selection { + border: none; + border-radius: var(--roundness); background: var(--sub-alt-color); - height: fit-content; - height: -moz-fit-content; - padding: 5px; - border-radius: var(--roundness); color: var(--text-color); - font: var(--font); - border: none; - outline: none; -} - -.select2-container--default - .select2-selection--single - .select2-selection__rendered { - color: var(--text-color); - outline: none; -} - -.select2-container--default - .select2-results__option--highlighted.select2-results__option--selectable { - background-color: var(--text-color); - color: var(--bg-color); -} - -.select2-container--default .select2-results__option--selected { - background-color: var(--main-color); - color: var(--bg-color); -} - -.select2-container--open .select2-dropdown--below, -.select2-container--open .select2-dropdown--above { - border-color: var(--sub-alt-color); - background: var(--bg-color); - color: var(--sub-color); - border-radius: var(--roundness); -} - -.select2-container--default .select2-selection--single { - color: var(--text-color); - background: var(--sub-alt-color); - outline: none; - border: none; - height: auto; - border-radius: var(--roundness); -} - -.select2-container--default.select2-container--disabled - .select2-selection--single { - background: #5051517a; -} - -.select2-selection:focus { - height: fit-content; - height: -moz-fit-content; - padding: 5px; - border-radius: var(--roundness); - color: var(--text-color); - font: var(--font); - border: none; - outline: none; -} -.select2-selection:active { - height: fit-content; - height: -moz-fit-content; - padding: 5px; - border-radius: var(--roundness); - color: var(--text-color); - font: var(--font); - border: none; - outline: none; -} - -.select2-container--default - .select2-selection--single - .select2-selection__arrow { - height: 35px; -} - -.select2-container--default - .select2-selection--single - .select2-selection__arrow - b { - border-color: var(--text-color) transparent transparent transparent; -} - -.select2-container--default.select2-container--open - .select2-selection--single - .select2-selection__arrow - b { - border-color: var(--text-color) transparent; -} - -.select2-container--default .select2-search--dropdown .select2-search__field { - border-color: var(--sub-alt-color); - background: var(--bg-color); - color: var(--text-color); - border-radius: var(--roundness); -} - -.select2-container--default .select2-results__group { - color: var(--text-color); -} - -.select2-container--default .select2-selection--multiple { - background: var(--sub-alt-color); - border-radius: var(--roundness); - color: var(--text-color); - outline: none; - border: none; -} - -.select2-selection__choice__display { - color: var(--bg-color); -} - -.select2-selection__choice__remove { - color: var(--main-color) !important; -} - -.select2-container .select2-search--inline .select2-search__field { - margin: 0; - border-radius: 0; + padding: 0.5em; + font-size: 1em; font-family: var(--font); - line-height: 1rem; + caret-color: var(--main-color); + line-height: 1.25em; + &:focus { + box-shadow: inherit; + } + &:focus-visible { + box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + } + .ss-arrow path { + stroke: var(--text-color); + transition: none; + } + &.ss-disabled { + opacity: 0.33; + pointer-events: none; + background: var(--sub-alt-color); + cursor: pointer; + } + .ss-values { + .ss-placeholder { + padding: 0; + margin: 0; + color: var(--sub-color); + } + .ss-single { + margin: 0; + } + .ss-value { + animation: unset !important; + background-color: unset; + .ss-value-text { + height: 100%; + color: var(--bg-color); + background: var(--main-color); + border-radius: calc(var(--roundness) / 2) 0 0 calc(var(--roundness) / 2); + } + .ss-value-delete { + border-left: 1px solid var(--bg-color); + background: var(--main-color); + height: 100%; + box-sizing: border-box; + width: 100%; + border-radius: 0 calc(var(--roundness) / 2) calc(var(--roundness) / 2) 0; + transition: background 0.125s; + svg path { + stroke: var(--bg-color); + } + &:hover { + background: var(--text-color); + svg path { + stroke: var(--bg-color); + } + } + } + } + } } -.select2-container--default.select2-container--focus - .select2-selection--multiple { +.ss-content { + transition: none; border: none; -} - -.select2-container--default .select2-selection--multiple { - border: none; - padding: 0.5rem; - font-family: var(--font); -} - -.select2-container--default - .select2-selection--multiple - .select2-selection__choice { - background-color: var(--main-color); - border: none; - border-radius: calc(var(--roundness) / 2); - box-sizing: border-box; - display: inline-block; - margin-left: 0; - margin-top: 0; - margin-right: 0.5rem; - padding: 0; - padding-left: 1.25rem; - position: relative; - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: bottom; - white-space: nowrap; -} - -.select2-container--default - .select2-selection--multiple - .select2-selection__choice__remove { - line-height: 1.5rem; - border-right: 1px solid var(--bg-color); - color: var(--bg-color) !important; - transition: 0.125s; -} - -.select2-container--default - .select2-selection--multiple - .select2-selection__choice__remove:hover { - background-color: var(--text-color); + background: var(--sub-alt-color); + color: var(--text-color); + .ss-search { + padding: 0.5em; + border-top: 0.1em solid var(--bg-color); + border-bottom: 0.1em solid var(--bg-color); + input { + border: none; + background: var(--bg-color); + font-size: 1em; + padding: 0.5em; + &:focus-visible { + box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + } + &:focus { + border: none; + } + &::placeholder { + color: var(--sub-color); + } + &::-webkit-search-cancel-button { + -webkit-appearance: none; + } + } + } + .ss-list { + .ss-optgroup { + .ss-optgroup-label { + margin-top: 1em; + padding: 0.5em; + padding-left: 1em; + .ss-optgroup-label-text { + color: var(--sub-color); + } + } + } + .ss-optgroup .ss-option, + .ss-optgroup .ss-option:not(.ss-disabled), + .ss-option, + .ss-option:not(.ss-disabled) { + padding: 0.5em; + padding-left: 0.5em; + color: var(--text-color); + &.ss-selected { + background: var(--main-color); + color: var(--bg-color); + } + &:hover, + &.ss-highlighted { + background: var(--text-color); + color: var(--bg-color); + } + // &:last-child { + // margin-bottom: 1em; + // } + } + .ss-optgroup .ss-option, + .ss-optgroup .ss-option:not(.ss-disabled) { + padding-left: 1em; + } + } + &.ss-open-below { + border-bottom-left-radius: var(--roundness); + border-bottom-right-radius: var(--roundness); + } + &.ss-open-above { + border-top-left-radius: var(--roundness); + border-top-right-radius: var(--roundness); + } } diff --git a/frontend/src/styles/leaderboards.scss b/frontend/src/styles/leaderboards.scss index 20b12f3dc..54b6fc942 100644 --- a/frontend/src/styles/leaderboards.scss +++ b/frontend/src/styles/leaderboards.scss @@ -29,7 +29,7 @@ grid-area: buttons; .timeRange { grid-template-columns: 1fr 1fr; - .select2 { + .languageSelect { grid-column: span 2; } } diff --git a/frontend/src/ts/elements/leaderboards.ts b/frontend/src/ts/elements/leaderboards.ts index b37b9b8f4..d261b81ab 100644 --- a/frontend/src/ts/elements/leaderboards.ts +++ b/frontend/src/ts/elements/leaderboards.ts @@ -11,6 +11,7 @@ import { getHTMLById as getBadgeHTMLbyId } from "../controllers/badge-controller import * as ConnectionState from "../states/connection"; import * as Skeleton from "../popups/skeleton"; import { debounce } from "throttle-debounce"; +import SlimSelect from "slim-select"; const wrapperId = "leaderboardsWrapper"; @@ -680,52 +681,57 @@ $("#leaderboardsWrapper").on("click", (e) => { } }); -const languageSelector = $( - "#leaderboardsWrapper #leaderboards .leaderboardsTop .buttonGroup.timeRange .languageSelect" -).select2({ - placeholder: "select a language", - width: "100%", +const languageSelector = new SlimSelect({ + select: + "#leaderboardsWrapper #leaderboards .leaderboardsTop .buttonGroup.timeRange .languageSelect", + settings: { + showSearch: false, + contentLocation: document.querySelector( + "#leaderboardsWrapper" + ) as HTMLElement, + }, data: [ { - id: "english", + value: "english", text: "english", selected: true, }, { - id: "spanish", + value: "spanish", text: "spanish", }, { - id: "german", + value: "german", text: "german", }, { - id: "french", + value: "french", text: "french", }, { - id: "portuguese", + value: "portuguese", text: "portuguese", }, { - id: "indonesian", + value: "indonesian", text: "indonesian", }, { - id: "italian", + value: "italian", text: "italian", }, { - id: "russian", + value: "russian", text: "russian", }, ], -}); - -languageSelector.on("select2:select", (e) => { - currentLanguage = e.params.data.id; - updateTitle(); - void update(); + events: { + afterChange: (newVal): void => { + currentLanguage = newVal[0]?.value as string; + updateTitle(); + void update(); + }, + }, }); let leftScrollEnabled = true; @@ -852,9 +858,8 @@ $( ).on("click", () => { currentTimeRange = "allTime"; currentLanguage = "english"; - languageSelector.prop("disabled", true); - languageSelector.val("english"); - languageSelector.trigger("change"); + languageSelector.disable(); + languageSelector.setSelected("english"); void update(); }); @@ -863,7 +868,7 @@ $( ).on("click", () => { currentTimeRange = "daily"; updateYesterdayButton(); - languageSelector.prop("disabled", false); + languageSelector.enable(); void update(); }); diff --git a/frontend/src/ts/index.ts b/frontend/src/ts/index.ts index 0debb0878..14f8d0115 100644 --- a/frontend/src/ts/index.ts +++ b/frontend/src/ts/index.ts @@ -3,7 +3,6 @@ import "jquery"; import "jquery-color"; import "jquery.easing"; -import "select2"; import "../styles/index.scss"; import "./firebase"; diff --git a/frontend/src/ts/pages/settings.ts b/frontend/src/ts/pages/settings.ts index 8f406acab..535b21729 100644 --- a/frontend/src/ts/pages/settings.ts +++ b/frontend/src/ts/pages/settings.ts @@ -18,6 +18,7 @@ import { getAuthenticatedUser, isAuthenticated } from "../firebase"; import Ape from "../ape"; import { areFunboxesCompatible } from "../test/funbox/funbox-validation"; import { get as getTypingSpeedUnit } from "../utils/typing-speed-units"; +import SlimSelect from "slim-select"; import * as Skeleton from "../popups/skeleton"; import * as CustomBackgroundFilter from "../elements/custom-background-filter"; @@ -421,10 +422,12 @@ function reset(): void { $(".pageSettings .section.themes .favThemes.buttons").empty(); $(".pageSettings .section.themes .allThemes.buttons").empty(); $(".pageSettings .section.themes .allCustomThemes.buttons").empty(); - $(".pageSettings .section.languageGroups .buttons").empty(); - $(".pageSettings select").empty().select2("destroy"); $(".pageSettings .section[data-config-name='funbox'] .buttons").empty(); $(".pageSettings .section[data-config-name='fontFamily'] .buttons").empty(); + for (const select of document.querySelectorAll(".pageSettings select")) { + //@ts-expect-error + select?.slim?.destroy?.(); + } } let groupsInitialized = false; @@ -436,11 +439,6 @@ async function fillSettingsPage(): Promise { } // Language Selection Combobox - const languageEl = document.querySelector( - ".pageSettings .section[data-config-name='language'] select" - ) as HTMLSelectElement; - languageEl.innerHTML = ""; - let languageElHTML = ""; let languageGroups; try { @@ -454,37 +452,32 @@ async function fillSettingsPage(): Promise { ); } + const languageSelectData = []; if (languageGroups) { for (const group of languageGroups) { - let langComboBox = ``; - group.languages.forEach((language: string) => { - langComboBox += ``; - }); - langComboBox += ``; - languageElHTML += langComboBox; + const groupData = { + label: group.name, + options: group.languages.map((language: string) => { + return { + value: language, + text: Misc.getLanguageDisplayString(language), + selected: language === Config.language, + }; + }), + }; + languageSelectData.push(groupData); } - languageEl.innerHTML = languageElHTML; } - $(languageEl).select2({ - width: "100%", + new SlimSelect({ + select: ".pageSettings .section[data-config-name='language'] select", + data: languageSelectData, + settings: { + searchPlaceholder: "search", + }, }); await Misc.sleep(0); - const layoutEl = document.querySelector( - ".pageSettings .section[data-config-name='layout'] select" - ) as HTMLSelectElement; - layoutEl.innerHTML = ``; - let layoutElHTML = ""; - - const keymapEl = document.querySelector( - ".pageSettings .section[data-config-name='keymapLayout'] select" - ) as HTMLSelectElement; - keymapEl.innerHTML = ``; - let keymapElHTML = ""; - let layoutsList; try { layoutsList = await Misc.getLayoutsList(); @@ -492,45 +485,48 @@ async function fillSettingsPage(): Promise { console.error(Misc.createErrorMessage(e, "Failed to refresh keymap")); } + const layoutSelectData = []; + const keymapLayoutSelectData = []; + + layoutSelectData.push({ + value: "default", + text: "off", + }); + + keymapLayoutSelectData.push({ + value: "overrideSync", + text: "emulator sync", + }); + if (layoutsList) { for (const layout of Object.keys(layoutsList)) { if (layout.toString() !== "korean") { - layoutElHTML += ``; + layoutSelectData.push({ + value: layout, + text: layout.replace(/_/g, " "), + }); } if (layout.toString() !== "default") { - keymapElHTML += ``; + keymapLayoutSelectData.push({ + value: layout, + text: layout.replace(/_/g, " "), + }); } } - layoutEl.innerHTML += layoutElHTML; - keymapEl.innerHTML += keymapElHTML; } - $(layoutEl).select2({ - width: "100%", + + new SlimSelect({ + select: ".pageSettings .section[data-config-name='layout'] select", + data: layoutSelectData, }); - $(keymapEl).select2({ - width: "100%", + + new SlimSelect({ + select: ".pageSettings .section[data-config-name='keymapLayout'] select", + data: keymapLayoutSelectData, }); await Misc.sleep(0); - const themeEl1 = document.querySelector( - ".pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.light" - ) as HTMLSelectElement; - themeEl1.innerHTML = ""; - let themeEl1HTML = ""; - - const themeEl2 = document.querySelector( - ".pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.dark" - ) as HTMLSelectElement; - themeEl2.innerHTML = ""; - let themeEl2HTML = ""; - let themes; try { themes = await Misc.getThemesList(); @@ -540,40 +536,47 @@ async function fillSettingsPage(): Promise { ); } + const themeSelectLightData = []; + const themeSelectDarkData = []; if (themes) { for (const theme of themes) { - themeEl1HTML += ``; - themeEl2HTML += ``; + themeSelectLightData.push({ + value: theme.name, + text: theme.name.replace(/_/g, " "), + selected: theme.name === Config.themeLight, + }); + themeSelectDarkData.push({ + value: theme.name, + text: theme.name.replace(/_/g, " "), + selected: theme.name === Config.themeDark, + }); } - themeEl1.innerHTML = themeEl1HTML; - themeEl2.innerHTML = themeEl2HTML; } - $(themeEl1).select2({ - width: "100%", + + new SlimSelect({ + select: + ".pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.light", + data: themeSelectLightData, + events: { + afterChange: (newVal): void => { + UpdateConfig.setThemeLight(newVal[0]?.value as string); + }, + }, }); - $(themeEl2).select2({ - width: "100%", + + new SlimSelect({ + select: + ".pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.dark", + data: themeSelectDarkData, + events: { + afterChange: (newVal): void => { + UpdateConfig.setThemeDark(newVal[0]?.value as string); + }, + }, }); await Misc.sleep(0); - $( - `.pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.light` - ) - .val(Config.themeLight) - .trigger("change.select2"); - $( - `.pageSettings .section[data-config-name='autoSwitchThemeInputs'] select.dark` - ) - .val(Config.themeDark) - .trigger("change.select2"); - const funboxEl = document.querySelector( ".pageSettings .section[data-config-name='funbox'] .buttons" ) as HTMLDivElement; @@ -1257,30 +1260,6 @@ $(".pageSettings .section.updateCookiePreferences button").on("click", () => { CookiePopup.showSettings(); }); -$(".pageSettings .section[data-config-name='autoSwitchThemeInputs']").on( - "change", - `select.light`, - (e) => { - const target = $(e.currentTarget); - if (target.hasClass("disabled") || target.hasClass("no-auto-handle")) { - return; - } - UpdateConfig.setThemeLight(target.val() as string); - } -); - -$(".pageSettings .section[data-config-name='autoSwitchThemeInputs']").on( - "change", - `select.dark`, - (e) => { - const target = $(e.currentTarget); - if (target.hasClass("disabled") || target.hasClass("no-auto-handle")) { - return; - } - UpdateConfig.setThemeDark(target.val() as string); - } -); - $(".pageSettings .section.discordIntegration .getLinkAndGoToOauth").on( "click", () => { @@ -1314,8 +1293,8 @@ export const page = new Page( // }, async () => { - Skeleton.remove("pageSettings"); reset(); + Skeleton.remove("pageSettings"); }, async () => { Skeleton.append("pageSettings", "main"); diff --git a/frontend/src/ts/popups/quote-report-popup.ts b/frontend/src/ts/popups/quote-report-popup.ts index 38eb18602..c6d7018fd 100644 --- a/frontend/src/ts/popups/quote-report-popup.ts +++ b/frontend/src/ts/popups/quote-report-popup.ts @@ -7,6 +7,7 @@ import QuotesController from "../controllers/quotes-controller"; import * as CaptchaController from "../controllers/captcha-controller"; import * as Skeleton from "./skeleton"; import { isPopupVisible, removeLanguageSize } from "../utils/misc"; +import SlimSelect from "slim-select"; const wrapperId = "quoteReportPopupWrapper"; @@ -34,6 +35,8 @@ const defaultOptions: Options = { noAnim: false, }; +let reasonSelect: SlimSelect | undefined = undefined; + export async function show(options = defaultOptions): Promise { Skeleton.append(wrapperId); @@ -59,9 +62,14 @@ export async function show(options = defaultOptions): Promise { $("#quoteReportPopup .reason").val("Grammatical error"); $("#quoteReportPopup .comment").val(""); $("#quoteReportPopup .characterCount").text("-"); - $("#quoteReportPopup .reason").select2({ - minimumResultsForSearch: Infinity, + + reasonSelect = new SlimSelect({ + select: "#quoteReportPopup .reason", + settings: { + showSearch: false, + }, }); + $("#quoteReportPopupWrapper") .stop(true, true) .css("opacity", 0) @@ -90,6 +98,8 @@ async function hide(): Promise { if (state.previousPopupShowCallback) { state.previousPopupShowCallback(); } + reasonSelect?.destroy(); + reasonSelect = undefined; Skeleton.remove(wrapperId); } ); diff --git a/frontend/src/ts/popups/quote-search-popup.ts b/frontend/src/ts/popups/quote-search-popup.ts index 6117ccd7a..4f0a93ea6 100644 --- a/frontend/src/ts/popups/quote-search-popup.ts +++ b/frontend/src/ts/popups/quote-search-popup.ts @@ -19,6 +19,7 @@ import Ape from "../ape"; import * as Loader from "../elements/loader"; import * as Skeleton from "./skeleton"; import { isPopupVisible } from "../utils/misc"; +import SlimSelect from "slim-select"; const wrapperId = "quoteSearchPopupWrapper"; @@ -209,6 +210,8 @@ async function updateResults(searchText: string): Promise { }); } +let lengthSelect: SlimSelect | undefined = undefined; + export async function show(clearText = true): Promise { Skeleton.append(wrapperId); @@ -233,31 +236,28 @@ export async function show(clearText = true): Promise { $("#quoteSearchPopup #goToApproveQuotes").addClass("hidden"); } - $("#quoteSearchPopup .quoteLengthFilter").select2({ - placeholder: "Filter by length", - maximumSelectionLength: Infinity, - multiple: true, - width: "100%", + lengthSelect = new SlimSelect({ + select: "#quoteSearchPopup .quoteLengthFilter", + settings: { + showSearch: false, + placeholderText: "Filter by length", + }, data: [ { - id: 0, text: "short", - selected: false, + value: "0", }, { - id: 1, text: "medium", - selected: false, + value: "1", }, { - id: 2, text: "long", - selected: false, + value: "2", }, { - id: 3, text: "thicc", - selected: false, + value: "3", }, ], }); @@ -289,6 +289,9 @@ function hide(noAnim = false, focusWords = true): void { () => { $("#quoteSearchPopupWrapper").addClass("hidden"); + lengthSelect?.destroy(); + lengthSelect = undefined; + if (focusWords) { TestUI.focusWords(); $("#quoteSearchPopup .quoteLengthFilter").val([]); diff --git a/frontend/src/ts/popups/quote-submit-popup.ts b/frontend/src/ts/popups/quote-submit-popup.ts index 644222324..71ffaf7e7 100644 --- a/frontend/src/ts/popups/quote-submit-popup.ts +++ b/frontend/src/ts/popups/quote-submit-popup.ts @@ -5,6 +5,7 @@ import * as CaptchaController from "../controllers/captcha-controller"; import * as Misc from "../utils/misc"; import Config from "../config"; import * as Skeleton from "./skeleton"; +import SlimSelect from "slim-select"; const wrapperId = "quoteSubmitPopupWrapper"; @@ -18,10 +19,11 @@ async function initDropdown(): Promise { `` ); } - $("#quoteSubmitPopup #submitQuoteLanguage").select2(); dropdownReady = true; } +let select: SlimSelect | undefined = undefined; + async function submitQuote(): Promise { const text = $("#quoteSubmitPopup #submitQuoteText").val() as string; const source = $("#quoteSubmitPopup #submitQuoteSource").val() as string; @@ -57,6 +59,11 @@ export async function show(noAnim = false): Promise { "submitQuote" ); await initDropdown(); + + select = new SlimSelect({ + select: "#quoteSubmitPopup #submitQuoteLanguage", + }); + $("#quoteSubmitPopup #submitQuoteLanguage").val( Misc.removeLanguageSize(Config.language) ); @@ -86,6 +93,8 @@ function hide(): void { $("#quoteSubmitPopupWrapper").addClass("hidden"); CaptchaController.reset("submitQuote"); Skeleton.remove(wrapperId); + select?.destroy(); + select = undefined; } ); } diff --git a/frontend/src/ts/popups/user-report-popup.ts b/frontend/src/ts/popups/user-report-popup.ts index 49e1e3321..87b97c181 100644 --- a/frontend/src/ts/popups/user-report-popup.ts +++ b/frontend/src/ts/popups/user-report-popup.ts @@ -4,6 +4,7 @@ import * as Notifications from "../elements/notifications"; import * as CaptchaController from "../controllers/captcha-controller"; import * as Skeleton from "./skeleton"; import { isPopupVisible } from "../utils/misc"; +import SlimSelect from "slim-select"; const wrapperId = "userReportPopupWrapper"; @@ -23,6 +24,8 @@ type ShowOptions = { lbOptOut: boolean; }; +let select: SlimSelect | undefined = undefined; + export async function show(options: ShowOptions): Promise { Skeleton.append(wrapperId); if (!isPopupVisible(wrapperId)) { @@ -39,9 +42,14 @@ export async function show(options: ShowOptions): Promise { $("#userReportPopup .reason").val("Inappropriate name"); $("#userReportPopup .comment").val(""); $("#userReportPopup .characterCount").text("-"); - $("#userReportPopup .reason").select2({ - minimumResultsForSearch: Infinity, + + select = new SlimSelect({ + select: "#userReportPopup .reason", + settings: { + showSearch: false, + }, }); + $("#userReportPopupWrapper") .stop(true, true) .css("opacity", 0) @@ -63,6 +71,8 @@ async function hide(): Promise { }, 125, () => { + select?.destroy(); + select = undefined; CaptchaController.reset("userReportPopup"); $("#userReportPopupWrapper").addClass("hidden"); Skeleton.remove(wrapperId); diff --git a/frontend/src/ts/popups/word-filter-popup.ts b/frontend/src/ts/popups/word-filter-popup.ts index 4ae608e5c..92753508c 100644 --- a/frontend/src/ts/popups/word-filter-popup.ts +++ b/frontend/src/ts/popups/word-filter-popup.ts @@ -2,6 +2,7 @@ import * as Misc from "../utils/misc"; import * as CustomText from "../test/custom-text"; import * as Notifications from "../elements/notifications"; import * as Skeleton from "./skeleton"; +import SlimSelect from "slim-select"; const wrapperId = "wordFilterPopupWrapper"; @@ -117,14 +118,6 @@ async function init(): Promise { return; } - LanguageList.forEach((language) => { - let prettyLang = language; - prettyLang = prettyLang.replace("_", " "); - $("#wordFilterPopup .languageInput").append(` - - `); - }); - try { LayoutList = await Misc.getLayoutsList(); } catch (e) { @@ -137,9 +130,17 @@ async function init(): Promise { return; } + LanguageList.forEach((language) => { + const prettyLang = language.replace(/_/gi, " "); + $("#wordFilterPopup .languageInput").append(` + + `); + }); + for (const layout in LayoutList) { + const prettyLayout = layout.replace(/_/gi, " "); $("#wordFilterPopup .layoutInput").append(` - + `); } @@ -153,6 +154,10 @@ async function init(): Promise { } } +let languageSelect: SlimSelect | undefined = undefined; +let layoutSelect: SlimSelect | undefined = undefined; +let presetSelect: SlimSelect | undefined = undefined; + let callbackFuncOnHide: (() => void) | undefined = undefined; export async function show( @@ -163,16 +168,14 @@ export async function show( if (!Misc.isPopupVisible(wrapperId)) { await init(); callbackFuncOnHide = callbackOnHide; - $("#wordFilterPopup .languageInput").select2({ - width: "100%", + languageSelect = new SlimSelect({ + select: "#wordFilterPopup .languageInput", }); - - $("#wordFilterPopup .layoutInput").select2({ - width: "100%", + layoutSelect = new SlimSelect({ + select: "#wordFilterPopup .layoutInput", }); - - $("#wordFilterPopup .presetInput").select2({ - width: "100%", + presetSelect = new SlimSelect({ + select: "#wordFilterPopup .presetInput", }); $("#wordFilterPopupWrapper .loadingIndicator").addClass("hidden"); $("#wordFilterPopupWrapper .button").removeClass("hidden"); @@ -189,12 +192,6 @@ export async function show( function hide(noAnim = false): void { if (Misc.isPopupVisible(wrapperId)) { - $("#wordFilterPopup .languageInput").select2("close"); - - $("#wordFilterPopup .layoutInput").select2("close"); - - $("#wordFilterPopup .presetInput").select2("close"); - $("#wordFilterPopupWrapper") .stop(true, true) .css("opacity", 1) @@ -204,6 +201,12 @@ function hide(noAnim = false): void { }, noAnim ? 0 : 125, () => { + languageSelect?.destroy(); + layoutSelect?.destroy(); + presetSelect?.destroy(); + languageSelect = undefined; + layoutSelect = undefined; + presetSelect = undefined; $("#wordFilterPopupWrapper").addClass("hidden"); Skeleton.remove(wrapperId); if (callbackFuncOnHide) callbackFuncOnHide(); @@ -286,10 +289,6 @@ $("#wordFilterPopupWrapper").on("mousedown", (e) => { } }); -$("#wordFilterPopup .languageInput").one("select2:open", function () { - $("input.select2-search__field").prop("placeholder", "search"); -}); - $("#wordFilterPopupWrapper .button.addButton").on("mousedown", () => { $("#wordFilterPopupWrapper .loadingIndicator").removeClass("hidden"); $("#wordFilterPopupWrapper .button").addClass("hidden"); diff --git a/frontend/src/ts/ready.ts b/frontend/src/ts/ready.ts index 8eb2dc28e..8e37e8a30 100644 --- a/frontend/src/ts/ready.ts +++ b/frontend/src/ts/ready.ts @@ -37,7 +37,7 @@ void UpdateConfig.loadFromLocalStorage(); Focus.set(true, true); $(document).ready(() => { - Misc.loadCSS("/./css/select2.min.css", true); + Misc.loadCSS("/./css/slimselect.min.css", true); Misc.loadCSS("/./css/balloon.min.css", true); Misc.loadCSS("/./css/fa.min.css", true); diff --git a/frontend/src/ts/settings/settings-group.ts b/frontend/src/ts/settings/settings-group.ts index 13774c492..91e3152db 100644 --- a/frontend/src/ts/settings/settings-group.ts +++ b/frontend/src/ts/settings/settings-group.ts @@ -1,5 +1,6 @@ import Config from "../config"; import * as Notifications from "../elements/notifications"; +import SlimSelect from "slim-select"; export default class SettingsGroup { public configName: string; @@ -25,20 +26,16 @@ export default class SettingsGroup { this.updateUI(); if (this.mode === "select") { - $(".pageSettings").on( - "change", - `.section[data-config-name='${this.configName}'] select`, - (e) => { - const target = $(e.currentTarget); - if ( - target.hasClass("disabled") || - target.hasClass("no-auto-handle") - ) { - return; - } - this.setValue(target.val() as T); - } + const selectElement = document.querySelector( + `.pageSettings .section[data-config-name=${this.configName}] select` ); + selectElement?.addEventListener("change", (e) => { + const target = $(e.target as HTMLSelectElement); + if (target.hasClass("disabled") || target.hasClass("no-auto-handle")) { + return; + } + this.setValue(target.val() as T); + }); } else if (this.mode === "button") { $(".pageSettings").on( "click", @@ -83,9 +80,16 @@ export default class SettingsGroup { `.pageSettings .section[data-config-name='${this.configName}'] button` ).removeClass("active"); if (this.mode === "select") { - $(`.pageSettings .section[data-config-name='${this.configName}'] select`) - .val(this.configValue as string) - .trigger("change.select2"); + const select = document.querySelector( + `.pageSettings .section[data-config-name='${this.configName}'] select` + ) as HTMLSelectElement; + select.value = this.configValue as string; + + //@ts-expect-error + const ss = select.slim as SlimSelect | undefined; + ss?.store.setSelectedBy("value", [this.configValue as string]); + ss?.render.renderValues(); + ss?.render.renderOptions(ss.store.getData()); } else if (this.mode === "button") { $( // this cant be an object? diff --git a/frontend/static/css/select2.min.css b/frontend/static/css/select2.min.css deleted file mode 100644 index f00f15472..000000000 --- a/frontend/static/css/select2.min.css +++ /dev/null @@ -1 +0,0 @@ -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{background-color:transparent;border:none;font-size:1em}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline;list-style:none;padding:0}.select2-container .select2-selection--multiple .select2-selection__clear{background-color:transparent;border:none;font-size:1em}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;margin-left:5px;padding:0;max-width:100%;resize:none;height:18px;vertical-align:bottom;font-family:sans-serif;overflow:hidden;word-break:keep-all}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option--selectable{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;height:26px;margin-right:20px;padding-right:0px}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;padding-bottom:5px;padding-right:5px;position:relative}.select2-container--default .select2-selection--multiple.select2-selection--clearable{padding-right:25px}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;font-weight:bold;height:20px;margin-right:10px;margin-top:5px;position:absolute;right:0;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:inline-block;margin-left:5px;margin-top:5px;padding:0;padding-left:20px;position:relative;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.select2-container--default .select2-selection--multiple .select2-selection__choice__display{cursor:default;padding-left:2px;padding-right:5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{background-color:transparent;border:none;border-right:1px solid #aaa;border-top-left-radius:4px;border-bottom-left-radius:4px;color:#999;cursor:pointer;font-size:1em;font-weight:bold;padding:0 4px;position:absolute;left:0;top:0}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:focus{background-color:#f1f1f1;color:#333;outline:none}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__display{padding-left:5px;padding-right:2px}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{border-left:1px solid #aaa;border-right:none;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:4px;border-bottom-right-radius:4px}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__clear{float:left;margin-left:10px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--group{padding:0}.select2-container--default .select2-results__option--disabled{color:#999}.select2-container--default .select2-results__option--selected{background-color:#ddd}.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;height:26px;margin-right:20px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0;padding-bottom:5px;padding-right:5px}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;display:inline-block;margin-left:5px;margin-top:5px;padding:0}.select2-container--classic .select2-selection--multiple .select2-selection__choice__display{cursor:default;padding-left:2px;padding-right:5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{background-color:transparent;border:none;border-top-left-radius:4px;border-bottom-left-radius:4px;color:#888;cursor:pointer;font-size:1em;font-weight:bold;padding:0 4px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555;outline:none}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__display{padding-left:5px;padding-right:2px}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:4px;border-bottom-right-radius:4px}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option--group{padding:0}.select2-container--classic .select2-results__option--disabled{color:grey}.select2-container--classic .select2-results__option--highlighted.select2-results__option--selectable{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} \ No newline at end of file diff --git a/frontend/static/css/slimselect.min.css b/frontend/static/css/slimselect.min.css new file mode 100644 index 000000000..754400af0 --- /dev/null +++ b/frontend/static/css/slimselect.min.css @@ -0,0 +1 @@ +:root{--ss-primary-color: #5897fb;--ss-bg-color: #ffffff;--ss-font-color: #4d4d4d;--ss-font-placeholder-color: #8d8d8d;--ss-disabled-color: #dcdee2;--ss-border-color: #dcdee2;--ss-highlight-color: #fffb8c;--ss-success-color: #00b755;--ss-error-color: #dc3545;--ss-focus-color: #5897fb;--ss-main-height: 30px;--ss-content-height: 300px;--ss-spacing-l: 7px;--ss-spacing-m: 5px;--ss-spacing-s: 3px;--ss-animation-timing: 0.2s;--ss-border-radius: 4px}@keyframes ss-valueIn{0%{transform:scale(0);opacity:0}100%{transform:scale(1);opacity:1}}@keyframes ss-valueOut{0%{transform:scale(1);opacity:1}100%{transform:scale(0);opacity:0}}.ss-hide{display:none !important}.ss-main{display:flex;flex-direction:row;position:relative;user-select:none;color:var(--ss-font-color);min-height:var(--ss-main-height);width:100%;padding:var(--ss-spacing-s);cursor:pointer;border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius);background-color:var(--ss-bg-color);outline:0;box-sizing:border-box;transition:background-color var(--ss-animation-timing);overflow:hidden}.ss-main:focus{box-shadow:0 0 5px var(--ss-focus-color)}.ss-main.ss-disabled{background-color:var(--ss-disabled-color);cursor:not-allowed}.ss-main.ss-disabled .ss-values .ss-disabled{color:var(--ss-font-color)}.ss-main.ss-disabled .ss-values .ss-value .ss-value-delete{cursor:not-allowed}.ss-main.ss-open-above{border-top-left-radius:0px;border-top-right-radius:0px}.ss-main.ss-open-below{border-bottom-left-radius:0px;border-bottom-right-radius:0px}.ss-main .ss-values{display:inline-flex;flex-wrap:wrap;gap:var(--ss-spacing-m);flex:1 1 100%}.ss-main .ss-values .ss-placeholder{display:flex;padding:var(--ss-spacing-s) var(--ss-spacing-m) var(--ss-spacing-s) var(--ss-spacing-m);margin:auto 0px auto 0px;line-height:1em;align-items:center;width:100%;color:var(--ss-font-placeholder-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ss-main .ss-values .ss-max{display:flex;user-select:none;align-items:center;width:fit-content;font-size:12px;color:var(--ss-bg-color);line-height:1;padding:var(--ss-spacing-s) var(--ss-spacing-m);background-color:var(--ss-primary-color);border-radius:var(--ss-border-radius)}.ss-main .ss-values .ss-single{display:flex;margin:auto 0px auto var(--ss-spacing-s)}.ss-main .ss-values .ss-value{display:flex;user-select:none;align-items:center;width:fit-content;background-color:var(--ss-primary-color);border-radius:var(--ss-border-radius);animation-name:ss-valueIn;animation-duration:var(--ss-animation-timing);animation-timing-function:ease-out;animation-fill-mode:both}.ss-main .ss-values .ss-value.ss-value-out{animation-name:ss-valueOut;animation-duration:var(--ss-animation-timing);animation-timing-function:ease-out}.ss-main .ss-values .ss-value .ss-value-text{font-size:12px;color:var(--ss-bg-color);line-height:1;padding:var(--ss-spacing-s) var(--ss-spacing-m)}.ss-main .ss-values .ss-value .ss-value-delete{display:flex;align-items:center;height:var(--ss-spacing-l);width:var(--ss-spacing-l);padding:var(--ss-spacing-s) var(--ss-spacing-m);cursor:pointer;border-left:solid 1px var(--ss-bg-color);box-sizing:content-box}.ss-main .ss-values .ss-value .ss-value-delete svg{height:var(--ss-spacing-l);width:var(--ss-spacing-l)}.ss-main .ss-values .ss-value .ss-value-delete svg path{fill:none;stroke:var(--ss-bg-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round}.ss-main .ss-deselect{flex:0 1 auto;display:flex;align-items:center;justify-content:center;width:fit-content;height:auto;margin:0 var(--ss-spacing-m) 0 var(--ss-spacing-m)}.ss-main .ss-deselect svg{width:8px;height:8px}.ss-main .ss-deselect svg path{fill:none;stroke:var(--ss-font-color);stroke-width:20;stroke-linecap:round;stroke-linejoin:round}.ss-main .ss-arrow{flex:0 1 auto;display:flex;align-items:center;justify-content:flex-end;width:12px;height:12px;margin:auto var(--ss-spacing-m) auto var(--ss-spacing-m)}.ss-main .ss-arrow path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;transition-timing-function:ease-out;transition:var(--ss-animation-timing)}.ss-content{position:absolute;display:flex;height:auto;flex-direction:column;width:auto;max-height:var(--ss-content-height);box-sizing:border-box;border:solid 1px var(--ss-border-color);background-color:var(--ss-bg-color);transition:transform var(--ss-animation-timing),opacity var(--ss-animation-timing);opacity:0;transform:scaleY(0);transform-origin:center top;overflow:hidden;z-index:10000}.ss-content.ss-relative{position:relative;height:100%}.ss-content.ss-open-above{flex-direction:column-reverse;opacity:1;transform:scaleY(1);transform-origin:center bottom;border-top-left-radius:var(--ss-border-radius);border-top-right-radius:var(--ss-border-radius)}.ss-content.ss-open-below{opacity:1;transform:scaleY(1);transform-origin:center top;border-bottom-left-radius:var(--ss-border-radius);border-bottom-right-radius:var(--ss-border-radius)}.ss-content .ss-search{flex:0 1 auto;display:flex;flex-direction:row;padding:var(--ss-spacing-l) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l)}.ss-content .ss-search input{display:inline-flex;font-size:inherit;line-height:inherit;flex:1 1 auto;width:100%;min-width:0px;padding:var(--ss-spacing-m) var(--ss-spacing-l);margin:0;border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius);background-color:var(--ss-bg-color);outline:0;text-align:left;box-sizing:border-box}.ss-content .ss-search input::placeholder{color:var(--ss-font-placeholder-color);vertical-align:middle}.ss-content .ss-search input:focus{box-shadow:0 0 5px var(--ss-focus-color)}.ss-content .ss-search .ss-addable{display:inline-flex;justify-content:center;align-items:center;cursor:pointer;flex:0 0 auto;height:auto;margin:0 0 0 var(--ss-spacing-m);border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius)}.ss-content .ss-search .ss-addable svg{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;width:12px;height:12px;margin:auto var(--ss-spacing-m) auto var(--ss-spacing-m)}.ss-content .ss-search .ss-addable svg path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round}.ss-content .ss-list{flex:1 1 auto;height:auto;overflow-x:hidden;overflow-y:auto}.ss-content .ss-list .ss-error{color:var(--ss-error-color);padding:var(--ss-spacing-l)}.ss-content .ss-list .ss-searching{color:var(--ss-font-color);padding:var(--ss-spacing-l)}.ss-content .ss-list .ss-optgroup.ss-close .ss-option{display:none !important}.ss-content .ss-list .ss-optgroup .ss-optgroup-label{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ss-spacing-m) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-label-text{flex:1 1 auto;font-weight:bold;color:var(--ss-font-color)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label:has(.ss-arrow){cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions{flex:0 1 auto;display:flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--ss-spacing-m)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall{flex:0 0 auto;display:flex;flex-direction:row;cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall:hover{opacity:.5}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall.ss-selected svg path{stroke:var(--ss-error-color)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall span{flex:0 1 auto;display:flex;align-items:center;justify-content:center;font-size:60%;text-align:center;padding:0 var(--ss-spacing-s) 0 0}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg{flex:0 1 auto;width:13px;height:13px}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg path{fill:none;stroke:var(--ss-success-color);stroke-linecap:round;stroke-linejoin:round}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg:first-child{stroke-width:5}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg:last-child{stroke-width:11}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable{flex:0 1 auto;display:flex;flex-direction:row;cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable .ss-arrow{flex:1 1 auto;width:10px;height:10px}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable .ss-arrow path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;transition-timing-function:ease-out;transition:var(--ss-animation-timing)}.ss-content .ss-list .ss-optgroup .ss-option{padding:var(--ss-spacing-s) var(--ss-spacing-s) var(--ss-spacing-s) calc(var(--ss-spacing-l)*3)}.ss-content .ss-list .ss-option{display:flex;padding:var(--ss-spacing-m) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l);color:var(--ss-font-color);cursor:pointer;user-select:none}.ss-content .ss-list .ss-option:hover{color:var(--ss-bg-color);background-color:var(--ss-primary-color)}.ss-content .ss-list .ss-option.ss-highlighted,.ss-content .ss-list .ss-option:not(.ss-disabled).ss-selected{color:var(--ss-bg-color);background-color:var(--ss-primary-color)}.ss-content .ss-list .ss-option.ss-disabled{cursor:not-allowed;background-color:var(--ss-disabled-color)}.ss-content .ss-list .ss-option.ss-disabled:hover{color:var(--ss-font-color)}.ss-content .ss-list .ss-option .ss-search-highlight{background-color:var(--ss-highlight-color)}/*# sourceMappingURL=slimselect.css.map */ \ No newline at end of file diff --git a/frontend/static/html/pages/settings.html b/frontend/static/html/pages/settings.html index 5912273aa..81ba19a31 100644 --- a/frontend/static/html/pages/settings.html +++ b/frontend/static/html/pages/settings.html @@ -956,7 +956,9 @@ keymap layout
Controls which layout is displayed on the keymap.
- +
+ +
diff --git a/frontend/static/html/popups.html b/frontend/static/html/popups.html index 760b4088f..37d835637 100644 --- a/frontend/static/html/popups.html +++ b/frontend/static/html/popups.html @@ -638,7 +638,7 @@ autocomplete="off" placeholder="Filter by text" /> - +
Favorites Only
diff --git a/frontend/webpack/config.base.js b/frontend/webpack/config.base.js index 583ea87ba..7fea9c2ce 100644 --- a/frontend/webpack/config.base.js +++ b/frontend/webpack/config.base.js @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -const { resolve, join } = require("path"); +const { resolve } = require("path"); const webpack = require("webpack"); const CopyPlugin = require("copy-webpack-plugin"); const CircularDependencyPlugin = require("circular-dependency-plugin"); @@ -115,7 +115,6 @@ const BASE_CONFIG = { jQuery: "jquery", jQueryColor: "jquery-color", jQueryEasing: "jquery.easing", - select2: "select2", }), new HtmlWebpackPlugin({ filename: "./index.html",