diff options
Diffstat (limited to 'src/app/browser.js')
-rw-r--r-- | src/app/browser.js | 259 |
1 files changed, 220 insertions, 39 deletions
diff --git a/src/app/browser.js b/src/app/browser.js index 40670bc..db68d31 100644 --- a/src/app/browser.js +++ b/src/app/browser.js @@ -2,9 +2,24 @@ const Fuse = require("fuse.js"); var fuse; var packages = []; +var packagecount = 0; + var Browser = { maxentries: 50, filters: { + getpkgs: () => { + let pkgs = []; + let other = []; + for (let i in packages) { + if (! Browser.filters.isfiltered(packages[i].categories)) { + pkgs.push(packages[i]); + } else { + other.push(packages[i]); + } + } + + return pkgs; + }, get: () => { let filtered = []; let unfiltered = []; @@ -27,6 +42,19 @@ var Browser = { let filtered = Browser.filters.get().filtered; let unfiltered = Browser.filters.get().unfiltered; let state = false; + + let filters = [ + "Mods", "Skins", + "Client-side", "Server-side", + ]; + + let newcategories = []; + for (let i = 0; i < categories.length; i++) { + if (filters.includes(categories[i])) { + newcategories.push(categories[i]); + } + }; categories = newcategories; + if (categories.length == 0) {return true} for (let i = 0; i < categories.length; i++) { if (filtered.includes(categories[i])) { @@ -53,14 +81,14 @@ var Browser = { let spacing = parseInt(getComputedStyle(filters).getPropertyValue("--spacing")); filters.style.top = filterRect.bottom - spacing; - filters.style.right = filterRect.right - filterRect.left + filterRect.width; + filters.style.right = filterRect.right - filterRect.left + filterRect.width - (spacing / 2); }, }, toggle: (state) => { if (state) { browser.scrollTo(0, 0); - overlay.classList.add("shown") - browser.classList.add("shown") + overlay.classList.add("shown"); + browser.classList.add("shown"); if (browserEntries.querySelectorAll(".el").length == 0) { Browser.loadfront(); @@ -69,18 +97,21 @@ var Browser = { } else if (! state) { if (state != undefined) { Browser.filters.toggle(false); - overlay.classList.remove("shown") - browser.classList.remove("shown") + overlay.classList.remove("shown"); + browser.classList.remove("shown"); + preview.classList.remove("shown"); return } } browser.scrollTo(0, 0); - overlay.classList.toggle("shown") - browser.classList.toggle("shown") + overlay.classList.toggle("shown"); + browser.classList.toggle("shown"); }, loadfront: async () => { Browser.loading(); + + packagecount = 0; if (packages.length < 1) { packages = await (await fetch("https://northstar.thunderstore.io/api/v1/package/")).json(); @@ -90,8 +121,15 @@ var Browser = { }) } - for (let i in packages) { - new BrowserElFromObj(packages[i]); + let pkgs = Browser.filters.getpkgs(); + for (let i in pkgs) { + if (packagecount >= Browser.maxentries) { + Browser.endoflist(); + break + } + + new BrowserElFromObj(pkgs[i]); + packagecount++; } }, loading: (string) => { @@ -107,21 +145,53 @@ var Browser = { browserEntries.innerHTML = `<div class="loading">${lang('gui.browser.loading')}</div>`; } }, - endoflist: () => { - if (browserEntries.querySelector(".message")) {return} - browserEntries.innerHTML += `<div class="message">${lang('gui.browser.endoflist')}</div>` + endoflist: (isEnd) => { + let pkgs = []; + let filtered = Browser.filters.getpkgs(); + for (let i = 0; i < filtered.length; i++) { + if ([packagecount + i]) { + pkgs.push(filtered[packagecount + i]); + } else { + break + } + } + + if (browserEntries.querySelector(".message")) { + browserEntries.querySelector(".message").remove(); + } + + if (pkgs.length == 0 || isEnd) { + Browser.msg(`${lang('gui.browser.endoflist')}`); + return + } + + Browser.msg(`<button id="loadmore">${lang("gui.browser.loadmore")}</button>`); + loadmore.addEventListener("click", () => { + Browser.loadpkgs(pkgs); + Browser.endoflist(pkgs); + }) }, search: (string) => { Browser.loading(); let res = fuse.search(string); if (res.length < 1) { - Browser.loading(lang("gui.browser.noresults")) + Browser.loading(lang("gui.browser.noresults")); return } + packagecount = 0; + + let count = 0; for (let i = 0; i < res.length; i++) { + if (count >= Browser.maxentries) {break} + if (Browser.filters.isfiltered(res[i].item.categories)) {continue} new BrowserElFromObj(res[i].item); + count++; + } + + if (count < 1) { + Browser.loading(lang("gui.browser.noresults")); } }, setbutton: (mod, string) => { @@ -157,6 +227,58 @@ var Browser = { } }, 1501) } + }, + loadpkgs: (pkgs, clear) => { + if (clear) {packagecount = 0} + + if (browserEntries.querySelector(".message")) { + browserEntries.querySelector(".message").remove(); + } + + let count = 0; + for (let i in pkgs) { + if (count >= Browser.maxentries) { + if (pkgs[i] === undefined) { + Browser.endoflist(true); + } + + Browser.endoflist(); + break + } + + try { + new BrowserElFromObj(pkgs[i]); + }catch(e) {} + + count++; + packagecount++; + } + }, + msg: (html) => { + let msg = document.createElement("div"); + msg.classList.add("message"); + msg.innerHTML = html; + + browserEntries.appendChild(msg); + } +} + +function openExternal(url) { + require("electron").shell.openExternal(url); +} + +var view = document.querySelector(".popup#preview webview"); +var Preview = { + show: () => { + preview.classList.add("shown"); + }, + hide: () => { + preview.classList.remove("shown"); + }, + set: (url, autoshow) => { + if (autoshow != false) {Preview.show()} + view.src = url; + document.querySelector("#preview #external").setAttribute("onclick", `openExternal("${url}")`); } } @@ -171,16 +293,14 @@ function BrowserElFromObj(obj) { download: pkg.download_url, version: pkg.version_number, categories: pkg.categories, - description: pkg.description + description: pkg.description, + dependencies: pkg.dependencies, }) } function BrowserEl(properties) { if (Browser.filters.isfiltered(properties.categories)) {return} - let entries = browser.querySelectorAll(".el").length; - if (entries == Browser.maxentries) {Browser.endoflist();return} - properties = { title: "No name", version: "1.0.0", @@ -230,25 +350,30 @@ function BrowserEl(properties) { } } } - - browserEntries.innerHTML += ` - <div class="el" id="mod-${normalize(properties.title)}"> - <div class="image"> - <img src="${properties.image}"> - </div> - <div class="text"> - <div class="title">${properties.title}</div> - <div class="description">${properties.description}</div> - <button onclick="installFromURL('${properties.download}')">${installstr}</button> - <button onclick="require('electron').shell.openExternal('${properties.url}')">${lang('gui.browser.info')}</button> - <button class="visual">${properties.version}</button> - <button class="visual">${lang("gui.browser.madeby")} ${properties.author}</button> - </div> + + let entry = document.createElement("div"); + entry.classList.add("el"); + entry.id = `mod-${normalize(properties.title)}`; + + entry.innerHTML = ` + <div class="image"> + <img src="${properties.image}"> + <img class="blur" src="${properties.image}"> + </div> + <div class="text"> + <div class="title">${properties.title}</div> + <div class="description">${properties.description}</div> + <button class="install" onclick='installFromURL("${properties.download}", ${JSON.stringify(properties.dependencies)}, true)'>${installstr}</button> + <button class="info" onclick="Preview.set('${properties.url}')">${lang('gui.browser.view')}</button> + <button class="visual">${properties.version}</button> + <button class="visual">${lang("gui.browser.madeby")} ${properties.author}</button> </div> ` + + browserEntries.appendChild(entry); } -ipcRenderer.on("removedmod", (event, mod) => { +ipcRenderer.on("removed-mod", (event, mod) => { setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.install")); if (mod.manifestname) { @@ -256,7 +381,7 @@ ipcRenderer.on("removedmod", (event, mod) => { } }) -ipcRenderer.on("failedmod", (event, modname) => { +ipcRenderer.on("failed-mod", (event, modname) => { setButtons(true); new Toast({ timeout: 10000, @@ -266,7 +391,17 @@ ipcRenderer.on("failedmod", (event, modname) => { }) }) -ipcRenderer.on("installedmod", (event, mod) => { +ipcRenderer.on("no-internet", (event, modname) => { + setButtons(true); + new Toast({ + timeout: 10000, + scheme: "error", + title: lang("gui.toast.noInternet.title"), + description: lang("gui.toast.noInternet.desc") + }) +}) + +ipcRenderer.on("installed-mod", (event, mod) => { setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.reinstall")); @@ -284,14 +419,21 @@ ipcRenderer.on("installedmod", (event, mod) => { title: lang("gui.toast.title.installed"), description: mod.name + " " + lang("gui.toast.desc.installed") }) + + if (installqueue.length != 0) { + installFromURL("https://thunderstore.io/package/download/" + installqueue[0]); + installqueue.shift(); + } }) function normalize(items) { let main = (string) => { - return string.replaceAll(" ", "").replaceAll(".", "").replaceAll("-", "").replaceAll("_", "").toLowerCase() + return string.replaceAll(" ", "") + .replaceAll(".", "").replaceAll("-", "") + .replaceAll("_", "").toLowerCase(); } if (typeof items == "string") { - return main(items) + return main(items); } else { let newArray = []; for (let i = 0; i < items.length; i++) { @@ -322,11 +464,50 @@ search.addEventListener("keyup", () => { } }) -browser.addEventListener("scroll", () => { - Browser.filters.toggle(false); +let events = ["scroll", "mousedown", "touchdown"]; +events.forEach((event) => { + browser.addEventListener(event, () => { + Preview.hide(); + + let mouseAt = document.elementsFromPoint(mouseX, mouseY); + if (! mouseAt.includes(document.querySelector("#filter")) + && ! mouseAt.includes(document.querySelector(".overlay"))) { + Browser.filters.toggle(false); + } + }) +}); + +view.addEventListener("dom-ready", () => { + let css = [ + fs.readFileSync(__dirname + "/css/theming.css", "utf8"), + fs.readFileSync(__dirname + "/css/webview.css", "utf8") + ] + + view.insertCSS(css.join(" ")); +}) + +view.addEventListener("did-stop-loading", () => { + view.style.display = "flex"; + setTimeout(() => { + view.classList.remove("loading"); + }, 200) +}) + +view.addEventListener("did-start-loading", () => { + view.style.display = "none"; + view.classList.add("loading"); +}) + +let mouseY = 0; +let mouseX = 0; +browser.addEventListener("mousemove", (event) => { + mouseY = event.clientY; + mouseX = event.clientX; }) let checks = document.querySelectorAll(".check"); for (let i = 0; i < checks.length; i++) { - checks[i].setAttribute("onclick", "this.classList.toggle('checked');Browser.loadfront();search.value = ''") + checks[i].setAttribute("onclick", + "this.classList.toggle('checked');Browser.loadfront();search.value = ''" + ) } |