From 138464759f45a463104bfc6ca92a118e7a74101c Mon Sep 17 00:00:00 2001 From: 0neGal Date: Fri, 14 Jun 2024 23:30:39 +0200 Subject: initial gamepad/keyboard navigation support Far from complete, but this does the bulk of the work, the rest is just fixing places where the selection moves in weird ways after doing some things, and overall improving the look and feel of it. --- src/app/index.html | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/app/index.html') diff --git a/src/app/index.html b/src/app/index.html index ffc13de..40b64a0 100644 --- a/src/app/index.html +++ b/src/app/index.html @@ -6,6 +6,8 @@ +
+
Test
@@ -33,7 +35,7 @@
- + - + diff --git a/src/app/js/navigate.js b/src/app/js/navigate.js index d9744fa..9f2a19f 100644 --- a/src/app/js/navigate.js +++ b/src/app/js/navigate.js @@ -115,7 +115,8 @@ navigate.get_els = (div) => { "button", "select", "textarea", - "[onclick]" + "[onclick]", + ".scroll-selection" ])] // this'll contain a filtered list of `els` @@ -129,13 +130,31 @@ navigate.get_els = (div) => { "#overlay", ".no-navigate", "button.visual", + ".scroll-selection", ".popup:not(.shown)" ] + // ignore, even if `.closest()` matches, if its just matching on + // itself instead of a different element + let ignore_closest_self = [ + ".scroll-selection" + ] + // check if `els[i].closest()` matches on any of the elements // inside of `ignore_closest` for (let ii = 0; ii < ignore_closest.length; ii++) { - if (els[i].closest(ignore_closest[ii])) { + let closest = els[i].closest(ignore_closest[ii]); + + // check if `.closest()` matches, but not on itself + if (closest) { + // ignore if `closest` is just `els[i]` and the selector + // is inside `ignore_closest_self` + if (closest == els[i] && + ignore_closest_self.includes(ignore_closest[ii])) { + + continue; + } + // it matches continue filter; } @@ -221,7 +240,7 @@ navigate.default_selection = () => { // this navigates `#selection` in the direction of `direction` // this can be: up, down, left and right -navigate.move = (direction) => { +navigate.move = async (direction) => { // get the `.active-selection` if there is one let active = document.querySelector(".active-selection"); @@ -238,6 +257,91 @@ navigate.move = (direction) => { } } + // is the active selection one that should be scrollable? + if (active.classList.contains("scroll-selection")) { + // scroll the respective `direction` if `active` has any more + // scroll left in that direction + + // short hand to easily scroll in `direction` by `amount` with + // smooth scrolling enabled + let scroll = (direction, amount) => { + // update the `#selection` element + navigate.selection(); + + // scroll inside `` if the active selection is one + if (active.tagName == "WEBVIEW") { + active.executeJavaScript(` + document.scrollingElement.scrollBy({ + behavior: "smooth", + ${direction}: ${amount} + }) + `) + + return; + } + + active.scrollBy({ + behavior: "smooth", + [direction]: amount + }) + } + + // get values needed for determining if we should scroll the + // active selection, and by how much + let scroll_el = { + top: active.scrollTop, + left: active.scrollLeft, + width: active.scrollWidth, + height: active.scrollHeight, + bounds: { + width: active.clientWidth, + height: active.clientWidth + } + } + + // get `scroll_el` from inside a `` if the active + // selection is one + if (active.tagName == "WEBVIEW") { + scroll_el = await active.executeJavaScript(`(() => { + return { + top: document.scrollingElement.scrollTop, + left: document.scrollingElement.scrollLeft, + width: document.scrollingElement.scrollWidth, + height: document.scrollingElement.scrollHeight, + bounds: { + width: document.scrollingElement.clientWidth, + height: document.scrollingElement.clientHeight + } + } + })()`) + } + + // decrease to increase scroll length, and in reverse + let scroll_scale = 2; + + if (direction == "up" && scroll_el.top > 0) { + return scroll("top", -scroll_el.bounds.height / scroll_scale); + } + + if (direction == "down" && + scroll_el.top <= scroll_el.height && + scroll_el.height != scroll_el.bounds.height) { + + return scroll("top", scroll_el.bounds.height / scroll_scale); + } + + if (direction == "left" && scroll_el.left > 0) { + return scroll("left", -width / scroll_scale); + } + + if (direction == "right" && + scroll_el.left <= scroll_el.width && + scroll_el.width != scroll_el.bounds.width) { + + return scroll("left", scroll_el.bounds.width / scroll_scale); + } + } + // attempt to get the element in the `direction` requested let move_to_el = navigate.get_relative_el(active, direction); @@ -269,7 +373,7 @@ navigate.move = (direction) => { // these elements cant be scrolled let no_scroll_parents = [ ".el .text", - ".gamesContainer" + ".gamesContainer", ] // run through unscrollable parent elements -- cgit v1.2.3 From fab59ba8b8b1c567ee158b9681c5b373fb7303e4 Mon Sep 17 00:00:00 2001 From: 0neGal Date: Fri, 20 Dec 2024 18:22:12 +0100 Subject: added sorting to mod browser fixes #251 --- src/app/css/grid.css | 18 ++++++++++++++++++ src/app/icons/sort.png | Bin 0 -> 1225 bytes src/app/index.html | 9 +++++++++ src/app/js/browser.js | 38 +++++++++++++++++++++++++++++++++++++- src/lang/en.json | 7 +++++++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/app/icons/sort.png (limited to 'src/app/index.html') diff --git a/src/app/css/grid.css b/src/app/css/grid.css index 188f32a..be405e0 100644 --- a/src/app/css/grid.css +++ b/src/app/css/grid.css @@ -77,6 +77,24 @@ width: var(--height) !important; } +.popup .misc button.long { + width: max-content !important; + padding-right: var(--spacing) !important; +} + +.popup .misc button select { + color: white; + border: none; + opacity: 0.6; + outline: none; + background: transparent; +} + +.popup .misc button select option { + color: white; + background: var(--selbg); +} + .popup .misc button img { margin: 0px; opacity: 0.6; diff --git a/src/app/icons/sort.png b/src/app/icons/sort.png new file mode 100644 index 0000000..3dd80d6 Binary files /dev/null and b/src/app/icons/sort.png differ diff --git a/src/app/index.html b/src/app/index.html index 9e97810..98c59d4 100644 --- a/src/app/index.html +++ b/src/app/index.html @@ -254,6 +254,15 @@
+ diff --git a/src/app/js/browser.js b/src/app/js/browser.js index aaca6a8..88e8017 100644 --- a/src/app/js/browser.js +++ b/src/app/js/browser.js @@ -153,10 +153,19 @@ var browser = { return browser.install({...properties}); } + packages[i].unix_created = new Date(packages[i].date_created).getTime(); + packages[i].unix_updated = new Date(packages[i].date_updated).getTime(); + packages[i].install = install; packages[i].has_update = has_update; packages[i].local_version = local_version; + packages[i].downloads = 0; + + for (let version of packages[i].versions) { + packages[i].downloads += version.downloads || 0; + } + if (local_version) { browser.mod_versions[normalized] = { install: install, @@ -169,6 +178,28 @@ var browser = { } } }, + // sorts `pkgs` based on `property` in package object + sort: (pkgs, property) => { + // get property from sort selector, if not specified + if (! property) { + property = sort.querySelector("select").value; + + // if we somehow still don't have a property, just return + if (! property) { + return pkgs; + } + } + + // if `property` doesn't even exist, just return + if (typeof pkgs[0][property] == "undefined") { + return pkgs; + } + + // sort in descending order + return pkgs.sort((a, b) => { + return b[property] - a[property]; + }) + }, loadfront: async () => { browser.loading(); @@ -198,7 +229,8 @@ var browser = { }) } - let pkgs = browser.filters.getpkgs(); + let pkgs = browser.sort(browser.filters.getpkgs()); + for (let i in pkgs) { if (packagecount >= browser.maxentries) { browser.endoflist(); @@ -349,6 +381,10 @@ var browser = { } } +sort.querySelector("select").addEventListener("change", () => { + browser.loadfront(); +}) + setInterval(browser.add_pkg_properties, 1500); if (navigator.onLine) { diff --git a/src/lang/en.json b/src/lang/en.json index c6a4946..5d622e2 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -124,6 +124,13 @@ "no_results": "No results...", "guide": "Guide", + "sort": { + "newest": "Newest", + "last_updated": "Last Updated", + "highest_rating": "Highest Rated", + "most_downloads": "Most Downloaded" + }, + "filter": { "mods": "Mods", "skins": "Skins", -- cgit v1.2.3