diff options
Diffstat (limited to 'src/app/js/settings.js')
-rw-r--r-- | src/app/js/settings.js | 210 |
1 files changed, 209 insertions, 1 deletions
diff --git a/src/app/js/settings.js b/src/app/js/settings.js index 57d542a..2d68c13 100644 --- a/src/app/js/settings.js +++ b/src/app/js/settings.js @@ -1,3 +1,5 @@ +var settings_fuse; + var Settings = { toggle: (state) => { Settings.load(); @@ -95,9 +97,24 @@ var Settings = { } } + // create Fuse based on options from `get_search_arr()` + settings_fuse = new Fuse(get_search_arr(), { + keys: ["text"], + threshold: 0.4, + ignoreLocation: true + }) + + // reset search + Settings.search(); + search_el.value = ""; + ipcRenderer.send("can-autoupdate"); ipcRenderer.on("cant-autoupdate", () => { - document.querySelector(".option[name=autoupdate]").style.display = "none"; + document.querySelector(".option[name=autoupdate]") + .style.display = "none"; + + document.querySelector(".option[name=autoupdate]") + .setAttribute("perma-hidden", true); }) }, switch: (el, state) => { @@ -110,7 +127,198 @@ var Settings = { if (el.classList.contains("switch") && el.tagName == "BUTTON") { el.classList.toggle("on"); } + }, + + // searches for `query` in the list of options, hides the options + // that dont match, and shows the one that do, if `query` is falsy, + // it'll simply reset everything back to being visible + search: (query = "") => { + // get list of elements that can be hidden + let search_els = [ + ...document.querySelectorAll(".options .title"), + ...document.querySelectorAll(".options .option"), + ...document.querySelectorAll(".options .buttons"), + ...document.querySelectorAll(".options .details"), + ] + + // this sets the visibility of all elements found in + // `search_els` unless the element has the `perma-hidden` + // attribute set + let set_all = (state) => { + // set `state` to the CSS equivalent + if (state) { + state = null; + } else { + state = "none"; + } + + // run through elements + for (let i = 0; i < search_els.length; i++) { + // check that the element shouldn't be perma hidden, and + // if so, hide it correctly. + if (search_els[i].hasAttribute("perma-hidden")) { + search_els[i].style.display = "none"; + continue; + } + + // set the visibility + search_els[i].style.display = state; + } + } + + // check if `query` is empty, and reset search if so + if (! query || ! query.trim()) { + set_all(true); + } else { + // hide everything + set_all(false); + } + + // unhides `el` and relevant elements related to it + let unhide = (el) => { + // list of elements that could be relevant through `el`'s + // `.closest()` function + let closest = [ + ".option", + "details", + ".buttons", + ] + + // run through `closest` + for (let i = 0; i < closest.length; i++) { + // shorthand + let closest_el = el.closest(closest[i]); + + // was a relevant element found? + if (closest_el) { + // is it supposed to always be hidden? do nothing + if (el.hasAttribute("perma-hidden") + || closest_el.hasAttribute("perma-hidden")) { + + break; + } + + // reset visibility + closest_el.style.display = null; + + // are we at a `<details>`? + if (closest[i] == "details") { + // attempt to get a `.title` inside that + // `<details>` element + let title = closest_el.querySelector(".title"); + + // did we find a title? + if (title) { + // reset visibility of title and also reset + // open state of `<details>` + title.style.display = null; + closest_el.setAttribute("open", false); + } + } + } + } + } + + // do a Fuse.js search with `query` + let res = settings_fuse.search(query); + + // if nothing was found, reset all + if (res.length == 0) { + return set_all(true); + } + + // run through results and unhide all of them + for (let i = 0; i < res.length; i++) { + unhide(res[i].item.el); + } + } +} + +// search on key events in search input +let search_el = document.body.querySelector("#options .search"); +search_el.addEventListener("keyup", () => { + Settings.search(search_el.value); +}) + +// returns a Fuse.js compatible Array for searching through the settings +function get_search_arr() { + // list of elements that should be taken into consideration when + // trying to do a search + let searchables_queries = [ + ".option .text", + ".buttons .text", + ".option .actions input", + ".option .actions select", + ".buttons .actions button:not(.switch)", + ] + + let searchables_els = []; + + // run through queries + for (let i = 0; i < searchables_queries.length; i++) { + // attempt to get element(s) with that query + let query = document.querySelectorAll( + ".options " + searchables_queries[i] + ) + + // if something was found add it + searchables_els = [ + ...query, + ...searchables_els + ] } + + let searchables = []; + + // run through the found elements + for (let i = 0; i < searchables_els.length; i++) { + let el = searchables_els[i]; + switch(el.tagName.toLowerCase()) { + // is this an `<input>`? + case "input": + // if no value is in the input, do nothing + if (! el.value) { + continue; + } + + // add to list of searchable elements, using the value + // of the input as the text + searchables.push({ + el: el, + text: el.value + }) + break; + + // is this a `<select>`? + case "select": + // get options in `<select>` + let options = el.children; + + // run through options + for (let ii = 0; ii < options.length; ii++) { + // add to list of searchable elements, using the + // insides of the option as the text, and the + // element being the `<select>` and not the + // `<option>`! + searchables.push({ + el: el, + text: options[ii].innerText + }) + } + break; + + default: + // add to list of searchable elements using the insides + // of the element as the text + searchables.push({ + el: el, + text: el.innerText + }) + } + } + + // return the actual searchable elements and text + return searchables; } events.on("popup-changed", () => { |